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: 404044 $")
00042
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <strings.h>
00054 #include <netdb.h>
00055 #include <fcntl.h>
00056 #include <sys/stat.h>
00057 #include <regex.h>
00058
00059 #include "asterisk/paths.h"
00060
00061 #include "asterisk/lock.h"
00062 #include "asterisk/frame.h"
00063 #include "asterisk/channel.h"
00064 #include "asterisk/module.h"
00065 #include "asterisk/pbx.h"
00066 #include "asterisk/sched.h"
00067 #include "asterisk/io.h"
00068 #include "asterisk/config.h"
00069 #include "asterisk/cli.h"
00070 #include "asterisk/translate.h"
00071 #include "asterisk/md5.h"
00072 #include "asterisk/cdr.h"
00073 #include "asterisk/crypto.h"
00074 #include "asterisk/acl.h"
00075 #include "asterisk/manager.h"
00076 #include "asterisk/callerid.h"
00077 #include "asterisk/app.h"
00078 #include "asterisk/astdb.h"
00079 #include "asterisk/musiconhold.h"
00080 #include "asterisk/features.h"
00081 #include "asterisk/utils.h"
00082 #include "asterisk/causes.h"
00083 #include "asterisk/localtime.h"
00084 #include "asterisk/dnsmgr.h"
00085 #include "asterisk/devicestate.h"
00086 #include "asterisk/netsock.h"
00087 #include "asterisk/stringfields.h"
00088 #include "asterisk/linkedlists.h"
00089 #include "asterisk/event.h"
00090 #include "asterisk/astobj2.h"
00091 #include "asterisk/timing.h"
00092 #include "asterisk/taskprocessor.h"
00093 #include "asterisk/test.h"
00094 #include "asterisk/data.h"
00095 #include "asterisk/netsock2.h"
00096
00097 #include "iax2.h"
00098 #include "iax2-parser.h"
00099 #include "iax2-provision.h"
00100 #include "jitterbuf.h"
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 #define SCHED_MULTITHREADED
00232
00233
00234
00235 #define DEBUG_SCHED_MULTITHREAD
00236
00237
00238 #ifdef SO_NO_CHECK
00239 static int nochecksums = 0;
00240 #endif
00241
00242 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00243 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00244
00245 #define DEFAULT_THREAD_COUNT 10
00246 #define DEFAULT_MAX_THREAD_COUNT 100
00247 #define DEFAULT_RETRY_TIME 1000
00248 #define MEMORY_SIZE 100
00249 #define DEFAULT_DROP 3
00250
00251 #define DEBUG_SUPPORT
00252
00253 #define MIN_REUSE_TIME 60
00254
00255
00256 #define GAMMA (0.01)
00257
00258 static struct ast_codec_pref prefs;
00259
00260 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00261
00262
00263
00264
00265 #define MAX_TRUNK_MTU 1240
00266
00267 static int global_max_trunk_mtu;
00268 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00269
00270 #define DEFAULT_CONTEXT "default"
00271
00272 static char default_parkinglot[AST_MAX_CONTEXT];
00273
00274 static char language[MAX_LANGUAGE] = "";
00275 static char regcontext[AST_MAX_CONTEXT] = "";
00276
00277 static struct ast_event_sub *network_change_event_subscription;
00278 static int network_change_event_sched_id = -1;
00279
00280 static int maxauthreq = 3;
00281 static int max_retries = 4;
00282 static int ping_time = 21;
00283 static int lagrq_time = 10;
00284 static int maxjitterbuffer=1000;
00285 static int resyncthreshold=1000;
00286 static int maxjitterinterps=10;
00287 static int jittertargetextra = 40;
00288
00289 #define MAX_TRUNKDATA 640 * 200
00290
00291 static int trunkfreq = 20;
00292 static int trunkmaxsize = MAX_TRUNKDATA;
00293
00294 static int authdebug = 1;
00295 static int autokill = 0;
00296 static int iaxcompat = 0;
00297 static int last_authmethod = 0;
00298
00299 static int iaxdefaultdpcache=10 * 60;
00300
00301 static int iaxdefaulttimeout = 5;
00302
00303 static struct {
00304 unsigned int tos;
00305 unsigned int cos;
00306 } qos = { 0, 0 };
00307
00308 static int min_reg_expire;
00309 static int max_reg_expire;
00310
00311 static int srvlookup = 0;
00312
00313 static struct ast_timer *timer;
00314
00315 static struct ast_netsock_list *netsock;
00316 static struct ast_netsock_list *outsock;
00317 static int defaultsockfd = -1;
00318
00319 static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00320
00321
00322 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00323
00324 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00325 ~AST_FORMAT_SLINEAR & \
00326 ~AST_FORMAT_SLINEAR16 & \
00327 ~AST_FORMAT_SIREN7 & \
00328 ~AST_FORMAT_SIREN14 & \
00329 ~AST_FORMAT_G719 & \
00330 ~AST_FORMAT_ULAW & \
00331 ~AST_FORMAT_ALAW & \
00332 ~AST_FORMAT_G722)
00333
00334 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00335 ~AST_FORMAT_G726 & \
00336 ~AST_FORMAT_G726_AAL2 & \
00337 ~AST_FORMAT_ADPCM)
00338
00339 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00340 ~AST_FORMAT_G723_1)
00341
00342
00343 #define DEFAULT_MAXMS 2000
00344 #define DEFAULT_FREQ_OK 60 * 1000
00345 #define DEFAULT_FREQ_NOTOK 10 * 1000
00346
00347
00348 #define IAX_CALLENCRYPTED(pvt) \
00349 (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
00350
00351 #define IAX_DEBUGDIGEST(msg, key) do { \
00352 int idx; \
00353 char digest[33] = ""; \
00354 \
00355 if (!iaxdebug) \
00356 break; \
00357 \
00358 for (idx = 0; idx < 16; idx++) \
00359 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00360 \
00361 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00362 } while(0)
00363
00364 static struct io_context *io;
00365 static struct ast_sched_thread *sched;
00366
00367 #define DONT_RESCHEDULE -2
00368
00369 static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00370
00371 static int iaxdebug = 0;
00372
00373 static int iaxtrunkdebug = 0;
00374
00375 static int test_losspct = 0;
00376 #ifdef IAXTESTS
00377 static int test_late = 0;
00378 static int test_resync = 0;
00379 static int test_jit = 0;
00380 static int test_jitpct = 0;
00381 #endif
00382
00383 static char accountcode[AST_MAX_ACCOUNT_CODE];
00384 static char mohinterpret[MAX_MUSICCLASS];
00385 static char mohsuggest[MAX_MUSICCLASS];
00386 static int amaflags = 0;
00387 static int adsi = 0;
00388 static int delayreject = 0;
00389 static int iax2_encryption = 0;
00390
00391 static struct ast_flags64 globalflags = { 0 };
00392
00393 static pthread_t netthreadid = AST_PTHREADT_NULL;
00394
00395 enum iax2_state {
00396 IAX_STATE_STARTED = (1 << 0),
00397 IAX_STATE_AUTHENTICATED = (1 << 1),
00398 IAX_STATE_TBD = (1 << 2),
00399 };
00400
00401 struct iax2_context {
00402 char context[AST_MAX_CONTEXT];
00403 struct iax2_context *next;
00404 };
00405
00406
00407 #define IAX_HASCALLERID (uint64_t)(1 << 0)
00408 #define IAX_DELME (uint64_t)(1 << 1)
00409 #define IAX_TEMPONLY (uint64_t)(1 << 2)
00410 #define IAX_TRUNK (uint64_t)(1 << 3)
00411 #define IAX_NOTRANSFER (uint64_t)(1 << 4)
00412 #define IAX_USEJITTERBUF (uint64_t)(1 << 5)
00413 #define IAX_DYNAMIC (uint64_t)(1 << 6)
00414 #define IAX_SENDANI (uint64_t)(1 << 7)
00415 #define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8)
00416 #define IAX_ALREADYGONE (uint64_t)(1 << 9)
00417 #define IAX_PROVISION (uint64_t)(1 << 10)
00418 #define IAX_QUELCH (uint64_t)(1 << 11)
00419 #define IAX_ENCRYPTED (uint64_t)(1 << 12)
00420 #define IAX_KEYPOPULATED (uint64_t)(1 << 13)
00421 #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14)
00422 #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15)
00423 #define IAX_CODEC_NOCAP (uint64_t)(1 << 16)
00424 #define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17)
00425 #define IAX_RTUPDATE (uint64_t)(1 << 18)
00426 #define IAX_RTAUTOCLEAR (uint64_t)(1 << 19)
00427 #define IAX_FORCEJITTERBUF (uint64_t)(1 << 20)
00428 #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21)
00429 #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22)
00430 #define IAX_TRANSFERMEDIA (uint64_t)(1 << 23)
00431 #define IAX_MAXAUTHREQ (uint64_t)(1 << 24)
00432 #define IAX_DELAYPBXSTART (uint64_t)(1 << 25)
00433 #define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26)
00434 #define IAX_IMMEDIATE (uint64_t)(1 << 27)
00435 #define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28)
00436 #define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29)
00437 #define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30)
00438 #define IAX_SHRINKCALLERID (uint64_t)(1 << 31)
00439 static int global_rtautoclear = 120;
00440
00441 static int reload_config(void);
00442
00443
00444
00445
00446 enum calltoken_peer_enum {
00447
00448 CALLTOKEN_DEFAULT = 0,
00449
00450 CALLTOKEN_YES = 1,
00451
00452
00453 CALLTOKEN_AUTO = 2,
00454
00455 CALLTOKEN_NO = 3,
00456 };
00457
00458 struct iax2_user {
00459 AST_DECLARE_STRING_FIELDS(
00460 AST_STRING_FIELD(name);
00461 AST_STRING_FIELD(secret);
00462 AST_STRING_FIELD(dbsecret);
00463 AST_STRING_FIELD(accountcode);
00464 AST_STRING_FIELD(mohinterpret);
00465 AST_STRING_FIELD(mohsuggest);
00466 AST_STRING_FIELD(inkeys);
00467 AST_STRING_FIELD(language);
00468 AST_STRING_FIELD(cid_num);
00469 AST_STRING_FIELD(cid_name);
00470 AST_STRING_FIELD(parkinglot);
00471 );
00472
00473 int authmethods;
00474 int encmethods;
00475 int amaflags;
00476 int adsi;
00477 uint64_t flags;
00478 format_t capability;
00479 int maxauthreq;
00480 int curauthreq;
00481 struct ast_codec_pref prefs;
00482 struct ast_ha *ha;
00483 struct iax2_context *contexts;
00484 struct ast_variable *vars;
00485 enum calltoken_peer_enum calltoken_required;
00486 };
00487
00488 struct iax2_peer {
00489 AST_DECLARE_STRING_FIELDS(
00490 AST_STRING_FIELD(name);
00491 AST_STRING_FIELD(username);
00492 AST_STRING_FIELD(secret);
00493 AST_STRING_FIELD(dbsecret);
00494 AST_STRING_FIELD(outkey);
00495
00496 AST_STRING_FIELD(regexten);
00497 AST_STRING_FIELD(context);
00498 AST_STRING_FIELD(peercontext);
00499 AST_STRING_FIELD(mailbox);
00500 AST_STRING_FIELD(mohinterpret);
00501 AST_STRING_FIELD(mohsuggest);
00502 AST_STRING_FIELD(inkeys);
00503
00504 AST_STRING_FIELD(cid_num);
00505 AST_STRING_FIELD(cid_name);
00506 AST_STRING_FIELD(zonetag);
00507 AST_STRING_FIELD(parkinglot);
00508 );
00509 struct ast_codec_pref prefs;
00510 struct ast_dnsmgr_entry *dnsmgr;
00511 struct ast_sockaddr addr;
00512 int formats;
00513 int sockfd;
00514 struct in_addr mask;
00515 int adsi;
00516 uint64_t flags;
00517
00518
00519 struct sockaddr_in defaddr;
00520 int authmethods;
00521 int encmethods;
00522
00523 int expire;
00524 int expiry;
00525 format_t capability;
00526
00527
00528 int callno;
00529 int pokeexpire;
00530 int lastms;
00531 int maxms;
00532
00533 int pokefreqok;
00534 int pokefreqnotok;
00535 int historicms;
00536 int smoothing;
00537 uint16_t maxcallno;
00538
00539 struct ast_event_sub *mwi_event_sub;
00540
00541 struct ast_ha *ha;
00542 enum calltoken_peer_enum calltoken_required;
00543 };
00544
00545 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00546
00547 struct iax2_trunk_peer {
00548 ast_mutex_t lock;
00549 int sockfd;
00550 struct sockaddr_in addr;
00551 struct timeval txtrunktime;
00552 struct timeval rxtrunktime;
00553 struct timeval lasttxtime;
00554 struct timeval trunkact;
00555 unsigned int lastsent;
00556
00557 unsigned char *trunkdata;
00558 unsigned int trunkdatalen;
00559 unsigned int trunkdataalloc;
00560 int trunkmaxmtu;
00561 int trunkerror;
00562 int calls;
00563 AST_LIST_ENTRY(iax2_trunk_peer) list;
00564 };
00565
00566 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00567
00568 struct iax_firmware {
00569 AST_LIST_ENTRY(iax_firmware) list;
00570 int fd;
00571 int mmaplen;
00572 int dead;
00573 struct ast_iax2_firmware_header *fwh;
00574 unsigned char *buf;
00575 };
00576
00577 enum iax_reg_state {
00578 REG_STATE_UNREGISTERED = 0,
00579 REG_STATE_REGSENT,
00580 REG_STATE_AUTHSENT,
00581 REG_STATE_REGISTERED,
00582 REG_STATE_REJECTED,
00583 REG_STATE_TIMEOUT,
00584 REG_STATE_NOAUTH
00585 };
00586
00587 enum iax_transfer_state {
00588 TRANSFER_NONE = 0,
00589 TRANSFER_BEGIN,
00590 TRANSFER_READY,
00591 TRANSFER_RELEASED,
00592 TRANSFER_PASSTHROUGH,
00593 TRANSFER_MBEGIN,
00594 TRANSFER_MREADY,
00595 TRANSFER_MRELEASED,
00596 TRANSFER_MPASSTHROUGH,
00597 TRANSFER_MEDIA,
00598 TRANSFER_MEDIAPASS
00599 };
00600
00601 struct iax2_registry {
00602 struct ast_sockaddr addr;
00603 char username[80];
00604 char secret[80];
00605 int expire;
00606 int refresh;
00607 enum iax_reg_state regstate;
00608 int messages;
00609 int callno;
00610 struct sockaddr_in us;
00611 struct ast_dnsmgr_entry *dnsmgr;
00612 AST_LIST_ENTRY(iax2_registry) entry;
00613 };
00614
00615 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00616
00617
00618 #define MIN_RETRY_TIME 100
00619 #define MAX_RETRY_TIME 10000
00620
00621 #define MAX_JITTER_BUFFER 50
00622 #define MIN_JITTER_BUFFER 10
00623
00624 #define DEFAULT_TRUNKDATA 640 * 10
00625
00626 #define MAX_TIMESTAMP_SKEW 160
00627
00628
00629 #define TS_GAP_FOR_JB_RESYNC 5000
00630
00631
00632 #define MARK_IAX_SUBCLASS_TX 0x8000
00633
00634 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00635 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00636 static int iaxdynamicthreadcount = 0;
00637 static int iaxdynamicthreadnum = 0;
00638 static int iaxactivethreadcount = 0;
00639
00640 struct iax_rr {
00641 int jitter;
00642 int losspct;
00643 int losscnt;
00644 int packets;
00645 int delay;
00646 int dropped;
00647 int ooo;
00648 };
00649
00650 struct iax2_pvt_ref;
00651
00652 struct chan_iax2_pvt {
00653
00654 int sockfd;
00655
00656 format_t voiceformat;
00657
00658 format_t videoformat;
00659
00660 format_t svoiceformat;
00661
00662 format_t svideoformat;
00663
00664 format_t capability;
00665
00666 unsigned int last;
00667
00668 unsigned int lastsent;
00669
00670 unsigned int lastvsent;
00671
00672 unsigned int nextpred;
00673
00674 int first_iax_message;
00675
00676 int last_iax_message;
00677
00678 unsigned int notsilenttx:1;
00679
00680 unsigned int pingtime;
00681
00682 int maxtime;
00683
00684 struct sockaddr_in addr;
00685
00686 struct ast_codec_pref prefs;
00687
00688 struct ast_codec_pref rprefs;
00689
00690 unsigned short callno;
00691
00692 struct callno_entry *callno_entry;
00693
00694 unsigned short peercallno;
00695
00696
00697
00698 format_t chosenformat;
00699
00700 format_t peerformat;
00701
00702 format_t peercapability;
00703
00704 struct timeval offset;
00705
00706 struct timeval rxcore;
00707
00708 jitterbuf *jb;
00709
00710 int jbid;
00711
00712 int lag;
00713
00714 int error;
00715
00716 struct ast_channel *owner;
00717
00718 struct ast_flags state;
00719
00720 int expiry;
00721
00722 unsigned char oseqno;
00723
00724 unsigned char rseqno;
00725
00726 unsigned char iseqno;
00727
00728 unsigned char aseqno;
00729
00730 AST_DECLARE_STRING_FIELDS(
00731
00732 AST_STRING_FIELD(peer);
00733
00734 AST_STRING_FIELD(context);
00735
00736 AST_STRING_FIELD(cid_num);
00737 AST_STRING_FIELD(cid_name);
00738
00739 AST_STRING_FIELD(ani);
00740
00741 AST_STRING_FIELD(dnid);
00742
00743 AST_STRING_FIELD(rdnis);
00744
00745 AST_STRING_FIELD(exten);
00746
00747 AST_STRING_FIELD(username);
00748
00749 AST_STRING_FIELD(secret);
00750
00751 AST_STRING_FIELD(challenge);
00752
00753 AST_STRING_FIELD(inkeys);
00754
00755 AST_STRING_FIELD(outkey);
00756
00757 AST_STRING_FIELD(language);
00758
00759 AST_STRING_FIELD(host);
00760
00761 AST_STRING_FIELD(dproot);
00762 AST_STRING_FIELD(accountcode);
00763 AST_STRING_FIELD(mohinterpret);
00764 AST_STRING_FIELD(mohsuggest);
00765
00766 AST_STRING_FIELD(osptoken);
00767
00768 AST_STRING_FIELD(parkinglot);
00769 );
00770
00771 int authrej;
00772
00773 int authmethods;
00774
00775 int encmethods;
00776
00777 ast_aes_encrypt_key ecx;
00778
00779 ast_aes_decrypt_key mydcx;
00780
00781 ast_aes_decrypt_key dcx;
00782
00783
00784 int keyrotateid;
00785
00786 unsigned char semirand[32];
00787
00788 struct iax2_registry *reg;
00789
00790 struct iax2_peer *peerpoke;
00791
00792 uint64_t flags;
00793 int adsi;
00794
00795
00796 enum iax_transfer_state transferring;
00797
00798 int transferid;
00799
00800 struct sockaddr_in transfer;
00801
00802 unsigned short transfercallno;
00803
00804 ast_aes_encrypt_key tdcx;
00805
00806
00807 int peeradsicpe;
00808
00809
00810 unsigned short bridgecallno;
00811
00812 int pingid;
00813 int lagid;
00814 int autoid;
00815 int authid;
00816 int authfail;
00817 int initid;
00818 int calling_ton;
00819 int calling_tns;
00820 int calling_pres;
00821 int amaflags;
00822 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00823
00824 struct ast_variable *vars;
00825
00826 struct ast_variable *iaxvars;
00827
00828 struct iax_rr remote_rr;
00829
00830 int min;
00831
00832 int frames_dropped;
00833
00834 int frames_received;
00835
00836 unsigned char calltoken_ie_len;
00837
00838 char hold_signaling;
00839
00840 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00841 };
00842
00843 struct signaling_queue_entry {
00844 struct ast_frame f;
00845 AST_LIST_ENTRY(signaling_queue_entry) next;
00846 };
00847
00848
00849 static struct ao2_container *callno_pool;
00850
00851
00852 static struct ao2_container *callno_pool_trunk;
00853
00854 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865 static AST_LIST_HEAD_NOLOCK(, iax_frame) frame_queue[IAX_MAX_CALLS];
00866
00867 static struct ast_taskprocessor *transmit_processor;
00868
00869 static int randomcalltokendata;
00870
00871 static const time_t MAX_CALLTOKEN_DELAY = 10;
00872
00873
00874
00875
00876
00877
00878
00879
00880 #ifdef LOW_MEMORY
00881 #define MAX_PEER_BUCKETS 17
00882 #else
00883 #define MAX_PEER_BUCKETS 563
00884 #endif
00885 static struct ao2_container *peers;
00886
00887 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00888 static struct ao2_container *users;
00889
00890
00891 static struct ao2_container *peercnts;
00892
00893
00894 static struct ao2_container *callno_limits;
00895
00896
00897 static struct ao2_container *calltoken_ignores;
00898
00899 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00900
00901 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00902
00903 static uint16_t global_maxcallno;
00904
00905
00906 static uint16_t global_maxcallno_nonval;
00907
00908 static uint16_t total_nonval_callno_used = 0;
00909
00910
00911
00912 struct peercnt {
00913
00914 unsigned long addr;
00915
00916 uint16_t cur;
00917
00918 uint16_t limit;
00919
00920
00921 unsigned char reg;
00922 };
00923
00924
00925 struct addr_range {
00926
00927 struct ast_ha ha;
00928
00929 uint16_t limit;
00930
00931 unsigned char delme;
00932 };
00933
00934 struct callno_entry {
00935
00936 uint16_t callno;
00937
00938 unsigned char validated;
00939 };
00940
00941 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00942
00943 enum {
00944
00945 CACHE_FLAG_EXISTS = (1 << 0),
00946
00947 CACHE_FLAG_NONEXISTENT = (1 << 1),
00948
00949 CACHE_FLAG_CANEXIST = (1 << 2),
00950
00951 CACHE_FLAG_PENDING = (1 << 3),
00952
00953 CACHE_FLAG_TIMEOUT = (1 << 4),
00954
00955 CACHE_FLAG_TRANSMITTED = (1 << 5),
00956
00957 CACHE_FLAG_UNKNOWN = (1 << 6),
00958
00959 CACHE_FLAG_MATCHMORE = (1 << 7),
00960 };
00961
00962 struct iax2_dpcache {
00963 char peercontext[AST_MAX_CONTEXT];
00964 char exten[AST_MAX_EXTENSION];
00965 struct timeval orig;
00966 struct timeval expiry;
00967 int flags;
00968 unsigned short callno;
00969 int waiters[256];
00970 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00971 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00972 };
00973
00974 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00975
00976 static void reg_source_db(struct iax2_peer *p);
00977 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00978 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00979
00980 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00981 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags);
00982 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00983
00984 enum iax2_thread_iostate {
00985 IAX_IOSTATE_IDLE,
00986 IAX_IOSTATE_READY,
00987 IAX_IOSTATE_PROCESSING,
00988 IAX_IOSTATE_SCHEDREADY,
00989 };
00990
00991 enum iax2_thread_type {
00992 IAX_THREAD_TYPE_POOL,
00993 IAX_THREAD_TYPE_DYNAMIC,
00994 };
00995
00996 struct iax2_pkt_buf {
00997 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00998 size_t len;
00999 unsigned char buf[1];
01000 };
01001
01002 struct iax2_thread {
01003 AST_LIST_ENTRY(iax2_thread) list;
01004 enum iax2_thread_type type;
01005 enum iax2_thread_iostate iostate;
01006 #ifdef SCHED_MULTITHREADED
01007 void (*schedfunc)(const void *);
01008 const void *scheddata;
01009 #endif
01010 #ifdef DEBUG_SCHED_MULTITHREAD
01011 char curfunc[80];
01012 #endif
01013 int actions;
01014 pthread_t threadid;
01015 int threadnum;
01016 struct sockaddr_in iosin;
01017 unsigned char readbuf[4096];
01018 unsigned char *buf;
01019 ssize_t buf_len;
01020 size_t buf_size;
01021 int iofd;
01022 time_t checktime;
01023 ast_mutex_t lock;
01024 ast_cond_t cond;
01025 ast_mutex_t init_lock;
01026 ast_cond_t init_cond;
01027
01028
01029
01030
01031 struct {
01032 unsigned short callno;
01033 struct sockaddr_in sin;
01034 unsigned char type;
01035 unsigned char csub;
01036 } ffinfo;
01037
01038
01039
01040 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
01041 unsigned char stop;
01042 };
01043
01044
01045 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
01046 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
01047 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
01048
01049 static void *iax2_process_thread(void *data);
01050 static void iax2_destroy(int callno);
01051
01052 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
01053 {
01054 ast_mutex_lock(lock);
01055 ast_cond_signal(cond);
01056 ast_mutex_unlock(lock);
01057 }
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 static struct ao2_container *iax_peercallno_pvts;
01079
01080
01081
01082
01083
01084
01085
01086
01087 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
01088
01089
01090
01091
01092
01093
01094 static struct ao2_container *iax_transfercallno_pvts;
01095
01096
01097
01098 #define TRUNK_CALL_START (IAX_MAX_CALLS / 2)
01099
01100
01101 static struct sockaddr_in debugaddr;
01102
01103 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
01104 {
01105 if (iaxdebug ||
01106 (sin && debugaddr.sin_addr.s_addr &&
01107 (!ntohs(debugaddr.sin_port) ||
01108 debugaddr.sin_port == sin->sin_port) &&
01109 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01110 if (iaxdebug) {
01111 iax_showframe(f, fhi, rx, sin, datalen);
01112 } else {
01113 iaxdebug = 1;
01114 iax_showframe(f, fhi, rx, sin, datalen);
01115 iaxdebug = 0;
01116 }
01117 }
01118 }
01119
01120 static void iax_debug_output(const char *data)
01121 {
01122 if (iaxdebug)
01123 ast_verbose("%s", data);
01124 }
01125
01126 static void iax_error_output(const char *data)
01127 {
01128 ast_log(LOG_WARNING, "%s", data);
01129 }
01130
01131 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
01132 {
01133 va_list args;
01134 char buf[1024];
01135
01136 va_start(args, fmt);
01137 vsnprintf(buf, sizeof(buf), fmt, args);
01138 va_end(args);
01139
01140 ast_log(LOG_ERROR, "%s", buf);
01141 }
01142
01143 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01144 {
01145 va_list args;
01146 char buf[1024];
01147
01148 va_start(args, fmt);
01149 vsnprintf(buf, sizeof(buf), fmt, args);
01150 va_end(args);
01151
01152 ast_log(LOG_WARNING, "%s", buf);
01153 }
01154
01155 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01156 {
01157 va_list args;
01158 char buf[1024];
01159
01160 va_start(args, fmt);
01161 vsnprintf(buf, sizeof(buf), fmt, args);
01162 va_end(args);
01163
01164 ast_verbose("%s", buf);
01165 }
01166
01167 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
01168 static int expire_registry(const void *data);
01169 static int iax2_answer(struct ast_channel *c);
01170 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01171 static int iax2_devicestate(void *data);
01172 static int iax2_digit_begin(struct ast_channel *c, char digit);
01173 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01174 static int iax2_do_register(struct iax2_registry *reg);
01175 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01176 static int iax2_hangup(struct ast_channel *c);
01177 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01178 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01179 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force);
01180 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01181 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01182 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01183 static int iax2_sendtext(struct ast_channel *c, const char *text);
01184 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01185 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen);
01186 static int iax2_transfer(struct ast_channel *c, const char *dest);
01187 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01188 static int iax2_sched_add(struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data);
01189
01190 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01191 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01192 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01193 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01194 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01195 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01196 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
01197 static struct ast_frame *iax2_read(struct ast_channel *c);
01198 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01199 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01200 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime);
01201 static void *iax2_dup_variable_datastore(void *);
01202 static void prune_peers(void);
01203 static void prune_users(void);
01204 static void iax2_free_variable_datastore(void *);
01205
01206 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01207 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01208 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01209 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01210 static void build_rand_pad(unsigned char *buf, ssize_t len);
01211 static struct callno_entry *get_unused_callno(int trunk, int validated);
01212 static int replace_callno(const void *obj);
01213 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01214 static void network_change_event_cb(const struct ast_event *, void *);
01215
01216 static const struct ast_channel_tech iax2_tech = {
01217 .type = "IAX2",
01218 .description = tdesc,
01219 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01220 .properties = AST_CHAN_TP_WANTSJITTER,
01221 .requester = iax2_request,
01222 .devicestate = iax2_devicestate,
01223 .send_digit_begin = iax2_digit_begin,
01224 .send_digit_end = iax2_digit_end,
01225 .send_text = iax2_sendtext,
01226 .send_image = iax2_sendimage,
01227 .send_html = iax2_sendhtml,
01228 .call = iax2_call,
01229 .hangup = iax2_hangup,
01230 .answer = iax2_answer,
01231 .read = iax2_read,
01232 .write = iax2_write,
01233 .write_video = iax2_write,
01234 .indicate = iax2_indicate,
01235 .setoption = iax2_setoption,
01236 .queryoption = iax2_queryoption,
01237 .bridge = iax2_bridge,
01238 .transfer = iax2_transfer,
01239 .fixup = iax2_fixup,
01240 .func_channel_read = acf_channel_read,
01241 };
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260 static void iax2_lock_owner(int callno)
01261 {
01262 for (;;) {
01263 if (!iaxs[callno] || !iaxs[callno]->owner) {
01264
01265 break;
01266 }
01267 if (!ast_channel_trylock(iaxs[callno]->owner)) {
01268
01269 break;
01270 }
01271
01272 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01273 }
01274 }
01275
01276 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 const 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;
01464 static time_t lasterror;
01465 time_t t;
01466
01467 thread = find_idle_thread();
01468 if (thread != NULL) {
01469 thread->schedfunc = func;
01470 thread->scheddata = data;
01471 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01472 #ifdef DEBUG_SCHED_MULTITHREAD
01473 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01474 #endif
01475 signal_condition(&thread->lock, &thread->cond);
01476 return 0;
01477 }
01478 time(&t);
01479 if (t != lasterror) {
01480 lasterror = t;
01481 ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname);
01482 }
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
02408
02409
02410
02411
02412
02413 ao2_lock(peercnts);
02414 peercnt->cur--;
02415 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02416
02417 if (peercnt->cur == 0) {
02418 ao2_unlink(peercnts, peercnt);
02419 }
02420 ao2_unlock(peercnts);
02421 }
02422
02423
02424
02425
02426
02427 static int peercnt_remove_cb(const void *obj)
02428 {
02429 struct peercnt *peercnt = (struct peercnt *) obj;
02430
02431 peercnt_remove(peercnt);
02432 ao2_ref(peercnt, -1);
02433
02434 return 0;
02435 }
02436
02437
02438
02439
02440
02441 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02442 {
02443 struct peercnt *peercnt;
02444 struct peercnt tmp = {
02445 .addr = sin->sin_addr.s_addr,
02446 };
02447
02448 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02449 peercnt_remove(peercnt);
02450 ao2_ref(peercnt, -1);
02451 }
02452 return 0;
02453 }
02454
02455
02456
02457
02458
02459 static void build_callno_limits(struct ast_variable *v)
02460 {
02461 struct addr_range *addr_range = NULL;
02462 struct addr_range tmp;
02463 struct ast_ha *ha;
02464 int limit;
02465 int error;
02466 int found;
02467
02468 for (; v; v = v->next) {
02469 limit = -1;
02470 error = 0;
02471 found = 0;
02472 ha = ast_append_ha("permit", v->name, NULL, &error);
02473
02474
02475 if (error) {
02476 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02477 continue;
02478 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02479 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02480 ast_free_ha(ha);
02481 continue;
02482 }
02483
02484 ast_copy_ha(ha, &tmp.ha);
02485
02486 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02487 ao2_lock(addr_range);
02488 found = 1;
02489 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02490 ast_free_ha(ha);
02491 return;
02492 }
02493
02494
02495 ast_copy_ha(ha, &addr_range->ha);
02496 ast_free_ha(ha);
02497 addr_range->limit = limit;
02498 addr_range->delme = 0;
02499
02500
02501 if (found) {
02502 ao2_unlock(addr_range);
02503 } else {
02504 ao2_link(callno_limits, addr_range);
02505 }
02506 ao2_ref(addr_range, -1);
02507 }
02508 }
02509
02510
02511
02512
02513
02514 static int add_calltoken_ignore(const char *addr)
02515 {
02516 struct addr_range tmp;
02517 struct addr_range *addr_range = NULL;
02518 struct ast_ha *ha = NULL;
02519 int error = 0;
02520
02521 if (ast_strlen_zero(addr)) {
02522 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02523 return -1;
02524 }
02525
02526 ha = ast_append_ha("permit", addr, NULL, &error);
02527
02528
02529 if (error) {
02530 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02531 return -1;
02532 }
02533
02534 ast_copy_ha(ha, &tmp.ha);
02535
02536 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02537 ao2_lock(addr_range);
02538 addr_range->delme = 0;
02539 ao2_unlock(addr_range);
02540 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02541
02542 ast_copy_ha(ha, &addr_range->ha);
02543 ao2_link(calltoken_ignores, addr_range);
02544 } else {
02545 ast_free_ha(ha);
02546 return -1;
02547 }
02548
02549 ast_free_ha(ha);
02550 ao2_ref(addr_range, -1);
02551
02552 return 0;
02553 }
02554
02555 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02556 {
02557 struct ao2_iterator i;
02558 struct peercnt *peercnt;
02559 struct sockaddr_in sin;
02560 int found = 0;
02561
02562 switch (cmd) {
02563 case CLI_INIT:
02564 e->command = "iax2 show callnumber usage";
02565 e->usage =
02566 "Usage: iax2 show callnumber usage [IP address]\n"
02567 " Shows current IP addresses which are consuming iax2 call numbers\n";
02568 return NULL;
02569 case CLI_GENERATE:
02570 return NULL;
02571 case CLI_HANDLER:
02572 if (a->argc < 4 || a->argc > 5)
02573 return CLI_SHOWUSAGE;
02574
02575 if (a->argc == 4) {
02576 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02577 }
02578
02579 i = ao2_iterator_init(peercnts, 0);
02580 while ((peercnt = ao2_iterator_next(&i))) {
02581 sin.sin_addr.s_addr = peercnt->addr;
02582 if (a->argc == 5) {
02583 if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) {
02584 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02585 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02586 ao2_ref(peercnt, -1);
02587 found = 1;
02588 break;
02589 }
02590 } else {
02591 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02592 }
02593 ao2_ref(peercnt, -1);
02594 }
02595 ao2_iterator_destroy(&i);
02596
02597 if (a->argc == 4) {
02598 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02599 "Non-CallToken Validated Callno Used: %d\n",
02600 global_maxcallno_nonval,
02601 total_nonval_callno_used);
02602
02603 ast_cli(a->fd, "Total Available Callno: %d\n"
02604 "Regular Callno Available: %d\n"
02605 "Trunk Callno Available: %d\n",
02606 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02607 ao2_container_count(callno_pool),
02608 ao2_container_count(callno_pool_trunk));
02609 } else if (a->argc == 5 && !found) {
02610 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] );
02611 }
02612
02613
02614 return CLI_SUCCESS;
02615 default:
02616 return NULL;
02617 }
02618 }
02619
02620 static struct callno_entry *get_unused_callno(int trunk, int validated)
02621 {
02622 struct callno_entry *callno_entry = NULL;
02623 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02624 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02625
02626 return NULL;
02627 }
02628
02629
02630
02631 ao2_lock(callno_pool);
02632
02633
02634
02635
02636 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02637 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02638 ao2_unlock(callno_pool);
02639 return NULL;
02640 }
02641
02642
02643
02644 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02645
02646 if (callno_entry) {
02647 callno_entry->validated = validated;
02648 if (!validated) {
02649 total_nonval_callno_used++;
02650 }
02651 }
02652
02653 ao2_unlock(callno_pool);
02654 return callno_entry;
02655 }
02656
02657 static int replace_callno(const void *obj)
02658 {
02659 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02660
02661
02662
02663 ao2_lock(callno_pool);
02664
02665 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02666 total_nonval_callno_used--;
02667 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02668 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02669 }
02670
02671 if (callno_entry->callno < TRUNK_CALL_START) {
02672 ao2_link(callno_pool, callno_entry);
02673 } else {
02674 ao2_link(callno_pool_trunk, callno_entry);
02675 }
02676 ao2_ref(callno_entry, -1);
02677
02678 ao2_unlock(callno_pool);
02679 return 0;
02680 }
02681
02682 static int callno_hash(const void *obj, const int flags)
02683 {
02684 return abs(ast_random());
02685 }
02686
02687 static int create_callno_pools(void)
02688 {
02689 uint16_t i;
02690
02691 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02692 return -1;
02693 }
02694
02695 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02696 return -1;
02697 }
02698
02699
02700 for (i = 2; i < IAX_MAX_CALLS; i++) {
02701 struct callno_entry *callno_entry;
02702
02703 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02704 return -1;
02705 }
02706
02707 callno_entry->callno = i;
02708
02709 if (i < TRUNK_CALL_START) {
02710 ao2_link(callno_pool, callno_entry);
02711 } else {
02712 ao2_link(callno_pool_trunk, callno_entry);
02713 }
02714
02715 ao2_ref(callno_entry, -1);
02716 }
02717
02718 return 0;
02719 }
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02730 {
02731 int i;
02732 struct peercnt *peercnt;
02733 struct peercnt tmp = {
02734 .addr = sin->sin_addr.s_addr,
02735 };
02736
02737 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02738
02739 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02740 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02741 if (i == -1) {
02742 ao2_ref(peercnt, -1);
02743 }
02744 }
02745
02746 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02747 }
02748
02749
02750
02751
02752
02753
02754
02755
02756 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02757 {
02758 if (frametype != AST_FRAME_IAX) {
02759 return 0;
02760 }
02761 switch (subclass) {
02762 case IAX_COMMAND_NEW:
02763 case IAX_COMMAND_REGREQ:
02764 case IAX_COMMAND_FWDOWNL:
02765 case IAX_COMMAND_REGREL:
02766 return 1;
02767 case IAX_COMMAND_POKE:
02768 if (!inbound) {
02769 return 1;
02770 }
02771 break;
02772 }
02773 return 0;
02774 }
02775
02776
02777
02778
02779 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02780 {
02781 int res = 0;
02782 int x;
02783
02784
02785 int validated = (new > NEW_ALLOW) ? 1 : 0;
02786 char host[80];
02787
02788 if (new <= NEW_ALLOW) {
02789 if (callno) {
02790 struct chan_iax2_pvt *pvt;
02791 struct chan_iax2_pvt tmp_pvt = {
02792 .callno = dcallno,
02793 .peercallno = callno,
02794 .transfercallno = callno,
02795
02796 .frames_received = check_dcallno,
02797 };
02798
02799 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02800
02801 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02802 if (return_locked) {
02803 ast_mutex_lock(&iaxsl[pvt->callno]);
02804 }
02805 res = pvt->callno;
02806 ao2_ref(pvt, -1);
02807 pvt = NULL;
02808 return res;
02809 }
02810
02811 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02812 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02813 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02814 if (return_locked) {
02815 ast_mutex_lock(&iaxsl[pvt->callno]);
02816 }
02817 res = pvt->callno;
02818 ao2_ref(pvt, -1);
02819 pvt = NULL;
02820 return res;
02821 }
02822 }
02823
02824
02825 if (dcallno) {
02826 ast_mutex_lock(&iaxsl[dcallno]);
02827 }
02828 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02829 iaxs[dcallno]->peercallno = callno;
02830 res = dcallno;
02831 store_by_peercallno(iaxs[dcallno]);
02832 if (!res || !return_locked) {
02833 ast_mutex_unlock(&iaxsl[dcallno]);
02834 }
02835 return res;
02836 }
02837 if (dcallno) {
02838 ast_mutex_unlock(&iaxsl[dcallno]);
02839 }
02840 #ifdef IAX_OLD_FIND
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852 for (x = 1; !res && x < maxnontrunkcall; x++) {
02853 ast_mutex_lock(&iaxsl[x]);
02854 if (iaxs[x]) {
02855
02856 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02857 res = x;
02858 }
02859 }
02860 if (!res || !return_locked)
02861 ast_mutex_unlock(&iaxsl[x]);
02862 }
02863 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02864 ast_mutex_lock(&iaxsl[x]);
02865 if (iaxs[x]) {
02866
02867 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02868 res = x;
02869 }
02870 }
02871 if (!res || !return_locked)
02872 ast_mutex_unlock(&iaxsl[x]);
02873 }
02874 #endif
02875 }
02876 if (!res && (new >= NEW_ALLOW)) {
02877 struct callno_entry *callno_entry;
02878
02879
02880
02881
02882
02883
02884 if (!iax2_getpeername(*sin, host, sizeof(host)))
02885 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02886
02887 if (peercnt_add(sin)) {
02888
02889
02890 return 0;
02891 }
02892
02893 if (!(callno_entry = get_unused_callno(0, validated))) {
02894
02895
02896 peercnt_remove_by_addr(sin);
02897 ast_log(LOG_WARNING, "No more space\n");
02898 return 0;
02899 }
02900 x = callno_entry->callno;
02901 ast_mutex_lock(&iaxsl[x]);
02902
02903 iaxs[x] = new_iax(sin, host);
02904 update_max_nontrunk();
02905 if (iaxs[x]) {
02906 if (iaxdebug)
02907 ast_debug(1, "Creating new call structure %d\n", x);
02908 iaxs[x]->callno_entry = callno_entry;
02909 iaxs[x]->sockfd = sockfd;
02910 iaxs[x]->addr.sin_port = sin->sin_port;
02911 iaxs[x]->addr.sin_family = sin->sin_family;
02912 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02913 iaxs[x]->peercallno = callno;
02914 iaxs[x]->callno = x;
02915 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02916 iaxs[x]->expiry = min_reg_expire;
02917 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02918 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02919 iaxs[x]->amaflags = amaflags;
02920 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02921 ast_string_field_set(iaxs[x], accountcode, accountcode);
02922 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02923 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02924 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02925
02926 if (iaxs[x]->peercallno) {
02927 store_by_peercallno(iaxs[x]);
02928 }
02929 } else {
02930 ast_log(LOG_WARNING, "Out of resources\n");
02931 ast_mutex_unlock(&iaxsl[x]);
02932 replace_callno(callno_entry);
02933 return 0;
02934 }
02935 if (!return_locked)
02936 ast_mutex_unlock(&iaxsl[x]);
02937 res = x;
02938 }
02939 return res;
02940 }
02941
02942 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02943 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02944 }
02945
02946 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02947
02948 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02949 }
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960
02961 static int iax2_queue_frame(int callno, struct ast_frame *f)
02962 {
02963 iax2_lock_owner(callno);
02964 if (iaxs[callno] && iaxs[callno]->owner) {
02965 ast_queue_frame(iaxs[callno]->owner, f);
02966 ast_channel_unlock(iaxs[callno]->owner);
02967 }
02968 return 0;
02969 }
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983
02984 static int iax2_queue_hangup(int callno)
02985 {
02986 iax2_lock_owner(callno);
02987 if (iaxs[callno] && iaxs[callno]->owner) {
02988 ast_queue_hangup(iaxs[callno]->owner);
02989 ast_channel_unlock(iaxs[callno]->owner);
02990 }
02991 return 0;
02992 }
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007 static int iax2_queue_control_data(int callno,
03008 enum ast_control_frame_type control, const void *data, size_t datalen)
03009 {
03010 iax2_lock_owner(callno);
03011 if (iaxs[callno] && iaxs[callno]->owner) {
03012 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
03013 ast_channel_unlock(iaxs[callno]->owner);
03014 }
03015 return 0;
03016 }
03017 static void destroy_firmware(struct iax_firmware *cur)
03018 {
03019
03020 if (cur->fwh) {
03021 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
03022 }
03023 close(cur->fd);
03024 ast_free(cur);
03025 }
03026
03027 static int try_firmware(char *s)
03028 {
03029 struct stat stbuf;
03030 struct iax_firmware *cur = NULL;
03031 int ifd, fd, res, len, chunk;
03032 struct ast_iax2_firmware_header *fwh, fwh2;
03033 struct MD5Context md5;
03034 unsigned char sum[16], buf[1024];
03035 char *s2, *last;
03036
03037 s2 = ast_alloca(strlen(s) + 100);
03038
03039 last = strrchr(s, '/');
03040 if (last)
03041 last++;
03042 else
03043 last = s;
03044
03045 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03046
03047 if ((res = stat(s, &stbuf) < 0)) {
03048 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03049 return -1;
03050 }
03051
03052
03053 if (S_ISDIR(stbuf.st_mode))
03054 return -1;
03055 ifd = open(s, O_RDONLY);
03056 if (ifd < 0) {
03057 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03058 return -1;
03059 }
03060 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03061 if (fd < 0) {
03062 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03063 close(ifd);
03064 return -1;
03065 }
03066
03067 unlink(s2);
03068
03069
03070 len = stbuf.st_size;
03071 while(len) {
03072 chunk = len;
03073 if (chunk > sizeof(buf))
03074 chunk = sizeof(buf);
03075 res = read(ifd, buf, chunk);
03076 if (res != chunk) {
03077 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03078 close(ifd);
03079 close(fd);
03080 return -1;
03081 }
03082 res = write(fd, buf, chunk);
03083 if (res != chunk) {
03084 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03085 close(ifd);
03086 close(fd);
03087 return -1;
03088 }
03089 len -= chunk;
03090 }
03091 close(ifd);
03092
03093 lseek(fd, 0, SEEK_SET);
03094 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03095 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03096 close(fd);
03097 return -1;
03098 }
03099 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03100 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03101 close(fd);
03102 return -1;
03103 }
03104 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03105 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03106 close(fd);
03107 return -1;
03108 }
03109 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03110 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03111 close(fd);
03112 return -1;
03113 }
03114 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
03115 if (fwh == MAP_FAILED) {
03116 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03117 close(fd);
03118 return -1;
03119 }
03120 MD5Init(&md5);
03121 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03122 MD5Final(sum, &md5);
03123 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03124 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03125 munmap((void*)fwh, stbuf.st_size);
03126 close(fd);
03127 return -1;
03128 }
03129
03130 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03131 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03132
03133 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03134
03135 break;
03136
03137
03138 munmap((void*)fwh, stbuf.st_size);
03139 close(fd);
03140 return 0;
03141 }
03142 }
03143
03144 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03145 cur->fd = -1;
03146 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03147 }
03148
03149 if (cur) {
03150 if (cur->fwh)
03151 munmap((void*)cur->fwh, cur->mmaplen);
03152 if (cur->fd > -1)
03153 close(cur->fd);
03154 cur->fwh = fwh;
03155 cur->fd = fd;
03156 cur->mmaplen = stbuf.st_size;
03157 cur->dead = 0;
03158 }
03159
03160 return 0;
03161 }
03162
03163 static int iax_check_version(char *dev)
03164 {
03165 int res = 0;
03166 struct iax_firmware *cur = NULL;
03167
03168 if (ast_strlen_zero(dev))
03169 return 0;
03170
03171 AST_LIST_LOCK(&firmwares);
03172 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03173 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03174 res = ntohs(cur->fwh->version);
03175 break;
03176 }
03177 }
03178 AST_LIST_UNLOCK(&firmwares);
03179
03180 return res;
03181 }
03182
03183 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03184 {
03185 int res = -1;
03186 unsigned int bs = desc & 0xff;
03187 unsigned int start = (desc >> 8) & 0xffffff;
03188 unsigned int bytes;
03189 struct iax_firmware *cur;
03190
03191 if (ast_strlen_zero((char *)dev) || !bs)
03192 return -1;
03193
03194 start *= bs;
03195
03196 AST_LIST_LOCK(&firmwares);
03197 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03198 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03199 continue;
03200 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03201 if (start < ntohl(cur->fwh->datalen)) {
03202 bytes = ntohl(cur->fwh->datalen) - start;
03203 if (bytes > bs)
03204 bytes = bs;
03205 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03206 } else {
03207 bytes = 0;
03208 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03209 }
03210 if (bytes == bs)
03211 res = 0;
03212 else
03213 res = 1;
03214 break;
03215 }
03216 AST_LIST_UNLOCK(&firmwares);
03217
03218 return res;
03219 }
03220
03221
03222 static void reload_firmware(int unload)
03223 {
03224 struct iax_firmware *cur = NULL;
03225 DIR *fwd;
03226 struct dirent *de;
03227 char dir[256], fn[256];
03228
03229 AST_LIST_LOCK(&firmwares);
03230
03231
03232 AST_LIST_TRAVERSE(&firmwares, cur, list)
03233 cur->dead = 1;
03234
03235
03236 if (!unload) {
03237 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03238 fwd = opendir(dir);
03239 if (fwd) {
03240 while((de = readdir(fwd))) {
03241 if (de->d_name[0] != '.') {
03242 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03243 if (!try_firmware(fn)) {
03244 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03245 }
03246 }
03247 }
03248 closedir(fwd);
03249 } else
03250 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03251 }
03252
03253
03254 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03255 if (!cur->dead)
03256 continue;
03257 AST_LIST_REMOVE_CURRENT(list);
03258 destroy_firmware(cur);
03259 }
03260 AST_LIST_TRAVERSE_SAFE_END;
03261
03262 AST_LIST_UNLOCK(&firmwares);
03263 }
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273 static int __do_deliver(void *data)
03274 {
03275
03276
03277 struct iax_frame *fr = data;
03278 fr->retrans = -1;
03279 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03280 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03281 iax2_queue_frame(fr->callno, &fr->af);
03282
03283 iax2_frame_free(fr);
03284
03285 return 0;
03286 }
03287
03288 static int handle_error(void)
03289 {
03290
03291
03292
03293 #if 0
03294 struct sockaddr_in *sin;
03295 int res;
03296 struct msghdr m;
03297 struct sock_extended_err e;
03298 m.msg_name = NULL;
03299 m.msg_namelen = 0;
03300 m.msg_iov = NULL;
03301 m.msg_control = &e;
03302 m.msg_controllen = sizeof(e);
03303 m.msg_flags = 0;
03304 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03305 if (res < 0)
03306 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03307 else {
03308 if (m.msg_controllen) {
03309 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03310 if (sin)
03311 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03312 else
03313 ast_log(LOG_WARNING, "No address detected??\n");
03314 } else {
03315 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03316 }
03317 }
03318 #endif
03319 return 0;
03320 }
03321
03322 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03323 {
03324 int res;
03325 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03326 sizeof(*sin));
03327 if (res < 0) {
03328 ast_debug(1, "Received error: %s\n", strerror(errno));
03329 handle_error();
03330 } else
03331 res = 0;
03332 return res;
03333 }
03334
03335 static int send_packet(struct iax_frame *f)
03336 {
03337 int res;
03338 int callno = f->callno;
03339
03340
03341 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03342 return -1;
03343
03344
03345 if (iaxdebug)
03346 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));
03347
03348 if (f->transfer) {
03349 iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03350 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03351 } else {
03352 iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03353 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03354 }
03355 if (res < 0) {
03356 if (iaxdebug)
03357 ast_debug(1, "Received error: %s\n", strerror(errno));
03358 handle_error();
03359 } else
03360 res = 0;
03361
03362 return res;
03363 }
03364
03365
03366
03367
03368
03369 static int iax2_predestroy(int callno)
03370 {
03371 struct ast_channel *c = NULL;
03372 struct chan_iax2_pvt *pvt = iaxs[callno];
03373
03374 if (!pvt)
03375 return -1;
03376
03377 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03378 iax2_destroy_helper(pvt);
03379 ast_set_flag64(pvt, IAX_ALREADYGONE);
03380 }
03381
03382 if ((c = pvt->owner)) {
03383 c->tech_pvt = NULL;
03384 iax2_queue_hangup(callno);
03385 pvt->owner = NULL;
03386 ast_module_unref(ast_module_info->self);
03387 }
03388
03389 return 0;
03390 }
03391
03392 static void iax2_destroy(int callno)
03393 {
03394 struct chan_iax2_pvt *pvt = NULL;
03395 struct ast_channel *owner = NULL;
03396
03397 retry:
03398 if ((pvt = iaxs[callno])) {
03399 #if 0
03400
03401
03402
03403
03404
03405
03406
03407 iax2_destroy_helper(pvt);
03408 #endif
03409 }
03410
03411 owner = pvt ? pvt->owner : NULL;
03412
03413 if (owner) {
03414 if (ast_channel_trylock(owner)) {
03415 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03416 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03417 goto retry;
03418 }
03419 }
03420
03421 if (!owner) {
03422 iaxs[callno] = NULL;
03423 }
03424
03425 if (pvt) {
03426 if (!owner) {
03427 pvt->owner = NULL;
03428 } else {
03429
03430
03431
03432 ast_queue_hangup(owner);
03433 }
03434
03435 if (pvt->peercallno) {
03436 remove_by_peercallno(pvt);
03437 }
03438
03439 if (pvt->transfercallno) {
03440 remove_by_transfercallno(pvt);
03441 }
03442
03443 if (!owner) {
03444 ao2_ref(pvt, -1);
03445 pvt = NULL;
03446 }
03447 }
03448
03449 if (owner) {
03450 ast_channel_unlock(owner);
03451 }
03452
03453 if (callno & TRUNK_CALL_START) {
03454 update_max_trunk();
03455 }
03456 }
03457
03458 static int update_packet(struct iax_frame *f)
03459 {
03460
03461 struct ast_iax2_full_hdr *fh = f->data;
03462 struct ast_frame af;
03463
03464
03465 if (f->encmethods) {
03466 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03467 }
03468
03469 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03470
03471 f->iseqno = iaxs[f->callno]->iseqno;
03472 fh->iseqno = f->iseqno;
03473
03474
03475 if (f->encmethods) {
03476
03477
03478 build_rand_pad(f->semirand, sizeof(f->semirand));
03479 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03480 }
03481 return 0;
03482 }
03483
03484 static int attempt_transmit(const void *data);
03485 static void __attempt_transmit(const void *data)
03486 {
03487
03488
03489 struct iax_frame *f = (struct iax_frame *)data;
03490 int freeme = 0;
03491 int callno = f->callno;
03492
03493
03494 if (callno)
03495 ast_mutex_lock(&iaxsl[callno]);
03496 if (callno && iaxs[callno]) {
03497 if (f->retries < 0) {
03498
03499 freeme = 1;
03500 } else if (f->retries >= max_retries) {
03501
03502 if (f->transfer) {
03503
03504 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03505 } else if (f->final) {
03506 iax2_destroy(callno);
03507 } else {
03508 if (iaxs[callno]->owner) {
03509 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n",
03510 ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),
03511 iaxs[f->callno]->owner->name,
03512 f->af.frametype,
03513 f->af.subclass.integer,
03514 f->ts,
03515 f->oseqno);
03516 }
03517 iaxs[callno]->error = ETIMEDOUT;
03518 if (iaxs[callno]->owner) {
03519 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03520
03521 iax2_queue_frame(callno, &fr);
03522
03523 if (iaxs[callno] && iaxs[callno]->owner)
03524 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03525 } else {
03526 if (iaxs[callno]->reg) {
03527 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03528 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03529 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03530 }
03531 iax2_destroy(callno);
03532 }
03533 }
03534 freeme = 1;
03535 } else {
03536
03537 update_packet(f);
03538
03539 send_packet(f);
03540 f->retries++;
03541
03542 f->retrytime *= 10;
03543 if (f->retrytime > MAX_RETRY_TIME)
03544 f->retrytime = MAX_RETRY_TIME;
03545
03546 if (f->transfer && (f->retrytime > 1000))
03547 f->retrytime = 1000;
03548 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03549 }
03550 } else {
03551
03552 f->retries = -1;
03553 freeme = 1;
03554 }
03555
03556 if (freeme) {
03557
03558 AST_LIST_REMOVE(&frame_queue[callno], f, list);
03559 ast_mutex_unlock(&iaxsl[callno]);
03560 f->retrans = -1;
03561
03562 iax2_frame_free(f);
03563 } else if (callno) {
03564 ast_mutex_unlock(&iaxsl[callno]);
03565 }
03566 }
03567
03568 static int attempt_transmit(const void *data)
03569 {
03570 #ifdef SCHED_MULTITHREADED
03571 if (schedule_action(__attempt_transmit, data))
03572 #endif
03573 __attempt_transmit(data);
03574 return 0;
03575 }
03576
03577 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03578 {
03579 struct iax2_peer *peer = NULL;
03580 struct iax2_user *user = NULL;
03581 static const char * const choices[] = { "all", NULL };
03582 char *cmplt;
03583
03584 switch (cmd) {
03585 case CLI_INIT:
03586 e->command = "iax2 prune realtime";
03587 e->usage =
03588 "Usage: iax2 prune realtime [<peername>|all]\n"
03589 " Prunes object(s) from the cache\n";
03590 return NULL;
03591 case CLI_GENERATE:
03592 if (a->pos == 3) {
03593 cmplt = ast_cli_complete(a->word, choices, a->n);
03594 if (!cmplt)
03595 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03596 return cmplt;
03597 }
03598 return NULL;
03599 }
03600 if (a->argc != 4)
03601 return CLI_SHOWUSAGE;
03602 if (!strcmp(a->argv[3], "all")) {
03603 prune_users();
03604 prune_peers();
03605 ast_cli(a->fd, "Cache flushed successfully.\n");
03606 return CLI_SUCCESS;
03607 }
03608 peer = find_peer(a->argv[3], 0);
03609 user = find_user(a->argv[3]);
03610 if (peer || user) {
03611 if (peer) {
03612 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03613 ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03614 expire_registry(peer_ref(peer));
03615 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03616 } else {
03617 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03618 }
03619 peer_unref(peer);
03620 }
03621 if (user) {
03622 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03623 ast_set_flag64(user, IAX_RTAUTOCLEAR);
03624 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03625 } else {
03626 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03627 }
03628 ao2_unlink(users,user);
03629 user_unref(user);
03630 }
03631 } else {
03632 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03633 }
03634
03635 return CLI_SUCCESS;
03636 }
03637
03638 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03639 {
03640 switch (cmd) {
03641 case CLI_INIT:
03642 e->command = "iax2 test losspct";
03643 e->usage =
03644 "Usage: iax2 test losspct <percentage>\n"
03645 " For testing, throws away <percentage> percent of incoming packets\n";
03646 return NULL;
03647 case CLI_GENERATE:
03648 return NULL;
03649 }
03650 if (a->argc != 4)
03651 return CLI_SHOWUSAGE;
03652
03653 test_losspct = atoi(a->argv[3]);
03654
03655 return CLI_SUCCESS;
03656 }
03657
03658 #ifdef IAXTESTS
03659 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03660 {
03661 switch (cmd) {
03662 case CLI_INIT:
03663 e->command = "iax2 test late";
03664 e->usage =
03665 "Usage: iax2 test late <ms>\n"
03666 " For testing, count the next frame as <ms> ms late\n";
03667 return NULL;
03668 case CLI_GENERATE:
03669 return NULL;
03670 }
03671
03672 if (a->argc != 4)
03673 return CLI_SHOWUSAGE;
03674
03675 test_late = atoi(a->argv[3]);
03676
03677 return CLI_SUCCESS;
03678 }
03679
03680 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03681 {
03682 switch (cmd) {
03683 case CLI_INIT:
03684 e->command = "iax2 test resync";
03685 e->usage =
03686 "Usage: iax2 test resync <ms>\n"
03687 " For testing, adjust all future frames by <ms> ms\n";
03688 return NULL;
03689 case CLI_GENERATE:
03690 return NULL;
03691 }
03692
03693 if (a->argc != 4)
03694 return CLI_SHOWUSAGE;
03695
03696 test_resync = atoi(a->argv[3]);
03697
03698 return CLI_SUCCESS;
03699 }
03700
03701 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03702 {
03703 switch (cmd) {
03704 case CLI_INIT:
03705 e->command = "iax2 test jitter";
03706 e->usage =
03707 "Usage: iax2 test jitter <ms> <pct>\n"
03708 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03709 " percentage of packets. If <pct> is not specified, adds\n"
03710 " jitter to all packets.\n";
03711 return NULL;
03712 case CLI_GENERATE:
03713 return NULL;
03714 }
03715
03716 if (a->argc < 4 || a->argc > 5)
03717 return CLI_SHOWUSAGE;
03718
03719 test_jit = atoi(a->argv[3]);
03720 if (a->argc == 5)
03721 test_jitpct = atoi(a->argv[4]);
03722
03723 return CLI_SUCCESS;
03724 }
03725 #endif
03726
03727
03728
03729 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03730 {
03731 int res = 0;
03732 if (peer->maxms) {
03733 if (peer->lastms < 0) {
03734 ast_copy_string(status, "UNREACHABLE", statuslen);
03735 } else if (peer->lastms > peer->maxms) {
03736 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03737 res = 1;
03738 } else if (peer->lastms) {
03739 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03740 res = 1;
03741 } else {
03742 ast_copy_string(status, "UNKNOWN", statuslen);
03743 }
03744 } else {
03745 ast_copy_string(status, "Unmonitored", statuslen);
03746 res = -1;
03747 }
03748 return res;
03749 }
03750
03751
03752 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03753 {
03754 char status[30];
03755 char cbuf[256];
03756 struct iax2_peer *peer;
03757 char codec_buf[512];
03758 struct ast_str *encmethods = ast_str_alloca(256);
03759 int x = 0, codec = 0, load_realtime = 0;
03760
03761 switch (cmd) {
03762 case CLI_INIT:
03763 e->command = "iax2 show peer";
03764 e->usage =
03765 "Usage: iax2 show peer <name>\n"
03766 " Display details on specific IAX peer\n";
03767 return NULL;
03768 case CLI_GENERATE:
03769 if (a->pos == 3)
03770 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03771 return NULL;
03772 }
03773
03774 if (a->argc < 4)
03775 return CLI_SHOWUSAGE;
03776
03777 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03778
03779 peer = find_peer(a->argv[3], load_realtime);
03780 if (peer) {
03781 struct sockaddr_in peer_addr;
03782
03783 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03784
03785 encmethods_to_str(peer->encmethods, &encmethods);
03786 ast_cli(a->fd, "\n\n");
03787 ast_cli(a->fd, " * Name : %s\n", peer->name);
03788 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03789 ast_cli(a->fd, " Context : %s\n", peer->context);
03790 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03791 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03792 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03793 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03794 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03795 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03796 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03797 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03798 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03799 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03800 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));
03801 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03802 ast_cli(a->fd, " Username : %s\n", peer->username);
03803 ast_cli(a->fd, " Codecs : ");
03804 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03805 ast_cli(a->fd, "%s\n", codec_buf);
03806
03807 ast_cli(a->fd, " Codec Order : (");
03808 for(x = 0; x < 32 ; x++) {
03809 codec = ast_codec_pref_index(&peer->prefs,x);
03810 if(!codec)
03811 break;
03812 ast_cli(a->fd, "%s", ast_getformatname(codec));
03813 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03814 ast_cli(a->fd, "|");
03815 }
03816
03817 if (!x)
03818 ast_cli(a->fd, "none");
03819 ast_cli(a->fd, ")\n");
03820
03821 ast_cli(a->fd, " Status : ");
03822 peer_status(peer, status, sizeof(status));
03823 ast_cli(a->fd, "%s\n",status);
03824 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");
03825 ast_cli(a->fd, "\n");
03826 peer_unref(peer);
03827 } else {
03828 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03829 ast_cli(a->fd, "\n");
03830 }
03831
03832 return CLI_SUCCESS;
03833 }
03834
03835 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
03836 {
03837 int which = 0;
03838 struct iax2_peer *peer;
03839 char *res = NULL;
03840 int wordlen = strlen(word);
03841 struct ao2_iterator i;
03842
03843 i = ao2_iterator_init(peers, 0);
03844 while ((peer = ao2_iterator_next(&i))) {
03845 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03846 && (!flags || ast_test_flag64(peer, flags))) {
03847 res = ast_strdup(peer->name);
03848 peer_unref(peer);
03849 break;
03850 }
03851 peer_unref(peer);
03852 }
03853 ao2_iterator_destroy(&i);
03854
03855 return res;
03856 }
03857
03858 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03859 {
03860 struct iax_frame *cur;
03861 int cnt = 0, dead = 0, final = 0, i = 0;
03862
03863 switch (cmd) {
03864 case CLI_INIT:
03865 e->command = "iax2 show stats";
03866 e->usage =
03867 "Usage: iax2 show stats\n"
03868 " Display statistics on IAX channel driver.\n";
03869 return NULL;
03870 case CLI_GENERATE:
03871 return NULL;
03872 }
03873
03874 if (a->argc != 3)
03875 return CLI_SHOWUSAGE;
03876
03877 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03878 ast_mutex_lock(&iaxsl[i]);
03879 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03880 if (cur->retries < 0)
03881 dead++;
03882 if (cur->final)
03883 final++;
03884 cnt++;
03885 }
03886 ast_mutex_unlock(&iaxsl[i]);
03887 }
03888
03889 ast_cli(a->fd, " IAX Statistics\n");
03890 ast_cli(a->fd, "---------------------\n");
03891 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03892 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03893 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03894 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03895
03896 trunk_timed = trunk_untimed = 0;
03897 if (trunk_maxmtu > trunk_nmaxmtu)
03898 trunk_nmaxmtu = trunk_maxmtu;
03899
03900 return CLI_SUCCESS;
03901 }
03902
03903
03904 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03905 {
03906 int mtuv;
03907
03908 switch (cmd) {
03909 case CLI_INIT:
03910 e->command = "iax2 set mtu";
03911 e->usage =
03912 "Usage: iax2 set mtu <value>\n"
03913 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03914 " zero to disable. Disabling means that the operating system\n"
03915 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03916 " packet exceeds the UDP payload size. This is substantially\n"
03917 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03918 " greater for G.711 samples.\n";
03919 return NULL;
03920 case CLI_GENERATE:
03921 return NULL;
03922 }
03923
03924 if (a->argc != 4)
03925 return CLI_SHOWUSAGE;
03926 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03927 mtuv = MAX_TRUNK_MTU;
03928 else
03929 mtuv = atoi(a->argv[3]);
03930
03931 if (mtuv == 0) {
03932 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03933 global_max_trunk_mtu = 0;
03934 return CLI_SUCCESS;
03935 }
03936 if (mtuv < 172 || mtuv > 4000) {
03937 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03938 return CLI_SHOWUSAGE;
03939 }
03940 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03941 global_max_trunk_mtu = mtuv;
03942 return CLI_SUCCESS;
03943 }
03944
03945 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03946 {
03947 struct iax2_dpcache *dp = NULL;
03948 char tmp[1024], *pc = NULL;
03949 int s, x, y;
03950 struct timeval now = ast_tvnow();
03951
03952 switch (cmd) {
03953 case CLI_INIT:
03954 e->command = "iax2 show cache";
03955 e->usage =
03956 "Usage: iax2 show cache\n"
03957 " Display currently cached IAX Dialplan results.\n";
03958 return NULL;
03959 case CLI_GENERATE:
03960 return NULL;
03961 }
03962
03963 AST_LIST_LOCK(&dpcache);
03964
03965 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03966
03967 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03968 s = dp->expiry.tv_sec - now.tv_sec;
03969 tmp[0] = '\0';
03970 if (dp->flags & CACHE_FLAG_EXISTS)
03971 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03972 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03973 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03974 if (dp->flags & CACHE_FLAG_CANEXIST)
03975 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03976 if (dp->flags & CACHE_FLAG_PENDING)
03977 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03978 if (dp->flags & CACHE_FLAG_TIMEOUT)
03979 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03980 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03981 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03982 if (dp->flags & CACHE_FLAG_MATCHMORE)
03983 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03984 if (dp->flags & CACHE_FLAG_UNKNOWN)
03985 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03986
03987 if (!ast_strlen_zero(tmp)) {
03988 tmp[strlen(tmp) - 1] = '\0';
03989 } else {
03990 ast_copy_string(tmp, "(none)", sizeof(tmp));
03991 }
03992 y = 0;
03993 pc = strchr(dp->peercontext, '@');
03994 if (!pc) {
03995 pc = dp->peercontext;
03996 } else {
03997 pc++;
03998 }
03999 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
04000 if (dp->waiters[x] > -1)
04001 y++;
04002 }
04003 if (s > 0) {
04004 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
04005 } else {
04006 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
04007 }
04008 }
04009
04010 AST_LIST_UNLOCK(&dpcache);
04011
04012 return CLI_SUCCESS;
04013 }
04014
04015 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
04016
04017 static void unwrap_timestamp(struct iax_frame *fr)
04018 {
04019
04020
04021 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
04022 const int lower_mask = (1 << ts_shift) - 1;
04023 const int upper_mask = ~lower_mask;
04024 const int last_upper = iaxs[fr->callno]->last & upper_mask;
04025
04026 if ( (fr->ts & upper_mask) == last_upper ) {
04027 const int x = fr->ts - iaxs[fr->callno]->last;
04028 const int threshold = (ts_shift == 15) ? 25000 : 50000;
04029
04030 if (x < -threshold) {
04031
04032
04033
04034
04035 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04036 if (iaxdebug)
04037 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04038 } else if (x > threshold) {
04039
04040
04041
04042
04043 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04044 if (iaxdebug)
04045 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04046 }
04047 }
04048 }
04049
04050 static int get_from_jb(const void *p);
04051
04052 static void update_jbsched(struct chan_iax2_pvt *pvt)
04053 {
04054 int when;
04055
04056 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04057
04058 when = jb_next(pvt->jb) - when;
04059
04060 if (when <= 0) {
04061
04062 when = 1;
04063 }
04064
04065 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
04066 CALLNO_TO_PTR(pvt->callno));
04067 }
04068
04069 static void __get_from_jb(const void *p)
04070 {
04071 int callno = PTR_TO_CALLNO(p);
04072 struct chan_iax2_pvt *pvt = NULL;
04073 struct iax_frame *fr;
04074 jb_frame frame;
04075 int ret;
04076 long ms;
04077 long next;
04078 struct timeval now = ast_tvnow();
04079
04080
04081 ast_mutex_lock(&iaxsl[callno]);
04082 pvt = iaxs[callno];
04083 if (!pvt) {
04084
04085 ast_mutex_unlock(&iaxsl[callno]);
04086 return;
04087 }
04088
04089 pvt->jbid = -1;
04090
04091
04092
04093
04094 now.tv_usec += 1000;
04095
04096 ms = ast_tvdiff_ms(now, pvt->rxcore);
04097
04098 if(ms >= (next = jb_next(pvt->jb))) {
04099 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04100 switch(ret) {
04101 case JB_OK:
04102 fr = frame.data;
04103 __do_deliver(fr);
04104
04105 pvt = iaxs[callno];
04106 break;
04107 case JB_INTERP:
04108 {
04109 struct ast_frame af = { 0, };
04110
04111
04112 af.frametype = AST_FRAME_VOICE;
04113 af.subclass.codec = pvt->voiceformat;
04114 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04115 af.src = "IAX2 JB interpolation";
04116 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04117 af.offset = AST_FRIENDLY_OFFSET;
04118
04119
04120
04121 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04122 iax2_queue_frame(callno, &af);
04123
04124 pvt = iaxs[callno];
04125 }
04126 }
04127 break;
04128 case JB_DROP:
04129 iax2_frame_free(frame.data);
04130 break;
04131 case JB_NOFRAME:
04132 case JB_EMPTY:
04133
04134 break;
04135 default:
04136
04137 break;
04138 }
04139 }
04140 if (pvt)
04141 update_jbsched(pvt);
04142 ast_mutex_unlock(&iaxsl[callno]);
04143 }
04144
04145 static int get_from_jb(const void *data)
04146 {
04147 #ifdef SCHED_MULTITHREADED
04148 if (schedule_action(__get_from_jb, data))
04149 #endif
04150 __get_from_jb(data);
04151 return 0;
04152 }
04153
04154
04155
04156
04157
04158
04159
04160 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
04161 {
04162 int type, len;
04163 int ret;
04164 int needfree = 0;
04165 struct ast_channel *owner = NULL;
04166 struct ast_channel *bridge = NULL;
04167
04168
04169
04170
04171
04172
04173 if (!fr->af.datalen) {
04174 memset(&fr->af.data, 0, sizeof(fr->af.data));
04175 }
04176
04177
04178 unwrap_timestamp(fr);
04179
04180
04181 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04182 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04183 else {
04184 #if 0
04185 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04186 #endif
04187 fr->af.delivery = ast_tv(0,0);
04188 }
04189
04190 type = JB_TYPE_CONTROL;
04191 len = 0;
04192
04193 if(fr->af.frametype == AST_FRAME_VOICE) {
04194 type = JB_TYPE_VOICE;
04195 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04196 } else if(fr->af.frametype == AST_FRAME_CNG) {
04197 type = JB_TYPE_SILENCE;
04198 }
04199
04200 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04201 if (tsout)
04202 *tsout = fr->ts;
04203 __do_deliver(fr);
04204 return -1;
04205 }
04206
04207 iax2_lock_owner(fr->callno);
04208 if (!iaxs[fr->callno]) {
04209
04210 iax2_frame_free(fr);
04211 return -1;
04212 }
04213 if ((owner = iaxs[fr->callno]->owner))
04214 bridge = ast_bridged_channel(owner);
04215
04216
04217
04218 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04219 jb_frame frame;
04220
04221 ast_channel_unlock(owner);
04222
04223
04224 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04225 __do_deliver(frame.data);
04226
04227 if (!iaxs[fr->callno])
04228 return -1;
04229 }
04230
04231 jb_reset(iaxs[fr->callno]->jb);
04232
04233 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04234
04235
04236 if (tsout)
04237 *tsout = fr->ts;
04238 __do_deliver(fr);
04239 return -1;
04240 }
04241 if (owner) {
04242 ast_channel_unlock(owner);
04243 }
04244
04245
04246
04247 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04248 calc_rxstamp(iaxs[fr->callno],fr->ts));
04249 if (ret == JB_DROP) {
04250 needfree++;
04251 } else if (ret == JB_SCHED) {
04252 update_jbsched(iaxs[fr->callno]);
04253 }
04254 if (tsout)
04255 *tsout = fr->ts;
04256 if (needfree) {
04257
04258 iax2_frame_free(fr);
04259 return -1;
04260 }
04261 return 0;
04262 }
04263
04264 static int transmit_frame(void *data)
04265 {
04266 struct iax_frame *fr = data;
04267
04268 ast_mutex_lock(&iaxsl[fr->callno]);
04269
04270 fr->sentyet = 1;
04271
04272 if (iaxs[fr->callno]) {
04273 send_packet(fr);
04274 }
04275
04276 if (fr->retries < 0) {
04277 ast_mutex_unlock(&iaxsl[fr->callno]);
04278
04279 iax_frame_free(fr);
04280 } else {
04281
04282 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04283 fr->retries++;
04284 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04285 ast_mutex_unlock(&iaxsl[fr->callno]);
04286 }
04287
04288 return 0;
04289 }
04290
04291 static int iax2_transmit(struct iax_frame *fr)
04292 {
04293 fr->sentyet = 0;
04294
04295 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04296 }
04297
04298 static int iax2_digit_begin(struct ast_channel *c, char digit)
04299 {
04300 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04301 }
04302
04303 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04304 {
04305 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04306 }
04307
04308 static int iax2_sendtext(struct ast_channel *c, const char *text)
04309 {
04310
04311 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04312 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04313 }
04314
04315 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04316 {
04317 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04318 }
04319
04320 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04321 {
04322 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04323 }
04324
04325 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04326 {
04327 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04328 ast_mutex_lock(&iaxsl[callno]);
04329 if (iaxs[callno])
04330 iaxs[callno]->owner = newchan;
04331 else
04332 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04333 ast_mutex_unlock(&iaxsl[callno]);
04334 return 0;
04335 }
04336
04337
04338
04339
04340
04341 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04342 {
04343 struct ast_variable *var = NULL;
04344 struct ast_variable *tmp;
04345 struct iax2_peer *peer=NULL;
04346 time_t regseconds = 0, nowtime;
04347 int dynamic=0;
04348
04349 if (peername) {
04350 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04351 if (!var && sin)
04352 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04353 } else if (sin) {
04354 char porta[25];
04355 sprintf(porta, "%d", ntohs(sin->sin_port));
04356 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04357 if (var) {
04358
04359 for (tmp = var; tmp; tmp = tmp->next) {
04360 if (!strcasecmp(tmp->name, "name"))
04361 peername = tmp->value;
04362 }
04363 }
04364 }
04365 if (!var && peername) {
04366 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04367
04368
04369
04370
04371
04372
04373 if (var && sin) {
04374 for (tmp = var; tmp; tmp = tmp->next) {
04375 if (!strcasecmp(tmp->name, "host")) {
04376 struct ast_hostent ahp;
04377 struct hostent *hp;
04378 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04379
04380 ast_variables_destroy(var);
04381 var = NULL;
04382 }
04383 break;
04384 }
04385 }
04386 }
04387 }
04388 if (!var)
04389 return NULL;
04390
04391 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04392
04393 if (!peer) {
04394 ast_variables_destroy(var);
04395 return NULL;
04396 }
04397
04398 for (tmp = var; tmp; tmp = tmp->next) {
04399
04400 if (!strcasecmp(tmp->name, "type")) {
04401 if (strcasecmp(tmp->value, "friend") &&
04402 strcasecmp(tmp->value, "peer")) {
04403
04404 peer = peer_unref(peer);
04405 break;
04406 }
04407 } else if (!strcasecmp(tmp->name, "regseconds")) {
04408 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04409 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04410 if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) {
04411 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name);
04412 }
04413 } else if (!strcasecmp(tmp->name, "port")) {
04414 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04415 } else if (!strcasecmp(tmp->name, "host")) {
04416 if (!strcasecmp(tmp->value, "dynamic"))
04417 dynamic = 1;
04418 }
04419 }
04420
04421 ast_variables_destroy(var);
04422
04423 if (!peer)
04424 return NULL;
04425
04426 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04427 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04428 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04429 if (peer->expire > -1) {
04430 if (!ast_sched_thread_del(sched, peer->expire)) {
04431 peer->expire = -1;
04432 peer_unref(peer);
04433 }
04434 }
04435 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04436 if (peer->expire == -1)
04437 peer_unref(peer);
04438 }
04439 ao2_link(peers, peer);
04440 if (ast_test_flag64(peer, IAX_DYNAMIC))
04441 reg_source_db(peer);
04442 } else {
04443 ast_set_flag64(peer, IAX_TEMPONLY);
04444 }
04445
04446 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04447 time(&nowtime);
04448 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04449 memset(&peer->addr, 0, sizeof(peer->addr));
04450 realtime_update_peer(peer->name, &peer->addr, 0);
04451 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04452 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04453 }
04454 else {
04455 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04456 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04457 }
04458 }
04459
04460 return peer;
04461 }
04462
04463 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04464 {
04465 struct ast_variable *var;
04466 struct ast_variable *tmp;
04467 struct iax2_user *user=NULL;
04468
04469 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04470 if (!var)
04471 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04472 if (!var && sin) {
04473 char porta[6];
04474 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04475 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04476 if (!var)
04477 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04478 }
04479 if (!var) {
04480 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04481
04482
04483
04484
04485
04486
04487 if (var) {
04488 for (tmp = var; tmp; tmp = tmp->next) {
04489 if (!strcasecmp(tmp->name, "host")) {
04490 struct ast_hostent ahp;
04491 struct hostent *hp;
04492 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) {
04493
04494 ast_variables_destroy(var);
04495 var = NULL;
04496 }
04497 break;
04498 }
04499 }
04500 }
04501 }
04502 if (!var)
04503 return NULL;
04504
04505 tmp = var;
04506 while(tmp) {
04507
04508 if (!strcasecmp(tmp->name, "type")) {
04509 if (strcasecmp(tmp->value, "friend") &&
04510 strcasecmp(tmp->value, "user")) {
04511 return NULL;
04512 }
04513 }
04514 tmp = tmp->next;
04515 }
04516
04517 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04518
04519 ast_variables_destroy(var);
04520
04521 if (!user)
04522 return NULL;
04523
04524 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04525 ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04526 ao2_link(users, user);
04527 } else {
04528 ast_set_flag64(user, IAX_TEMPONLY);
04529 }
04530
04531 return user;
04532 }
04533
04534 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
04535 {
04536 char port[10];
04537 char regseconds[20];
04538 const char *sysname = ast_config_AST_SYSTEM_NAME;
04539 char *syslabel = NULL;
04540
04541 if (ast_strlen_zero(sysname))
04542 sysname = NULL;
04543 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04544 syslabel = "regserver";
04545
04546 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04547 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04548 ast_update_realtime("iaxpeers", "name", peername,
04549 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port,
04550 "regseconds", regseconds, syslabel, sysname, SENTINEL);
04551 }
04552
04553 struct create_addr_info {
04554 format_t capability;
04555 uint64_t flags;
04556 int maxtime;
04557 int encmethods;
04558 int found;
04559 int sockfd;
04560 int adsi;
04561 char username[80];
04562 char secret[80];
04563 char outkey[80];
04564 char timezone[80];
04565 char prefs[32];
04566 char cid_num[80];
04567 char cid_name[80];
04568 char context[AST_MAX_CONTEXT];
04569 char peercontext[AST_MAX_CONTEXT];
04570 char mohinterpret[MAX_MUSICCLASS];
04571 char mohsuggest[MAX_MUSICCLASS];
04572 };
04573
04574 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04575 {
04576 struct iax2_peer *peer;
04577 int res = -1;
04578 struct ast_codec_pref ourprefs;
04579 struct sockaddr_in peer_addr;
04580
04581 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04582 cai->sockfd = defaultsockfd;
04583 cai->maxtime = 0;
04584 sin->sin_family = AF_INET;
04585
04586 if (!(peer = find_peer(peername, 1))) {
04587 struct ast_sockaddr sin_tmp;
04588
04589 cai->found = 0;
04590 sin_tmp.ss.ss_family = AF_INET;
04591 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04592 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04593 return -1;
04594 }
04595 ast_sockaddr_to_sin(&sin_tmp, sin);
04596 if (sin->sin_port == 0) {
04597 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04598 }
04599
04600
04601 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04602 if (c)
04603 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04604 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04605 return 0;
04606 }
04607
04608 cai->found = 1;
04609
04610 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04611
04612
04613 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04614 goto return_unref;
04615 }
04616
04617
04618 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04619 goto return_unref;
04620
04621 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04622 cai->maxtime = peer->maxms;
04623 cai->capability = peer->capability;
04624 cai->encmethods = peer->encmethods;
04625 cai->sockfd = peer->sockfd;
04626 cai->adsi = peer->adsi;
04627 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04628
04629 if (c) {
04630 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04631 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04632 }
04633 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04634 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04635 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04636 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04637 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04638 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04639 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04640 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04641 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04642 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04643 if (ast_strlen_zero(peer->dbsecret)) {
04644 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04645 } else {
04646 char *family;
04647 char *key = NULL;
04648
04649 family = ast_strdupa(peer->dbsecret);
04650 key = strchr(family, '/');
04651 if (key)
04652 *key++ = '\0';
04653 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04654 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04655 goto return_unref;
04656 }
04657 }
04658
04659 if (peer_addr.sin_addr.s_addr) {
04660 sin->sin_addr = peer_addr.sin_addr;
04661 sin->sin_port = peer_addr.sin_port;
04662 } else {
04663 sin->sin_addr = peer->defaddr.sin_addr;
04664 sin->sin_port = peer->defaddr.sin_port;
04665 }
04666
04667 res = 0;
04668
04669 return_unref:
04670 peer_unref(peer);
04671
04672 return res;
04673 }
04674
04675 static void __auto_congest(const void *nothing)
04676 {
04677 int callno = PTR_TO_CALLNO(nothing);
04678 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04679 ast_mutex_lock(&iaxsl[callno]);
04680 if (iaxs[callno]) {
04681 iaxs[callno]->initid = -1;
04682 iax2_queue_frame(callno, &f);
04683 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04684 }
04685 ast_mutex_unlock(&iaxsl[callno]);
04686 }
04687
04688 static int auto_congest(const void *data)
04689 {
04690 #ifdef SCHED_MULTITHREADED
04691 if (schedule_action(__auto_congest, data))
04692 #endif
04693 __auto_congest(data);
04694 return 0;
04695 }
04696
04697 static unsigned int iax2_datetime(const char *tz)
04698 {
04699 struct timeval t = ast_tvnow();
04700 struct ast_tm tm;
04701 unsigned int tmp;
04702 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04703 tmp = (tm.tm_sec >> 1) & 0x1f;
04704 tmp |= (tm.tm_min & 0x3f) << 5;
04705 tmp |= (tm.tm_hour & 0x1f) << 11;
04706 tmp |= (tm.tm_mday & 0x1f) << 16;
04707 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04708 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04709 return tmp;
04710 }
04711
04712 struct parsed_dial_string {
04713 char *username;
04714 char *password;
04715 char *key;
04716 char *peer;
04717 char *port;
04718 char *exten;
04719 char *context;
04720 char *options;
04721 };
04722
04723 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04724 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04725 int sockfd, struct iax_ie_data *ied)
04726 {
04727 struct {
04728 struct ast_iax2_full_hdr f;
04729 struct iax_ie_data ied;
04730 } data;
04731 size_t size = sizeof(struct ast_iax2_full_hdr);
04732
04733 if (ied) {
04734 size += ied->pos;
04735 memcpy(&data.ied, ied->buf, ied->pos);
04736 }
04737
04738 data.f.scallno = htons(0x8000 | callno);
04739 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS);
04740 data.f.ts = htonl(ts);
04741 data.f.iseqno = seqno;
04742 data.f.oseqno = 0;
04743 data.f.type = AST_FRAME_IAX;
04744 data.f.csub = compress_subclass(command);
04745
04746 iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr));
04747
04748 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04749 }
04750
04751 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04752 {
04753
04754 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04755 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04756 ied->buf[ied->pos++] = 0;
04757 pvt->calltoken_ie_len = 2;
04758 }
04759 }
04760
04761 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04762 {
04763 struct chan_iax2_pvt *pvt = iaxs[callno];
04764 int frametype = f->af.frametype;
04765 int subclass = f->af.subclass.integer;
04766 struct {
04767 struct ast_iax2_full_hdr fh;
04768 struct iax_ie_data ied;
04769 } data = {
04770 .ied.buf = { 0 },
04771 .ied.pos = 0,
04772 };
04773
04774 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04775
04776 if (!pvt) {
04777 return;
04778 }
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04792 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04793 (f->datalen > sizeof(data))) {
04794
04795 return;
04796 }
04797
04798
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808
04809
04810
04811
04812 memcpy(&data, f->data, f->datalen);
04813 data.ied.pos = ie_data_pos;
04814
04815
04816
04817 data.ied.pos -= pvt->calltoken_ie_len;
04818 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04819
04820
04821 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04822
04823
04824 AST_LIST_REMOVE(&frame_queue[callno], f, list);
04825
04826
04827 iax2_frame_free(f);
04828
04829
04830 pvt->oseqno = 0;
04831 pvt->rseqno = 0;
04832 pvt->iseqno = 0;
04833 pvt->aseqno = 0;
04834 if (pvt->peercallno) {
04835 remove_by_peercallno(pvt);
04836 pvt->peercallno = 0;
04837 }
04838
04839
04840 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04841 }
04842
04843 static void requirecalltoken_mark_auto(const char *name, int subclass)
04844 {
04845 struct iax2_user *user = NULL;
04846 struct iax2_peer *peer = NULL;
04847
04848 if (ast_strlen_zero(name)) {
04849 return;
04850 }
04851
04852 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04853 user->calltoken_required = CALLTOKEN_YES;
04854 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04855 peer->calltoken_required = CALLTOKEN_YES;
04856 }
04857
04858 if (peer) {
04859 peer_unref(peer);
04860 }
04861 if (user) {
04862 user_unref(user);
04863 }
04864 }
04865
04866
04867
04868
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880
04881
04882
04883 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04884 struct sockaddr_in *sin, int fd)
04885 {
04886 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04887 #define CALLTOKEN_IE_FORMAT "%u?%s"
04888 struct ast_str *buf = ast_str_alloca(256);
04889 time_t t = time(NULL);
04890 char hash[41];
04891 int subclass = uncompress_subclass(fh->csub);
04892
04893
04894 if (ies->calltoken && !ies->calltokendata) {
04895 struct iax_ie_data ied = {
04896 .buf = { 0 },
04897 .pos = 0,
04898 };
04899
04900
04901 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04902 ast_sha1_hash(hash, ast_str_buffer(buf));
04903
04904 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04905 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04906 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04907
04908 return 1;
04909
04910
04911 } else if (ies->calltoken && ies->calltokendata) {
04912 char *rec_hash = NULL;
04913 char *rec_ts = NULL;
04914 unsigned int rec_time;
04915
04916
04917 rec_hash = strchr((char *) ies->calltokendata, '?');
04918 if (rec_hash) {
04919 *rec_hash++ = '\0';
04920 rec_ts = (char *) ies->calltokendata;
04921 }
04922
04923
04924 if (!rec_hash || !rec_ts) {
04925 goto reject;
04926 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04927 goto reject;
04928 }
04929
04930
04931 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04932 ast_sha1_hash(hash, ast_str_buffer(buf));
04933
04934
04935 if (strcmp(hash, rec_hash)) {
04936 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04937 goto reject;
04938 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04939 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04940 goto reject;
04941 }
04942
04943
04944
04945 requirecalltoken_mark_auto(ies->username, subclass);
04946 return 0;
04947
04948
04949 } else {
04950 if (calltoken_required(sin, ies->username, subclass)) {
04951 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"));
04952 goto reject;
04953 }
04954 return 0;
04955 }
04956
04957 reject:
04958
04959 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04960 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04961 } else {
04962 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04963 }
04964
04965 return 1;
04966 }
04967
04968
04969
04970
04971
04972
04973
04974
04975
04976
04977
04978
04979
04980
04981
04982
04983
04984
04985
04986 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04987 {
04988 if (ast_strlen_zero(data))
04989 return;
04990
04991 pds->peer = strsep(&data, "/");
04992 pds->exten = strsep(&data, "/");
04993 pds->options = data;
04994
04995 if (pds->exten) {
04996 data = pds->exten;
04997 pds->exten = strsep(&data, "@");
04998 pds->context = data;
04999 }
05000
05001 if (strchr(pds->peer, '@')) {
05002 data = pds->peer;
05003 pds->username = strsep(&data, "@");
05004 pds->peer = data;
05005 }
05006
05007 if (pds->username) {
05008 data = pds->username;
05009 pds->username = strsep(&data, ":");
05010 pds->password = data;
05011 }
05012
05013 data = pds->peer;
05014 pds->peer = strsep(&data, ":");
05015 pds->port = data;
05016
05017
05018
05019
05020 if (pds->password && (pds->password[0] == '[')) {
05021 pds->key = ast_strip_quoted(pds->password, "[", "]");
05022 pds->password = NULL;
05023 }
05024 }
05025
05026 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
05027 {
05028 struct sockaddr_in sin;
05029 char *l=NULL, *n=NULL, *tmpstr;
05030 struct iax_ie_data ied;
05031 char *defaultrdest = "s";
05032 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05033 struct parsed_dial_string pds;
05034 struct create_addr_info cai;
05035 struct ast_var_t *var;
05036 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
05037 const char* osp_token_ptr;
05038 unsigned int osp_token_length;
05039 unsigned char osp_block_index;
05040 unsigned int osp_block_length;
05041 unsigned char osp_buffer[256];
05042
05043 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05044 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
05045 return -1;
05046 }
05047
05048 memset(&cai, 0, sizeof(cai));
05049 cai.encmethods = iax2_encryption;
05050
05051 memset(&pds, 0, sizeof(pds));
05052 tmpstr = ast_strdupa(dest);
05053 parse_dial_string(tmpstr, &pds);
05054
05055 if (ast_strlen_zero(pds.peer)) {
05056 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05057 return -1;
05058 }
05059 if (!pds.exten) {
05060 pds.exten = defaultrdest;
05061 }
05062 if (create_addr(pds.peer, c, &sin, &cai)) {
05063 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05064 return -1;
05065 }
05066 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05067 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05068 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05069 return -1;
05070 }
05071 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05072 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05073 return -1;
05074 }
05075 if (!pds.username && !ast_strlen_zero(cai.username))
05076 pds.username = cai.username;
05077 if (!pds.password && !ast_strlen_zero(cai.secret))
05078 pds.password = cai.secret;
05079 if (!pds.key && !ast_strlen_zero(cai.outkey))
05080 pds.key = cai.outkey;
05081 if (!pds.context && !ast_strlen_zero(cai.peercontext))
05082 pds.context = cai.peercontext;
05083
05084
05085 ast_copy_string(c->context, cai.context, sizeof(c->context));
05086
05087 if (pds.port)
05088 sin.sin_port = htons(atoi(pds.port));
05089
05090 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05091 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05092
05093
05094 memset(&ied, 0, sizeof(ied));
05095
05096
05097 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05098 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05099 if (pds.options && strchr(pds.options, 'a')) {
05100
05101 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05102 }
05103
05104
05105 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05106
05107 if (l) {
05108 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05109 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05110 ast_party_id_presentation(&c->connected.id));
05111 } else if (n) {
05112 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05113 ast_party_id_presentation(&c->connected.id));
05114 } else {
05115 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05116 }
05117
05118 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05119 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05120
05121 if (n)
05122 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05123 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05124 && c->connected.ani.number.valid
05125 && c->connected.ani.number.str) {
05126 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05127 }
05128
05129 if (!ast_strlen_zero(c->language))
05130 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
05131 if (!ast_strlen_zero(c->dialed.number.str)) {
05132 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05133 }
05134 if (c->redirecting.from.number.valid
05135 && !ast_strlen_zero(c->redirecting.from.number.str)) {
05136 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05137 }
05138
05139 if (pds.context)
05140 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05141
05142 if (pds.username)
05143 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05144
05145 if (cai.encmethods)
05146 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05147
05148 ast_mutex_lock(&iaxsl[callno]);
05149
05150 if (!ast_strlen_zero(c->context))
05151 ast_string_field_set(iaxs[callno], context, c->context);
05152
05153 if (pds.username)
05154 ast_string_field_set(iaxs[callno], username, pds.username);
05155
05156 iaxs[callno]->encmethods = cai.encmethods;
05157
05158 iaxs[callno]->adsi = cai.adsi;
05159
05160 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05161 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05162
05163 if (pds.key)
05164 ast_string_field_set(iaxs[callno], outkey, pds.key);
05165 if (pds.password)
05166 ast_string_field_set(iaxs[callno], secret, pds.password);
05167
05168 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
05169 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
05170 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05171 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05172 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05173 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05174
05175 if (iaxs[callno]->maxtime) {
05176
05177 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05178 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05179 } else if (autokill) {
05180 iaxs[callno]->pingtime = autokill / 2;
05181 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05182 }
05183
05184
05185 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05186 if (!ast_strlen_zero(osp_token_ptr)) {
05187 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05188 osp_block_index = 0;
05189 while (osp_token_length > 0) {
05190 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05191 osp_buffer[0] = osp_block_index;
05192 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05193 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05194 osp_block_index++;
05195 osp_token_ptr += osp_block_length;
05196 osp_token_length -= osp_block_length;
05197 }
05198 } else
05199 ast_log(LOG_WARNING, "OSP token is too long\n");
05200 } else if (iaxdebug)
05201 ast_debug(1, "OSP token is undefined\n");
05202
05203
05204 iaxs[callno]->sockfd = cai.sockfd;
05205
05206
05207 if (variablestore) {
05208 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05209 ast_debug(1, "Found an IAX variable store on this channel\n");
05210 AST_LIST_LOCK(variablelist);
05211 AST_LIST_TRAVERSE(variablelist, var, entries) {
05212 char tmp[256];
05213 int i;
05214 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05215
05216 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05217 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05218 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05219 }
05220 }
05221 AST_LIST_UNLOCK(variablelist);
05222 }
05223
05224
05225 add_empty_calltoken_ie(iaxs[callno], &ied);
05226 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05227
05228 ast_mutex_unlock(&iaxsl[callno]);
05229 ast_setstate(c, AST_STATE_RINGING);
05230
05231 return 0;
05232 }
05233
05234 static int iax2_hangup(struct ast_channel *c)
05235 {
05236 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05237 struct iax_ie_data ied;
05238 int alreadygone;
05239 memset(&ied, 0, sizeof(ied));
05240 ast_mutex_lock(&iaxsl[callno]);
05241 if (callno && iaxs[callno]) {
05242 ast_debug(1, "We're hanging up %s now...\n", c->name);
05243 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05244
05245 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05246 if (!iaxs[callno]->error && !alreadygone) {
05247 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05248 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05249 }
05250 if (!iaxs[callno]) {
05251 ast_mutex_unlock(&iaxsl[callno]);
05252 return 0;
05253 }
05254 }
05255
05256 iax2_predestroy(callno);
05257
05258 if (iaxs[callno] && alreadygone) {
05259 ast_debug(1, "Really destroying %s now...\n", c->name);
05260 iax2_destroy(callno);
05261 } else if (iaxs[callno]) {
05262 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05263 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05264 iax2_destroy(callno);
05265 }
05266 }
05267 } else if (c->tech_pvt) {
05268
05269
05270
05271
05272 c->tech_pvt = NULL;
05273 }
05274 ast_mutex_unlock(&iaxsl[callno]);
05275 ast_verb(3, "Hungup '%s'\n", c->name);
05276 return 0;
05277 }
05278
05279
05280
05281
05282 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05283 {
05284 unsigned short callno = pvt->callno;
05285
05286 if (!pvt->peercallno) {
05287
05288 int count = 10;
05289 while (count-- && pvt && !pvt->peercallno) {
05290 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05291 pvt = iaxs[callno];
05292 }
05293 if (!pvt || !pvt->peercallno) {
05294 return -1;
05295 }
05296 }
05297
05298 return 0;
05299 }
05300
05301 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05302 {
05303 struct ast_option_header *h;
05304 int res;
05305
05306 switch (option) {
05307 case AST_OPTION_TXGAIN:
05308 case AST_OPTION_RXGAIN:
05309
05310 errno = ENOSYS;
05311 return -1;
05312 case AST_OPTION_OPRMODE:
05313 errno = EINVAL;
05314 return -1;
05315 case AST_OPTION_SECURE_SIGNALING:
05316 case AST_OPTION_SECURE_MEDIA:
05317 {
05318 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05319 ast_mutex_lock(&iaxsl[callno]);
05320 if ((*(int *) data)) {
05321 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05322 } else {
05323 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05324 }
05325 ast_mutex_unlock(&iaxsl[callno]);
05326 return 0;
05327 }
05328
05329
05330
05331
05332 case AST_OPTION_TONE_VERIFY:
05333 case AST_OPTION_TDD:
05334 case AST_OPTION_RELAXDTMF:
05335 case AST_OPTION_AUDIO_MODE:
05336 case AST_OPTION_DIGIT_DETECT:
05337 case AST_OPTION_FAX_DETECT:
05338 {
05339 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05340 struct chan_iax2_pvt *pvt;
05341
05342 ast_mutex_lock(&iaxsl[callno]);
05343 pvt = iaxs[callno];
05344
05345 if (wait_for_peercallno(pvt)) {
05346 ast_mutex_unlock(&iaxsl[callno]);
05347 return -1;
05348 }
05349
05350 ast_mutex_unlock(&iaxsl[callno]);
05351
05352 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05353 return -1;
05354 }
05355
05356 h->flag = AST_OPTION_FLAG_REQUEST;
05357 h->option = htons(option);
05358 memcpy(h->data, data, datalen);
05359 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05360 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05361 datalen + sizeof(*h), -1);
05362 ast_free(h);
05363 return res;
05364 }
05365 default:
05366 return -1;
05367 }
05368
05369
05370 return -1;
05371 }
05372
05373 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
05374 {
05375 switch (option) {
05376 case AST_OPTION_SECURE_SIGNALING:
05377 case AST_OPTION_SECURE_MEDIA:
05378 {
05379 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05380 ast_mutex_lock(&iaxsl[callno]);
05381 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05382 ast_mutex_unlock(&iaxsl[callno]);
05383 return 0;
05384 }
05385 default:
05386 return -1;
05387 }
05388 }
05389
05390 static struct ast_frame *iax2_read(struct ast_channel *c)
05391 {
05392 ast_debug(1, "I should never be called!\n");
05393 return &ast_null_frame;
05394 }
05395
05396 static int iax2_key_rotate(const void *vpvt)
05397 {
05398 int res = 0;
05399 struct chan_iax2_pvt *pvt = (void *) vpvt;
05400 struct MD5Context md5;
05401 char key[17] = "";
05402 struct iax_ie_data ied = {
05403 .pos = 0,
05404 };
05405
05406 ast_mutex_lock(&iaxsl[pvt->callno]);
05407 pvt->keyrotateid =
05408 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05409
05410 snprintf(key, sizeof(key), "%lX", ast_random());
05411
05412 MD5Init(&md5);
05413 MD5Update(&md5, (unsigned char *) key, strlen(key));
05414 MD5Final((unsigned char *) key, &md5);
05415
05416 IAX_DEBUGDIGEST("Sending", key);
05417
05418 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05419
05420 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05421
05422 build_ecx_key((unsigned char *) key, pvt);
05423
05424 ast_mutex_unlock(&iaxsl[pvt->callno]);
05425
05426 return res;
05427 }
05428
05429 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05430 {
05431 int res;
05432 struct iax_ie_data ied0;
05433 struct iax_ie_data ied1;
05434 unsigned int transferid = (unsigned int)ast_random();
05435
05436 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05437 ast_debug(1, "transfers are not supported for encrypted calls at this time\n");
05438 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05439 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05440 return 0;
05441 }
05442
05443 memset(&ied0, 0, sizeof(ied0));
05444 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05445 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05446 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05447
05448 memset(&ied1, 0, sizeof(ied1));
05449 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05450 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05451 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05452
05453 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05454 if (res)
05455 return -1;
05456 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05457 if (res)
05458 return -1;
05459 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05460 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05461 return 0;
05462 }
05463
05464 static void lock_both(unsigned short callno0, unsigned short callno1)
05465 {
05466 ast_mutex_lock(&iaxsl[callno0]);
05467 while (ast_mutex_trylock(&iaxsl[callno1])) {
05468 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05469 }
05470 }
05471
05472 static void unlock_both(unsigned short callno0, unsigned short callno1)
05473 {
05474 ast_mutex_unlock(&iaxsl[callno1]);
05475 ast_mutex_unlock(&iaxsl[callno0]);
05476 }
05477
05478 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)
05479 {
05480 struct ast_channel *cs[3];
05481 struct ast_channel *who, *other;
05482 int to = -1;
05483 int res = -1;
05484 int transferstarted=0;
05485 struct ast_frame *f;
05486 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05487 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05488 struct timeval waittimer = {0, 0};
05489
05490
05491 if (timeoutms > 0) {
05492 return AST_BRIDGE_FAILED;
05493 }
05494
05495 timeoutms = -1;
05496
05497 lock_both(callno0, callno1);
05498 if (!iaxs[callno0] || !iaxs[callno1]) {
05499 unlock_both(callno0, callno1);
05500 return AST_BRIDGE_FAILED;
05501 }
05502
05503 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05504 iaxs[callno0]->bridgecallno = callno1;
05505 iaxs[callno1]->bridgecallno = callno0;
05506 }
05507 unlock_both(callno0, callno1);
05508
05509
05510 cs[0] = c0;
05511 cs[1] = c1;
05512 for (;;) {
05513
05514 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05515 ast_verb(3, "Can't masquerade, we're different...\n");
05516
05517 if (c0->tech == &iax2_tech) {
05518 ast_mutex_lock(&iaxsl[callno0]);
05519 iaxs[callno0]->bridgecallno = 0;
05520 ast_mutex_unlock(&iaxsl[callno0]);
05521 }
05522 if (c1->tech == &iax2_tech) {
05523 ast_mutex_lock(&iaxsl[callno1]);
05524 iaxs[callno1]->bridgecallno = 0;
05525 ast_mutex_unlock(&iaxsl[callno1]);
05526 }
05527 return AST_BRIDGE_FAILED_NOWARN;
05528 }
05529 if (c0->nativeformats != c1->nativeformats) {
05530 char buf0[256];
05531 char buf1[256];
05532 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05533 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05534 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05535
05536 lock_both(callno0, callno1);
05537 if (iaxs[callno0])
05538 iaxs[callno0]->bridgecallno = 0;
05539 if (iaxs[callno1])
05540 iaxs[callno1]->bridgecallno = 0;
05541 unlock_both(callno0, callno1);
05542 return AST_BRIDGE_FAILED_NOWARN;
05543 }
05544
05545 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05546
05547 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05548 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05549 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05550 transferstarted = 1;
05551 }
05552 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05553
05554 struct timeval now = ast_tvnow();
05555 if (ast_tvzero(waittimer)) {
05556 waittimer = now;
05557 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05558 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05559 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05560 *fo = NULL;
05561 *rc = c0;
05562 res = AST_BRIDGE_COMPLETE;
05563 break;
05564 }
05565 }
05566 to = 1000;
05567 who = ast_waitfor_n(cs, 2, &to);
05568
05569
05570
05571
05572
05573 if (timeoutms > -1) {
05574 timeoutms -= (1000 - to);
05575 if (timeoutms < 0)
05576 timeoutms = 0;
05577 }
05578 if (!who) {
05579 if (!timeoutms) {
05580 res = AST_BRIDGE_RETRY;
05581 break;
05582 }
05583 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05584 res = AST_BRIDGE_FAILED;
05585 break;
05586 }
05587 continue;
05588 }
05589 f = ast_read(who);
05590 if (!f) {
05591 *fo = NULL;
05592 *rc = who;
05593 res = AST_BRIDGE_COMPLETE;
05594 break;
05595 }
05596 other = (who == c0) ? c1 : c0;
05597 if (f->frametype == AST_FRAME_CONTROL && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
05598 switch (f->subclass.integer) {
05599 case AST_CONTROL_VIDUPDATE:
05600 case AST_CONTROL_SRCUPDATE:
05601 case AST_CONTROL_SRCCHANGE:
05602 case AST_CONTROL_T38_PARAMETERS:
05603 ast_write(other, f);
05604 break;
05605 default:
05606 *fo = f;
05607 *rc = who;
05608 res = AST_BRIDGE_COMPLETE;
05609 break;
05610 }
05611 if (res == AST_BRIDGE_COMPLETE) {
05612 break;
05613 }
05614 } else if (f->frametype == AST_FRAME_VOICE
05615 || f->frametype == AST_FRAME_TEXT
05616 || f->frametype == AST_FRAME_VIDEO
05617 || f->frametype == AST_FRAME_IMAGE) {
05618 ast_write(other, f);
05619 } else if (f->frametype == AST_FRAME_DTMF) {
05620
05621
05622
05623 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05624
05625 if (flags & monitored_source) {
05626 *rc = who;
05627 *fo = f;
05628 res = AST_BRIDGE_COMPLETE;
05629
05630 break;
05631 }
05632 ast_write(other, f);
05633 }
05634 ast_frfree(f);
05635
05636 cs[2] = cs[0];
05637 cs[0] = cs[1];
05638 cs[1] = cs[2];
05639 }
05640 lock_both(callno0, callno1);
05641 if(iaxs[callno0])
05642 iaxs[callno0]->bridgecallno = 0;
05643 if(iaxs[callno1])
05644 iaxs[callno1]->bridgecallno = 0;
05645 unlock_both(callno0, callno1);
05646 return res;
05647 }
05648
05649 static int iax2_answer(struct ast_channel *c)
05650 {
05651 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05652 ast_debug(1, "Answering IAX2 call\n");
05653 ast_mutex_lock(&iaxsl[callno]);
05654 if (iaxs[callno])
05655 iax2_ami_channelupdate(iaxs[callno]);
05656 ast_mutex_unlock(&iaxsl[callno]);
05657 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05658 }
05659
05660 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05661 {
05662 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05663 struct chan_iax2_pvt *pvt;
05664 int res = 0;
05665
05666 if (iaxdebug)
05667 ast_debug(1, "Indicating condition %d\n", condition);
05668
05669 ast_mutex_lock(&iaxsl[callno]);
05670 pvt = iaxs[callno];
05671
05672 if (wait_for_peercallno(pvt)) {
05673 res = -1;
05674 goto done;
05675 }
05676
05677 switch (condition) {
05678 case AST_CONTROL_HOLD:
05679 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05680 ast_moh_start(c, data, pvt->mohinterpret);
05681 goto done;
05682 }
05683 break;
05684 case AST_CONTROL_UNHOLD:
05685 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05686 ast_moh_stop(c);
05687 goto done;
05688 }
05689 break;
05690 case AST_CONTROL_CONNECTED_LINE:
05691 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05692 goto done;
05693 break;
05694 }
05695
05696 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05697
05698 done:
05699 ast_mutex_unlock(&iaxsl[callno]);
05700
05701 return res;
05702 }
05703
05704 static int iax2_transfer(struct ast_channel *c, const char *dest)
05705 {
05706 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05707 struct iax_ie_data ied = { "", };
05708 char tmp[256], *context;
05709 enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05710 ast_copy_string(tmp, dest, sizeof(tmp));
05711 context = strchr(tmp, '@');
05712 if (context) {
05713 *context = '\0';
05714 context++;
05715 }
05716 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05717 if (context)
05718 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05719 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05720 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05721 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05722 }
05723
05724 static int iax2_getpeertrunk(struct sockaddr_in sin)
05725 {
05726 struct iax2_peer *peer;
05727 int res = 0;
05728 struct ao2_iterator i;
05729
05730 i = ao2_iterator_init(peers, 0);
05731 while ((peer = ao2_iterator_next(&i))) {
05732 struct sockaddr_in peer_addr;
05733
05734 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05735
05736 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05737 (peer_addr.sin_port == sin.sin_port)) {
05738 res = ast_test_flag64(peer, IAX_TRUNK);
05739 peer_unref(peer);
05740 break;
05741 }
05742 peer_unref(peer);
05743 }
05744 ao2_iterator_destroy(&i);
05745
05746 return res;
05747 }
05748
05749
05750 static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid, unsigned int cachable)
05751 {
05752 struct ast_channel *tmp;
05753 struct chan_iax2_pvt *i;
05754 struct ast_variable *v = NULL;
05755
05756 if (!(i = iaxs[callno])) {
05757 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05758 return NULL;
05759 }
05760
05761
05762 ast_mutex_unlock(&iaxsl[callno]);
05763 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);
05764 ast_mutex_lock(&iaxsl[callno]);
05765 if (i != iaxs[callno]) {
05766 if (tmp) {
05767
05768 ast_mutex_unlock(&iaxsl[callno]);
05769 tmp = ast_channel_release(tmp);
05770 ast_mutex_lock(&iaxsl[callno]);
05771 }
05772 return NULL;
05773 }
05774 iax2_ami_channelupdate(i);
05775 if (!tmp)
05776 return NULL;
05777 tmp->tech = &iax2_tech;
05778
05779 tmp->nativeformats = capability;
05780 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05781 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05782 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05783
05784 if (!ast_strlen_zero(i->parkinglot))
05785 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05786
05787
05788 if (!ast_strlen_zero(i->ani)) {
05789 tmp->caller.ani.number.valid = 1;
05790 tmp->caller.ani.number.str = ast_strdup(i->ani);
05791 } else if (!ast_strlen_zero(i->cid_num)) {
05792 tmp->caller.ani.number.valid = 1;
05793 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05794 }
05795 tmp->dialed.number.str = ast_strdup(i->dnid);
05796 if (!ast_strlen_zero(i->rdnis)) {
05797 tmp->redirecting.from.number.valid = 1;
05798 tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05799 }
05800 tmp->caller.id.name.presentation = i->calling_pres;
05801 tmp->caller.id.number.presentation = i->calling_pres;
05802 tmp->caller.id.number.plan = i->calling_ton;
05803 tmp->dialed.transit_network_select = i->calling_tns;
05804 if (!ast_strlen_zero(i->language))
05805 ast_string_field_set(tmp, language, i->language);
05806 if (!ast_strlen_zero(i->accountcode))
05807 ast_string_field_set(tmp, accountcode, i->accountcode);
05808 if (i->amaflags)
05809 tmp->amaflags = i->amaflags;
05810 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05811 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05812 if (i->adsi)
05813 tmp->adsicpe = i->peeradsicpe;
05814 else
05815 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05816 i->owner = tmp;
05817 i->capability = capability;
05818
05819 if (!cachable) {
05820 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE;
05821 }
05822
05823
05824 if (i->vars) {
05825 for (v = i->vars ; v ; v = v->next)
05826 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05827 }
05828 if (i->iaxvars) {
05829 struct ast_datastore *variablestore;
05830 struct ast_variable *var, *prev = NULL;
05831 AST_LIST_HEAD(, ast_var_t) *varlist;
05832 ast_debug(1, "Loading up the channel with IAXVARs\n");
05833 varlist = ast_calloc(1, sizeof(*varlist));
05834 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05835 if (variablestore && varlist) {
05836 variablestore->data = varlist;
05837 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05838 AST_LIST_HEAD_INIT(varlist);
05839 for (var = i->iaxvars; var; var = var->next) {
05840 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05841 if (prev)
05842 ast_free(prev);
05843 prev = var;
05844 if (!newvar) {
05845
05846 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05847 } else {
05848 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05849 }
05850 }
05851 if (prev)
05852 ast_free(prev);
05853 i->iaxvars = NULL;
05854 ast_channel_datastore_add(i->owner, variablestore);
05855 } else {
05856 if (variablestore) {
05857 ast_datastore_free(variablestore);
05858 }
05859 if (varlist) {
05860 ast_free(varlist);
05861 }
05862 }
05863 }
05864
05865 if (state != AST_STATE_DOWN) {
05866 if (ast_pbx_start(tmp)) {
05867 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05868 ast_hangup(tmp);
05869 i->owner = NULL;
05870 return NULL;
05871 }
05872 }
05873
05874 ast_module_ref(ast_module_info->self);
05875 return tmp;
05876 }
05877
05878 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05879 {
05880 unsigned long int mssincetx;
05881 long int ms, pred;
05882
05883 tpeer->trunkact = *now;
05884 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05885 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05886
05887 tpeer->txtrunktime = *now;
05888 tpeer->lastsent = 999999;
05889 }
05890
05891 tpeer->lasttxtime = *now;
05892
05893
05894 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05895
05896 pred = tpeer->lastsent + sampms;
05897 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05898 ms = pred;
05899
05900
05901 if (ms == tpeer->lastsent)
05902 ms = tpeer->lastsent + 1;
05903 tpeer->lastsent = ms;
05904 return ms;
05905 }
05906
05907 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05908 {
05909 long ms;
05910 if (ast_tvzero(iaxs[callno]->rxcore)) {
05911
05912 iaxs[callno]->rxcore = ast_tvnow();
05913
05914 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05915 }
05916
05917 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05918
05919 return ms + ts;
05920 }
05921
05922 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05923 {
05924 int ms;
05925 int voice = 0;
05926 int genuine = 0;
05927 int adjust;
05928 int rate = ast_format_rate(f->subclass.codec) / 1000;
05929 struct timeval *delivery = NULL;
05930
05931
05932
05933
05934
05935
05936
05937
05938 if (f->frametype == AST_FRAME_VOICE) {
05939 voice = 1;
05940 delivery = &f->delivery;
05941 } else if (f->frametype == AST_FRAME_IAX) {
05942 genuine = 1;
05943 } else if (f->frametype == AST_FRAME_CNG) {
05944 p->notsilenttx = 0;
05945 }
05946
05947 if (ast_tvzero(p->offset)) {
05948 p->offset = ast_tvnow();
05949
05950 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05951 }
05952
05953 if (ts)
05954 return ts;
05955
05956 if (delivery && !ast_tvzero(*delivery)) {
05957 ms = ast_tvdiff_ms(*delivery, p->offset);
05958 if (ms < 0) {
05959 ms = 0;
05960 }
05961 if (iaxdebug)
05962 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05963 } else {
05964 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05965 if (ms < 0)
05966 ms = 0;
05967 if (voice) {
05968
05969 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05970
05971
05972
05973
05974
05975
05976
05977
05978
05979
05980
05981
05982
05983
05984
05985
05986
05987
05988 adjust = (ms - p->nextpred);
05989 if (adjust < 0)
05990 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05991 else if (adjust > 0)
05992 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05993
05994 if (!p->nextpred) {
05995 p->nextpred = ms;
05996 if (p->nextpred <= p->lastsent)
05997 p->nextpred = p->lastsent + 3;
05998 }
05999 ms = p->nextpred;
06000 } else {
06001
06002
06003
06004
06005
06006
06007
06008
06009
06010 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
06011 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
06012 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
06013
06014 if (f->samples >= rate)
06015 {
06016 int diff = ms % (f->samples / rate);
06017 if (diff)
06018 ms += f->samples/rate - diff;
06019 }
06020
06021 p->nextpred = ms;
06022 p->notsilenttx = 1;
06023 }
06024 } else if ( f->frametype == AST_FRAME_VIDEO ) {
06025
06026
06027
06028
06029
06030
06031
06032
06033 if ( (unsigned int)ms < p->lastsent )
06034 ms = p->lastsent;
06035 } else {
06036
06037
06038 if (genuine) {
06039
06040 if (ms <= p->lastsent)
06041 ms = p->lastsent + 3;
06042 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
06043
06044 ms = p->lastsent + 3;
06045 }
06046 }
06047 }
06048 p->lastsent = ms;
06049 if (voice)
06050 p->nextpred = p->nextpred + f->samples / rate;
06051 return ms;
06052 }
06053
06054 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
06055 {
06056
06057
06058 int ms;
06059 #ifdef IAXTESTS
06060 int jit;
06061 #endif
06062
06063 if (ast_tvzero(p->rxcore)) {
06064 p->rxcore = ast_tvnow();
06065 if (iaxdebug)
06066 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06067 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06068 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06069 #if 1
06070 if (iaxdebug)
06071 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06072 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06073 #endif
06074 }
06075
06076 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06077 #ifdef IAXTESTS
06078 if (test_jit) {
06079 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06080 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06081 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06082 jit = -jit;
06083 ms += jit;
06084 }
06085 }
06086 if (test_late) {
06087 ms += test_late;
06088 test_late = 0;
06089 }
06090 #endif
06091 return ms;
06092 }
06093
06094 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
06095 {
06096 struct iax2_trunk_peer *tpeer = NULL;
06097
06098
06099 AST_LIST_LOCK(&tpeers);
06100
06101 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06102 if (!inaddrcmp(&tpeer->addr, sin)) {
06103 ast_mutex_lock(&tpeer->lock);
06104 break;
06105 }
06106 }
06107
06108 if (!tpeer) {
06109 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06110 ast_mutex_init(&tpeer->lock);
06111 tpeer->lastsent = 9999;
06112 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06113 tpeer->trunkact = ast_tvnow();
06114 ast_mutex_lock(&tpeer->lock);
06115 tpeer->sockfd = fd;
06116 #ifdef SO_NO_CHECK
06117 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06118 #endif
06119 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06120 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06121 }
06122 }
06123
06124 AST_LIST_UNLOCK(&tpeers);
06125
06126 return tpeer;
06127 }
06128
06129 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
06130 {
06131 struct ast_frame *f;
06132 struct iax2_trunk_peer *tpeer;
06133 void *tmp, *ptr;
06134 struct timeval now;
06135 struct ast_iax2_meta_trunk_entry *met;
06136 struct ast_iax2_meta_trunk_mini *mtm;
06137
06138 f = &fr->af;
06139 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06140 if (tpeer) {
06141 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06142
06143 if (tpeer->trunkdataalloc < trunkmaxsize) {
06144 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06145 ast_mutex_unlock(&tpeer->lock);
06146 return -1;
06147 }
06148
06149 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06150 tpeer->trunkdata = tmp;
06151 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);
06152 } else {
06153 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));
06154 ast_mutex_unlock(&tpeer->lock);
06155 return -1;
06156 }
06157 }
06158
06159
06160 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06161 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06162 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06163 mtm->len = htons(f->datalen);
06164 mtm->mini.callno = htons(pvt->callno);
06165 mtm->mini.ts = htons(0xffff & fr->ts);
06166 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06167 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06168 } else {
06169 met = (struct ast_iax2_meta_trunk_entry *)ptr;
06170
06171 met->callno = htons(pvt->callno);
06172 met->len = htons(f->datalen);
06173
06174 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06175 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06176 }
06177
06178 memcpy(ptr, f->data.ptr, f->datalen);
06179 tpeer->trunkdatalen += f->datalen;
06180
06181 tpeer->calls++;
06182
06183
06184 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
06185 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
06186
06187
06188 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06189 now = ast_tvnow();
06190 send_trunk(tpeer, &now);
06191 trunk_untimed ++;
06192 }
06193
06194 ast_mutex_unlock(&tpeer->lock);
06195 }
06196 return 0;
06197 }
06198
06199
06200
06201 static void build_rand_pad(unsigned char *buf, ssize_t len)
06202 {
06203 long tmp;
06204 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06205 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06206 buf += sizeof(tmp);
06207 len -= sizeof(tmp);
06208 }
06209 }
06210
06211 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06212 {
06213 build_ecx_key(digest, pvt);
06214 ast_aes_set_decrypt_key(digest, &pvt->dcx);
06215 }
06216
06217 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06218 {
06219
06220
06221
06222 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06223 ast_aes_set_encrypt_key(digest, &pvt->ecx);
06224 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06225 }
06226
06227 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
06228 {
06229 #if 0
06230
06231 int x;
06232 if (len % 16)
06233 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06234 for (x=0;x<len;x++)
06235 dst[x] = src[x] ^ 0xff;
06236 #else
06237 unsigned char lastblock[16] = { 0 };
06238 int x;
06239 while(len > 0) {
06240 ast_aes_decrypt(src, dst, dcx);
06241 for (x=0;x<16;x++)
06242 dst[x] ^= lastblock[x];
06243 memcpy(lastblock, src, sizeof(lastblock));
06244 dst += 16;
06245 src += 16;
06246 len -= 16;
06247 }
06248 #endif
06249 }
06250
06251 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
06252 {
06253 #if 0
06254
06255 int x;
06256 if (len % 16)
06257 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06258 for (x=0;x<len;x++)
06259 dst[x] = src[x] ^ 0xff;
06260 #else
06261 unsigned char curblock[16] = { 0 };
06262 int x;
06263 while(len > 0) {
06264 for (x=0;x<16;x++)
06265 curblock[x] ^= src[x];
06266 ast_aes_encrypt(curblock, dst, ecx);
06267 memcpy(curblock, dst, sizeof(curblock));
06268 dst += 16;
06269 src += 16;
06270 len -= 16;
06271 }
06272 #endif
06273 }
06274
06275 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06276 {
06277 int padding;
06278 unsigned char *workspace;
06279
06280 workspace = ast_alloca(*datalen);
06281 memset(f, 0, sizeof(*f));
06282 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06283 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06284 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06285 return -1;
06286
06287 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06288
06289 padding = 16 + (workspace[15] & 0x0f);
06290 if (iaxdebug)
06291 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06292 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06293 return -1;
06294
06295 *datalen -= padding;
06296 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06297 f->frametype = fh->type;
06298 if (f->frametype == AST_FRAME_VIDEO) {
06299 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06300 } else if (f->frametype == AST_FRAME_VOICE) {
06301 f->subclass.codec = uncompress_subclass(fh->csub);
06302 } else {
06303 f->subclass.integer = uncompress_subclass(fh->csub);
06304 }
06305 } else {
06306 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06307 if (iaxdebug)
06308 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06309 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06310 return -1;
06311
06312 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06313 padding = 16 + (workspace[15] & 0x0f);
06314 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06315 return -1;
06316 *datalen -= padding;
06317 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06318 }
06319 return 0;
06320 }
06321
06322 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06323 {
06324 int padding;
06325 unsigned char *workspace;
06326 workspace = ast_alloca(*datalen + 32);
06327 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06328 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06329 if (iaxdebug)
06330 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06331 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06332 padding = 16 + (padding & 0xf);
06333 memcpy(workspace, poo, padding);
06334 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06335 workspace[15] &= 0xf0;
06336 workspace[15] |= (padding & 0xf);
06337 if (iaxdebug)
06338 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06339 *datalen += padding;
06340 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06341 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06342 memcpy(poo, workspace + *datalen - 32, 32);
06343 } else {
06344 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06345 if (iaxdebug)
06346 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06347 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06348 padding = 16 + (padding & 0xf);
06349 memcpy(workspace, poo, padding);
06350 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06351 workspace[15] &= 0xf0;
06352 workspace[15] |= (padding & 0x0f);
06353 *datalen += padding;
06354 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06355 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06356 memcpy(poo, workspace + *datalen - 32, 32);
06357 }
06358 return 0;
06359 }
06360
06361 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06362 {
06363 int res=-1;
06364 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06365
06366 struct MD5Context md5;
06367 unsigned char digest[16];
06368 char *tmppw, *stringp;
06369
06370 tmppw = ast_strdupa(iaxs[callno]->secret);
06371 stringp = tmppw;
06372 while ((tmppw = strsep(&stringp, ";"))) {
06373 MD5Init(&md5);
06374 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06375 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06376 MD5Final(digest, &md5);
06377 build_encryption_keys(digest, iaxs[callno]);
06378 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06379 if (!res) {
06380 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06381 break;
06382 }
06383 }
06384 } else
06385 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06386 return res;
06387 }
06388
06389 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06390 {
06391
06392
06393
06394 struct ast_iax2_full_hdr *fh;
06395 struct ast_iax2_mini_hdr *mh;
06396 struct ast_iax2_video_hdr *vh;
06397 struct {
06398 struct iax_frame fr2;
06399 unsigned char buffer[4096];
06400 } frb;
06401 struct iax_frame *fr;
06402 int res;
06403 int sendmini=0;
06404 unsigned int lastsent;
06405 unsigned int fts;
06406
06407 frb.fr2.afdatalen = sizeof(frb.buffer);
06408
06409 if (!pvt) {
06410 ast_log(LOG_WARNING, "No private structure for packet?\n");
06411 return -1;
06412 }
06413
06414 lastsent = pvt->lastsent;
06415
06416
06417 fts = calc_timestamp(pvt, ts, f);
06418
06419
06420
06421
06422 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06423 return 0;
06424 #if 0
06425 ast_log(LOG_NOTICE,
06426 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06427 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06428 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06429 pvt->keyrotateid != -1 ? "" : "no "
06430 );
06431 #endif
06432 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06433 iax2_key_rotate(pvt);
06434 }
06435
06436 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
06437 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06438 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06439 &&
06440 (f->frametype == AST_FRAME_VOICE)
06441 &&
06442 (f->subclass.codec == pvt->svoiceformat)
06443 ) {
06444
06445 now = 1;
06446
06447 sendmini = 1;
06448 }
06449 if ( f->frametype == AST_FRAME_VIDEO ) {
06450
06451
06452
06453
06454
06455 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06456 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06457 ) {
06458 now = 1;
06459 sendmini = 1;
06460 } else {
06461 now = 0;
06462 sendmini = 0;
06463 }
06464 pvt->lastvsent = fts;
06465 }
06466 if (f->frametype == AST_FRAME_IAX) {
06467
06468 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06469 if (!pvt->first_iax_message) {
06470 pvt->first_iax_message = pvt->last_iax_message;
06471 }
06472 }
06473
06474 if (now) {
06475 fr = &frb.fr2;
06476 } else
06477 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));
06478 if (!fr) {
06479 ast_log(LOG_WARNING, "Out of memory\n");
06480 return -1;
06481 }
06482
06483 iax_frame_wrap(fr, f);
06484
06485 fr->ts = fts;
06486 fr->callno = pvt->callno;
06487 fr->transfer = transfer;
06488 fr->final = final;
06489 fr->encmethods = 0;
06490 if (!sendmini) {
06491
06492 if (seqno > -1)
06493 fr->oseqno = seqno;
06494 else
06495 fr->oseqno = pvt->oseqno++;
06496 fr->iseqno = pvt->iseqno;
06497 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06498 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06499 fh->ts = htonl(fr->ts);
06500 fh->oseqno = fr->oseqno;
06501 if (transfer) {
06502 fh->iseqno = 0;
06503 } else
06504 fh->iseqno = fr->iseqno;
06505
06506 if (!transfer)
06507 pvt->aseqno = fr->iseqno;
06508 fh->type = fr->af.frametype & 0xFF;
06509
06510 if (fr->af.frametype == AST_FRAME_VIDEO) {
06511 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06512 } else if (fr->af.frametype == AST_FRAME_VOICE) {
06513 fh->csub = compress_subclass(fr->af.subclass.codec);
06514 } else {
06515 fh->csub = compress_subclass(fr->af.subclass.integer);
06516 }
06517
06518 if (transfer) {
06519 fr->dcallno = pvt->transfercallno;
06520 } else
06521 fr->dcallno = pvt->peercallno;
06522 fh->dcallno = htons(fr->dcallno);
06523 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06524 fr->data = fh;
06525 fr->retries = 0;
06526
06527 fr->retrytime = pvt->pingtime * 2;
06528 if (fr->retrytime < MIN_RETRY_TIME)
06529 fr->retrytime = MIN_RETRY_TIME;
06530 if (fr->retrytime > MAX_RETRY_TIME)
06531 fr->retrytime = MAX_RETRY_TIME;
06532
06533 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06534 fr->retries = -1;
06535 else if (f->frametype == AST_FRAME_VOICE)
06536 pvt->svoiceformat = f->subclass.codec;
06537 else if (f->frametype == AST_FRAME_VIDEO)
06538 pvt->svideoformat = f->subclass.codec & ~0x1LL;
06539 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06540 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06541 if (fr->transfer)
06542 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06543 else
06544 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06545 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06546 fr->encmethods = pvt->encmethods;
06547 fr->ecx = pvt->ecx;
06548 fr->mydcx = pvt->mydcx;
06549 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06550 } else
06551 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06552 }
06553
06554 if (now) {
06555 res = send_packet(fr);
06556 } else
06557 res = iax2_transmit(fr);
06558 } else {
06559 if (ast_test_flag64(pvt, IAX_TRUNK)) {
06560 iax2_trunk_queue(pvt, fr);
06561 res = 0;
06562 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06563
06564 fr->oseqno = -1;
06565 fr->iseqno = -1;
06566 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06567 vh->zeros = 0;
06568 vh->callno = htons(0x8000 | fr->callno);
06569 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06570 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06571 fr->data = vh;
06572 fr->retries = -1;
06573 res = send_packet(fr);
06574 } else {
06575
06576 fr->oseqno = -1;
06577 fr->iseqno = -1;
06578
06579 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06580 mh->callno = htons(fr->callno);
06581 mh->ts = htons(fr->ts & 0xFFFF);
06582 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06583 fr->data = mh;
06584 fr->retries = -1;
06585 if (pvt->transferring == TRANSFER_MEDIAPASS)
06586 fr->transfer = 1;
06587 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06588 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06589 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06590 } else
06591 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06592 }
06593 res = send_packet(fr);
06594 }
06595 }
06596 return res;
06597 }
06598
06599 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06600 {
06601 regex_t regexbuf;
06602 int havepattern = 0;
06603
06604 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06605 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06606
06607 struct iax2_user *user = NULL;
06608 char auth[90];
06609 char *pstr = "";
06610 struct ao2_iterator i;
06611
06612 switch (cmd) {
06613 case CLI_INIT:
06614 e->command = "iax2 show users [like]";
06615 e->usage =
06616 "Usage: iax2 show users [like <pattern>]\n"
06617 " Lists all known IAX2 users.\n"
06618 " Optional regular expression pattern is used to filter the user list.\n";
06619 return NULL;
06620 case CLI_GENERATE:
06621 return NULL;
06622 }
06623
06624 switch (a->argc) {
06625 case 5:
06626 if (!strcasecmp(a->argv[3], "like")) {
06627 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06628 return CLI_SHOWUSAGE;
06629 havepattern = 1;
06630 } else
06631 return CLI_SHOWUSAGE;
06632 case 3:
06633 break;
06634 default:
06635 return CLI_SHOWUSAGE;
06636 }
06637
06638 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06639 i = ao2_iterator_init(users, 0);
06640 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
06641 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06642 continue;
06643
06644 if (!ast_strlen_zero(user->secret)) {
06645 ast_copy_string(auth,user->secret, sizeof(auth));
06646 } else if (!ast_strlen_zero(user->inkeys)) {
06647 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06648 } else
06649 ast_copy_string(auth, "-no secret-", sizeof(auth));
06650
06651 if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06652 pstr = "REQ Only";
06653 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06654 pstr = "Disabled";
06655 else
06656 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06657
06658 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06659 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06660 user->ha ? "Yes" : "No", pstr);
06661 }
06662 ao2_iterator_destroy(&i);
06663
06664 if (havepattern)
06665 regfree(®exbuf);
06666
06667 return CLI_SUCCESS;
06668 #undef FORMAT
06669 #undef FORMAT2
06670 }
06671
06672 static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
06673 {
06674 regex_t regexbuf;
06675 int havepattern = 0;
06676 int total_peers = 0;
06677 int online_peers = 0;
06678 int offline_peers = 0;
06679 int unmonitored_peers = 0;
06680 struct ao2_iterator i;
06681
06682 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
06683 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
06684
06685 struct iax2_peer *peer = NULL;
06686 char name[256];
06687 struct ast_str *encmethods = ast_str_alloca(256);
06688 int registeredonly=0;
06689 char idtext[256] = "";
06690 switch (argc) {
06691 case 6:
06692 if (!strcasecmp(argv[3], "registered"))
06693 registeredonly = 1;
06694 else
06695 return RESULT_SHOWUSAGE;
06696 if (!strcasecmp(argv[4], "like")) {
06697 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06698 return RESULT_SHOWUSAGE;
06699 havepattern = 1;
06700 } else
06701 return RESULT_SHOWUSAGE;
06702 break;
06703 case 5:
06704 if (!strcasecmp(argv[3], "like")) {
06705 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06706 return RESULT_SHOWUSAGE;
06707 havepattern = 1;
06708 } else
06709 return RESULT_SHOWUSAGE;
06710 break;
06711 case 4:
06712 if (!strcasecmp(argv[3], "registered"))
06713 registeredonly = 1;
06714 else
06715 return RESULT_SHOWUSAGE;
06716 break;
06717 case 3:
06718 break;
06719 default:
06720 return RESULT_SHOWUSAGE;
06721 }
06722
06723
06724 if (!s)
06725 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status");
06726
06727 i = ao2_iterator_init(peers, 0);
06728 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06729 char nm[20];
06730 char status[20];
06731 int retstatus;
06732 struct sockaddr_in peer_addr;
06733
06734 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06735
06736 if (registeredonly && !peer_addr.sin_addr.s_addr) {
06737 continue;
06738 }
06739 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
06740 continue;
06741 }
06742
06743 if (!ast_strlen_zero(peer->username))
06744 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06745 else
06746 ast_copy_string(name, peer->name, sizeof(name));
06747
06748 encmethods_to_str(peer->encmethods, &encmethods);
06749 retstatus = peer_status(peer, status, sizeof(status));
06750 if (retstatus > 0)
06751 online_peers++;
06752 else if (!retstatus)
06753 offline_peers++;
06754 else
06755 unmonitored_peers++;
06756
06757 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06758
06759 if (s) {
06760 astman_append(s,
06761 "Event: PeerEntry\r\n%s"
06762 "Channeltype: IAX2\r\n"
06763 "ObjectName: %s\r\n"
06764 "ChanObjectType: peer\r\n"
06765 "IPaddress: %s\r\n"
06766 "IPport: %d\r\n"
06767 "Dynamic: %s\r\n"
06768 "Trunk: %s\r\n"
06769 "Encryption: %s\r\n"
06770 "Status: %s\r\n\r\n",
06771 idtext,
06772 name,
06773 ast_sockaddr_stringify_addr(&peer->addr),
06774 ast_sockaddr_port(&peer->addr),
06775 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06776 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06777 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06778 status);
06779 } else {
06780 ast_cli(fd, FORMAT, name,
06781 ast_sockaddr_stringify_addr(&peer->addr),
06782 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06783 nm,
06784 ast_sockaddr_port(&peer->addr),
06785 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
06786 peer->encmethods ? "(E)" : " ",
06787 status);
06788 }
06789 total_peers++;
06790 }
06791 ao2_iterator_destroy(&i);
06792
06793 if (!s)
06794 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06795 total_peers, online_peers, offline_peers, unmonitored_peers);
06796
06797 if (havepattern)
06798 regfree(®exbuf);
06799
06800 if (total)
06801 *total = total_peers;
06802
06803 return RESULT_SUCCESS;
06804 #undef FORMAT
06805 #undef FORMAT2
06806 }
06807
06808 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06809 {
06810 struct iax2_thread *thread = NULL;
06811 time_t t;
06812 int threadcount = 0, dynamiccount = 0;
06813 char type;
06814
06815 switch (cmd) {
06816 case CLI_INIT:
06817 e->command = "iax2 show threads";
06818 e->usage =
06819 "Usage: iax2 show threads\n"
06820 " Lists status of IAX helper threads\n";
06821 return NULL;
06822 case CLI_GENERATE:
06823 return NULL;
06824 }
06825 if (a->argc != 3)
06826 return CLI_SHOWUSAGE;
06827
06828 ast_cli(a->fd, "IAX2 Thread Information\n");
06829 time(&t);
06830 ast_cli(a->fd, "Idle Threads:\n");
06831 AST_LIST_LOCK(&idle_list);
06832 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06833 #ifdef DEBUG_SCHED_MULTITHREAD
06834 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06835 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06836 #else
06837 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06838 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06839 #endif
06840 threadcount++;
06841 }
06842 AST_LIST_UNLOCK(&idle_list);
06843 ast_cli(a->fd, "Active Threads:\n");
06844 AST_LIST_LOCK(&active_list);
06845 AST_LIST_TRAVERSE(&active_list, thread, list) {
06846 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06847 type = 'D';
06848 else
06849 type = 'P';
06850 #ifdef DEBUG_SCHED_MULTITHREAD
06851 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06852 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06853 #else
06854 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06855 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06856 #endif
06857 threadcount++;
06858 }
06859 AST_LIST_UNLOCK(&active_list);
06860 ast_cli(a->fd, "Dynamic Threads:\n");
06861 AST_LIST_LOCK(&dynamic_list);
06862 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06863 #ifdef DEBUG_SCHED_MULTITHREAD
06864 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06865 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06866 #else
06867 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06868 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06869 #endif
06870 dynamiccount++;
06871 }
06872 AST_LIST_UNLOCK(&dynamic_list);
06873 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06874 return CLI_SUCCESS;
06875 }
06876
06877 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06878 {
06879 struct iax2_peer *p;
06880
06881 switch (cmd) {
06882 case CLI_INIT:
06883 e->command = "iax2 unregister";
06884 e->usage =
06885 "Usage: iax2 unregister <peername>\n"
06886 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06887 return NULL;
06888 case CLI_GENERATE:
06889 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06890 }
06891
06892 if (a->argc != 3)
06893 return CLI_SHOWUSAGE;
06894
06895 p = find_peer(a->argv[2], 1);
06896 if (p) {
06897 if (p->expire > 0) {
06898 struct iax2_peer tmp_peer = {
06899 .name = a->argv[2],
06900 };
06901 struct iax2_peer *peer;
06902
06903 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06904 if (peer) {
06905 expire_registry(peer_ref(peer));
06906 peer_unref(peer);
06907 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06908 } else {
06909 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06910 }
06911 } else {
06912 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06913 }
06914 peer_unref(p);
06915 } else {
06916 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06917 }
06918 return CLI_SUCCESS;
06919 }
06920
06921 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06922 {
06923 int which = 0;
06924 struct iax2_peer *p = NULL;
06925 char *res = NULL;
06926 int wordlen = strlen(word);
06927
06928
06929 if (pos == 2) {
06930 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06931 while ((p = ao2_iterator_next(&i))) {
06932 if (!strncasecmp(p->name, word, wordlen) &&
06933 ++which > state && p->expire > 0) {
06934 res = ast_strdup(p->name);
06935 peer_unref(p);
06936 break;
06937 }
06938 peer_unref(p);
06939 }
06940 ao2_iterator_destroy(&i);
06941 }
06942
06943 return res;
06944 }
06945
06946 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06947 {
06948 switch (cmd) {
06949 case CLI_INIT:
06950 e->command = "iax2 show peers";
06951 e->usage =
06952 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06953 " Lists all known IAX2 peers.\n"
06954 " Optional 'registered' argument lists only peers with known addresses.\n"
06955 " Optional regular expression pattern is used to filter the peer list.\n";
06956 return NULL;
06957 case CLI_GENERATE:
06958 return NULL;
06959 }
06960
06961 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06962 case RESULT_SHOWUSAGE:
06963 return CLI_SHOWUSAGE;
06964 case RESULT_FAILURE:
06965 return CLI_FAILURE;
06966 default:
06967 return CLI_SUCCESS;
06968 }
06969 }
06970
06971 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06972 {
06973 ast_cli_netstats(s, -1, 0);
06974 astman_append(s, "\r\n");
06975 return RESULT_SUCCESS;
06976 }
06977
06978 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06979 {
06980 struct iax_firmware *cur = NULL;
06981
06982 switch (cmd) {
06983 case CLI_INIT:
06984 e->command = "iax2 show firmware";
06985 e->usage =
06986 "Usage: iax2 show firmware\n"
06987 " Lists all known IAX firmware images.\n";
06988 return NULL;
06989 case CLI_GENERATE:
06990 return NULL;
06991 }
06992
06993 if (a->argc != 3 && a->argc != 4)
06994 return CLI_SHOWUSAGE;
06995
06996 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06997 AST_LIST_LOCK(&firmwares);
06998 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06999 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
07000 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
07001 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
07002 }
07003 }
07004 AST_LIST_UNLOCK(&firmwares);
07005
07006 return CLI_SUCCESS;
07007 }
07008
07009
07010 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
07011 {
07012 static const char * const a[] = { "iax2", "show", "peers" };
07013 const char *id = astman_get_header(m,"ActionID");
07014 char idtext[256] = "";
07015 int total = 0;
07016
07017 if (!ast_strlen_zero(id))
07018 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07019
07020 astman_send_listack(s, m, "Peer status list will follow", "start");
07021
07022 __iax2_show_peers(-1, &total, s, 3, a);
07023
07024 astman_append(s,
07025 "Event: PeerlistComplete\r\n"
07026 "EventList: Complete\r\n"
07027 "ListItems: %d\r\n"
07028 "%s"
07029 "\r\n", total, idtext);
07030 return 0;
07031 }
07032
07033
07034 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
07035 {
07036 struct iax2_peer *peer = NULL;
07037 int peer_count = 0;
07038 char nm[20];
07039 char status[20];
07040 const char *id = astman_get_header(m,"ActionID");
07041 char idtext[256] = "";
07042 struct ast_str *encmethods = ast_str_alloca(256);
07043 struct ao2_iterator i;
07044
07045 if (!ast_strlen_zero(id))
07046 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07047
07048 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
07049
07050
07051 i = ao2_iterator_init(peers, 0);
07052 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
07053 encmethods_to_str(peer->encmethods, &encmethods);
07054 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
07055 if (!ast_strlen_zero(peer->username)) {
07056 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07057 } else {
07058 astman_append(s, "ObjectName: %s\r\n", peer->name);
07059 }
07060 astman_append(s, "ChanObjectType: peer\r\n");
07061 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07062 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07063 astman_append(s, "Mask: %s\r\n", nm);
07064 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07065 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07066 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07067 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07068 peer_status(peer, status, sizeof(status));
07069 astman_append(s, "Status: %s\r\n\r\n", status);
07070 peer_count++;
07071 }
07072 ao2_iterator_destroy(&i);
07073
07074 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07075 return RESULT_SUCCESS;
07076 }
07077
07078
07079 static char *regstate2str(int regstate)
07080 {
07081 switch(regstate) {
07082 case REG_STATE_UNREGISTERED:
07083 return "Unregistered";
07084 case REG_STATE_REGSENT:
07085 return "Request Sent";
07086 case REG_STATE_AUTHSENT:
07087 return "Auth. Sent";
07088 case REG_STATE_REGISTERED:
07089 return "Registered";
07090 case REG_STATE_REJECTED:
07091 return "Rejected";
07092 case REG_STATE_TIMEOUT:
07093 return "Timeout";
07094 case REG_STATE_NOAUTH:
07095 return "No Authentication";
07096 default:
07097 return "Unknown";
07098 }
07099 }
07100
07101 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07102 {
07103 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
07104 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
07105 struct iax2_registry *reg = NULL;
07106 char host[80];
07107 char perceived[80];
07108 int counter = 0;
07109
07110 switch (cmd) {
07111 case CLI_INIT:
07112 e->command = "iax2 show registry";
07113 e->usage =
07114 "Usage: iax2 show registry\n"
07115 " Lists all registration requests and status.\n";
07116 return NULL;
07117 case CLI_GENERATE:
07118 return NULL;
07119 }
07120 if (a->argc != 3)
07121 return CLI_SHOWUSAGE;
07122 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07123 AST_LIST_LOCK(®istrations);
07124 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07125 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07126 if (reg->us.sin_addr.s_addr)
07127 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07128 else
07129 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07130 ast_cli(a->fd, FORMAT, host,
07131 (reg->dnsmgr) ? "Y" : "N",
07132 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07133 counter++;
07134 }
07135 AST_LIST_UNLOCK(®istrations);
07136 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07137 return CLI_SUCCESS;
07138 #undef FORMAT
07139 #undef FORMAT2
07140 }
07141
07142 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
07143 {
07144 const char *id = astman_get_header(m, "ActionID");
07145 struct iax2_registry *reg = NULL;
07146 char idtext[256] = "";
07147 char host[80] = "";
07148 char perceived[80] = "";
07149 int total = 0;
07150
07151 if (!ast_strlen_zero(id))
07152 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07153
07154 astman_send_listack(s, m, "Registrations will follow", "start");
07155
07156 AST_LIST_LOCK(®istrations);
07157 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07158 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07159
07160 if (reg->us.sin_addr.s_addr) {
07161 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07162 } else {
07163 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07164 }
07165
07166 astman_append(s,
07167 "Event: RegistryEntry\r\n"
07168 "%s"
07169 "Host: %s\r\n"
07170 "DNSmanager: %s\r\n"
07171 "Username: %s\r\n"
07172 "Perceived: %s\r\n"
07173 "Refresh: %d\r\n"
07174 "State: %s\r\n"
07175 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
07176 reg->refresh, regstate2str(reg->regstate));
07177
07178 total++;
07179 }
07180 AST_LIST_UNLOCK(®istrations);
07181
07182 astman_append(s,
07183 "Event: RegistrationsComplete\r\n"
07184 "EventList: Complete\r\n"
07185 "ListItems: %d\r\n"
07186 "%s"
07187 "\r\n", total, idtext);
07188
07189 return 0;
07190 }
07191
07192 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07193 {
07194 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
07195 #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"
07196 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
07197 int x;
07198 int numchans = 0;
07199 char first_message[10] = { 0, };
07200 char last_message[10] = { 0, };
07201
07202 switch (cmd) {
07203 case CLI_INIT:
07204 e->command = "iax2 show channels";
07205 e->usage =
07206 "Usage: iax2 show channels\n"
07207 " Lists all currently active IAX channels.\n";
07208 return NULL;
07209 case CLI_GENERATE:
07210 return NULL;
07211 }
07212
07213 if (a->argc != 3)
07214 return CLI_SHOWUSAGE;
07215 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07216 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07217 ast_mutex_lock(&iaxsl[x]);
07218 if (iaxs[x]) {
07219 int lag, jitter, localdelay;
07220 jb_info jbinfo;
07221 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07222 jb_getinfo(iaxs[x]->jb, &jbinfo);
07223 jitter = jbinfo.jitter;
07224 localdelay = jbinfo.current - jbinfo.min;
07225 } else {
07226 jitter = -1;
07227 localdelay = 0;
07228 }
07229
07230 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07231 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07232 lag = iaxs[x]->remote_rr.delay;
07233 ast_cli(a->fd, FORMAT,
07234 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07235 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07236 S_OR(iaxs[x]->username, "(None)"),
07237 iaxs[x]->callno, iaxs[x]->peercallno,
07238 iaxs[x]->oseqno, iaxs[x]->iseqno,
07239 lag,
07240 jitter,
07241 localdelay,
07242 ast_getformatname(iaxs[x]->voiceformat),
07243 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07244 first_message,
07245 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07246 last_message);
07247 numchans++;
07248 }
07249 ast_mutex_unlock(&iaxsl[x]);
07250 }
07251 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07252 return CLI_SUCCESS;
07253 #undef FORMAT
07254 #undef FORMAT2
07255 #undef FORMATB
07256 }
07257
07258 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07259 {
07260 int x;
07261 int numchans = 0;
07262 char first_message[10] = { 0, };
07263 char last_message[10] = { 0, };
07264 #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"
07265 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07266 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07267 ast_mutex_lock(&iaxsl[x]);
07268 if (iaxs[x]) {
07269 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07270 jb_info jbinfo;
07271 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07272 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07273
07274 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07275 jb_getinfo(iaxs[x]->jb, &jbinfo);
07276 localjitter = jbinfo.jitter;
07277 localdelay = jbinfo.current - jbinfo.min;
07278 locallost = jbinfo.frames_lost;
07279 locallosspct = jbinfo.losspct/1000;
07280 localdropped = jbinfo.frames_dropped;
07281 localooo = jbinfo.frames_ooo;
07282 } else {
07283 localjitter = -1;
07284 localdelay = 0;
07285 locallost = -1;
07286 locallosspct = -1;
07287 localdropped = 0;
07288 localooo = -1;
07289 }
07290 if (s)
07291 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07292 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07293 iaxs[x]->pingtime,
07294 localjitter,
07295 localdelay,
07296 locallost,
07297 locallosspct,
07298 localdropped,
07299 localooo,
07300 iaxs[x]->frames_received/1000,
07301 iaxs[x]->remote_rr.jitter,
07302 iaxs[x]->remote_rr.delay,
07303 iaxs[x]->remote_rr.losscnt,
07304 iaxs[x]->remote_rr.losspct,
07305 iaxs[x]->remote_rr.dropped,
07306 iaxs[x]->remote_rr.ooo,
07307 iaxs[x]->remote_rr.packets/1000,
07308 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07309 first_message,
07310 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07311 last_message);
07312 else
07313 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07314 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07315 iaxs[x]->pingtime,
07316 localjitter,
07317 localdelay,
07318 locallost,
07319 locallosspct,
07320 localdropped,
07321 localooo,
07322 iaxs[x]->frames_received/1000,
07323 iaxs[x]->remote_rr.jitter,
07324 iaxs[x]->remote_rr.delay,
07325 iaxs[x]->remote_rr.losscnt,
07326 iaxs[x]->remote_rr.losspct,
07327 iaxs[x]->remote_rr.dropped,
07328 iaxs[x]->remote_rr.ooo,
07329 iaxs[x]->remote_rr.packets/1000,
07330 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07331 first_message,
07332 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07333 last_message);
07334 numchans++;
07335 }
07336 ast_mutex_unlock(&iaxsl[x]);
07337 }
07338
07339 return numchans;
07340 }
07341
07342 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07343 {
07344 int numchans = 0;
07345
07346 switch (cmd) {
07347 case CLI_INIT:
07348 e->command = "iax2 show netstats";
07349 e->usage =
07350 "Usage: iax2 show netstats\n"
07351 " Lists network status for all currently active IAX channels.\n";
07352 return NULL;
07353 case CLI_GENERATE:
07354 return NULL;
07355 }
07356 if (a->argc != 3)
07357 return CLI_SHOWUSAGE;
07358 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07359 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07360 numchans = ast_cli_netstats(NULL, a->fd, 1);
07361 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07362 return CLI_SUCCESS;
07363 }
07364
07365 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07366 {
07367 switch (cmd) {
07368 case CLI_INIT:
07369 e->command = "iax2 set debug {on|off|peer}";
07370 e->usage =
07371 "Usage: iax2 set debug {on|off|peer peername}\n"
07372 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07373 return NULL;
07374 case CLI_GENERATE:
07375 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07376 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07377 return NULL;
07378 }
07379
07380 if (a->argc < e->args || a->argc > e->args + 1)
07381 return CLI_SHOWUSAGE;
07382
07383 if (!strcasecmp(a->argv[3], "peer")) {
07384 struct iax2_peer *peer;
07385 struct sockaddr_in peer_addr;
07386
07387
07388 if (a->argc != e->args + 1)
07389 return CLI_SHOWUSAGE;
07390
07391 peer = find_peer(a->argv[4], 1);
07392
07393 if (!peer) {
07394 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07395 return CLI_FAILURE;
07396 }
07397
07398 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07399
07400 debugaddr.sin_addr = peer_addr.sin_addr;
07401 debugaddr.sin_port = peer_addr.sin_port;
07402
07403 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07404 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07405
07406 ao2_ref(peer, -1);
07407 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07408 iaxdebug = 1;
07409 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07410 } else {
07411 iaxdebug = 0;
07412 memset(&debugaddr, 0, sizeof(debugaddr));
07413 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07414 }
07415 return CLI_SUCCESS;
07416 }
07417
07418 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07419 {
07420 switch (cmd) {
07421 case CLI_INIT:
07422 e->command = "iax2 set debug trunk {on|off}";
07423 e->usage =
07424 "Usage: iax2 set debug trunk {on|off}\n"
07425 " Enables/Disables debugging of IAX trunking\n";
07426 return NULL;
07427 case CLI_GENERATE:
07428 return NULL;
07429 }
07430
07431 if (a->argc != e->args)
07432 return CLI_SHOWUSAGE;
07433
07434 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07435 iaxtrunkdebug = 1;
07436 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07437 } else {
07438 iaxtrunkdebug = 0;
07439 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07440 }
07441 return CLI_SUCCESS;
07442 }
07443
07444 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07445 {
07446 switch (cmd) {
07447 case CLI_INIT:
07448 e->command = "iax2 set debug jb {on|off}";
07449 e->usage =
07450 "Usage: iax2 set debug jb {on|off}\n"
07451 " Enables/Disables jitterbuffer debugging information\n";
07452 return NULL;
07453 case CLI_GENERATE:
07454 return NULL;
07455 }
07456
07457 if (a->argc != e->args)
07458 return CLI_SHOWUSAGE;
07459
07460 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07461 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07462 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07463 } else {
07464 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07465 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07466 }
07467 return CLI_SUCCESS;
07468 }
07469
07470 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07471 {
07472 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07473 int res = -1;
07474 ast_mutex_lock(&iaxsl[callno]);
07475 if (iaxs[callno]) {
07476
07477 if (!iaxs[callno]->error) {
07478 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07479 res = 0;
07480
07481 else if (f->frametype == AST_FRAME_NULL)
07482 res = 0;
07483 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07484 res = 0;
07485 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07486 res = 0;
07487 else
07488
07489 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07490 } else {
07491 ast_debug(1, "Write error: %s\n", strerror(errno));
07492 }
07493 }
07494
07495 ast_mutex_unlock(&iaxsl[callno]);
07496 return res;
07497 }
07498
07499 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07500 int now, int transfer, int final)
07501 {
07502 struct ast_frame f = { 0, };
07503 int res = 0;
07504
07505 f.frametype = type;
07506 f.subclass.integer = command;
07507 f.datalen = datalen;
07508 f.src = __FUNCTION__;
07509 f.data.ptr = (void *) data;
07510
07511 if ((res = queue_signalling(i, &f)) <= 0) {
07512 return res;
07513 }
07514
07515 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07516 }
07517
07518 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07519 {
07520 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07521 }
07522
07523 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07524 {
07525 int res;
07526 ast_mutex_lock(&iaxsl[callno]);
07527 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07528 ast_mutex_unlock(&iaxsl[callno]);
07529 return res;
07530 }
07531
07532
07533
07534
07535
07536
07537 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)
07538 {
07539 int call_num = i->callno;
07540
07541 iax2_predestroy(i->callno);
07542 if (!iaxs[call_num])
07543 return -1;
07544 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07545 }
07546
07547 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)
07548 {
07549 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07550 }
07551
07552 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07553 {
07554 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07555 }
07556
07557 static int apply_context(struct iax2_context *con, const char *context)
07558 {
07559 while(con) {
07560 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07561 return -1;
07562 con = con->next;
07563 }
07564 return 0;
07565 }
07566
07567
07568 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07569 {
07570
07571 int res = -1;
07572 int version = 2;
07573 struct iax2_user *user = NULL, *best = NULL;
07574 int bestscore = 0;
07575 int gotcapability = 0;
07576 struct ast_variable *v = NULL, *tmpvar = NULL;
07577 struct ao2_iterator i;
07578 struct ast_sockaddr addr;
07579
07580 if (!iaxs[callno])
07581 return res;
07582 if (ies->called_number)
07583 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07584 if (ies->calling_number) {
07585 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07586 ast_shrink_phone_number(ies->calling_number);
07587 }
07588 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07589 }
07590 if (ies->calling_name)
07591 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07592 if (ies->calling_ani)
07593 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07594 if (ies->dnid)
07595 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07596 if (ies->rdnis)
07597 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07598 if (ies->called_context)
07599 ast_string_field_set(iaxs[callno], context, ies->called_context);
07600 if (ies->language)
07601 ast_string_field_set(iaxs[callno], language, ies->language);
07602 if (ies->username)
07603 ast_string_field_set(iaxs[callno], username, ies->username);
07604 if (ies->calling_ton > -1)
07605 iaxs[callno]->calling_ton = ies->calling_ton;
07606 if (ies->calling_tns > -1)
07607 iaxs[callno]->calling_tns = ies->calling_tns;
07608 if (ies->calling_pres > -1)
07609 iaxs[callno]->calling_pres = ies->calling_pres;
07610 if (ies->format)
07611 iaxs[callno]->peerformat = ies->format;
07612 if (ies->adsicpe)
07613 iaxs[callno]->peeradsicpe = ies->adsicpe;
07614 if (ies->capability) {
07615 gotcapability = 1;
07616 iaxs[callno]->peercapability = ies->capability;
07617 }
07618 if (ies->version)
07619 version = ies->version;
07620
07621
07622 if (ies->codec_prefs) {
07623 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07624 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07625 }
07626
07627 if (!gotcapability)
07628 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07629 if (version > IAX_PROTO_VERSION) {
07630 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07631 ast_inet_ntoa(sin->sin_addr), version);
07632 return res;
07633 }
07634
07635 ast_sockaddr_from_sin(&addr, sin);
07636 i = ao2_iterator_init(users, 0);
07637 while ((user = ao2_iterator_next(&i))) {
07638 if ((ast_strlen_zero(iaxs[callno]->username) ||
07639 !strcmp(iaxs[callno]->username, user->name))
07640 && ast_apply_ha(user->ha, &addr) == AST_SENSE_ALLOW
07641 && (ast_strlen_zero(iaxs[callno]->context) ||
07642 apply_context(user->contexts, iaxs[callno]->context))) {
07643 if (!ast_strlen_zero(iaxs[callno]->username)) {
07644
07645 if (best)
07646 user_unref(best);
07647 best = user;
07648 break;
07649 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07650
07651 if (user->ha) {
07652
07653 if (bestscore < 4) {
07654 bestscore = 4;
07655 if (best)
07656 user_unref(best);
07657 best = user;
07658 continue;
07659 }
07660 } else {
07661
07662 if (bestscore < 3) {
07663 bestscore = 3;
07664 if (best)
07665 user_unref(best);
07666 best = user;
07667 continue;
07668 }
07669 }
07670 } else {
07671 if (user->ha) {
07672
07673 if (bestscore < 2) {
07674 bestscore = 2;
07675 if (best)
07676 user_unref(best);
07677 best = user;
07678 continue;
07679 }
07680 } else {
07681
07682 if (bestscore < 1) {
07683 bestscore = 1;
07684 if (best)
07685 user_unref(best);
07686 best = user;
07687 continue;
07688 }
07689 }
07690 }
07691 }
07692 user_unref(user);
07693 }
07694 ao2_iterator_destroy(&i);
07695 user = best;
07696 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07697 user = realtime_user(iaxs[callno]->username, sin);
07698 if (user && (ast_apply_ha(user->ha, &addr) == AST_SENSE_DENY
07699 || (!ast_strlen_zero(iaxs[callno]->context) &&
07700 !apply_context(user->contexts, iaxs[callno]->context)))) {
07701 user = user_unref(user);
07702 }
07703 }
07704 if (user) {
07705
07706
07707 for (v = user->vars ; v ; v = v->next) {
07708 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07709 tmpvar->next = iaxs[callno]->vars;
07710 iaxs[callno]->vars = tmpvar;
07711 }
07712 }
07713
07714 if (user->maxauthreq > 0)
07715 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07716 iaxs[callno]->prefs = user->prefs;
07717 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07718 iaxs[callno]->encmethods = user->encmethods;
07719
07720 if (ast_strlen_zero(iaxs[callno]->username))
07721 ast_string_field_set(iaxs[callno], username, user->name);
07722
07723 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07724 iaxs[callno]->capability = user->capability;
07725
07726 if (ast_strlen_zero(iaxs[callno]->context)) {
07727 if (user->contexts)
07728 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07729 else
07730 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07731 }
07732
07733 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07734
07735 iaxs[callno]->authmethods = user->authmethods;
07736 iaxs[callno]->adsi = user->adsi;
07737
07738 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07739 iaxs[callno]->calling_tns = 0;
07740 iaxs[callno]->calling_ton = 0;
07741 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07742 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07743 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07744 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07745 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07746 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07747 }
07748 if (!ast_strlen_zero(user->accountcode))
07749 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07750 if (!ast_strlen_zero(user->mohinterpret))
07751 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07752 if (!ast_strlen_zero(user->mohsuggest))
07753 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07754 if (!ast_strlen_zero(user->parkinglot))
07755 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07756 if (user->amaflags)
07757 iaxs[callno]->amaflags = user->amaflags;
07758 if (!ast_strlen_zero(user->language))
07759 ast_string_field_set(iaxs[callno], language, user->language);
07760 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07761
07762 if (!ast_strlen_zero(user->dbsecret)) {
07763 char *family, *key=NULL;
07764 char buf[80];
07765 family = ast_strdupa(user->dbsecret);
07766 key = strchr(family, '/');
07767 if (key) {
07768 *key = '\0';
07769 key++;
07770 }
07771 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07772 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07773 else
07774 ast_string_field_set(iaxs[callno], secret, buf);
07775 } else
07776 ast_string_field_set(iaxs[callno], secret, user->secret);
07777 res = 0;
07778 user = user_unref(user);
07779 } else {
07780
07781
07782
07783
07784 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07785 ast_string_field_set(iaxs[callno], secret, "badsecret");
07786 iaxs[callno]->authrej = 1;
07787 if (!ast_strlen_zero(iaxs[callno]->username)) {
07788
07789 res = 0;
07790 }
07791 }
07792 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07793 return res;
07794 }
07795
07796 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07797 {
07798 struct ast_iax2_full_hdr fh;
07799 fh.scallno = htons(src | IAX_FLAG_FULL);
07800 fh.dcallno = htons(dst);
07801 fh.ts = 0;
07802 fh.oseqno = 0;
07803 fh.iseqno = 0;
07804 fh.type = AST_FRAME_IAX;
07805 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07806 iax_outputframe(NULL, &fh, 0, sin, 0);
07807 #if 0
07808 if (option_debug)
07809 #endif
07810 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07811 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07812 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07813 }
07814
07815 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07816 {
07817
07818 p->encmethods &= enc;
07819 if (p->encmethods) {
07820 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07821 p->keyrotateid = -2;
07822 }
07823 if (p->encmethods & IAX_ENCRYPT_AES128)
07824 p->encmethods = IAX_ENCRYPT_AES128;
07825 else
07826 p->encmethods = 0;
07827 }
07828 }
07829
07830
07831
07832
07833
07834
07835
07836 static int authenticate_request(int call_num)
07837 {
07838 struct iax_ie_data ied;
07839 int res = -1, authreq_restrict = 0;
07840 char challenge[10];
07841 struct chan_iax2_pvt *p = iaxs[call_num];
07842
07843 memset(&ied, 0, sizeof(ied));
07844
07845
07846 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07847 struct iax2_user *user, tmp_user = {
07848 .name = p->username,
07849 };
07850
07851 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07852 if (user) {
07853 if (user->curauthreq == user->maxauthreq)
07854 authreq_restrict = 1;
07855 else
07856 user->curauthreq++;
07857 user = user_unref(user);
07858 }
07859 }
07860
07861
07862 if (authreq_restrict) {
07863 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07864 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07865 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07866 return 0;
07867 }
07868
07869 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07870 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07871 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07872 ast_string_field_set(p, challenge, challenge);
07873
07874 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07875 }
07876 if (p->encmethods)
07877 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07878
07879 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07880
07881 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07882
07883 if (p->encmethods)
07884 ast_set_flag64(p, IAX_ENCRYPTED);
07885
07886 return res;
07887 }
07888
07889 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07890 {
07891 char requeststr[256];
07892 char md5secret[256] = "";
07893 char secret[256] = "";
07894 char rsasecret[256] = "";
07895 int res = -1;
07896 int x;
07897 struct iax2_user *user, tmp_user = {
07898 .name = p->username,
07899 };
07900
07901 if (p->authrej) {
07902 return res;
07903 }
07904 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07905 if (user) {
07906 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07907 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07908 ast_clear_flag64(p, IAX_MAXAUTHREQ);
07909 }
07910 ast_string_field_set(p, host, user->name);
07911 user = user_unref(user);
07912 }
07913 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07914 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n");
07915 return res;
07916 }
07917 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07918 return res;
07919 if (ies->password)
07920 ast_copy_string(secret, ies->password, sizeof(secret));
07921 if (ies->md5_result)
07922 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07923 if (ies->rsa_result)
07924 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07925 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07926 struct ast_key *key;
07927 char *keyn;
07928 char tmpkey[256];
07929 char *stringp=NULL;
07930 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07931 stringp=tmpkey;
07932 keyn = strsep(&stringp, ":");
07933 while(keyn) {
07934 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07935 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07936 res = 0;
07937 break;
07938 } else if (!key)
07939 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07940 keyn = strsep(&stringp, ":");
07941 }
07942 } else if (p->authmethods & IAX_AUTH_MD5) {
07943 struct MD5Context md5;
07944 unsigned char digest[16];
07945 char *tmppw, *stringp;
07946
07947 tmppw = ast_strdupa(p->secret);
07948 stringp = tmppw;
07949 while((tmppw = strsep(&stringp, ";"))) {
07950 MD5Init(&md5);
07951 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07952 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07953 MD5Final(digest, &md5);
07954
07955 for (x=0;x<16;x++)
07956 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07957 if (!strcasecmp(requeststr, md5secret)) {
07958 res = 0;
07959 break;
07960 }
07961 }
07962 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07963 if (!strcmp(secret, p->secret))
07964 res = 0;
07965 }
07966 return res;
07967 }
07968
07969
07970 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07971 {
07972 char requeststr[256] = "";
07973 char peer[256] = "";
07974 char md5secret[256] = "";
07975 char rsasecret[256] = "";
07976 char secret[256] = "";
07977 struct iax2_peer *p = NULL;
07978 struct ast_key *key;
07979 char *keyn;
07980 int x;
07981 int expire = 0;
07982 int res = -1;
07983 struct ast_sockaddr addr;
07984
07985 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07986
07987 if (ies->username)
07988 ast_copy_string(peer, ies->username, sizeof(peer));
07989 if (ies->password)
07990 ast_copy_string(secret, ies->password, sizeof(secret));
07991 if (ies->md5_result)
07992 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07993 if (ies->rsa_result)
07994 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07995 if (ies->refresh)
07996 expire = ies->refresh;
07997
07998 if (ast_strlen_zero(peer)) {
07999 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
08000 return -1;
08001 }
08002
08003
08004 ast_mutex_unlock(&iaxsl[callno]);
08005 p = find_peer(peer, 1);
08006 ast_mutex_lock(&iaxsl[callno]);
08007 if (!p || !iaxs[callno]) {
08008 if (iaxs[callno]) {
08009 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
08010
08011 ast_string_field_set(iaxs[callno], secret, "badsecret");
08012
08013
08014
08015
08016
08017
08018
08019
08020
08021 if (ast_strlen_zero(iaxs[callno]->challenge) &&
08022 !(!ast_strlen_zero(secret) && plaintext)) {
08023
08024 res = 0;
08025 }
08026 }
08027 if (authdebug && !p)
08028 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08029 goto return_unref;
08030 }
08031
08032 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
08033 if (authdebug)
08034 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08035 goto return_unref;
08036 }
08037
08038 ast_sockaddr_from_sin(&addr, sin);
08039 if (!ast_apply_ha(p->ha, &addr)) {
08040 if (authdebug)
08041 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08042 goto return_unref;
08043 }
08044 ast_string_field_set(iaxs[callno], secret, p->secret);
08045 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
08046
08047 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08048 if (!ast_strlen_zero(p->inkeys)) {
08049 char tmpkeys[256];
08050 char *stringp=NULL;
08051 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
08052 stringp=tmpkeys;
08053 keyn = strsep(&stringp, ":");
08054 while(keyn) {
08055 key = ast_key_get(keyn, AST_KEY_PUBLIC);
08056 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
08057 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08058 break;
08059 } else if (!key)
08060 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08061 keyn = strsep(&stringp, ":");
08062 }
08063 if (!keyn) {
08064 if (authdebug)
08065 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08066 goto return_unref;
08067 }
08068 } else {
08069 if (authdebug)
08070 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08071 goto return_unref;
08072 }
08073 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08074 struct MD5Context md5;
08075 unsigned char digest[16];
08076 char *tmppw, *stringp;
08077
08078 tmppw = ast_strdupa(p->secret);
08079 stringp = tmppw;
08080 while((tmppw = strsep(&stringp, ";"))) {
08081 MD5Init(&md5);
08082 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08083 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08084 MD5Final(digest, &md5);
08085 for (x=0;x<16;x++)
08086 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08087 if (!strcasecmp(requeststr, md5secret))
08088 break;
08089 }
08090 if (tmppw) {
08091 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08092 } else {
08093 if (authdebug)
08094 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08095 goto return_unref;
08096 }
08097 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08098
08099 if (strcmp(secret, p->secret)) {
08100 if (authdebug)
08101 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08102 goto return_unref;
08103 } else
08104 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08105 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08106
08107 goto return_unref;
08108 }
08109 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08110
08111
08112 res = 0;
08113
08114 return_unref:
08115 if (iaxs[callno]) {
08116 ast_string_field_set(iaxs[callno], peer, peer);
08117
08118
08119 if (expire && (expire < iaxs[callno]->expiry)) {
08120 iaxs[callno]->expiry = expire;
08121 }
08122 }
08123
08124 if (p) {
08125 peer_unref(p);
08126 }
08127 return res;
08128 }
08129
08130 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)
08131 {
08132 int res = -1;
08133 int x;
08134 if (!ast_strlen_zero(keyn)) {
08135 if (!(authmethods & IAX_AUTH_RSA)) {
08136 if (ast_strlen_zero(secret))
08137 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));
08138 } else if (ast_strlen_zero(challenge)) {
08139 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08140 } else {
08141 char sig[256];
08142 struct ast_key *key;
08143 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08144 if (!key) {
08145 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08146 } else {
08147 if (ast_sign(key, (char*)challenge, sig)) {
08148 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08149 res = -1;
08150 } else {
08151 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08152 res = 0;
08153 }
08154 }
08155 }
08156 }
08157
08158 if (res && !ast_strlen_zero(secret)) {
08159 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08160 struct MD5Context md5;
08161 unsigned char digest[16];
08162 char digres[128];
08163 MD5Init(&md5);
08164 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08165 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08166 MD5Final(digest, &md5);
08167
08168 for (x=0;x<16;x++)
08169 sprintf(digres + (x << 1), "%2.2x", digest[x]);
08170 if (pvt) {
08171 build_encryption_keys(digest, pvt);
08172 }
08173 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08174 res = 0;
08175 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08176 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08177 res = 0;
08178 } else
08179 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08180 }
08181 return res;
08182 }
08183
08184
08185
08186
08187
08188 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08189 {
08190 struct iax2_peer *peer = NULL;
08191
08192 int res = -1;
08193 int authmethods = 0;
08194 struct iax_ie_data ied;
08195 uint16_t callno = p->callno;
08196
08197 memset(&ied, 0, sizeof(ied));
08198
08199 if (ies->username)
08200 ast_string_field_set(p, username, ies->username);
08201 if (ies->challenge)
08202 ast_string_field_set(p, challenge, ies->challenge);
08203 if (ies->authmethods)
08204 authmethods = ies->authmethods;
08205 if (authmethods & IAX_AUTH_MD5)
08206 merge_encryption(p, ies->encmethods);
08207 else
08208 p->encmethods = 0;
08209
08210
08211 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08212
08213 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08214 } else {
08215 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08216 while ((peer = ao2_iterator_next(&i))) {
08217 struct sockaddr_in peer_addr;
08218
08219 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08220
08221 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08222
08223 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08224
08225 && (!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)))
08226
08227 ) {
08228 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08229 if (!res) {
08230 peer_unref(peer);
08231 break;
08232 }
08233 }
08234 peer_unref(peer);
08235 }
08236 ao2_iterator_destroy(&i);
08237 if (!peer) {
08238
08239
08240 const char *peer_name = ast_strdupa(p->peer);
08241 ast_mutex_unlock(&iaxsl[callno]);
08242 if ((peer = realtime_peer(peer_name, NULL))) {
08243 ast_mutex_lock(&iaxsl[callno]);
08244 if (!(p = iaxs[callno])) {
08245 peer_unref(peer);
08246 return -1;
08247 }
08248 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08249 peer_unref(peer);
08250 }
08251 if (!peer) {
08252 ast_mutex_lock(&iaxsl[callno]);
08253 if (!(p = iaxs[callno]))
08254 return -1;
08255 }
08256 }
08257 }
08258
08259 if (ies->encmethods) {
08260 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08261 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08262 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n");
08263 return -1;
08264 }
08265 if (!res) {
08266 struct ast_datastore *variablestore;
08267 struct ast_variable *var, *prev = NULL;
08268 AST_LIST_HEAD(, ast_var_t) *varlist;
08269 varlist = ast_calloc(1, sizeof(*varlist));
08270 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08271 if (variablestore && varlist && p->owner) {
08272 variablestore->data = varlist;
08273 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08274 AST_LIST_HEAD_INIT(varlist);
08275 for (var = ies->vars; var; var = var->next) {
08276 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08277 if (prev)
08278 ast_free(prev);
08279 prev = var;
08280 if (!newvar) {
08281
08282 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08283 } else {
08284 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08285 }
08286 }
08287 if (prev)
08288 ast_free(prev);
08289 ies->vars = NULL;
08290 ast_channel_datastore_add(p->owner, variablestore);
08291 } else {
08292 if (p->owner)
08293 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08294 if (variablestore)
08295 ast_datastore_free(variablestore);
08296 if (varlist)
08297 ast_free(varlist);
08298 }
08299 }
08300
08301 if (!res)
08302 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08303 return res;
08304 }
08305
08306 static int iax2_do_register(struct iax2_registry *reg);
08307
08308 static void __iax2_do_register_s(const void *data)
08309 {
08310 struct iax2_registry *reg = (struct iax2_registry *)data;
08311 reg->expire = -1;
08312 iax2_do_register(reg);
08313 }
08314
08315 static int iax2_do_register_s(const void *data)
08316 {
08317 #ifdef SCHED_MULTITHREADED
08318 if (schedule_action(__iax2_do_register_s, data))
08319 #endif
08320 __iax2_do_register_s(data);
08321 return 0;
08322 }
08323
08324 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08325 {
08326 int newcall = 0;
08327 char newip[256];
08328 struct iax_ie_data ied;
08329 struct sockaddr_in new = { 0, };
08330
08331 memset(&ied, 0, sizeof(ied));
08332 if (ies->apparent_addr)
08333 memmove(&new, ies->apparent_addr, sizeof(new));
08334 if (ies->callno)
08335 newcall = ies->callno;
08336 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08337 ast_log(LOG_WARNING, "Invalid transfer request\n");
08338 return -1;
08339 }
08340 pvt->transfercallno = newcall;
08341 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08342 inet_aton(newip, &pvt->transfer.sin_addr);
08343 pvt->transfer.sin_family = AF_INET;
08344 pvt->transferid = ies->transferid;
08345
08346
08347 if (pvt->transferring == TRANSFER_NONE) {
08348 store_by_transfercallno(pvt);
08349 }
08350 pvt->transferring = TRANSFER_BEGIN;
08351
08352 if (ies->transferid)
08353 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08354 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08355 return 0;
08356 }
08357
08358 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08359 {
08360 char exten[256] = "";
08361 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08362 struct iax2_dpcache *dp = NULL;
08363
08364 if (ies->called_number)
08365 ast_copy_string(exten, ies->called_number, sizeof(exten));
08366
08367 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08368 status = CACHE_FLAG_EXISTS;
08369 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08370 status = CACHE_FLAG_CANEXIST;
08371 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08372 status = CACHE_FLAG_NONEXISTENT;
08373
08374 if (ies->refresh)
08375 expiry = ies->refresh;
08376 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08377 matchmore = CACHE_FLAG_MATCHMORE;
08378
08379 AST_LIST_LOCK(&dpcache);
08380 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08381 if (strcmp(dp->exten, exten))
08382 continue;
08383 AST_LIST_REMOVE_CURRENT(peer_list);
08384 dp->callno = 0;
08385 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08386 if (dp->flags & CACHE_FLAG_PENDING) {
08387 dp->flags &= ~CACHE_FLAG_PENDING;
08388 dp->flags |= status;
08389 dp->flags |= matchmore;
08390 }
08391
08392 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08393 if (dp->waiters[x] > -1) {
08394 if (write(dp->waiters[x], "asdf", 4) < 0) {
08395 }
08396 }
08397 }
08398 }
08399 AST_LIST_TRAVERSE_SAFE_END;
08400 AST_LIST_UNLOCK(&dpcache);
08401
08402 return 0;
08403 }
08404
08405 static int complete_transfer(int callno, struct iax_ies *ies)
08406 {
08407 int peercallno = 0;
08408 struct chan_iax2_pvt *pvt = iaxs[callno];
08409 struct iax_frame *cur;
08410 jb_frame frame;
08411
08412 if (ies->callno)
08413 peercallno = ies->callno;
08414
08415 if (peercallno < 1) {
08416 ast_log(LOG_WARNING, "Invalid transfer request\n");
08417 return -1;
08418 }
08419 remove_by_transfercallno(pvt);
08420
08421
08422
08423 peercnt_remove_by_addr(&pvt->addr);
08424 peercnt_add(&pvt->transfer);
08425
08426 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08427 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08428
08429 pvt->oseqno = 0;
08430 pvt->rseqno = 0;
08431 pvt->iseqno = 0;
08432 pvt->aseqno = 0;
08433
08434 if (pvt->peercallno) {
08435 remove_by_peercallno(pvt);
08436 }
08437 pvt->peercallno = peercallno;
08438
08439 store_by_peercallno(pvt);
08440 pvt->transferring = TRANSFER_NONE;
08441 pvt->svoiceformat = -1;
08442 pvt->voiceformat = 0;
08443 pvt->svideoformat = -1;
08444 pvt->videoformat = 0;
08445 pvt->transfercallno = 0;
08446 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08447 memset(&pvt->offset, 0, sizeof(pvt->offset));
08448
08449 while(jb_getall(pvt->jb,&frame) == JB_OK)
08450 iax2_frame_free(frame.data);
08451 jb_reset(pvt->jb);
08452 pvt->lag = 0;
08453 pvt->last = 0;
08454 pvt->lastsent = 0;
08455 pvt->nextpred = 0;
08456 pvt->pingtime = DEFAULT_RETRY_TIME;
08457 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08458
08459
08460
08461 cur->retries = -1;
08462 }
08463 return 0;
08464 }
08465
08466
08467 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08468 {
08469 struct iax2_registry *reg;
08470
08471 char peer[256] = "";
08472 char msgstatus[60];
08473 int refresh = 60;
08474 char ourip[256] = "<Unspecified>";
08475 struct sockaddr_in oldus;
08476 struct sockaddr_in us;
08477 int oldmsgs;
08478 struct sockaddr_in reg_addr;
08479
08480 memset(&us, 0, sizeof(us));
08481 if (ies->apparent_addr) {
08482 memmove(&us, ies->apparent_addr, sizeof(us));
08483 }
08484 if (ies->username) {
08485 ast_copy_string(peer, ies->username, sizeof(peer));
08486 }
08487 if (ies->refresh) {
08488 refresh = ies->refresh;
08489 }
08490 if (ies->calling_number) {
08491
08492 }
08493 reg = iaxs[callno]->reg;
08494 if (!reg) {
08495 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08496 return -1;
08497 }
08498 memcpy(&oldus, ®->us, sizeof(oldus));
08499 oldmsgs = reg->messages;
08500 ast_sockaddr_to_sin(®->addr, ®_addr);
08501 if (inaddrcmp(®_addr, sin)) {
08502 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08503 return -1;
08504 }
08505 memcpy(®->us, &us, sizeof(reg->us));
08506 if (ies->msgcount >= 0) {
08507 reg->messages = ies->msgcount & 0xffff;
08508 }
08509
08510
08511
08512 reg->refresh = refresh;
08513 reg->expire = iax2_sched_replace(reg->expire, sched,
08514 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08515 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08516 if (reg->messages > 255) {
08517 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08518 } else if (reg->messages > 1) {
08519 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08520 } else if (reg->messages > 0) {
08521 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08522 } else {
08523 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08524 }
08525 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08526 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08527 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08528 }
08529 reg->regstate = REG_STATE_REGISTERED;
08530 return 0;
08531 }
08532
08533 static int iax2_append_register(const char *hostname, const char *username,
08534 const char *secret, const char *porta)
08535 {
08536 struct iax2_registry *reg;
08537
08538 if (!(reg = ast_calloc(1, sizeof(*reg))))
08539 return -1;
08540
08541 reg->addr.ss.ss_family = AF_INET;
08542 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08543 ast_free(reg);
08544 return -1;
08545 }
08546
08547 ast_copy_string(reg->username, username, sizeof(reg->username));
08548
08549 if (secret)
08550 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08551
08552 reg->expire = -1;
08553 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08554 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08555
08556 AST_LIST_LOCK(®istrations);
08557 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08558 AST_LIST_UNLOCK(®istrations);
08559
08560 return 0;
08561 }
08562
08563 static int iax2_register(const char *value, int lineno)
08564 {
08565 char copy[256];
08566 char *username, *hostname, *secret;
08567 char *porta;
08568 char *stringp=NULL;
08569
08570 if (!value)
08571 return -1;
08572
08573 ast_copy_string(copy, value, sizeof(copy));
08574 stringp = copy;
08575 username = strsep(&stringp, "@");
08576 hostname = strsep(&stringp, "@");
08577
08578 if (!hostname) {
08579 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08580 return -1;
08581 }
08582
08583 stringp = username;
08584 username = strsep(&stringp, ":");
08585 secret = strsep(&stringp, ":");
08586 stringp = hostname;
08587 hostname = strsep(&stringp, ":");
08588 porta = strsep(&stringp, ":");
08589
08590 if (porta && !atoi(porta)) {
08591 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08592 return -1;
08593 }
08594
08595 return iax2_append_register(hostname, username, secret, porta);
08596 }
08597
08598
08599 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08600 {
08601 char multi[256];
08602 char *stringp, *ext;
08603 if (!ast_strlen_zero(regcontext)) {
08604 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08605 stringp = multi;
08606 while((ext = strsep(&stringp, "&"))) {
08607 if (onoff) {
08608 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08609 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08610 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08611 } else
08612 ast_context_remove_extension(regcontext, ext, 1, NULL);
08613 }
08614 }
08615 }
08616 static void prune_peers(void);
08617
08618 static void unlink_peer(struct iax2_peer *peer)
08619 {
08620 if (peer->expire > -1) {
08621 if (!ast_sched_thread_del(sched, peer->expire)) {
08622 peer->expire = -1;
08623 peer_unref(peer);
08624 }
08625 }
08626
08627 if (peer->pokeexpire > -1) {
08628 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08629 peer->pokeexpire = -1;
08630 peer_unref(peer);
08631 }
08632 }
08633
08634 ao2_unlink(peers, peer);
08635 }
08636
08637 static void __expire_registry(const void *data)
08638 {
08639 struct iax2_peer *peer = (struct iax2_peer *) data;
08640
08641 if (!peer)
08642 return;
08643 if (peer->expire == -1) {
08644
08645 return;
08646 }
08647
08648 peer->expire = -1;
08649
08650 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08651 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08652 realtime_update_peer(peer->name, &peer->addr, 0);
08653 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08654
08655 peercnt_modify((unsigned char) 0, 0, &peer->addr);
08656
08657 memset(&peer->addr, 0, sizeof(peer->addr));
08658
08659 peer->expiry = min_reg_expire;
08660 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08661 ast_db_del("IAX/Registry", peer->name);
08662 register_peer_exten(peer, 0);
08663 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
08664 if (iax2_regfunk)
08665 iax2_regfunk(peer->name, 0);
08666
08667 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08668 unlink_peer(peer);
08669
08670 peer_unref(peer);
08671 }
08672
08673 static int expire_registry(const void *data)
08674 {
08675 #ifdef SCHED_MULTITHREADED
08676 if (schedule_action(__expire_registry, data))
08677 #endif
08678 __expire_registry(data);
08679 return 0;
08680 }
08681
08682 static void reg_source_db(struct iax2_peer *p)
08683 {
08684 char data[80];
08685 char *expiry;
08686
08687 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08688 return;
08689 }
08690
08691 expiry = strrchr(data, ':');
08692 if (!expiry) {
08693 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08694 return;
08695 }
08696 *expiry++ = '\0';
08697
08698 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08699 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08700 return;
08701 }
08702
08703 p->expiry = atoi(expiry);
08704
08705 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08706 ast_sockaddr_stringify(&p->addr), p->expiry);
08707
08708 iax2_poke_peer(p, 0);
08709 if (p->expire > -1) {
08710 if (!ast_sched_thread_del(sched, p->expire)) {
08711 p->expire = -1;
08712 peer_unref(p);
08713 }
08714 }
08715
08716 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08717
08718 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08719 if (p->expire == -1) {
08720 peer_unref(p);
08721 }
08722
08723 if (iax2_regfunk) {
08724 iax2_regfunk(p->name, 1);
08725 }
08726
08727 register_peer_exten(p, 1);
08728 }
08729
08730
08731
08732
08733
08734
08735
08736 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08737 {
08738
08739 struct iax_ie_data ied = {
08740 .pos = 0,
08741 };
08742 struct iax2_peer *p;
08743 int msgcount;
08744 char data[80];
08745 int version;
08746 const char *peer_name;
08747 int res = -1;
08748 struct ast_sockaddr sockaddr;
08749
08750 ast_sockaddr_from_sin(&sockaddr, sin);
08751
08752 peer_name = ast_strdupa(iaxs[callno]->peer);
08753
08754
08755 ast_mutex_unlock(&iaxsl[callno]);
08756 if (!(p = find_peer(peer_name, 1))) {
08757 ast_mutex_lock(&iaxsl[callno]);
08758 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08759 return -1;
08760 }
08761 ast_mutex_lock(&iaxsl[callno]);
08762 if (!iaxs[callno])
08763 goto return_unref;
08764
08765 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08766 if (sin->sin_addr.s_addr) {
08767 time_t nowtime;
08768 time(&nowtime);
08769 realtime_update_peer(peer_name, &sockaddr, nowtime);
08770 } else {
08771 realtime_update_peer(peer_name, &sockaddr, 0);
08772 }
08773 }
08774
08775
08776 if (!refresh) {
08777 refresh = min_reg_expire;
08778 }
08779 if (refresh > max_reg_expire) {
08780 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08781 p->name, max_reg_expire, refresh);
08782 p->expiry = max_reg_expire;
08783 } else if (refresh < min_reg_expire) {
08784 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08785 p->name, min_reg_expire, refresh);
08786 p->expiry = min_reg_expire;
08787 } else {
08788 p->expiry = refresh;
08789 }
08790
08791 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08792 if (iax2_regfunk) {
08793 iax2_regfunk(p->name, 1);
08794 }
08795
08796
08797 peercnt_modify((unsigned char) 0, 0, &p->addr);
08798
08799
08800 ast_sockaddr_from_sin(&p->addr, sin);
08801
08802 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08803 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08804 ast_db_put("IAX/Registry", p->name, data);
08805 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08806 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08807 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08808 register_peer_exten(p, 1);
08809 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08810 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08811 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08812 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08813 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08814 register_peer_exten(p, 0);
08815 ast_db_del("IAX/Registry", p->name);
08816 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name);
08817 }
08818
08819
08820 iax2_poke_peer(p, callno);
08821 }
08822
08823
08824 if (p->maxcallno) {
08825 peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr);
08826 }
08827
08828
08829 if (!iaxs[callno]) {
08830 res = -1;
08831 goto return_unref;
08832 }
08833
08834
08835 p->sockfd = fd;
08836
08837 if (p->expire > -1) {
08838 if (!ast_sched_thread_del(sched, p->expire)) {
08839 p->expire = -1;
08840 peer_unref(p);
08841 }
08842 }
08843
08844 if (p->expiry && sin->sin_addr.s_addr) {
08845 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08846 if (p->expire == -1)
08847 peer_unref(p);
08848 }
08849 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08850 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08851 if (sin->sin_addr.s_addr) {
08852 struct sockaddr_in peer_addr;
08853
08854 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08855
08856 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08857 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08858 if (!ast_strlen_zero(p->mailbox)) {
08859 struct ast_event *event;
08860 int new, old;
08861 char *mailbox, *context;
08862
08863 context = mailbox = ast_strdupa(p->mailbox);
08864 strsep(&context, "@");
08865 if (ast_strlen_zero(context))
08866 context = "default";
08867
08868 event = ast_event_get_cached(AST_EVENT_MWI,
08869 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08870 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08871 AST_EVENT_IE_END);
08872 if (event) {
08873 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08874 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08875 ast_event_destroy(event);
08876 } else {
08877 ast_app_inboxcount(p->mailbox, &new, &old);
08878 }
08879
08880 if (new > 255) {
08881 new = 255;
08882 }
08883 if (old > 255) {
08884 old = 255;
08885 }
08886 msgcount = (old << 8) | new;
08887
08888 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08889 }
08890 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08891 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08892 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08893 }
08894 }
08895 version = iax_check_version(devtype);
08896 if (version)
08897 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08898
08899 res = 0;
08900
08901 return_unref:
08902 peer_unref(p);
08903
08904 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08905 }
08906
08907 static int registry_authrequest(int callno)
08908 {
08909 struct iax_ie_data ied;
08910 struct iax2_peer *p;
08911 char challenge[10];
08912 const char *peer_name;
08913 int sentauthmethod;
08914
08915 peer_name = ast_strdupa(iaxs[callno]->peer);
08916
08917
08918 ast_mutex_unlock(&iaxsl[callno]);
08919 if ((p = find_peer(peer_name, 1))) {
08920 last_authmethod = p->authmethods;
08921 }
08922
08923 ast_mutex_lock(&iaxsl[callno]);
08924 if (!iaxs[callno])
08925 goto return_unref;
08926
08927 memset(&ied, 0, sizeof(ied));
08928
08929
08930
08931
08932
08933
08934 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08935 if (!p) {
08936 iaxs[callno]->authmethods = sentauthmethod;
08937 }
08938 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08939 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08940
08941 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08942 ast_string_field_set(iaxs[callno], challenge, challenge);
08943 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08944 }
08945 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08946
08947 return_unref:
08948 if (p) {
08949 peer_unref(p);
08950 }
08951
08952 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08953 }
08954
08955 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08956 {
08957 struct iax2_registry *reg;
08958
08959 struct iax_ie_data ied;
08960 char peer[256] = "";
08961 char challenge[256] = "";
08962 int res;
08963 int authmethods = 0;
08964 if (ies->authmethods)
08965 authmethods = ies->authmethods;
08966 if (ies->username)
08967 ast_copy_string(peer, ies->username, sizeof(peer));
08968 if (ies->challenge)
08969 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08970 memset(&ied, 0, sizeof(ied));
08971 reg = iaxs[callno]->reg;
08972 if (reg) {
08973 struct sockaddr_in reg_addr;
08974
08975 ast_sockaddr_to_sin(®->addr, ®_addr);
08976
08977 if (inaddrcmp(®_addr, sin)) {
08978 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08979 return -1;
08980 }
08981 if (ast_strlen_zero(reg->secret)) {
08982 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08983 reg->regstate = REG_STATE_NOAUTH;
08984 return -1;
08985 }
08986 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08987 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08988 if (reg->secret[0] == '[') {
08989 char tmpkey[256];
08990 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08991 tmpkey[strlen(tmpkey) - 1] = '\0';
08992 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08993 } else
08994 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08995 if (!res) {
08996 reg->regstate = REG_STATE_AUTHSENT;
08997 add_empty_calltoken_ie(iaxs[callno], &ied);
08998 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08999 } else
09000 return -1;
09001 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
09002 } else
09003 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
09004 return -1;
09005 }
09006
09007 static void stop_stuff(int callno)
09008 {
09009 iax2_destroy_helper(iaxs[callno]);
09010 }
09011
09012 static void __auth_reject(const void *nothing)
09013 {
09014
09015 int callno = (int)(long)(nothing);
09016 struct iax_ie_data ied;
09017 ast_mutex_lock(&iaxsl[callno]);
09018 if (iaxs[callno]) {
09019 memset(&ied, 0, sizeof(ied));
09020 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
09021 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
09022 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
09023 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09024 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09025 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09026 }
09027 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09028 }
09029 ast_mutex_unlock(&iaxsl[callno]);
09030 }
09031
09032 static int auth_reject(const void *data)
09033 {
09034 int callno = (int)(long)(data);
09035 ast_mutex_lock(&iaxsl[callno]);
09036 if (iaxs[callno])
09037 iaxs[callno]->authid = -1;
09038 ast_mutex_unlock(&iaxsl[callno]);
09039 #ifdef SCHED_MULTITHREADED
09040 if (schedule_action(__auth_reject, data))
09041 #endif
09042 __auth_reject(data);
09043 return 0;
09044 }
09045
09046 static int auth_fail(int callno, int failcode)
09047 {
09048
09049
09050 if (iaxs[callno]) {
09051 iaxs[callno]->authfail = failcode;
09052 if (delayreject) {
09053 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
09054 sched, 1000, auth_reject, (void *)(long)callno);
09055 } else
09056 auth_reject((void *)(long)callno);
09057 }
09058 return 0;
09059 }
09060
09061 static void __auto_hangup(const void *nothing)
09062 {
09063
09064 int callno = (int)(long)(nothing);
09065 struct iax_ie_data ied;
09066 ast_mutex_lock(&iaxsl[callno]);
09067 if (iaxs[callno]) {
09068 memset(&ied, 0, sizeof(ied));
09069 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09070 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09071 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09072 }
09073 ast_mutex_unlock(&iaxsl[callno]);
09074 }
09075
09076 static int auto_hangup(const void *data)
09077 {
09078 int callno = (int)(long)(data);
09079 ast_mutex_lock(&iaxsl[callno]);
09080 if (iaxs[callno]) {
09081 iaxs[callno]->autoid = -1;
09082 }
09083 ast_mutex_unlock(&iaxsl[callno]);
09084 #ifdef SCHED_MULTITHREADED
09085 if (schedule_action(__auto_hangup, data))
09086 #endif
09087 __auto_hangup(data);
09088 return 0;
09089 }
09090
09091 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09092 {
09093 struct iax_ie_data ied;
09094
09095 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09096 sched, 30000, auto_hangup, (void *)(long)callno);
09097 memset(&ied, 0, sizeof(ied));
09098 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09099 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09100 dp->flags |= CACHE_FLAG_TRANSMITTED;
09101 }
09102
09103 static int iax2_vnak(int callno)
09104 {
09105 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09106 }
09107
09108 static void vnak_retransmit(int callno, int last)
09109 {
09110 struct iax_frame *f;
09111
09112 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09113
09114 if (((unsigned char) (f->oseqno - last) < 128) &&
09115 (f->retries >= 0)) {
09116 send_packet(f);
09117 }
09118 }
09119 }
09120
09121 static void __iax2_poke_peer_s(const void *data)
09122 {
09123 struct iax2_peer *peer = (struct iax2_peer *)data;
09124 iax2_poke_peer(peer, 0);
09125 peer_unref(peer);
09126 }
09127
09128 static int iax2_poke_peer_s(const void *data)
09129 {
09130 struct iax2_peer *peer = (struct iax2_peer *)data;
09131 peer->pokeexpire = -1;
09132 #ifdef SCHED_MULTITHREADED
09133 if (schedule_action(__iax2_poke_peer_s, data))
09134 #endif
09135 __iax2_poke_peer_s(data);
09136 return 0;
09137 }
09138
09139 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09140 {
09141 int res = 0;
09142 struct iax_frame *fr;
09143 struct ast_iax2_meta_hdr *meta;
09144 struct ast_iax2_meta_trunk_hdr *mth;
09145 int calls = 0;
09146
09147
09148 fr = (struct iax_frame *)tpeer->trunkdata;
09149
09150 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09151 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09152 if (tpeer->trunkdatalen) {
09153
09154 meta->zeros = 0;
09155 meta->metacmd = IAX_META_TRUNK;
09156 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09157 meta->cmddata = IAX_META_TRUNK_MINI;
09158 else
09159 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09160 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09161
09162 fr->direction = DIRECTION_OUTGRESS;
09163 fr->retrans = -1;
09164 fr->transfer = 0;
09165
09166 fr->data = fr->afdata;
09167 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09168 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09169 calls = tpeer->calls;
09170 #if 0
09171 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));
09172 #endif
09173
09174 tpeer->trunkdatalen = 0;
09175 tpeer->calls = 0;
09176 }
09177 if (res < 0)
09178 return res;
09179 return calls;
09180 }
09181
09182 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09183 {
09184
09185 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09186 return 1;
09187 return 0;
09188 }
09189
09190 static int timing_read(int *id, int fd, short events, void *cbdata)
09191 {
09192 int res, processed = 0, totalcalls = 0;
09193 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09194 struct timeval now = ast_tvnow();
09195
09196 if (iaxtrunkdebug)
09197 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09198
09199 if (timer) {
09200 if (ast_timer_ack(timer, 1) < 0) {
09201 ast_log(LOG_ERROR, "Timer failed acknowledge\n");
09202 return 0;
09203 }
09204 }
09205
09206
09207 AST_LIST_LOCK(&tpeers);
09208 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09209 processed++;
09210 res = 0;
09211 ast_mutex_lock(&tpeer->lock);
09212
09213
09214 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09215
09216
09217 AST_LIST_REMOVE_CURRENT(list);
09218 drop = tpeer;
09219 } else {
09220 res = send_trunk(tpeer, &now);
09221 trunk_timed++;
09222 if (iaxtrunkdebug)
09223 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);
09224 }
09225 totalcalls += res;
09226 res = 0;
09227 ast_mutex_unlock(&tpeer->lock);
09228 }
09229 AST_LIST_TRAVERSE_SAFE_END;
09230 AST_LIST_UNLOCK(&tpeers);
09231
09232 if (drop) {
09233 ast_mutex_lock(&drop->lock);
09234
09235
09236 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09237 if (drop->trunkdata) {
09238 ast_free(drop->trunkdata);
09239 drop->trunkdata = NULL;
09240 }
09241 ast_mutex_unlock(&drop->lock);
09242 ast_mutex_destroy(&drop->lock);
09243 ast_free(drop);
09244
09245 }
09246
09247 if (iaxtrunkdebug)
09248 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09249 iaxtrunkdebug = 0;
09250
09251 return 1;
09252 }
09253
09254 struct dpreq_data {
09255 int callno;
09256 char context[AST_MAX_EXTENSION];
09257 char callednum[AST_MAX_EXTENSION];
09258 char *callerid;
09259 };
09260
09261 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09262 {
09263 unsigned short dpstatus = 0;
09264 struct iax_ie_data ied1;
09265 int mm;
09266
09267 memset(&ied1, 0, sizeof(ied1));
09268 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09269
09270 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09271 dpstatus = IAX_DPSTATUS_EXISTS;
09272 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09273 dpstatus = IAX_DPSTATUS_CANEXIST;
09274 } else {
09275 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09276 }
09277 if (ast_ignore_pattern(context, callednum))
09278 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09279 if (mm)
09280 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09281 if (!skiplock)
09282 ast_mutex_lock(&iaxsl[callno]);
09283 if (iaxs[callno]) {
09284 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09285 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09286 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09287 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09288 }
09289 if (!skiplock)
09290 ast_mutex_unlock(&iaxsl[callno]);
09291 }
09292
09293 static void *dp_lookup_thread(void *data)
09294 {
09295
09296 struct dpreq_data *dpr = data;
09297 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09298 if (dpr->callerid)
09299 ast_free(dpr->callerid);
09300 ast_free(dpr);
09301 return NULL;
09302 }
09303
09304 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09305 {
09306 pthread_t newthread;
09307 struct dpreq_data *dpr;
09308
09309 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09310 return;
09311
09312 dpr->callno = callno;
09313 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09314 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09315 if (callerid)
09316 dpr->callerid = ast_strdup(callerid);
09317 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09318 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09319 }
09320 }
09321
09322 struct iax_dual {
09323 struct ast_channel *chan1;
09324 struct ast_channel *chan2;
09325 char *park_exten;
09326 char *park_context;
09327 };
09328
09329 static void *iax_park_thread(void *stuff)
09330 {
09331 struct iax_dual *d;
09332 int res;
09333 int ext = 0;
09334
09335 d = stuff;
09336
09337 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09338 d->chan2->name, d->chan1->name);
09339
09340 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09341 if (res) {
09342
09343 ast_hangup(d->chan1);
09344 } else {
09345 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09346 }
09347 ast_hangup(d->chan2);
09348
09349 ast_free(d->park_exten);
09350 ast_free(d->park_context);
09351 ast_free(d);
09352 return NULL;
09353 }
09354
09355
09356 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
09357 {
09358 struct iax_dual *d;
09359 struct ast_channel *chan1m, *chan2m;
09360 pthread_t th;
09361
09362 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09363 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09364 d = ast_calloc(1, sizeof(*d));
09365 if (!chan1m || !chan2m || !d) {
09366 if (chan1m) {
09367 ast_hangup(chan1m);
09368 }
09369 if (chan2m) {
09370 ast_hangup(chan2m);
09371 }
09372 ast_free(d);
09373 return -1;
09374 }
09375 d->park_exten = ast_strdup(park_exten);
09376 d->park_context = ast_strdup(park_context);
09377 if (!d->park_exten || !d->park_context) {
09378 ast_hangup(chan1m);
09379 ast_hangup(chan2m);
09380 ast_free(d->park_exten);
09381 ast_free(d->park_context);
09382 ast_free(d);
09383 return -1;
09384 }
09385
09386
09387 chan1m->readformat = chan1->readformat;
09388 chan1m->writeformat = chan1->writeformat;
09389
09390
09391 if (ast_channel_masquerade(chan1m, chan1)) {
09392 ast_hangup(chan1m);
09393 ast_hangup(chan2m);
09394 ast_free(d->park_exten);
09395 ast_free(d->park_context);
09396 ast_free(d);
09397 return -1;
09398 }
09399
09400
09401 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09402 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09403 chan1m->priority = chan1->priority;
09404
09405 ast_do_masquerade(chan1m);
09406
09407
09408
09409
09410
09411 chan2m->readformat = chan2->readformat;
09412 chan2m->writeformat = chan2->writeformat;
09413 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09414
09415
09416 if (ast_channel_masquerade(chan2m, chan2)) {
09417 ast_hangup(chan1m);
09418 ast_hangup(chan2m);
09419 ast_free(d->park_exten);
09420 ast_free(d->park_context);
09421 ast_free(d);
09422 return -1;
09423 }
09424
09425
09426 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09427 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09428 chan2m->priority = chan2->priority;
09429
09430 ast_do_masquerade(chan2m);
09431
09432 d->chan1 = chan1m;
09433 d->chan2 = chan2m;
09434 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09435
09436 ast_hangup(chan1m);
09437 ast_hangup(chan2m);
09438 ast_free(d->park_exten);
09439 ast_free(d->park_context);
09440 ast_free(d);
09441 return -1;
09442 }
09443 return 0;
09444 }
09445
09446 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09447 {
09448 unsigned int ourver;
09449 char rsi[80];
09450 snprintf(rsi, sizeof(rsi), "si-%s", si);
09451 if (iax_provision_version(&ourver, rsi, 1))
09452 return 0;
09453 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09454 if (ourver != ver)
09455 iax2_provision(sin, sockfd, NULL, rsi, 1);
09456 return 0;
09457 }
09458
09459 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09460 {
09461 jb_info stats;
09462 jb_getinfo(pvt->jb, &stats);
09463
09464 memset(iep, 0, sizeof(*iep));
09465
09466 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09467 if(stats.frames_in == 0) stats.frames_in = 1;
09468 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09469 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09470 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09471 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09472 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09473 }
09474
09475 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09476 {
09477 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09478 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09479 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09480 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09481 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09482 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09483 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09484 }
09485
09486 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09487 {
09488 int i;
09489 unsigned int length, offset = 0;
09490 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09491
09492 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09493 length = ies->ospblocklength[i];
09494 if (length != 0) {
09495 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09496
09497 offset = 0;
09498 break;
09499 } else {
09500 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09501 offset += length;
09502 }
09503 } else {
09504 break;
09505 }
09506 }
09507 *(full_osptoken + offset) = '\0';
09508 if (strlen(full_osptoken) != offset) {
09509
09510 *full_osptoken = '\0';
09511 }
09512
09513 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09514 }
09515
09516 static void log_jitterstats(unsigned short callno)
09517 {
09518 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09519 jb_info jbinfo;
09520
09521 ast_mutex_lock(&iaxsl[callno]);
09522 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09523 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09524 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09525 localjitter = jbinfo.jitter;
09526 localdelay = jbinfo.current - jbinfo.min;
09527 locallost = jbinfo.frames_lost;
09528 locallosspct = jbinfo.losspct/1000;
09529 localdropped = jbinfo.frames_dropped;
09530 localooo = jbinfo.frames_ooo;
09531 localpackets = jbinfo.frames_in;
09532 }
09533 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",
09534 iaxs[callno]->owner->name,
09535 iaxs[callno]->pingtime,
09536 localjitter,
09537 localdelay,
09538 locallost,
09539 locallosspct,
09540 localdropped,
09541 localooo,
09542 localpackets,
09543 iaxs[callno]->remote_rr.jitter,
09544 iaxs[callno]->remote_rr.delay,
09545 iaxs[callno]->remote_rr.losscnt,
09546 iaxs[callno]->remote_rr.losspct/1000,
09547 iaxs[callno]->remote_rr.dropped,
09548 iaxs[callno]->remote_rr.ooo,
09549 iaxs[callno]->remote_rr.packets);
09550 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",
09551 iaxs[callno]->owner->name,
09552 iaxs[callno]->pingtime,
09553 localjitter,
09554 localdelay,
09555 locallost,
09556 locallosspct,
09557 localdropped,
09558 localooo,
09559 localpackets,
09560 iaxs[callno]->remote_rr.jitter,
09561 iaxs[callno]->remote_rr.delay,
09562 iaxs[callno]->remote_rr.losscnt,
09563 iaxs[callno]->remote_rr.losspct/1000,
09564 iaxs[callno]->remote_rr.dropped,
09565 iaxs[callno]->remote_rr.ooo,
09566 iaxs[callno]->remote_rr.packets);
09567 }
09568 ast_mutex_unlock(&iaxsl[callno]);
09569 }
09570
09571 static int socket_process(struct iax2_thread *thread);
09572
09573
09574
09575
09576 static void handle_deferred_full_frames(struct iax2_thread *thread)
09577 {
09578 struct iax2_pkt_buf *pkt_buf;
09579
09580 ast_mutex_lock(&thread->lock);
09581
09582 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09583 ast_mutex_unlock(&thread->lock);
09584
09585 thread->buf = pkt_buf->buf;
09586 thread->buf_len = pkt_buf->len;
09587 thread->buf_size = pkt_buf->len + 1;
09588
09589 socket_process(thread);
09590
09591 thread->buf = NULL;
09592 ast_free(pkt_buf);
09593
09594 ast_mutex_lock(&thread->lock);
09595 }
09596
09597 ast_mutex_unlock(&thread->lock);
09598 }
09599
09600
09601
09602
09603
09604
09605
09606 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09607 {
09608 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09609 struct ast_iax2_full_hdr *fh, *cur_fh;
09610
09611 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09612 return;
09613
09614 pkt_buf->len = from_here->buf_len;
09615 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09616
09617 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09618 ast_mutex_lock(&to_here->lock);
09619 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09620 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09621 if (fh->oseqno < cur_fh->oseqno) {
09622 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09623 break;
09624 }
09625 }
09626 AST_LIST_TRAVERSE_SAFE_END
09627
09628 if (!cur_pkt_buf)
09629 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09630
09631 to_here->iostate = IAX_IOSTATE_READY;
09632 ast_cond_signal(&to_here->cond);
09633
09634 ast_mutex_unlock(&to_here->lock);
09635 }
09636
09637 static int socket_read(int *id, int fd, short events, void *cbdata)
09638 {
09639 struct iax2_thread *thread;
09640 socklen_t len;
09641 time_t t;
09642 static time_t last_errtime = 0;
09643 struct ast_iax2_full_hdr *fh;
09644
09645 if (!(thread = find_idle_thread())) {
09646 time(&t);
09647 if (t != last_errtime) {
09648 last_errtime = t;
09649 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09650 }
09651 usleep(1);
09652 return 1;
09653 }
09654
09655 len = sizeof(thread->iosin);
09656 thread->iofd = fd;
09657 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09658 thread->buf_size = sizeof(thread->readbuf);
09659 thread->buf = thread->readbuf;
09660 if (thread->buf_len < 0) {
09661 if (errno != ECONNREFUSED && errno != EAGAIN)
09662 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09663 handle_error();
09664 thread->iostate = IAX_IOSTATE_IDLE;
09665 signal_condition(&thread->lock, &thread->cond);
09666 return 1;
09667 }
09668 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09669 thread->iostate = IAX_IOSTATE_IDLE;
09670 signal_condition(&thread->lock, &thread->cond);
09671 return 1;
09672 }
09673
09674
09675
09676
09677 fh = (struct ast_iax2_full_hdr *) thread->buf;
09678 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09679 struct iax2_thread *cur = NULL;
09680 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09681
09682 AST_LIST_LOCK(&active_list);
09683 AST_LIST_TRAVERSE(&active_list, cur, list) {
09684 if ((cur->ffinfo.callno == callno) &&
09685 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09686 break;
09687 }
09688 if (cur) {
09689
09690
09691 defer_full_frame(thread, cur);
09692 AST_LIST_UNLOCK(&active_list);
09693 thread->iostate = IAX_IOSTATE_IDLE;
09694 signal_condition(&thread->lock, &thread->cond);
09695 return 1;
09696 } else {
09697
09698 thread->ffinfo.callno = callno;
09699 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09700 thread->ffinfo.type = fh->type;
09701 thread->ffinfo.csub = fh->csub;
09702 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09703 }
09704 AST_LIST_UNLOCK(&active_list);
09705 }
09706
09707
09708 thread->iostate = IAX_IOSTATE_READY;
09709 #ifdef DEBUG_SCHED_MULTITHREAD
09710 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09711 #endif
09712 signal_condition(&thread->lock, &thread->cond);
09713
09714 return 1;
09715 }
09716
09717 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09718 struct iax_frame *fr)
09719 {
09720 unsigned char metatype;
09721 struct ast_iax2_meta_trunk_mini *mtm;
09722 struct ast_iax2_meta_trunk_hdr *mth;
09723 struct ast_iax2_meta_trunk_entry *mte;
09724 struct iax2_trunk_peer *tpeer;
09725 unsigned int ts;
09726 void *ptr;
09727 struct timeval rxtrunktime;
09728 struct ast_frame f = { 0, };
09729
09730 if (packet_len < sizeof(*meta)) {
09731 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09732 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09733 return 1;
09734 }
09735
09736 if (meta->metacmd != IAX_META_TRUNK)
09737 return 1;
09738
09739 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09740 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09741 (int) (sizeof(*meta) + sizeof(*mth)));
09742 return 1;
09743 }
09744 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09745 ts = ntohl(mth->ts);
09746 metatype = meta->cmddata;
09747 packet_len -= (sizeof(*meta) + sizeof(*mth));
09748 ptr = mth->data;
09749 tpeer = find_tpeer(sin, sockfd);
09750 if (!tpeer) {
09751 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09752 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09753 return 1;
09754 }
09755 tpeer->trunkact = ast_tvnow();
09756 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09757 tpeer->rxtrunktime = tpeer->trunkact;
09758 rxtrunktime = tpeer->rxtrunktime;
09759 ast_mutex_unlock(&tpeer->lock);
09760 while (packet_len >= sizeof(*mte)) {
09761
09762 unsigned short callno, trunked_ts, len;
09763
09764 if (metatype == IAX_META_TRUNK_MINI) {
09765 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09766 ptr += sizeof(*mtm);
09767 packet_len -= sizeof(*mtm);
09768 len = ntohs(mtm->len);
09769 callno = ntohs(mtm->mini.callno);
09770 trunked_ts = ntohs(mtm->mini.ts);
09771 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09772 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09773 ptr += sizeof(*mte);
09774 packet_len -= sizeof(*mte);
09775 len = ntohs(mte->len);
09776 callno = ntohs(mte->callno);
09777 trunked_ts = 0;
09778 } else {
09779 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09780 break;
09781 }
09782
09783 if (len > packet_len)
09784 break;
09785 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09786 if (!fr->callno)
09787 continue;
09788
09789
09790
09791
09792 memset(&f, 0, sizeof(f));
09793 f.frametype = AST_FRAME_VOICE;
09794 if (!iaxs[fr->callno]) {
09795
09796 } else if (iaxs[fr->callno]->voiceformat == 0) {
09797 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09798 iax2_vnak(fr->callno);
09799 } else {
09800 f.subclass.codec = iaxs[fr->callno]->voiceformat;
09801 f.datalen = len;
09802 if (f.datalen >= 0) {
09803 if (f.datalen)
09804 f.data.ptr = ptr;
09805 else
09806 f.data.ptr = NULL;
09807 if (trunked_ts)
09808 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09809 else
09810 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09811
09812 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09813 struct iax_frame *duped_fr;
09814
09815
09816 f.src = "IAX2";
09817 f.mallocd = 0;
09818 f.offset = 0;
09819 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09820 f.samples = ast_codec_get_samples(&f);
09821 else
09822 f.samples = 0;
09823 fr->outoforder = 0;
09824 iax_frame_wrap(fr, &f);
09825 duped_fr = iaxfrdup2(fr);
09826 if (duped_fr)
09827 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09828 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09829 iaxs[fr->callno]->last = fr->ts;
09830 }
09831 } else {
09832 ast_log(LOG_WARNING, "Datalen < 0?\n");
09833 }
09834 }
09835 ast_mutex_unlock(&iaxsl[fr->callno]);
09836 ptr += len;
09837 packet_len -= len;
09838 }
09839
09840 return 1;
09841 }
09842
09843 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09844 {
09845 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09846 AST_LIST_HEAD(, ast_var_t) *varlist;
09847 struct ast_var_t *var;
09848
09849 if (!variablestore) {
09850 *buf = '\0';
09851 return 0;
09852 }
09853 varlist = variablestore->data;
09854
09855 AST_LIST_LOCK(varlist);
09856 AST_LIST_TRAVERSE(varlist, var, entries) {
09857 if (strcmp(var->name, data) == 0) {
09858 ast_copy_string(buf, var->value, len);
09859 break;
09860 }
09861 }
09862 AST_LIST_UNLOCK(varlist);
09863 return 0;
09864 }
09865
09866 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09867 {
09868 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09869 AST_LIST_HEAD(, ast_var_t) *varlist;
09870 struct ast_var_t *var;
09871
09872 if (!variablestore) {
09873 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09874 if (!variablestore) {
09875 ast_log(LOG_ERROR, "Memory allocation error\n");
09876 return -1;
09877 }
09878 varlist = ast_calloc(1, sizeof(*varlist));
09879 if (!varlist) {
09880 ast_datastore_free(variablestore);
09881 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09882 return -1;
09883 }
09884
09885 AST_LIST_HEAD_INIT(varlist);
09886 variablestore->data = varlist;
09887 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09888 ast_channel_datastore_add(chan, variablestore);
09889 } else
09890 varlist = variablestore->data;
09891
09892 AST_LIST_LOCK(varlist);
09893 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09894 if (strcmp(var->name, data) == 0) {
09895 AST_LIST_REMOVE_CURRENT(entries);
09896 ast_var_delete(var);
09897 break;
09898 }
09899 }
09900 AST_LIST_TRAVERSE_SAFE_END;
09901 var = ast_var_assign(data, value);
09902 if (var)
09903 AST_LIST_INSERT_TAIL(varlist, var, entries);
09904 else
09905 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09906 AST_LIST_UNLOCK(varlist);
09907 return 0;
09908 }
09909
09910 static struct ast_custom_function iaxvar_function = {
09911 .name = "IAXVAR",
09912 .read = acf_iaxvar_read,
09913 .write = acf_iaxvar_write,
09914 };
09915
09916 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
09917 {
09918 iax2_lock_owner(callno);
09919 if (iaxs[callno] && iaxs[callno]->owner) {
09920 struct ast_channel *owner;
09921 const char *name;
09922
09923 owner = iaxs[callno]->owner;
09924 if (causecode) {
09925 owner->hangupcause = causecode;
09926 }
09927 name = ast_strdupa(owner->name);
09928 ast_channel_ref(owner);
09929 ast_channel_unlock(owner);
09930 ast_mutex_unlock(&iaxsl[callno]);
09931 ast_set_hangupsource(owner, name, 0);
09932 ast_channel_unref(owner);
09933 ast_mutex_lock(&iaxsl[callno]);
09934 }
09935 }
09936
09937 static int socket_process(struct iax2_thread *thread)
09938 {
09939 struct sockaddr_in sin;
09940 int res;
09941 int updatehistory=1;
09942 int new = NEW_PREVENT;
09943 int dcallno = 0;
09944 char decrypted = 0;
09945 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09946 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09947 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09948 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09949 struct iax_frame *fr;
09950 struct iax_frame *cur;
09951 struct ast_frame f = { 0, };
09952 struct ast_channel *c = NULL;
09953 struct iax2_dpcache *dp;
09954 struct iax2_peer *peer;
09955 struct iax_ies ies;
09956 struct iax_ie_data ied0, ied1;
09957 format_t format;
09958 int fd;
09959 int exists;
09960 int minivid = 0;
09961 char empty[32]="";
09962 struct iax_frame *duped_fr;
09963 char host_pref_buf[128];
09964 char caller_pref_buf[128];
09965 struct ast_codec_pref pref;
09966 char *using_prefs = "mine";
09967
09968
09969 fr = ast_alloca(sizeof(*fr) + 4096);
09970 memset(fr, 0, sizeof(*fr));
09971 fr->afdatalen = 4096;
09972
09973
09974 res = thread->buf_len;
09975 fd = thread->iofd;
09976 memcpy(&sin, &thread->iosin, sizeof(sin));
09977
09978 if (res < sizeof(*mh)) {
09979 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09980 return 1;
09981 }
09982 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09983 if (res < sizeof(*vh)) {
09984 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));
09985 return 1;
09986 }
09987
09988
09989 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09990 minivid = 1;
09991 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09992 return socket_process_meta(res, meta, &sin, fd, fr);
09993
09994 #ifdef DEBUG_SUPPORT
09995 if (res >= sizeof(*fh))
09996 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09997 #endif
09998 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09999 if (res < sizeof(*fh)) {
10000 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));
10001 return 1;
10002 }
10003
10004
10005 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10006
10007
10008
10009
10010
10011
10012 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
10013 ast_mutex_lock(&iaxsl[fr->callno]);
10014 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10015 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10016 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10017 ast_mutex_unlock(&iaxsl[fr->callno]);
10018 return 1;
10019 }
10020 decrypted = 1;
10021 }
10022 ast_mutex_unlock(&iaxsl[fr->callno]);
10023 }
10024
10025
10026 f.frametype = fh->type;
10027 if (f.frametype == AST_FRAME_VIDEO) {
10028 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
10029 } else if (f.frametype == AST_FRAME_VOICE) {
10030 f.subclass.codec = uncompress_subclass(fh->csub);
10031 } else {
10032 f.subclass.integer = uncompress_subclass(fh->csub);
10033 }
10034
10035
10036 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
10037
10038 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10039 return 1;
10040 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10041
10042 return 1;
10043 }
10044
10045 f.datalen = res - sizeof(*fh);
10046 if (f.datalen) {
10047 if (f.frametype == AST_FRAME_IAX) {
10048 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10049 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
10050 ast_variables_destroy(ies.vars);
10051 return 1;
10052 }
10053 f.data.ptr = NULL;
10054 f.datalen = 0;
10055 } else {
10056 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10057 memset(&ies, 0, sizeof(ies));
10058 }
10059 } else {
10060 if (f.frametype == AST_FRAME_IAX)
10061 f.data.ptr = NULL;
10062 else
10063 f.data.ptr = empty;
10064 memset(&ies, 0, sizeof(ies));
10065 }
10066
10067 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10068
10069 if (handle_call_token(fh, &ies, &sin, fd)) {
10070 ast_variables_destroy(ies.vars);
10071 return 1;
10072 }
10073
10074 if (ies.calltoken && ies.calltokendata) {
10075
10076
10077
10078
10079 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10080 } else {
10081 new = NEW_ALLOW;
10082 }
10083 }
10084 } else {
10085
10086 f.frametype = AST_FRAME_NULL;
10087 f.subclass.integer = 0;
10088 memset(&ies, 0, sizeof(ies));
10089 }
10090
10091 if (!fr->callno) {
10092 int check_dcallno = 0;
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10103 check_dcallno = 1;
10104 }
10105
10106 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10107 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10108 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10109 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10110 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10111 }
10112 ast_variables_destroy(ies.vars);
10113 return 1;
10114 }
10115 }
10116
10117 if (fr->callno > 0)
10118 ast_mutex_lock(&iaxsl[fr->callno]);
10119
10120 if (!fr->callno || !iaxs[fr->callno]) {
10121
10122
10123 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10124
10125 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10126 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10127 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10128 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10129 (f.frametype != AST_FRAME_IAX))
10130 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10131 fd);
10132 }
10133 if (fr->callno > 0)
10134 ast_mutex_unlock(&iaxsl[fr->callno]);
10135 ast_variables_destroy(ies.vars);
10136 return 1;
10137 }
10138 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10139 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10140 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10141 ast_variables_destroy(ies.vars);
10142 ast_mutex_unlock(&iaxsl[fr->callno]);
10143 return 1;
10144 }
10145 decrypted = 1;
10146 }
10147
10148 #ifdef DEBUG_SUPPORT
10149 if (decrypted) {
10150 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10151 }
10152 #endif
10153
10154
10155
10156 iaxs[fr->callno]->frames_received++;
10157
10158 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10159 f.subclass.integer != IAX_COMMAND_TXCNT &&
10160 f.subclass.integer != IAX_COMMAND_TXACC) {
10161 unsigned short new_peercallno;
10162
10163 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10164 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10165 if (iaxs[fr->callno]->peercallno) {
10166 remove_by_peercallno(iaxs[fr->callno]);
10167 }
10168 iaxs[fr->callno]->peercallno = new_peercallno;
10169 store_by_peercallno(iaxs[fr->callno]);
10170 }
10171 }
10172 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10173 if (iaxdebug)
10174 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10175
10176 fr->oseqno = fh->oseqno;
10177 fr->iseqno = fh->iseqno;
10178 fr->ts = ntohl(fh->ts);
10179 #ifdef IAXTESTS
10180 if (test_resync) {
10181 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10182 fr->ts += test_resync;
10183 }
10184 #endif
10185 #if 0
10186 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10187 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10188 (f.subclass == IAX_COMMAND_NEW ||
10189 f.subclass == IAX_COMMAND_AUTHREQ ||
10190 f.subclass == IAX_COMMAND_ACCEPT ||
10191 f.subclass == IAX_COMMAND_REJECT)) ) )
10192 #endif
10193 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10194 updatehistory = 0;
10195 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10196 (iaxs[fr->callno]->iseqno ||
10197 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10198 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10199 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10200 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10201 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10202 (f.frametype != AST_FRAME_IAX))) {
10203 if (
10204 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10205 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10206 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10207 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10208 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10209 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10210 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10211 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10212 (f.frametype != AST_FRAME_IAX)) {
10213
10214 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10215 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10216
10217
10218 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10219
10220 if ((f.frametype != AST_FRAME_IAX) ||
10221 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10222 ast_debug(1, "Acking anyway\n");
10223
10224
10225 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10226 }
10227 } else {
10228
10229 iax2_vnak(fr->callno);
10230 }
10231 ast_variables_destroy(ies.vars);
10232 ast_mutex_unlock(&iaxsl[fr->callno]);
10233 return 1;
10234 }
10235 } else {
10236
10237 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10238 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10239 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10240 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10241 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10242 (f.frametype != AST_FRAME_IAX))
10243 iaxs[fr->callno]->iseqno++;
10244 }
10245
10246 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10247 if (res < thread->buf_size)
10248 thread->buf[res++] = '\0';
10249 else
10250 thread->buf[res - 1] = '\0';
10251 }
10252
10253
10254
10255 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10256 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10257 (f.frametype != AST_FRAME_IAX))) {
10258 unsigned char x;
10259 int call_to_destroy;
10260
10261 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10262 x = fr->iseqno;
10263 else
10264 x = iaxs[fr->callno]->oseqno;
10265 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10266
10267
10268 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10269
10270 if (iaxdebug)
10271 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10272 call_to_destroy = 0;
10273 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10274
10275 if (x == cur->oseqno) {
10276 cur->retries = -1;
10277
10278 if (cur->final)
10279 call_to_destroy = fr->callno;
10280 }
10281 }
10282 if (call_to_destroy) {
10283 if (iaxdebug)
10284 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10285 ast_mutex_lock(&iaxsl[call_to_destroy]);
10286 iax2_destroy(call_to_destroy);
10287 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10288 }
10289 }
10290
10291 if (iaxs[fr->callno])
10292 iaxs[fr->callno]->rseqno = fr->iseqno;
10293 else {
10294
10295 ast_variables_destroy(ies.vars);
10296 ast_mutex_unlock(&iaxsl[fr->callno]);
10297 return 1;
10298 }
10299 } else {
10300 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10301 }
10302 }
10303 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10304 ((f.frametype != AST_FRAME_IAX) ||
10305 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10306 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10307
10308 ast_variables_destroy(ies.vars);
10309 ast_mutex_unlock(&iaxsl[fr->callno]);
10310 return 1;
10311 }
10312
10313
10314
10315
10316 if ((f.frametype == AST_FRAME_VOICE) ||
10317 (f.frametype == AST_FRAME_VIDEO) ||
10318 (f.frametype == AST_FRAME_IAX)) {
10319 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10320 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10321 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
10322 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
10323 ast_variables_destroy(ies.vars);
10324 ast_mutex_unlock(&iaxsl[fr->callno]);
10325 return 1;
10326 }
10327 }
10328
10329 if (ies.vars) {
10330 struct ast_datastore *variablestore = NULL;
10331 struct ast_variable *var, *prev = NULL;
10332 AST_LIST_HEAD(, ast_var_t) *varlist;
10333
10334 iax2_lock_owner(fr->callno);
10335 if (!iaxs[fr->callno]) {
10336 ast_variables_destroy(ies.vars);
10337 ast_mutex_unlock(&iaxsl[fr->callno]);
10338 return 1;
10339 }
10340 if ((c = iaxs[fr->callno]->owner)) {
10341 varlist = ast_calloc(1, sizeof(*varlist));
10342 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10343
10344 if (variablestore && varlist) {
10345 variablestore->data = varlist;
10346 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10347 AST_LIST_HEAD_INIT(varlist);
10348 ast_debug(1, "I can haz IAX vars?\n");
10349 for (var = ies.vars; var; var = var->next) {
10350 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10351 if (prev) {
10352 ast_free(prev);
10353 }
10354 prev = var;
10355 if (!newvar) {
10356
10357 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10358 } else {
10359 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10360 }
10361 }
10362 if (prev) {
10363 ast_free(prev);
10364 }
10365 ies.vars = NULL;
10366 ast_channel_datastore_add(c, variablestore);
10367 } else {
10368 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10369 if (variablestore) {
10370 ast_datastore_free(variablestore);
10371 }
10372 if (varlist) {
10373 ast_free(varlist);
10374 }
10375 }
10376 ast_channel_unlock(c);
10377 } else {
10378
10379
10380 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10381 for (var = ies.vars; var && var->next; var = var->next);
10382 if (var) {
10383 var->next = iaxs[fr->callno]->iaxvars;
10384 iaxs[fr->callno]->iaxvars = ies.vars;
10385 ies.vars = NULL;
10386 }
10387 }
10388 }
10389
10390 if (ies.vars) {
10391 ast_debug(1, "I have IAX variables, but they were not processed\n");
10392 }
10393 }
10394
10395
10396
10397 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10398 send_signaling(iaxs[fr->callno]);
10399 }
10400
10401 if (f.frametype == AST_FRAME_VOICE) {
10402 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10403 iaxs[fr->callno]->voiceformat = f.subclass.codec;
10404 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10405 if (iaxs[fr->callno]->owner) {
10406 iax2_lock_owner(fr->callno);
10407 if (iaxs[fr->callno]) {
10408 if (iaxs[fr->callno]->owner) {
10409 format_t orignative;
10410
10411 orignative = iaxs[fr->callno]->owner->nativeformats;
10412 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10413 if (iaxs[fr->callno]->owner->readformat)
10414 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10415 iaxs[fr->callno]->owner->nativeformats = orignative;
10416 ast_channel_unlock(iaxs[fr->callno]->owner);
10417 }
10418 } else {
10419 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10420
10421 if (ies.vars) {
10422 ast_variables_destroy(ies.vars);
10423 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10424 ies.vars = NULL;
10425 }
10426 ast_mutex_unlock(&iaxsl[fr->callno]);
10427 return 1;
10428 }
10429 }
10430 }
10431 }
10432 if (f.frametype == AST_FRAME_VIDEO) {
10433 if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10434 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10435 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10436 }
10437 }
10438 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10439 if (f.subclass.integer == AST_CONTROL_BUSY) {
10440 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10441 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10442 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10443 }
10444 }
10445 if (f.frametype == AST_FRAME_IAX) {
10446 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10447
10448 if (iaxdebug)
10449 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10450
10451
10452 if (iaxs[fr->callno]->last < fr->ts &&
10453 f.subclass.integer != IAX_COMMAND_ACK &&
10454 f.subclass.integer != IAX_COMMAND_PONG &&
10455 f.subclass.integer != IAX_COMMAND_LAGRP) {
10456 iaxs[fr->callno]->last = fr->ts;
10457 if (iaxdebug)
10458 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10459 }
10460 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10461 if (!iaxs[fr->callno]->first_iax_message) {
10462 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10463 }
10464 switch(f.subclass.integer) {
10465 case IAX_COMMAND_ACK:
10466
10467 break;
10468 case IAX_COMMAND_QUELCH:
10469 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10470
10471 if (iaxs[fr->callno]->owner) {
10472 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10473 "Status: On\r\n"
10474 "Channel: %s\r\n"
10475 "Uniqueid: %s\r\n",
10476 iaxs[fr->callno]->owner->name,
10477 iaxs[fr->callno]->owner->uniqueid);
10478 }
10479
10480 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10481 if (ies.musiconhold) {
10482 iax2_lock_owner(fr->callno);
10483 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10484 break;
10485 }
10486 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10487 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10488
10489
10490
10491
10492
10493 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10494 S_OR(moh_suggest, NULL),
10495 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10496 }
10497 ast_channel_unlock(iaxs[fr->callno]->owner);
10498 }
10499 }
10500 break;
10501 case IAX_COMMAND_UNQUELCH:
10502 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10503 iax2_lock_owner(fr->callno);
10504 if (!iaxs[fr->callno]) {
10505 break;
10506 }
10507
10508 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10509 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10510 "Status: Off\r\n"
10511 "Channel: %s\r\n"
10512 "Uniqueid: %s\r\n",
10513 iaxs[fr->callno]->owner->name,
10514 iaxs[fr->callno]->owner->uniqueid);
10515 }
10516
10517 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10518 if (!iaxs[fr->callno]->owner) {
10519 break;
10520 }
10521 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10522
10523
10524
10525
10526 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10527 }
10528 ast_channel_unlock(iaxs[fr->callno]->owner);
10529 }
10530 break;
10531 case IAX_COMMAND_TXACC:
10532 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10533
10534 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10535
10536 if (cur->transfer) {
10537 cur->retries = -1;
10538 }
10539 }
10540 memset(&ied1, 0, sizeof(ied1));
10541 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10542 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10543 iaxs[fr->callno]->transferring = TRANSFER_READY;
10544 }
10545 break;
10546 case IAX_COMMAND_NEW:
10547
10548 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10549 break;
10550 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10551 ast_mutex_unlock(&iaxsl[fr->callno]);
10552 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10553 ast_mutex_lock(&iaxsl[fr->callno]);
10554 if (!iaxs[fr->callno]) {
10555 break;
10556 }
10557 }
10558
10559 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10560 int new_callno;
10561 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10562 fr->callno = new_callno;
10563 }
10564
10565 if (delayreject)
10566 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10567 if (check_access(fr->callno, &sin, &ies)) {
10568
10569 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10570 if (authdebug)
10571 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);
10572 break;
10573 }
10574 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10575 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10576 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10577 break;
10578 }
10579 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10580 const char *context, *exten, *cid_num;
10581
10582 context = ast_strdupa(iaxs[fr->callno]->context);
10583 exten = ast_strdupa(iaxs[fr->callno]->exten);
10584 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10585
10586
10587 ast_mutex_unlock(&iaxsl[fr->callno]);
10588 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10589 ast_mutex_lock(&iaxsl[fr->callno]);
10590
10591 if (!iaxs[fr->callno]) {
10592 break;
10593 }
10594 } else
10595 exists = 0;
10596
10597 save_osptoken(fr, &ies);
10598 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10599 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10600 memset(&ied0, 0, sizeof(ied0));
10601 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10602 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10603 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10604 if (!iaxs[fr->callno]) {
10605 break;
10606 }
10607 if (authdebug)
10608 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);
10609 } else {
10610
10611
10612 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10613 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10614 using_prefs = "reqonly";
10615 } else {
10616 using_prefs = "disabled";
10617 }
10618 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10619 memset(&pref, 0, sizeof(pref));
10620 strcpy(caller_pref_buf, "disabled");
10621 strcpy(host_pref_buf, "disabled");
10622 } else {
10623 using_prefs = "mine";
10624
10625 if (ies.codec_prefs)
10626 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10627 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10628
10629 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10630 pref = iaxs[fr->callno]->rprefs;
10631 using_prefs = "caller";
10632 } else {
10633 pref = iaxs[fr->callno]->prefs;
10634 }
10635 } else
10636 pref = iaxs[fr->callno]->prefs;
10637
10638 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10639 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10640 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10641 }
10642 if (!format) {
10643 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10644 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10645 if (!format) {
10646 memset(&ied0, 0, sizeof(ied0));
10647 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10648 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10649 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10650 if (!iaxs[fr->callno]) {
10651 break;
10652 }
10653 if (authdebug) {
10654 char tmp[256], tmp2[256], tmp3[256];
10655 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10656 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10657 ast_inet_ntoa(sin.sin_addr),
10658 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10659 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10660 } else {
10661 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10662 ast_inet_ntoa(sin.sin_addr),
10663 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10664 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10665 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10666 }
10667 }
10668 } else {
10669
10670 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10671 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10672 format = 0;
10673 } else {
10674 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10675 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10676 memset(&pref, 0, sizeof(pref));
10677 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10678 strcpy(caller_pref_buf,"disabled");
10679 strcpy(host_pref_buf,"disabled");
10680 } else {
10681 using_prefs = "mine";
10682 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10683
10684 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10685 pref = iaxs[fr->callno]->prefs;
10686 } else {
10687 pref = iaxs[fr->callno]->rprefs;
10688 using_prefs = "caller";
10689 }
10690 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10691 } else
10692 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10693 }
10694 }
10695
10696 if (!format) {
10697 char tmp[256], tmp2[256], tmp3[256];
10698 memset(&ied0, 0, sizeof(ied0));
10699 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10700 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10701 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10702 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10703 if (!iaxs[fr->callno]) {
10704 break;
10705 }
10706 if (authdebug) {
10707 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10708 ast_inet_ntoa(sin.sin_addr),
10709 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10710 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10711 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10712 }
10713 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10714 break;
10715 }
10716 }
10717 }
10718 if (format) {
10719
10720 memset(&ied1, 0, sizeof(ied1));
10721 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10722 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10723 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10724 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10725 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10726 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10727 "%srequested format = %s,\n"
10728 "%srequested prefs = %s,\n"
10729 "%sactual format = %s,\n"
10730 "%shost prefs = %s,\n"
10731 "%spriority = %s\n",
10732 ast_inet_ntoa(sin.sin_addr),
10733 VERBOSE_PREFIX_4,
10734 ast_getformatname(iaxs[fr->callno]->peerformat),
10735 VERBOSE_PREFIX_4,
10736 caller_pref_buf,
10737 VERBOSE_PREFIX_4,
10738 ast_getformatname(format),
10739 VERBOSE_PREFIX_4,
10740 host_pref_buf,
10741 VERBOSE_PREFIX_4,
10742 using_prefs);
10743
10744 iaxs[fr->callno]->chosenformat = format;
10745 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10746 } else {
10747 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10748
10749 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10750 }
10751 }
10752 }
10753 break;
10754 }
10755 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10756 merge_encryption(iaxs[fr->callno],ies.encmethods);
10757 else
10758 iaxs[fr->callno]->encmethods = 0;
10759 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10760 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10761 break;
10762 case IAX_COMMAND_DPREQ:
10763
10764 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10765 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10766 if (iaxcompat) {
10767
10768 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10769 } else {
10770
10771 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10772 }
10773 }
10774 break;
10775 case IAX_COMMAND_HANGUP:
10776 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10777 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10778
10779 if (iaxs[fr->callno]->owner) {
10780 set_hangup_source_and_cause(fr->callno, ies.causecode);
10781 if (!iaxs[fr->callno]) {
10782 break;
10783 }
10784 }
10785
10786
10787 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10788 iax2_destroy(fr->callno);
10789 break;
10790 case IAX_COMMAND_REJECT:
10791
10792 if (iaxs[fr->callno]->owner) {
10793 set_hangup_source_and_cause(fr->callno, ies.causecode);
10794 if (!iaxs[fr->callno]) {
10795 break;
10796 }
10797 }
10798
10799 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10800 if (iaxs[fr->callno]->owner && authdebug)
10801 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10802 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10803 ies.cause ? ies.cause : "<Unknown>");
10804 ast_debug(1, "Immediately destroying %d, having received reject\n",
10805 fr->callno);
10806 }
10807
10808 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10809 fr->ts, NULL, 0, fr->iseqno);
10810 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10811 iaxs[fr->callno]->error = EPERM;
10812 iax2_destroy(fr->callno);
10813 break;
10814 case IAX_COMMAND_TRANSFER:
10815 {
10816 struct ast_channel *bridged_chan;
10817 struct ast_channel *owner;
10818
10819 iax2_lock_owner(fr->callno);
10820 if (!iaxs[fr->callno]) {
10821
10822 break;
10823 }
10824 owner = iaxs[fr->callno]->owner;
10825 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10826 if (bridged_chan && ies.called_number) {
10827 const char *context;
10828
10829 context = ast_strdupa(iaxs[fr->callno]->context);
10830
10831 ast_channel_ref(owner);
10832 ast_channel_ref(bridged_chan);
10833 ast_channel_unlock(owner);
10834 ast_mutex_unlock(&iaxsl[fr->callno]);
10835
10836
10837 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10838 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10839
10840
10841 if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10842 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10843 if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10844 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10845 bridged_chan->name);
10846 }
10847 } else {
10848 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10849 ast_log(LOG_WARNING,
10850 "Async goto of '%s' to '%s@%s' failed\n",
10851 bridged_chan->name, ies.called_number, context);
10852 } else {
10853 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10854 bridged_chan->name, ies.called_number, context);
10855 }
10856 }
10857 ast_channel_unref(owner);
10858 ast_channel_unref(bridged_chan);
10859
10860 ast_mutex_lock(&iaxsl[fr->callno]);
10861 } else {
10862 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10863 if (owner) {
10864 ast_channel_unlock(owner);
10865 }
10866 }
10867
10868 break;
10869 }
10870 case IAX_COMMAND_ACCEPT:
10871
10872 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10873 break;
10874 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10875
10876 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10877 iax2_destroy(fr->callno);
10878 break;
10879 }
10880 if (ies.format) {
10881 iaxs[fr->callno]->peerformat = ies.format;
10882 } else {
10883 if (iaxs[fr->callno]->owner)
10884 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10885 else
10886 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10887 }
10888 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));
10889 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10890 memset(&ied0, 0, sizeof(ied0));
10891 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10892 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10893 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10894 if (!iaxs[fr->callno]) {
10895 break;
10896 }
10897 if (authdebug) {
10898 char tmp1[256], tmp2[256];
10899 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10900 ast_inet_ntoa(sin.sin_addr),
10901 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10902 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10903 }
10904 } else {
10905 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10906 iax2_lock_owner(fr->callno);
10907 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10908
10909 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10910 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10911
10912
10913 if (iaxs[fr->callno]->owner->writeformat)
10914 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10915 if (iaxs[fr->callno]->owner->readformat)
10916 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10917 ast_channel_unlock(iaxs[fr->callno]->owner);
10918 }
10919 }
10920 if (iaxs[fr->callno]) {
10921 AST_LIST_LOCK(&dpcache);
10922 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10923 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10924 iax2_dprequest(dp, fr->callno);
10925 AST_LIST_UNLOCK(&dpcache);
10926 }
10927 break;
10928 case IAX_COMMAND_POKE:
10929
10930 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10931 break;
10932 case IAX_COMMAND_PING:
10933 {
10934 struct iax_ie_data pingied;
10935 construct_rr(iaxs[fr->callno], &pingied);
10936
10937 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10938 }
10939 break;
10940 case IAX_COMMAND_PONG:
10941
10942 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10943
10944 save_rr(fr, &ies);
10945
10946
10947 log_jitterstats(fr->callno);
10948
10949 if (iaxs[fr->callno]->peerpoke) {
10950 peer = iaxs[fr->callno]->peerpoke;
10951 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10952 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10953 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10954 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);
10955 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
10956 }
10957 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10958 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10959 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10960 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);
10961 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
10962 }
10963 }
10964 peer->lastms = iaxs[fr->callno]->pingtime;
10965 if (peer->smoothing && (peer->lastms > -1))
10966 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10967 else if (peer->smoothing && peer->lastms < 0)
10968 peer->historicms = (0 + peer->historicms) / 2;
10969 else
10970 peer->historicms = iaxs[fr->callno]->pingtime;
10971
10972
10973 if (peer->pokeexpire > -1) {
10974 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10975 peer_unref(peer);
10976 peer->pokeexpire = -1;
10977 }
10978 }
10979
10980 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10981 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10982 else
10983 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10984 if (peer->pokeexpire == -1)
10985 peer_unref(peer);
10986
10987 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10988
10989 iax2_destroy(fr->callno);
10990 peer->callno = 0;
10991 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10992 }
10993 break;
10994 case IAX_COMMAND_LAGRQ:
10995 case IAX_COMMAND_LAGRP:
10996 f.src = "LAGRQ";
10997 f.mallocd = 0;
10998 f.offset = 0;
10999 f.samples = 0;
11000 iax_frame_wrap(fr, &f);
11001 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
11002
11003 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
11004 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11005 } else {
11006
11007 unsigned int ts;
11008
11009 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11010 iaxs[fr->callno]->lag = ts - fr->ts;
11011 if (iaxdebug)
11012 ast_debug(1, "Peer %s lag measured as %dms\n",
11013 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
11014 }
11015 break;
11016 case IAX_COMMAND_AUTHREQ:
11017 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11018 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>");
11019 break;
11020 }
11021 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11022 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11023 .subclass.integer = AST_CONTROL_HANGUP,
11024 };
11025 ast_log(LOG_WARNING,
11026 "I don't know how to authenticate %s to %s\n",
11027 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
11028 iax2_queue_frame(fr->callno, &hangup_fr);
11029 }
11030 break;
11031 case IAX_COMMAND_AUTHREP:
11032
11033 if (delayreject)
11034 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11035
11036 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11037 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>");
11038 break;
11039 }
11040 if (authenticate_verify(iaxs[fr->callno], &ies)) {
11041 if (authdebug)
11042 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);
11043 memset(&ied0, 0, sizeof(ied0));
11044 auth_fail(fr->callno, IAX_COMMAND_REJECT);
11045 break;
11046 }
11047 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11048
11049 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
11050 } else
11051 exists = 0;
11052 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11053 if (authdebug)
11054 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);
11055 memset(&ied0, 0, sizeof(ied0));
11056 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11057 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11058 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11059 if (!iaxs[fr->callno]) {
11060 break;
11061 }
11062 } else {
11063
11064 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11065 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11066 using_prefs = "reqonly";
11067 } else {
11068 using_prefs = "disabled";
11069 }
11070 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11071 memset(&pref, 0, sizeof(pref));
11072 strcpy(caller_pref_buf, "disabled");
11073 strcpy(host_pref_buf, "disabled");
11074 } else {
11075 using_prefs = "mine";
11076 if (ies.codec_prefs)
11077 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11078 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11079 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11080 pref = iaxs[fr->callno]->rprefs;
11081 using_prefs = "caller";
11082 } else {
11083 pref = iaxs[fr->callno]->prefs;
11084 }
11085 } else
11086 pref = iaxs[fr->callno]->prefs;
11087 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11088 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11089 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11090 }
11091 if (!format) {
11092 char tmp1[256], tmp2[256], tmp3[256];
11093 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11094 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11095 ast_getformatname(iaxs[fr->callno]->peerformat),
11096 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11097 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11098 }
11099 if (!format) {
11100 if (authdebug) {
11101 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11102 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11103 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11104 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11105 } else {
11106 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11107 ast_inet_ntoa(sin.sin_addr),
11108 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11109 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11110 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11111 }
11112 }
11113 memset(&ied0, 0, sizeof(ied0));
11114 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11115 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11116 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11117 if (!iaxs[fr->callno]) {
11118 break;
11119 }
11120 } else {
11121
11122 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11123 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11124 format = 0;
11125 } else {
11126 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11127 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11128 memset(&pref, 0, sizeof(pref));
11129 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11130 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11131 strcpy(caller_pref_buf,"disabled");
11132 strcpy(host_pref_buf,"disabled");
11133 } else {
11134 using_prefs = "mine";
11135 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11136
11137 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11138 pref = iaxs[fr->callno]->prefs;
11139 } else {
11140 pref = iaxs[fr->callno]->rprefs;
11141 using_prefs = "caller";
11142 }
11143 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11144 } else
11145 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11146 }
11147 }
11148 if (!format) {
11149 char tmp1[256], tmp2[256], tmp3[256];
11150 ast_log(LOG_ERROR, "No best format in %s???\n",
11151 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11152 if (authdebug) {
11153 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11154 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11155 ast_inet_ntoa(sin.sin_addr),
11156 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11157 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11158 } else {
11159 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11160 ast_inet_ntoa(sin.sin_addr),
11161 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11162 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11163 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11164 }
11165 }
11166 memset(&ied0, 0, sizeof(ied0));
11167 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11168 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11169 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11170 if (!iaxs[fr->callno]) {
11171 break;
11172 }
11173 }
11174 }
11175 }
11176 if (format) {
11177
11178 memset(&ied1, 0, sizeof(ied1));
11179 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11180 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11181 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11182 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11183 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11184 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11185 "%srequested format = %s,\n"
11186 "%srequested prefs = %s,\n"
11187 "%sactual format = %s,\n"
11188 "%shost prefs = %s,\n"
11189 "%spriority = %s\n",
11190 ast_inet_ntoa(sin.sin_addr),
11191 VERBOSE_PREFIX_4,
11192 ast_getformatname(iaxs[fr->callno]->peerformat),
11193 VERBOSE_PREFIX_4,
11194 caller_pref_buf,
11195 VERBOSE_PREFIX_4,
11196 ast_getformatname(format),
11197 VERBOSE_PREFIX_4,
11198 host_pref_buf,
11199 VERBOSE_PREFIX_4,
11200 using_prefs);
11201
11202 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11203 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
11204 iax2_destroy(fr->callno);
11205 else if (ies.vars) {
11206 struct ast_datastore *variablestore;
11207 struct ast_variable *var, *prev = NULL;
11208 AST_LIST_HEAD(, ast_var_t) *varlist;
11209 varlist = ast_calloc(1, sizeof(*varlist));
11210 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11211 if (variablestore && varlist) {
11212 variablestore->data = varlist;
11213 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11214 AST_LIST_HEAD_INIT(varlist);
11215 ast_debug(1, "I can haz IAX vars? w00t\n");
11216 for (var = ies.vars; var; var = var->next) {
11217 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11218 if (prev)
11219 ast_free(prev);
11220 prev = var;
11221 if (!newvar) {
11222
11223 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11224 } else {
11225 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11226 }
11227 }
11228 if (prev)
11229 ast_free(prev);
11230 ies.vars = NULL;
11231 ast_channel_datastore_add(c, variablestore);
11232 } else {
11233 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11234 if (variablestore)
11235 ast_datastore_free(variablestore);
11236 if (varlist)
11237 ast_free(varlist);
11238 }
11239 }
11240 } else {
11241 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11242
11243 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11244 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11245 goto immediatedial;
11246 }
11247 }
11248 }
11249 }
11250 break;
11251 case IAX_COMMAND_DIAL:
11252 immediatedial:
11253 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11254 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11255 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11256 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11257 if (authdebug)
11258 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);
11259 memset(&ied0, 0, sizeof(ied0));
11260 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11261 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11262 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11263 if (!iaxs[fr->callno]) {
11264 break;
11265 }
11266 } else {
11267 char tmp[256];
11268 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11269 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11270 ast_inet_ntoa(sin.sin_addr),
11271 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11272 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11273 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11274 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
11275 iax2_destroy(fr->callno);
11276 else if (ies.vars) {
11277 struct ast_datastore *variablestore;
11278 struct ast_variable *var, *prev = NULL;
11279 AST_LIST_HEAD(, ast_var_t) *varlist;
11280 varlist = ast_calloc(1, sizeof(*varlist));
11281 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11282 ast_debug(1, "I can haz IAX vars? w00t\n");
11283 if (variablestore && varlist) {
11284 variablestore->data = varlist;
11285 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11286 AST_LIST_HEAD_INIT(varlist);
11287 for (var = ies.vars; var; var = var->next) {
11288 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11289 if (prev)
11290 ast_free(prev);
11291 prev = var;
11292 if (!newvar) {
11293
11294 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11295 } else {
11296 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11297 }
11298 }
11299 if (prev)
11300 ast_free(prev);
11301 ies.vars = NULL;
11302 ast_channel_datastore_add(c, variablestore);
11303 } else {
11304 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11305 if (variablestore)
11306 ast_datastore_free(variablestore);
11307 if (varlist)
11308 ast_free(varlist);
11309 }
11310 }
11311 }
11312 }
11313 break;
11314 case IAX_COMMAND_INVAL:
11315 iaxs[fr->callno]->error = ENOTCONN;
11316 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11317 iax2_destroy(fr->callno);
11318 ast_debug(1, "Destroying call %d\n", fr->callno);
11319 break;
11320 case IAX_COMMAND_VNAK:
11321 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11322
11323 vnak_retransmit(fr->callno, fr->iseqno);
11324 break;
11325 case IAX_COMMAND_REGREQ:
11326 case IAX_COMMAND_REGREL:
11327
11328 if (delayreject)
11329 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11330 if (register_verify(fr->callno, &sin, &ies)) {
11331 if (!iaxs[fr->callno]) {
11332 break;
11333 }
11334
11335 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11336 break;
11337 }
11338 if (!iaxs[fr->callno]) {
11339 break;
11340 }
11341 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11342 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11343
11344 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11345 memset(&sin, 0, sizeof(sin));
11346 sin.sin_family = AF_INET;
11347 }
11348 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11349 ast_log(LOG_WARNING, "Registry error\n");
11350 }
11351 if (!iaxs[fr->callno]) {
11352 break;
11353 }
11354 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11355 ast_mutex_unlock(&iaxsl[fr->callno]);
11356 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11357 ast_mutex_lock(&iaxsl[fr->callno]);
11358 }
11359 break;
11360 }
11361 registry_authrequest(fr->callno);
11362 break;
11363 case IAX_COMMAND_REGACK:
11364 if (iax2_ack_registry(&ies, &sin, fr->callno))
11365 ast_log(LOG_WARNING, "Registration failure\n");
11366
11367 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11368 iax2_destroy(fr->callno);
11369 break;
11370 case IAX_COMMAND_REGREJ:
11371 if (iaxs[fr->callno]->reg) {
11372 if (authdebug) {
11373 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));
11374 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>");
11375 }
11376 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11377 }
11378
11379 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11380 iax2_destroy(fr->callno);
11381 break;
11382 case IAX_COMMAND_REGAUTH:
11383
11384 if (registry_rerequest(&ies, fr->callno, &sin)) {
11385 memset(&ied0, 0, sizeof(ied0));
11386 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11387 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11388 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11389 }
11390 break;
11391 case IAX_COMMAND_TXREJ:
11392 while (iaxs[fr->callno]
11393 && iaxs[fr->callno]->bridgecallno
11394 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11395 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11396 }
11397 if (!iaxs[fr->callno]) {
11398 break;
11399 }
11400
11401 iaxs[fr->callno]->transferring = TRANSFER_NONE;
11402 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11403 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11404
11405 if (!iaxs[fr->callno]->bridgecallno) {
11406 break;
11407 }
11408
11409 if (iaxs[iaxs[fr->callno]->bridgecallno]
11410 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11411 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE;
11412 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11413 }
11414 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11415 break;
11416 case IAX_COMMAND_TXREADY:
11417 while (iaxs[fr->callno]
11418 && iaxs[fr->callno]->bridgecallno
11419 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
11420 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
11421 }
11422 if (!iaxs[fr->callno]) {
11423 break;
11424 }
11425
11426 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
11427 iaxs[fr->callno]->transferring = TRANSFER_READY;
11428 } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) {
11429 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11430 } else {
11431 if (iaxs[fr->callno]->bridgecallno) {
11432 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11433 }
11434 break;
11435 }
11436 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11437
11438 if (!iaxs[fr->callno]->bridgecallno) {
11439 break;
11440 }
11441
11442 if (!iaxs[iaxs[fr->callno]->bridgecallno]
11443 || (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY
11444 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) {
11445 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11446 break;
11447 }
11448
11449
11450
11451
11452
11453 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11454 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11455 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11456
11457 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11458 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11459
11460 memset(&ied0, 0, sizeof(ied0));
11461 memset(&ied1, 0, sizeof(ied1));
11462 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11463 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11464 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11465 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11466 } else {
11467 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11468 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11469
11470 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11471 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11472 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11473 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11474
11475
11476 stop_stuff(fr->callno);
11477 stop_stuff(iaxs[fr->callno]->bridgecallno);
11478
11479 memset(&ied0, 0, sizeof(ied0));
11480 memset(&ied1, 0, sizeof(ied1));
11481 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11482 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11483 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11484 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11485 }
11486 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
11487 break;
11488 case IAX_COMMAND_TXREQ:
11489 try_transfer(iaxs[fr->callno], &ies);
11490 break;
11491 case IAX_COMMAND_TXCNT:
11492 if (iaxs[fr->callno]->transferring)
11493 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11494 break;
11495 case IAX_COMMAND_TXREL:
11496
11497 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11498 complete_transfer(fr->callno, &ies);
11499 stop_stuff(fr->callno);
11500 break;
11501 case IAX_COMMAND_TXMEDIA:
11502 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11503 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11504
11505 if (cur->transfer) {
11506 cur->retries = -1;
11507 }
11508 }
11509
11510 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11511 }
11512 break;
11513 case IAX_COMMAND_RTKEY:
11514 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11515 ast_log(LOG_WARNING,
11516 "we've been told to rotate our encryption key, "
11517 "but this isn't an encrypted call. bad things will happen.\n"
11518 );
11519 break;
11520 }
11521
11522 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11523
11524 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11525 break;
11526 case IAX_COMMAND_DPREP:
11527 complete_dpreply(iaxs[fr->callno], &ies);
11528 break;
11529 case IAX_COMMAND_UNSUPPORT:
11530 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11531 break;
11532 case IAX_COMMAND_FWDOWNL:
11533
11534 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11535 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11536 break;
11537 }
11538 memset(&ied0, 0, sizeof(ied0));
11539 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11540 if (res < 0)
11541 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11542 else if (res > 0)
11543 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11544 else
11545 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11546 break;
11547 case IAX_COMMAND_CALLTOKEN:
11548 {
11549 struct iax_frame *cur;
11550
11551 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11552 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11553 }
11554 break;
11555 }
11556 default:
11557 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11558 memset(&ied0, 0, sizeof(ied0));
11559 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11560 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11561 }
11562
11563 if (ies.vars) {
11564 ast_variables_destroy(ies.vars);
11565 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11566 ies.vars = NULL;
11567 }
11568
11569
11570 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11571 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11572 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11573 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11574 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11575 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) {
11576 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11577 }
11578 }
11579 ast_mutex_unlock(&iaxsl[fr->callno]);
11580 return 1;
11581 }
11582
11583 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11584 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11585 } else if (minivid) {
11586 f.frametype = AST_FRAME_VIDEO;
11587 if (iaxs[fr->callno]->videoformat > 0)
11588 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11589 else {
11590 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11591 iax2_vnak(fr->callno);
11592 ast_variables_destroy(ies.vars);
11593 ast_mutex_unlock(&iaxsl[fr->callno]);
11594 return 1;
11595 }
11596 f.datalen = res - sizeof(*vh);
11597 if (f.datalen)
11598 f.data.ptr = thread->buf + sizeof(*vh);
11599 else
11600 f.data.ptr = NULL;
11601 #ifdef IAXTESTS
11602 if (test_resync) {
11603 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11604 } else
11605 #endif
11606 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11607 } else {
11608
11609 f.frametype = AST_FRAME_VOICE;
11610 if (iaxs[fr->callno]->voiceformat > 0)
11611 f.subclass.codec = iaxs[fr->callno]->voiceformat;
11612 else {
11613 ast_debug(1, "Received mini frame before first full voice frame\n");
11614 iax2_vnak(fr->callno);
11615 ast_variables_destroy(ies.vars);
11616 ast_mutex_unlock(&iaxsl[fr->callno]);
11617 return 1;
11618 }
11619 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11620 if (f.datalen < 0) {
11621 ast_log(LOG_WARNING, "Datalen < 0?\n");
11622 ast_variables_destroy(ies.vars);
11623 ast_mutex_unlock(&iaxsl[fr->callno]);
11624 return 1;
11625 }
11626 if (f.datalen)
11627 f.data.ptr = thread->buf + sizeof(*mh);
11628 else
11629 f.data.ptr = NULL;
11630 #ifdef IAXTESTS
11631 if (test_resync) {
11632 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11633 } else
11634 #endif
11635 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11636
11637 }
11638
11639 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11640 ast_variables_destroy(ies.vars);
11641 ast_mutex_unlock(&iaxsl[fr->callno]);
11642 return 1;
11643 }
11644
11645 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11646 struct ast_party_connected_line connected;
11647
11648 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11649 ast_variables_destroy(ies.vars);
11650 ast_mutex_unlock(&iaxsl[fr->callno]);
11651 return 1;
11652 }
11653
11654
11655 ast_party_connected_line_init(&connected);
11656 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11657 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11658
11659 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11660 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11661 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11662 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11663
11664 iax2_lock_owner(fr->callno);
11665 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
11666 ast_set_callerid(iaxs[fr->callno]->owner,
11667 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11668 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11669 NULL);
11670 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11671 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11672 ast_channel_unlock(iaxs[fr->callno]->owner);
11673 }
11674 }
11675 ast_party_connected_line_free(&connected);
11676 }
11677
11678 f.src = "IAX2";
11679 f.mallocd = 0;
11680 f.offset = 0;
11681 f.len = 0;
11682 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11683 f.samples = ast_codec_get_samples(&f);
11684
11685 if (f.subclass.codec == AST_FORMAT_SLINEAR)
11686 ast_frame_byteswap_be(&f);
11687 } else
11688 f.samples = 0;
11689 iax_frame_wrap(fr, &f);
11690
11691
11692 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11693
11694 fr->outoforder = 0;
11695 } else {
11696 if (iaxdebug && iaxs[fr->callno]) {
11697 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);
11698 }
11699 fr->outoforder = -1;
11700 }
11701 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11702 duped_fr = iaxfrdup2(fr);
11703 if (duped_fr) {
11704 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11705 }
11706 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11707 iaxs[fr->callno]->last = fr->ts;
11708 #if 1
11709 if (iaxdebug)
11710 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11711 #endif
11712 }
11713
11714
11715 ast_variables_destroy(ies.vars);
11716 ast_mutex_unlock(&iaxsl[fr->callno]);
11717 return 1;
11718 }
11719
11720
11721 static void iax2_process_thread_cleanup(void *data)
11722 {
11723 struct iax2_thread *thread = data;
11724 ast_mutex_destroy(&thread->lock);
11725 ast_cond_destroy(&thread->cond);
11726 ast_mutex_destroy(&thread->init_lock);
11727 ast_cond_destroy(&thread->init_cond);
11728 ast_free(thread);
11729
11730 ast_atomic_dec_and_test(&iaxactivethreadcount);
11731 }
11732
11733 static void *iax2_process_thread(void *data)
11734 {
11735 struct iax2_thread *thread = data;
11736 struct timeval wait;
11737 struct timespec ts;
11738 int put_into_idle = 0;
11739 int first_time = 1;
11740 int old_state;
11741
11742 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11743
11744 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11745 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11746
11747 for (;;) {
11748
11749 ast_mutex_lock(&thread->lock);
11750
11751 if (thread->stop) {
11752 ast_mutex_unlock(&thread->lock);
11753 break;
11754 }
11755
11756
11757 if (first_time) {
11758 signal_condition(&thread->init_lock, &thread->init_cond);
11759 first_time = 0;
11760 }
11761
11762
11763 if (put_into_idle) {
11764 insert_idle_thread(thread);
11765 }
11766
11767 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11768 struct iax2_thread *t = NULL;
11769
11770 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11771 ts.tv_sec = wait.tv_sec;
11772 ts.tv_nsec = wait.tv_usec * 1000;
11773 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11774
11775
11776 if (!put_into_idle || thread->stop) {
11777 ast_mutex_unlock(&thread->lock);
11778 break;
11779 }
11780 AST_LIST_LOCK(&dynamic_list);
11781
11782 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11783 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11784 AST_LIST_UNLOCK(&dynamic_list);
11785 if (t) {
11786
11787
11788
11789 ast_mutex_unlock(&thread->lock);
11790 break;
11791 }
11792
11793
11794
11795 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11796 ts.tv_sec = wait.tv_sec;
11797 ts.tv_nsec = wait.tv_usec * 1000;
11798 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11799 ast_mutex_unlock(&thread->lock);
11800 break;
11801 }
11802 }
11803 } else {
11804 ast_cond_wait(&thread->cond, &thread->lock);
11805 }
11806
11807
11808 put_into_idle = 1;
11809
11810 ast_mutex_unlock(&thread->lock);
11811
11812 if (thread->stop) {
11813 break;
11814 }
11815
11816
11817 switch (thread->iostate) {
11818 case IAX_IOSTATE_IDLE:
11819 continue;
11820 case IAX_IOSTATE_READY:
11821 thread->actions++;
11822 thread->iostate = IAX_IOSTATE_PROCESSING;
11823 socket_process(thread);
11824 handle_deferred_full_frames(thread);
11825 break;
11826 case IAX_IOSTATE_SCHEDREADY:
11827 thread->actions++;
11828 thread->iostate = IAX_IOSTATE_PROCESSING;
11829 #ifdef SCHED_MULTITHREADED
11830 thread->schedfunc(thread->scheddata);
11831 #endif
11832 break;
11833 default:
11834 break;
11835 }
11836
11837
11838
11839
11840 AST_LIST_LOCK(&active_list);
11841 AST_LIST_REMOVE(&active_list, thread, list);
11842 AST_LIST_UNLOCK(&active_list);
11843
11844
11845 handle_deferred_full_frames(thread);
11846
11847 time(&thread->checktime);
11848 thread->iostate = IAX_IOSTATE_IDLE;
11849 #ifdef DEBUG_SCHED_MULTITHREAD
11850 thread->curfunc[0]='\0';
11851 #endif
11852 }
11853
11854
11855
11856
11857
11858
11859 AST_LIST_LOCK(&idle_list);
11860 AST_LIST_REMOVE(&idle_list, thread, list);
11861 AST_LIST_UNLOCK(&idle_list);
11862
11863 AST_LIST_LOCK(&dynamic_list);
11864 AST_LIST_REMOVE(&dynamic_list, thread, list);
11865 AST_LIST_UNLOCK(&dynamic_list);
11866
11867 if (!thread->stop) {
11868
11869 pthread_detach(pthread_self());
11870 }
11871
11872
11873
11874
11875 pthread_cleanup_pop(1);
11876 return NULL;
11877 }
11878
11879 static int iax2_do_register(struct iax2_registry *reg)
11880 {
11881 struct iax_ie_data ied;
11882 if (iaxdebug)
11883 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11884
11885 if (reg->dnsmgr &&
11886 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
11887
11888 ast_dnsmgr_refresh(reg->dnsmgr);
11889 }
11890
11891
11892
11893
11894
11895 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11896 int callno = reg->callno;
11897 ast_mutex_lock(&iaxsl[callno]);
11898 iax2_destroy(callno);
11899 ast_mutex_unlock(&iaxsl[callno]);
11900 reg->callno = 0;
11901 }
11902 if (!ast_sockaddr_ipv4(®->addr)) {
11903 if (iaxdebug)
11904 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11905
11906 reg->expire = iax2_sched_replace(reg->expire, sched,
11907 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11908 return -1;
11909 }
11910
11911 if (!reg->callno) {
11912 struct sockaddr_in reg_addr;
11913
11914 ast_debug(3, "Allocate call number\n");
11915
11916 ast_sockaddr_to_sin(®->addr, ®_addr);
11917
11918 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
11919 if (reg->callno < 1) {
11920 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11921 return -1;
11922 } else
11923 ast_debug(3, "Registration created on call %d\n", reg->callno);
11924 iaxs[reg->callno]->reg = reg;
11925 ast_mutex_unlock(&iaxsl[reg->callno]);
11926 }
11927
11928 reg->expire = iax2_sched_replace(reg->expire, sched,
11929 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11930
11931 memset(&ied, 0, sizeof(ied));
11932 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11933 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11934 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11935 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11936 reg->regstate = REG_STATE_REGSENT;
11937 return 0;
11938 }
11939
11940 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
11941 {
11942
11943
11944 struct iax_ie_data provdata;
11945 struct iax_ie_data ied;
11946 unsigned int sig;
11947 struct sockaddr_in sin;
11948 int callno;
11949 struct create_addr_info cai;
11950
11951 memset(&cai, 0, sizeof(cai));
11952
11953 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11954
11955 if (iax_provision_build(&provdata, &sig, template, force)) {
11956 ast_debug(1, "No provisioning found for template '%s'\n", template);
11957 return 0;
11958 }
11959
11960 if (end) {
11961 memcpy(&sin, end, sizeof(sin));
11962 cai.sockfd = sockfd;
11963 } else if (create_addr(dest, NULL, &sin, &cai))
11964 return -1;
11965
11966
11967 memset(&ied, 0, sizeof(ied));
11968 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11969
11970 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11971 if (!callno)
11972 return -1;
11973
11974 if (iaxs[callno]) {
11975
11976 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11977 sched, 15000, auto_hangup, (void *)(long)callno);
11978 ast_set_flag64(iaxs[callno], IAX_PROVISION);
11979
11980 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11981 }
11982 ast_mutex_unlock(&iaxsl[callno]);
11983
11984 return 1;
11985 }
11986
11987 static char *papp = "IAX2Provision";
11988
11989
11990
11991
11992 static int iax2_prov_app(struct ast_channel *chan, const char *data)
11993 {
11994 int res;
11995 char *sdata;
11996 char *opts;
11997 int force =0;
11998 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11999 if (ast_strlen_zero(data))
12000 data = "default";
12001 sdata = ast_strdupa(data);
12002 opts = strchr(sdata, '|');
12003 if (opts)
12004 *opts='\0';
12005
12006 if (chan->tech != &iax2_tech) {
12007 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
12008 return -1;
12009 }
12010 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
12011 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
12012 return -1;
12013 }
12014 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
12015 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
12016 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
12017 sdata, res);
12018 return res;
12019 }
12020
12021 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
12022 {
12023 int force = 0;
12024 int res;
12025
12026 switch (cmd) {
12027 case CLI_INIT:
12028 e->command = "iax2 provision";
12029 e->usage =
12030 "Usage: iax2 provision <host> <template> [forced]\n"
12031 " Provisions the given peer or IP address using a template\n"
12032 " matching either 'template' or '*' if the template is not\n"
12033 " found. If 'forced' is specified, even empty provisioning\n"
12034 " fields will be provisioned as empty fields.\n";
12035 return NULL;
12036 case CLI_GENERATE:
12037 if (a->pos == 3)
12038 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12039 return NULL;
12040 }
12041
12042 if (a->argc < 4)
12043 return CLI_SHOWUSAGE;
12044 if (a->argc > 4) {
12045 if (!strcasecmp(a->argv[4], "forced"))
12046 force = 1;
12047 else
12048 return CLI_SHOWUSAGE;
12049 }
12050 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12051 if (res < 0)
12052 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
12053 else if (res < 1)
12054 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
12055 else
12056 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
12057 return CLI_SUCCESS;
12058 }
12059
12060 static void __iax2_poke_noanswer(const void *data)
12061 {
12062 struct iax2_peer *peer = (struct iax2_peer *)data;
12063 int callno;
12064
12065 if (peer->lastms > -1) {
12066 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12067 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
12068 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name);
12069 }
12070 if ((callno = peer->callno) > 0) {
12071 ast_mutex_lock(&iaxsl[callno]);
12072 iax2_destroy(callno);
12073 ast_mutex_unlock(&iaxsl[callno]);
12074 }
12075 peer->callno = 0;
12076 peer->lastms = -1;
12077
12078 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
12079 if (peer->pokeexpire == -1)
12080 peer_unref(peer);
12081 }
12082
12083 static int iax2_poke_noanswer(const void *data)
12084 {
12085 struct iax2_peer *peer = (struct iax2_peer *)data;
12086 peer->pokeexpire = -1;
12087 #ifdef SCHED_MULTITHREADED
12088 if (schedule_action(__iax2_poke_noanswer, data))
12089 #endif
12090 __iax2_poke_noanswer(data);
12091 peer_unref(peer);
12092 return 0;
12093 }
12094
12095 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
12096 {
12097 struct iax2_peer *peer = obj;
12098
12099 iax2_poke_peer(peer, 0);
12100
12101 return 0;
12102 }
12103
12104 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
12105 {
12106 int callno;
12107 struct sockaddr_in peer_addr;
12108
12109 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
12110
12111
12112 peer->lastms = 0;
12113 peer->historicms = 0;
12114 peer->pokeexpire = -1;
12115 peer->callno = 0;
12116 return 0;
12117 }
12118
12119 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12120
12121
12122 if ((callno = peer->callno) > 0) {
12123 ast_log(LOG_NOTICE, "Still have a callno...\n");
12124 ast_mutex_lock(&iaxsl[callno]);
12125 iax2_destroy(callno);
12126 ast_mutex_unlock(&iaxsl[callno]);
12127 }
12128 if (heldcall)
12129 ast_mutex_unlock(&iaxsl[heldcall]);
12130 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12131 if (heldcall)
12132 ast_mutex_lock(&iaxsl[heldcall]);
12133 if (peer->callno < 1) {
12134 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12135 return -1;
12136 }
12137
12138
12139 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12140 iaxs[peer->callno]->peerpoke = peer;
12141
12142 if (peer->pokeexpire > -1) {
12143 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
12144 peer->pokeexpire = -1;
12145 peer_unref(peer);
12146 }
12147 }
12148
12149
12150
12151 if (peer->lastms < 0)
12152 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12153 else
12154 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12155
12156 if (peer->pokeexpire == -1)
12157 peer_unref(peer);
12158
12159
12160 ast_mutex_lock(&iaxsl[callno]);
12161 if (iaxs[callno]) {
12162 struct iax_ie_data ied = {
12163 .buf = { 0 },
12164 .pos = 0,
12165 };
12166 add_empty_calltoken_ie(iaxs[callno], &ied);
12167 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12168 }
12169 ast_mutex_unlock(&iaxsl[callno]);
12170
12171 return 0;
12172 }
12173
12174 static void free_context(struct iax2_context *con)
12175 {
12176 struct iax2_context *conl;
12177 while(con) {
12178 conl = con;
12179 con = con->next;
12180 ast_free(conl);
12181 }
12182 }
12183
12184 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
12185 {
12186 int callno;
12187 int res;
12188 format_t fmt, native;
12189 struct sockaddr_in sin;
12190 struct ast_channel *c;
12191 struct parsed_dial_string pds;
12192 struct create_addr_info cai;
12193 char *tmpstr;
12194
12195 memset(&pds, 0, sizeof(pds));
12196 tmpstr = ast_strdupa(data);
12197 parse_dial_string(tmpstr, &pds);
12198
12199 if (ast_strlen_zero(pds.peer)) {
12200 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12201 return NULL;
12202 }
12203
12204 memset(&cai, 0, sizeof(cai));
12205 cai.capability = iax2_capability;
12206
12207 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12208
12209
12210 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12211 *cause = AST_CAUSE_UNREGISTERED;
12212 return NULL;
12213 }
12214
12215 if (pds.port)
12216 sin.sin_port = htons(atoi(pds.port));
12217
12218 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12219 if (callno < 1) {
12220 ast_log(LOG_WARNING, "Unable to create call\n");
12221 *cause = AST_CAUSE_CONGESTION;
12222 return NULL;
12223 }
12224
12225
12226 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12227 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12228 int new_callno;
12229 if ((new_callno = make_trunk(callno, 1)) != -1)
12230 callno = new_callno;
12231 }
12232 iaxs[callno]->maxtime = cai.maxtime;
12233 if (cai.found)
12234 ast_string_field_set(iaxs[callno], host, pds.peer);
12235
12236 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found);
12237
12238 ast_mutex_unlock(&iaxsl[callno]);
12239
12240 if (c) {
12241
12242 if (c->nativeformats & format)
12243 c->nativeformats &= format;
12244 else {
12245 native = c->nativeformats;
12246 fmt = format;
12247 res = ast_translator_best_choice(&fmt, &native);
12248 if (res < 0) {
12249 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12250 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12251 ast_hangup(c);
12252 return NULL;
12253 }
12254 c->nativeformats = native;
12255 }
12256 c->readformat = ast_best_codec(c->nativeformats);
12257 c->writeformat = c->readformat;
12258 }
12259
12260 return c;
12261 }
12262
12263 static void *network_thread(void *ignore)
12264 {
12265 if (timer) {
12266 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12267 }
12268
12269 for (;;) {
12270 pthread_testcancel();
12271
12272
12273
12274 if (ast_io_wait(io, 1000) <= 0) {
12275 break;
12276 }
12277 }
12278
12279 return NULL;
12280 }
12281
12282 static int start_network_thread(void)
12283 {
12284 struct iax2_thread *thread;
12285 int threadcount = 0;
12286 int x;
12287 for (x = 0; x < iaxthreadcount; x++) {
12288 thread = ast_calloc(1, sizeof(*thread));
12289 if (thread) {
12290 thread->type = IAX_THREAD_TYPE_POOL;
12291 thread->threadnum = ++threadcount;
12292 ast_mutex_init(&thread->lock);
12293 ast_cond_init(&thread->cond, NULL);
12294 ast_mutex_init(&thread->init_lock);
12295 ast_cond_init(&thread->init_cond, NULL);
12296
12297 ast_mutex_lock(&thread->init_lock);
12298
12299 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12300 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12301 ast_mutex_destroy(&thread->lock);
12302 ast_cond_destroy(&thread->cond);
12303 ast_mutex_unlock(&thread->init_lock);
12304 ast_mutex_destroy(&thread->init_lock);
12305 ast_cond_destroy(&thread->init_cond);
12306 ast_free(thread);
12307 thread = NULL;
12308 continue;
12309 }
12310
12311 ast_cond_wait(&thread->init_cond, &thread->init_lock);
12312
12313
12314 ast_mutex_unlock(&thread->init_lock);
12315
12316 AST_LIST_LOCK(&idle_list);
12317 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12318 AST_LIST_UNLOCK(&idle_list);
12319 }
12320 }
12321 if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) {
12322 ast_log(LOG_ERROR, "Failed to create new thread!\n");
12323 return -1;
12324 }
12325 ast_verb(2, "%d helper threads started\n", threadcount);
12326 return 0;
12327 }
12328
12329 static struct iax2_context *build_context(const char *context)
12330 {
12331 struct iax2_context *con;
12332
12333 if ((con = ast_calloc(1, sizeof(*con))))
12334 ast_copy_string(con->context, context, sizeof(con->context));
12335
12336 return con;
12337 }
12338
12339 static int get_auth_methods(const char *value)
12340 {
12341 int methods = 0;
12342 if (strstr(value, "rsa"))
12343 methods |= IAX_AUTH_RSA;
12344 if (strstr(value, "md5"))
12345 methods |= IAX_AUTH_MD5;
12346 if (strstr(value, "plaintext"))
12347 methods |= IAX_AUTH_PLAINTEXT;
12348 return methods;
12349 }
12350
12351
12352
12353
12354
12355 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12356 {
12357 int sd;
12358 int res;
12359
12360 sd = socket(AF_INET, SOCK_DGRAM, 0);
12361 if (sd < 0) {
12362 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12363 return -1;
12364 }
12365
12366 res = bind(sd, sa, salen);
12367 if (res < 0) {
12368 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12369 close(sd);
12370 return 1;
12371 }
12372
12373 close(sd);
12374 return 0;
12375 }
12376
12377
12378
12379
12380 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12381 {
12382 struct sockaddr_in sin;
12383 struct ast_sockaddr sin_tmp;
12384 int nonlocal = 1;
12385 int port = IAX_DEFAULT_PORTNO;
12386 int sockfd = defaultsockfd;
12387 char *tmp;
12388 char *addr;
12389 char *portstr;
12390
12391 tmp = ast_strdupa(srcaddr);
12392 addr = strsep(&tmp, ":");
12393 portstr = tmp;
12394
12395 if (portstr) {
12396 port = atoi(portstr);
12397 if (port < 1)
12398 port = IAX_DEFAULT_PORTNO;
12399 }
12400
12401 sin_tmp.ss.ss_family = AF_INET;
12402 if (!ast_get_ip(&sin_tmp, addr)) {
12403 struct ast_netsock *sock;
12404 int res;
12405
12406 ast_sockaddr_to_sin(&sin_tmp, &sin);
12407 sin.sin_port = 0;
12408 sin.sin_family = AF_INET;
12409 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12410 if (res == 0) {
12411
12412 sin.sin_port = htons(port);
12413 if (!(sock = ast_netsock_find(netsock, &sin)))
12414 sock = ast_netsock_find(outsock, &sin);
12415 if (sock) {
12416 sockfd = ast_netsock_sockfd(sock);
12417 nonlocal = 0;
12418 } else {
12419 unsigned int orig_saddr = sin.sin_addr.s_addr;
12420
12421 sin.sin_addr.s_addr = INADDR_ANY;
12422 if (ast_netsock_find(netsock, &sin)) {
12423 sin.sin_addr.s_addr = orig_saddr;
12424 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12425 if (sock) {
12426 sockfd = ast_netsock_sockfd(sock);
12427 ast_netsock_unref(sock);
12428 nonlocal = 0;
12429 } else {
12430 nonlocal = 2;
12431 }
12432 }
12433 }
12434 }
12435 }
12436
12437 peer->sockfd = sockfd;
12438
12439 if (nonlocal == 1) {
12440 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12441 srcaddr, peer->name);
12442 return -1;
12443 } else if (nonlocal == 2) {
12444 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12445 srcaddr, peer->name);
12446 return -1;
12447 } else {
12448 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12449 return 0;
12450 }
12451 }
12452
12453 static void peer_destructor(void *obj)
12454 {
12455 struct iax2_peer *peer = obj;
12456 int callno = peer->callno;
12457
12458 ast_free_ha(peer->ha);
12459
12460 if (callno > 0) {
12461 ast_mutex_lock(&iaxsl[callno]);
12462 iax2_destroy(callno);
12463 ast_mutex_unlock(&iaxsl[callno]);
12464 }
12465
12466 register_peer_exten(peer, 0);
12467
12468 if (peer->dnsmgr)
12469 ast_dnsmgr_release(peer->dnsmgr);
12470
12471 if (peer->mwi_event_sub)
12472 ast_event_unsubscribe(peer->mwi_event_sub);
12473
12474 ast_string_field_free_memory(peer);
12475 }
12476
12477
12478 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12479 {
12480 struct iax2_peer *peer = NULL;
12481 struct ast_ha *oldha = NULL;
12482 int maskfound = 0;
12483 int found = 0;
12484 int firstpass = 1;
12485 struct iax2_peer tmp_peer = {
12486 .name = name,
12487 };
12488
12489 if (!temponly) {
12490 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12491 if (peer && !ast_test_flag64(peer, IAX_DELME))
12492 firstpass = 0;
12493 }
12494
12495 if (peer) {
12496 found++;
12497 if (firstpass) {
12498 oldha = peer->ha;
12499 peer->ha = NULL;
12500 }
12501 unlink_peer(peer);
12502 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12503 peer->expire = -1;
12504 peer->pokeexpire = -1;
12505 peer->sockfd = defaultsockfd;
12506 peer->addr.ss.ss_family = AF_INET;
12507 peer->addr.len = sizeof(struct sockaddr_in);
12508 if (ast_string_field_init(peer, 32))
12509 peer = peer_unref(peer);
12510 }
12511
12512 if (peer) {
12513 if (firstpass) {
12514 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12515 peer->encmethods = iax2_encryption;
12516 peer->adsi = adsi;
12517 ast_string_field_set(peer,secret,"");
12518 if (!found) {
12519 ast_string_field_set(peer, name, name);
12520 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12521 peer->expiry = min_reg_expire;
12522 }
12523 peer->prefs = prefs;
12524 peer->capability = iax2_capability;
12525 peer->smoothing = 0;
12526 peer->pokefreqok = DEFAULT_FREQ_OK;
12527 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12528 peer->maxcallno = 0;
12529 peercnt_modify((unsigned char) 0, 0, &peer->addr);
12530 peer->calltoken_required = CALLTOKEN_DEFAULT;
12531 ast_string_field_set(peer,context,"");
12532 ast_string_field_set(peer,peercontext,"");
12533 ast_clear_flag64(peer, IAX_HASCALLERID);
12534 ast_string_field_set(peer, cid_name, "");
12535 ast_string_field_set(peer, cid_num, "");
12536 ast_string_field_set(peer, mohinterpret, mohinterpret);
12537 ast_string_field_set(peer, mohsuggest, mohsuggest);
12538 }
12539
12540 if (!v) {
12541 v = alt;
12542 alt = NULL;
12543 }
12544 while(v) {
12545 if (!strcasecmp(v->name, "secret")) {
12546 ast_string_field_set(peer, secret, v->value);
12547 } else if (!strcasecmp(v->name, "mailbox")) {
12548 ast_string_field_set(peer, mailbox, v->value);
12549 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12550 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12551 ast_string_field_set(peer, mailbox, name);
12552 }
12553 } else if (!strcasecmp(v->name, "mohinterpret")) {
12554 ast_string_field_set(peer, mohinterpret, v->value);
12555 } else if (!strcasecmp(v->name, "mohsuggest")) {
12556 ast_string_field_set(peer, mohsuggest, v->value);
12557 } else if (!strcasecmp(v->name, "dbsecret")) {
12558 ast_string_field_set(peer, dbsecret, v->value);
12559 } else if (!strcasecmp(v->name, "trunk")) {
12560 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12561 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12562 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12563 ast_clear_flag64(peer, IAX_TRUNK);
12564 }
12565 } else if (!strcasecmp(v->name, "auth")) {
12566 peer->authmethods = get_auth_methods(v->value);
12567 } else if (!strcasecmp(v->name, "encryption")) {
12568 peer->encmethods |= get_encrypt_methods(v->value);
12569 if (!peer->encmethods) {
12570 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12571 }
12572 } else if (!strcasecmp(v->name, "forceencryption")) {
12573 if (ast_false(v->value)) {
12574 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12575 } else {
12576 peer->encmethods |= get_encrypt_methods(v->value);
12577 if (peer->encmethods) {
12578 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12579 }
12580 }
12581 } else if (!strcasecmp(v->name, "transfer")) {
12582 if (!strcasecmp(v->value, "mediaonly")) {
12583 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12584 } else if (ast_true(v->value)) {
12585 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12586 } else
12587 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12588 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12589 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12590 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12591 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12592 } else if (!strcasecmp(v->name, "host")) {
12593 if (!strcasecmp(v->value, "dynamic")) {
12594
12595 ast_set_flag64(peer, IAX_DYNAMIC);
12596 if (!found) {
12597
12598
12599 if (ast_sockaddr_port(&peer->addr)) {
12600 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12601 }
12602 ast_sockaddr_setnull(&peer->addr);
12603 }
12604 } else {
12605
12606 ast_sched_thread_del(sched, peer->expire);
12607 ast_clear_flag64(peer, IAX_DYNAMIC);
12608 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12609 return peer_unref(peer);
12610 if (!ast_sockaddr_port(&peer->addr)) {
12611 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12612 }
12613 }
12614 if (!maskfound)
12615 inet_aton("255.255.255.255", &peer->mask);
12616 } else if (!strcasecmp(v->name, "defaultip")) {
12617 struct ast_sockaddr peer_defaddr_tmp;
12618
12619 peer_defaddr_tmp.ss.ss_family = AF_INET;
12620 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12621 return peer_unref(peer);
12622 }
12623 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12624 &peer->defaddr);
12625 } else if (!strcasecmp(v->name, "sourceaddress")) {
12626 peer_set_srcaddr(peer, v->value);
12627 } else if (!strcasecmp(v->name, "permit") ||
12628 !strcasecmp(v->name, "deny")) {
12629 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12630 } else if (!strcasecmp(v->name, "mask")) {
12631 maskfound++;
12632 inet_aton(v->value, &peer->mask);
12633 } else if (!strcasecmp(v->name, "context")) {
12634 ast_string_field_set(peer, context, v->value);
12635 } else if (!strcasecmp(v->name, "regexten")) {
12636 ast_string_field_set(peer, regexten, v->value);
12637 } else if (!strcasecmp(v->name, "peercontext")) {
12638 ast_string_field_set(peer, peercontext, v->value);
12639 } else if (!strcasecmp(v->name, "port")) {
12640 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12641 peer->defaddr.sin_port = htons(atoi(v->value));
12642 } else {
12643 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12644 }
12645 } else if (!strcasecmp(v->name, "username")) {
12646 ast_string_field_set(peer, username, v->value);
12647 } else if (!strcasecmp(v->name, "allow")) {
12648 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12649 } else if (!strcasecmp(v->name, "disallow")) {
12650 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12651 } else if (!strcasecmp(v->name, "callerid")) {
12652 if (!ast_strlen_zero(v->value)) {
12653 char name2[80];
12654 char num2[80];
12655 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12656 ast_string_field_set(peer, cid_name, name2);
12657 ast_string_field_set(peer, cid_num, num2);
12658 } else {
12659 ast_string_field_set(peer, cid_name, "");
12660 ast_string_field_set(peer, cid_num, "");
12661 }
12662 ast_set_flag64(peer, IAX_HASCALLERID);
12663 } else if (!strcasecmp(v->name, "fullname")) {
12664 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12665 ast_set_flag64(peer, IAX_HASCALLERID);
12666 } else if (!strcasecmp(v->name, "cid_number")) {
12667 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12668 ast_set_flag64(peer, IAX_HASCALLERID);
12669 } else if (!strcasecmp(v->name, "sendani")) {
12670 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12671 } else if (!strcasecmp(v->name, "inkeys")) {
12672 ast_string_field_set(peer, inkeys, v->value);
12673 } else if (!strcasecmp(v->name, "outkey")) {
12674 ast_string_field_set(peer, outkey, v->value);
12675 } else if (!strcasecmp(v->name, "qualify")) {
12676 if (!strcasecmp(v->value, "no")) {
12677 peer->maxms = 0;
12678 } else if (!strcasecmp(v->value, "yes")) {
12679 peer->maxms = DEFAULT_MAXMS;
12680 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12681 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);
12682 peer->maxms = 0;
12683 }
12684 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12685 peer->smoothing = ast_true(v->value);
12686 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12687 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12688 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);
12689 }
12690 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12691 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12692 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);
12693 }
12694 } else if (!strcasecmp(v->name, "timezone")) {
12695 ast_string_field_set(peer, zonetag, v->value);
12696 } else if (!strcasecmp(v->name, "adsi")) {
12697 peer->adsi = ast_true(v->value);
12698 } else if (!strcasecmp(v->name, "connectedline")) {
12699 if (ast_true(v->value)) {
12700 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12701 } else if (!strcasecmp(v->value, "send")) {
12702 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12703 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12704 } else if (!strcasecmp(v->value, "receive")) {
12705 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12706 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12707 } else {
12708 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12709 }
12710 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12711 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12712 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12713 } else {
12714 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr);
12715 }
12716 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12717
12718 if (ast_false(v->value)) {
12719 peer->calltoken_required = CALLTOKEN_NO;
12720 } else if (!strcasecmp(v->value, "auto")) {
12721 peer->calltoken_required = CALLTOKEN_AUTO;
12722 } else if (ast_true(v->value)) {
12723 peer->calltoken_required = CALLTOKEN_YES;
12724 } else {
12725 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12726 }
12727 }
12728
12729 v = v->next;
12730 if (!v) {
12731 v = alt;
12732 alt = NULL;
12733 }
12734 }
12735 if (!peer->authmethods)
12736 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12737 ast_clear_flag64(peer, IAX_DELME);
12738 }
12739
12740 if (oldha)
12741 ast_free_ha(oldha);
12742
12743 if (!ast_strlen_zero(peer->mailbox)) {
12744 char *mailbox, *context;
12745 context = mailbox = ast_strdupa(peer->mailbox);
12746 strsep(&context, "@");
12747 if (ast_strlen_zero(context))
12748 context = "default";
12749 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12750 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12751 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12752 AST_EVENT_IE_END);
12753 }
12754
12755 return peer;
12756 }
12757
12758 static void user_destructor(void *obj)
12759 {
12760 struct iax2_user *user = obj;
12761
12762 ast_free_ha(user->ha);
12763 free_context(user->contexts);
12764 if(user->vars) {
12765 ast_variables_destroy(user->vars);
12766 user->vars = NULL;
12767 }
12768 ast_string_field_free_memory(user);
12769 }
12770
12771
12772 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12773 {
12774 struct iax2_user *user = NULL;
12775 struct iax2_context *con, *conl = NULL;
12776 struct ast_ha *oldha = NULL;
12777 struct iax2_context *oldcon = NULL;
12778 int format;
12779 int firstpass=1;
12780 int oldcurauthreq = 0;
12781 char *varname = NULL, *varval = NULL;
12782 struct ast_variable *tmpvar = NULL;
12783 struct iax2_user tmp_user = {
12784 .name = name,
12785 };
12786
12787 if (!temponly) {
12788 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12789 if (user && !ast_test_flag64(user, IAX_DELME))
12790 firstpass = 0;
12791 }
12792
12793 if (user) {
12794 if (firstpass) {
12795 oldcurauthreq = user->curauthreq;
12796 oldha = user->ha;
12797 oldcon = user->contexts;
12798 user->ha = NULL;
12799 user->contexts = NULL;
12800 }
12801
12802 ao2_unlink(users, user);
12803 } else {
12804 user = ao2_alloc(sizeof(*user), user_destructor);
12805 }
12806
12807 if (user) {
12808 if (firstpass) {
12809 ast_string_field_free_memory(user);
12810 memset(user, 0, sizeof(struct iax2_user));
12811 if (ast_string_field_init(user, 32)) {
12812 user = user_unref(user);
12813 goto cleanup;
12814 }
12815 user->maxauthreq = maxauthreq;
12816 user->curauthreq = oldcurauthreq;
12817 user->prefs = prefs;
12818 user->capability = iax2_capability;
12819 user->encmethods = iax2_encryption;
12820 user->adsi = adsi;
12821 user->calltoken_required = CALLTOKEN_DEFAULT;
12822 ast_string_field_set(user, name, name);
12823 ast_string_field_set(user, language, language);
12824 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);
12825 ast_clear_flag64(user, IAX_HASCALLERID);
12826 ast_string_field_set(user, cid_name, "");
12827 ast_string_field_set(user, cid_num, "");
12828 ast_string_field_set(user, accountcode, accountcode);
12829 ast_string_field_set(user, mohinterpret, mohinterpret);
12830 ast_string_field_set(user, mohsuggest, mohsuggest);
12831 }
12832 if (!v) {
12833 v = alt;
12834 alt = NULL;
12835 }
12836 while(v) {
12837 if (!strcasecmp(v->name, "context")) {
12838 con = build_context(v->value);
12839 if (con) {
12840 if (conl)
12841 conl->next = con;
12842 else
12843 user->contexts = con;
12844 conl = con;
12845 }
12846 } else if (!strcasecmp(v->name, "permit") ||
12847 !strcasecmp(v->name, "deny")) {
12848 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12849 } else if (!strcasecmp(v->name, "setvar")) {
12850 varname = ast_strdupa(v->value);
12851 if ((varval = strchr(varname, '='))) {
12852 *varval = '\0';
12853 varval++;
12854 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12855 tmpvar->next = user->vars;
12856 user->vars = tmpvar;
12857 }
12858 }
12859 } else if (!strcasecmp(v->name, "allow")) {
12860 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12861 } else if (!strcasecmp(v->name, "disallow")) {
12862 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12863 } else if (!strcasecmp(v->name, "trunk")) {
12864 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
12865 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12866 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12867 ast_clear_flag64(user, IAX_TRUNK);
12868 }
12869 } else if (!strcasecmp(v->name, "auth")) {
12870 user->authmethods = get_auth_methods(v->value);
12871 } else if (!strcasecmp(v->name, "encryption")) {
12872 user->encmethods |= get_encrypt_methods(v->value);
12873 if (!user->encmethods) {
12874 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12875 }
12876 } else if (!strcasecmp(v->name, "forceencryption")) {
12877 if (ast_false(v->value)) {
12878 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12879 } else {
12880 user->encmethods |= get_encrypt_methods(v->value);
12881 if (user->encmethods) {
12882 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12883 }
12884 }
12885 } else if (!strcasecmp(v->name, "transfer")) {
12886 if (!strcasecmp(v->value, "mediaonly")) {
12887 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12888 } else if (ast_true(v->value)) {
12889 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12890 } else
12891 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12892 } else if (!strcasecmp(v->name, "codecpriority")) {
12893 if(!strcasecmp(v->value, "caller"))
12894 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12895 else if(!strcasecmp(v->value, "disabled"))
12896 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12897 else if(!strcasecmp(v->value, "reqonly")) {
12898 ast_set_flag64(user, IAX_CODEC_NOCAP);
12899 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12900 }
12901 } else if (!strcasecmp(v->name, "immediate")) {
12902 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12903 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12904 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12905 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12906 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12907 } else if (!strcasecmp(v->name, "dbsecret")) {
12908 ast_string_field_set(user, dbsecret, v->value);
12909 } else if (!strcasecmp(v->name, "secret")) {
12910 if (!ast_strlen_zero(user->secret)) {
12911 char *old = ast_strdupa(user->secret);
12912
12913 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12914 } else
12915 ast_string_field_set(user, secret, v->value);
12916 } else if (!strcasecmp(v->name, "callerid")) {
12917 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12918 char name2[80];
12919 char num2[80];
12920 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12921 ast_string_field_set(user, cid_name, name2);
12922 ast_string_field_set(user, cid_num, num2);
12923 ast_set_flag64(user, IAX_HASCALLERID);
12924 } else {
12925 ast_clear_flag64(user, IAX_HASCALLERID);
12926 ast_string_field_set(user, cid_name, "");
12927 ast_string_field_set(user, cid_num, "");
12928 }
12929 } else if (!strcasecmp(v->name, "fullname")) {
12930 if (!ast_strlen_zero(v->value)) {
12931 ast_string_field_set(user, cid_name, v->value);
12932 ast_set_flag64(user, IAX_HASCALLERID);
12933 } else {
12934 ast_string_field_set(user, cid_name, "");
12935 if (ast_strlen_zero(user->cid_num))
12936 ast_clear_flag64(user, IAX_HASCALLERID);
12937 }
12938 } else if (!strcasecmp(v->name, "cid_number")) {
12939 if (!ast_strlen_zero(v->value)) {
12940 ast_string_field_set(user, cid_num, v->value);
12941 ast_set_flag64(user, IAX_HASCALLERID);
12942 } else {
12943 ast_string_field_set(user, cid_num, "");
12944 if (ast_strlen_zero(user->cid_name))
12945 ast_clear_flag64(user, IAX_HASCALLERID);
12946 }
12947 } else if (!strcasecmp(v->name, "accountcode")) {
12948 ast_string_field_set(user, accountcode, v->value);
12949 } else if (!strcasecmp(v->name, "mohinterpret")) {
12950 ast_string_field_set(user, mohinterpret, v->value);
12951 } else if (!strcasecmp(v->name, "mohsuggest")) {
12952 ast_string_field_set(user, mohsuggest, v->value);
12953 } else if (!strcasecmp(v->name, "parkinglot")) {
12954 ast_string_field_set(user, parkinglot, v->value);
12955 } else if (!strcasecmp(v->name, "language")) {
12956 ast_string_field_set(user, language, v->value);
12957 } else if (!strcasecmp(v->name, "amaflags")) {
12958 format = ast_cdr_amaflags2int(v->value);
12959 if (format < 0) {
12960 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12961 } else {
12962 user->amaflags = format;
12963 }
12964 } else if (!strcasecmp(v->name, "inkeys")) {
12965 ast_string_field_set(user, inkeys, v->value);
12966 } else if (!strcasecmp(v->name, "maxauthreq")) {
12967 user->maxauthreq = atoi(v->value);
12968 if (user->maxauthreq < 0)
12969 user->maxauthreq = 0;
12970 } else if (!strcasecmp(v->name, "adsi")) {
12971 user->adsi = ast_true(v->value);
12972 } else if (!strcasecmp(v->name, "connectedline")) {
12973 if (ast_true(v->value)) {
12974 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12975 } else if (!strcasecmp(v->value, "send")) {
12976 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12977 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12978 } else if (!strcasecmp(v->value, "receive")) {
12979 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12980 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12981 } else {
12982 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12983 }
12984 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12985
12986 if (ast_false(v->value)) {
12987 user->calltoken_required = CALLTOKEN_NO;
12988 } else if (!strcasecmp(v->value, "auto")) {
12989 user->calltoken_required = CALLTOKEN_AUTO;
12990 } else if (ast_true(v->value)) {
12991 user->calltoken_required = CALLTOKEN_YES;
12992 } else {
12993 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12994 }
12995 }
12996
12997 v = v->next;
12998 if (!v) {
12999 v = alt;
13000 alt = NULL;
13001 }
13002 }
13003 if (!user->authmethods) {
13004 if (!ast_strlen_zero(user->secret)) {
13005 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13006 if (!ast_strlen_zero(user->inkeys))
13007 user->authmethods |= IAX_AUTH_RSA;
13008 } else if (!ast_strlen_zero(user->inkeys)) {
13009 user->authmethods = IAX_AUTH_RSA;
13010 } else {
13011 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
13012 }
13013 }
13014 ast_clear_flag64(user, IAX_DELME);
13015 }
13016 cleanup:
13017 if (oldha)
13018 ast_free_ha(oldha);
13019 if (oldcon)
13020 free_context(oldcon);
13021 return user;
13022 }
13023
13024 static int peer_delme_cb(void *obj, void *arg, int flags)
13025 {
13026 struct iax2_peer *peer = obj;
13027
13028 ast_set_flag64(peer, IAX_DELME);
13029
13030 return 0;
13031 }
13032
13033 static int user_delme_cb(void *obj, void *arg, int flags)
13034 {
13035 struct iax2_user *user = obj;
13036
13037 ast_set_flag64(user, IAX_DELME);
13038
13039 return 0;
13040 }
13041
13042 static void delete_users(void)
13043 {
13044 struct iax2_registry *reg;
13045
13046 ao2_callback(users, 0, user_delme_cb, NULL);
13047
13048 AST_LIST_LOCK(®istrations);
13049 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
13050 if (sched) {
13051 ast_sched_thread_del(sched, reg->expire);
13052 }
13053 if (reg->callno) {
13054 int callno = reg->callno;
13055 ast_mutex_lock(&iaxsl[callno]);
13056 if (iaxs[callno]) {
13057 iaxs[callno]->reg = NULL;
13058 iax2_destroy(callno);
13059 }
13060 ast_mutex_unlock(&iaxsl[callno]);
13061 }
13062 if (reg->dnsmgr)
13063 ast_dnsmgr_release(reg->dnsmgr);
13064 ast_free(reg);
13065 }
13066 AST_LIST_UNLOCK(®istrations);
13067
13068 ao2_callback(peers, 0, peer_delme_cb, NULL);
13069 }
13070
13071 static void prune_users(void)
13072 {
13073 struct iax2_user *user;
13074 struct ao2_iterator i;
13075
13076 i = ao2_iterator_init(users, 0);
13077 while ((user = ao2_iterator_next(&i))) {
13078 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
13079 ao2_unlink(users, user);
13080 }
13081 user_unref(user);
13082 }
13083 ao2_iterator_destroy(&i);
13084 }
13085
13086
13087 static void prune_peers(void)
13088 {
13089 struct iax2_peer *peer;
13090 struct ao2_iterator i;
13091
13092 i = ao2_iterator_init(peers, 0);
13093 while ((peer = ao2_iterator_next(&i))) {
13094 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
13095 unlink_peer(peer);
13096 }
13097 peer_unref(peer);
13098 }
13099 ao2_iterator_destroy(&i);
13100 }
13101
13102 static void set_config_destroy(void)
13103 {
13104 strcpy(accountcode, "");
13105 strcpy(language, "");
13106 strcpy(mohinterpret, "");
13107 strcpy(mohsuggest, "");
13108 trunkmaxsize = MAX_TRUNKDATA;
13109 amaflags = 0;
13110 delayreject = 0;
13111 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
13112 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13113 delete_users();
13114 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
13115 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
13116 }
13117
13118
13119 static int set_config(const char *config_file, int reload)
13120 {
13121 struct ast_config *cfg, *ucfg;
13122 format_t capability = iax2_capability;
13123 struct ast_variable *v;
13124 char *cat;
13125 const char *utype;
13126 const char *tosval;
13127 int format;
13128 int portno = IAX_DEFAULT_PORTNO;
13129 int x;
13130 int mtuv;
13131 int subscribe_network_change = 1;
13132 struct iax2_user *user;
13133 struct iax2_peer *peer;
13134 struct ast_netsock *ns;
13135 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13136 #if 0
13137 static unsigned short int last_port=0;
13138 #endif
13139
13140 cfg = ast_config_load(config_file, config_flags);
13141
13142 if (!cfg) {
13143 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13144 return -1;
13145 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13146 ucfg = ast_config_load("users.conf", config_flags);
13147 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13148 return 0;
13149
13150 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13151 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13152 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13153 ast_config_destroy(ucfg);
13154 return 0;
13155 }
13156 if (!cfg) {
13157
13158 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file);
13159 return -1;
13160 }
13161 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13162 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13163 return 0;
13164 } else {
13165 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13166 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13167 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
13168 ast_config_destroy(cfg);
13169 return 0;
13170 }
13171 }
13172
13173 if (reload) {
13174 set_config_destroy();
13175 }
13176
13177
13178 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13179
13180
13181 memset(&globalflags, 0, sizeof(globalflags));
13182 ast_set_flag64(&globalflags, IAX_RTUPDATE);
13183 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13184
13185 #ifdef SO_NO_CHECK
13186 nochecksums = 0;
13187 #endif
13188
13189 default_parkinglot[0] = '\0';
13190
13191 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13192 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13193 global_max_trunk_mtu = MAX_TRUNK_MTU;
13194 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13195 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13196
13197 maxauthreq = 3;
13198
13199 srvlookup = 0;
13200
13201 v = ast_variable_browse(cfg, "general");
13202
13203
13204 tosval = ast_variable_retrieve(cfg, "general", "tos");
13205 if (tosval) {
13206 if (ast_str2tos(tosval, &qos.tos))
13207 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13208 }
13209
13210 tosval = ast_variable_retrieve(cfg, "general", "cos");
13211 if (tosval) {
13212 if (ast_str2cos(tosval, &qos.cos))
13213 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13214 }
13215 while(v) {
13216 if (!strcasecmp(v->name, "bindport")){
13217 if (reload)
13218 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13219 else
13220 portno = atoi(v->value);
13221 } else if (!strcasecmp(v->name, "pingtime"))
13222 ping_time = atoi(v->value);
13223 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13224 if (reload) {
13225 if (atoi(v->value) != iaxthreadcount)
13226 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13227 } else {
13228 iaxthreadcount = atoi(v->value);
13229 if (iaxthreadcount < 1) {
13230 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13231 iaxthreadcount = 1;
13232 } else if (iaxthreadcount > 256) {
13233 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13234 iaxthreadcount = 256;
13235 }
13236 }
13237 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13238 if (reload) {
13239 AST_LIST_LOCK(&dynamic_list);
13240 iaxmaxthreadcount = atoi(v->value);
13241 AST_LIST_UNLOCK(&dynamic_list);
13242 } else {
13243 iaxmaxthreadcount = atoi(v->value);
13244 if (iaxmaxthreadcount < 0) {
13245 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13246 iaxmaxthreadcount = 0;
13247 } else if (iaxmaxthreadcount > 256) {
13248 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13249 iaxmaxthreadcount = 256;
13250 }
13251 }
13252 } else if (!strcasecmp(v->name, "nochecksums")) {
13253 #ifdef SO_NO_CHECK
13254 if (ast_true(v->value))
13255 nochecksums = 1;
13256 else
13257 nochecksums = 0;
13258 #else
13259 if (ast_true(v->value))
13260 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13261 #endif
13262 }
13263 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13264 maxjitterbuffer = atoi(v->value);
13265 else if (!strcasecmp(v->name, "resyncthreshold"))
13266 resyncthreshold = atoi(v->value);
13267 else if (!strcasecmp(v->name, "maxjitterinterps"))
13268 maxjitterinterps = atoi(v->value);
13269 else if (!strcasecmp(v->name, "jittertargetextra"))
13270 jittertargetextra = atoi(v->value);
13271 else if (!strcasecmp(v->name, "lagrqtime"))
13272 lagrq_time = atoi(v->value);
13273 else if (!strcasecmp(v->name, "maxregexpire"))
13274 max_reg_expire = atoi(v->value);
13275 else if (!strcasecmp(v->name, "minregexpire"))
13276 min_reg_expire = atoi(v->value);
13277 else if (!strcasecmp(v->name, "bindaddr")) {
13278 if (reload) {
13279 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13280 } else {
13281 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13282 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13283 } else {
13284 if (strchr(v->value, ':'))
13285 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13286 else
13287 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13288 if (defaultsockfd < 0)
13289 defaultsockfd = ast_netsock_sockfd(ns);
13290 ast_netsock_unref(ns);
13291 }
13292 }
13293 } else if (!strcasecmp(v->name, "authdebug")) {
13294 authdebug = ast_true(v->value);
13295 } else if (!strcasecmp(v->name, "encryption")) {
13296 iax2_encryption |= get_encrypt_methods(v->value);
13297 if (!iax2_encryption) {
13298 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13299 }
13300 } else if (!strcasecmp(v->name, "forceencryption")) {
13301 if (ast_false(v->value)) {
13302 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13303 } else {
13304 iax2_encryption |= get_encrypt_methods(v->value);
13305 if (iax2_encryption) {
13306 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13307 }
13308 }
13309 } else if (!strcasecmp(v->name, "transfer")) {
13310 if (!strcasecmp(v->value, "mediaonly")) {
13311 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13312 } else if (ast_true(v->value)) {
13313 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13314 } else
13315 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13316 } else if (!strcasecmp(v->name, "codecpriority")) {
13317 if(!strcasecmp(v->value, "caller"))
13318 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13319 else if(!strcasecmp(v->value, "disabled"))
13320 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13321 else if(!strcasecmp(v->value, "reqonly")) {
13322 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13323 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13324 }
13325 } else if (!strcasecmp(v->name, "jitterbuffer"))
13326 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13327 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13328 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13329 else if (!strcasecmp(v->name, "delayreject"))
13330 delayreject = ast_true(v->value);
13331 else if (!strcasecmp(v->name, "allowfwdownload"))
13332 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13333 else if (!strcasecmp(v->name, "rtcachefriends"))
13334 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13335 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13336 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13337 else if (!strcasecmp(v->name, "rtupdate"))
13338 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13339 else if (!strcasecmp(v->name, "rtsavesysname"))
13340 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13341 else if (!strcasecmp(v->name, "trunktimestamps"))
13342 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13343 else if (!strcasecmp(v->name, "rtautoclear")) {
13344 int i = atoi(v->value);
13345 if(i > 0)
13346 global_rtautoclear = i;
13347 else
13348 i = 0;
13349 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13350 } else if (!strcasecmp(v->name, "trunkfreq")) {
13351 trunkfreq = atoi(v->value);
13352 if (trunkfreq < 10) {
13353 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n");
13354 trunkfreq = 10;
13355 } else if (trunkfreq > 1000) {
13356 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n");
13357 trunkfreq = 1000;
13358 }
13359 if (timer) {
13360 ast_timer_set_rate(timer, 1000 / trunkfreq);
13361 }
13362 } else if (!strcasecmp(v->name, "trunkmtu")) {
13363 mtuv = atoi(v->value);
13364 if (mtuv == 0 )
13365 global_max_trunk_mtu = 0;
13366 else if (mtuv >= 172 && mtuv < 4000)
13367 global_max_trunk_mtu = mtuv;
13368 else
13369 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13370 mtuv, v->lineno);
13371 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13372 trunkmaxsize = atoi(v->value);
13373 if (trunkmaxsize == 0)
13374 trunkmaxsize = MAX_TRUNKDATA;
13375 } else if (!strcasecmp(v->name, "autokill")) {
13376 if (sscanf(v->value, "%30d", &x) == 1) {
13377 if (x >= 0)
13378 autokill = x;
13379 else
13380 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13381 } else if (ast_true(v->value)) {
13382 autokill = DEFAULT_MAXMS;
13383 } else {
13384 autokill = 0;
13385 }
13386 } else if (!strcasecmp(v->name, "bandwidth")) {
13387 if (!strcasecmp(v->value, "low")) {
13388 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13389 } else if (!strcasecmp(v->value, "medium")) {
13390 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13391 } else if (!strcasecmp(v->value, "high")) {
13392 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13393 } else
13394 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13395 } else if (!strcasecmp(v->name, "allow")) {
13396 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13397 } else if (!strcasecmp(v->name, "disallow")) {
13398 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13399 } else if (!strcasecmp(v->name, "register")) {
13400 iax2_register(v->value, v->lineno);
13401 } else if (!strcasecmp(v->name, "iaxcompat")) {
13402 iaxcompat = ast_true(v->value);
13403 } else if (!strcasecmp(v->name, "regcontext")) {
13404 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13405
13406 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13407 } else if (!strcasecmp(v->name, "tos")) {
13408 if (ast_str2tos(v->value, &qos.tos))
13409 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13410 } else if (!strcasecmp(v->name, "cos")) {
13411 if (ast_str2cos(v->value, &qos.cos))
13412 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13413 } else if (!strcasecmp(v->name, "parkinglot")) {
13414 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13415 } else if (!strcasecmp(v->name, "accountcode")) {
13416 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13417 } else if (!strcasecmp(v->name, "mohinterpret")) {
13418 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13419 } else if (!strcasecmp(v->name, "mohsuggest")) {
13420 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13421 } else if (!strcasecmp(v->name, "amaflags")) {
13422 format = ast_cdr_amaflags2int(v->value);
13423 if (format < 0) {
13424 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13425 } else {
13426 amaflags = format;
13427 }
13428 } else if (!strcasecmp(v->name, "language")) {
13429 ast_copy_string(language, v->value, sizeof(language));
13430 } else if (!strcasecmp(v->name, "maxauthreq")) {
13431 maxauthreq = atoi(v->value);
13432 if (maxauthreq < 0)
13433 maxauthreq = 0;
13434 } else if (!strcasecmp(v->name, "adsi")) {
13435 adsi = ast_true(v->value);
13436 } else if (!strcasecmp(v->name, "srvlookup")) {
13437 srvlookup = ast_true(v->value);
13438 } else if (!strcasecmp(v->name, "connectedline")) {
13439 if (ast_true(v->value)) {
13440 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13441 } else if (!strcasecmp(v->value, "send")) {
13442 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13443 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13444 } else if (!strcasecmp(v->value, "receive")) {
13445 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13446 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13447 } else {
13448 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13449 }
13450 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13451 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13452 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13453 }
13454 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13455 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13456 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);
13457 }
13458 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13459 if (add_calltoken_ignore(v->value)) {
13460 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13461 }
13462 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13463 if (ast_true(v->value)) {
13464 subscribe_network_change = 1;
13465 } else if (ast_false(v->value)) {
13466 subscribe_network_change = 0;
13467 } else {
13468 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13469 }
13470 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13471 if (ast_true(v->value)) {
13472 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13473 } else if (ast_false(v->value)) {
13474 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13475 } else {
13476 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13477 }
13478 }
13479
13480 v = v->next;
13481 }
13482
13483 if (subscribe_network_change) {
13484 network_change_event_subscribe();
13485 } else {
13486 network_change_event_unsubscribe();
13487 }
13488
13489 if (defaultsockfd < 0) {
13490 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13491 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13492 } else {
13493 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13494 defaultsockfd = ast_netsock_sockfd(ns);
13495 ast_netsock_unref(ns);
13496 }
13497 }
13498 if (reload) {
13499 ast_netsock_release(outsock);
13500 outsock = ast_netsock_list_alloc();
13501 if (!outsock) {
13502 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13503 return -1;
13504 }
13505 ast_netsock_init(outsock);
13506 }
13507
13508 if (min_reg_expire > max_reg_expire) {
13509 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13510 min_reg_expire, max_reg_expire, max_reg_expire);
13511 min_reg_expire = max_reg_expire;
13512 }
13513 iax2_capability = capability;
13514
13515 if (ucfg) {
13516 struct ast_variable *gen;
13517 int genhasiax;
13518 int genregisteriax;
13519 const char *hasiax, *registeriax;
13520
13521 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13522 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13523 gen = ast_variable_browse(ucfg, "general");
13524 cat = ast_category_browse(ucfg, NULL);
13525 while (cat) {
13526 if (strcasecmp(cat, "general")) {
13527 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13528 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13529 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13530
13531 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13532 if (user) {
13533 ao2_link(users, user);
13534 user = user_unref(user);
13535 }
13536 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13537 if (peer) {
13538 if (ast_test_flag64(peer, IAX_DYNAMIC))
13539 reg_source_db(peer);
13540 ao2_link(peers, peer);
13541 peer = peer_unref(peer);
13542 }
13543 }
13544 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13545 char tmp[256];
13546 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13547 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13548 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13549 if (!host)
13550 host = ast_variable_retrieve(ucfg, "general", "host");
13551 if (!username)
13552 username = ast_variable_retrieve(ucfg, "general", "username");
13553 if (!secret)
13554 secret = ast_variable_retrieve(ucfg, "general", "secret");
13555 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13556 if (!ast_strlen_zero(secret))
13557 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13558 else
13559 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13560 iax2_register(tmp, 0);
13561 }
13562 }
13563 }
13564 cat = ast_category_browse(ucfg, cat);
13565 }
13566 ast_config_destroy(ucfg);
13567 }
13568
13569 cat = ast_category_browse(cfg, NULL);
13570 while(cat) {
13571 if (strcasecmp(cat, "general")) {
13572 utype = ast_variable_retrieve(cfg, cat, "type");
13573 if (!strcasecmp(cat, "callnumberlimits")) {
13574 build_callno_limits(ast_variable_browse(cfg, cat));
13575 } else if (utype) {
13576 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13577 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13578 if (user) {
13579 ao2_link(users, user);
13580 user = user_unref(user);
13581 }
13582 }
13583 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13584 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13585 if (peer) {
13586 if (ast_test_flag64(peer, IAX_DYNAMIC))
13587 reg_source_db(peer);
13588 ao2_link(peers, peer);
13589 peer = peer_unref(peer);
13590 }
13591 } else if (strcasecmp(utype, "user")) {
13592 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13593 }
13594 } else
13595 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13596 }
13597 cat = ast_category_browse(cfg, cat);
13598 }
13599 ast_config_destroy(cfg);
13600 return 1;
13601 }
13602
13603 static void poke_all_peers(void)
13604 {
13605 struct ao2_iterator i;
13606 struct iax2_peer *peer;
13607
13608 i = ao2_iterator_init(peers, 0);
13609 while ((peer = ao2_iterator_next(&i))) {
13610 iax2_poke_peer(peer, 0);
13611 peer_unref(peer);
13612 }
13613 ao2_iterator_destroy(&i);
13614 }
13615 static int reload_config(void)
13616 {
13617 static const char config[] = "iax.conf";
13618 struct iax2_registry *reg;
13619
13620 if (set_config(config, 1) > 0) {
13621 prune_peers();
13622 prune_users();
13623 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13624 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13625 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13626 trunk_timed = trunk_untimed = 0;
13627 trunk_nmaxmtu = trunk_maxmtu = 0;
13628 memset(&debugaddr, '\0', sizeof(debugaddr));
13629
13630 AST_LIST_LOCK(®istrations);
13631 AST_LIST_TRAVERSE(®istrations, reg, entry)
13632 iax2_do_register(reg);
13633 AST_LIST_UNLOCK(®istrations);
13634
13635
13636 poke_all_peers();
13637 }
13638
13639 reload_firmware(0);
13640 iax_provision_reload(1);
13641 ast_unload_realtime("iaxpeers");
13642
13643 return 0;
13644 }
13645
13646 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13647 {
13648 switch (cmd) {
13649 case CLI_INIT:
13650 e->command = "iax2 reload";
13651 e->usage =
13652 "Usage: iax2 reload\n"
13653 " Reloads IAX configuration from iax.conf\n";
13654 return NULL;
13655 case CLI_GENERATE:
13656 return NULL;
13657 }
13658
13659 reload_config();
13660
13661 return CLI_SUCCESS;
13662 }
13663
13664 static int reload(void)
13665 {
13666 return reload_config();
13667 }
13668
13669 static int cache_get_callno_locked(const char *data)
13670 {
13671 struct sockaddr_in sin;
13672 int x;
13673 int callno;
13674 struct iax_ie_data ied;
13675 struct create_addr_info cai;
13676 struct parsed_dial_string pds;
13677 char *tmpstr;
13678
13679 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13680
13681
13682 if (!ast_mutex_trylock(&iaxsl[x])) {
13683 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13684 return x;
13685 ast_mutex_unlock(&iaxsl[x]);
13686 }
13687 }
13688
13689
13690
13691 memset(&cai, 0, sizeof(cai));
13692 memset(&ied, 0, sizeof(ied));
13693 memset(&pds, 0, sizeof(pds));
13694
13695 tmpstr = ast_strdupa(data);
13696 parse_dial_string(tmpstr, &pds);
13697
13698 if (ast_strlen_zero(pds.peer)) {
13699 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13700 return -1;
13701 }
13702
13703
13704 if (create_addr(pds.peer, NULL, &sin, &cai))
13705 return -1;
13706
13707 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13708 pds.peer, pds.username, pds.password, pds.context);
13709
13710 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13711 if (callno < 1) {
13712 ast_log(LOG_WARNING, "Unable to create call\n");
13713 return -1;
13714 }
13715
13716 ast_string_field_set(iaxs[callno], dproot, data);
13717 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13718
13719 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13720 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13721
13722
13723
13724 if (pds.exten)
13725 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13726 if (pds.username)
13727 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13728 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13729 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13730
13731 if (pds.password)
13732 ast_string_field_set(iaxs[callno], secret, pds.password);
13733 if (pds.key)
13734 ast_string_field_set(iaxs[callno], outkey, pds.key);
13735
13736 add_empty_calltoken_ie(iaxs[callno], &ied);
13737 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13738
13739 return callno;
13740 }
13741
13742 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13743 {
13744 struct iax2_dpcache *dp = NULL;
13745 struct timeval now = ast_tvnow();
13746 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13747 struct ast_channel *c = NULL;
13748 struct ast_frame *f = NULL;
13749
13750 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13751 if (ast_tvcmp(now, dp->expiry) > 0) {
13752 AST_LIST_REMOVE_CURRENT(cache_list);
13753 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13754 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13755 else
13756 ast_free(dp);
13757 continue;
13758 }
13759 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13760 break;
13761 }
13762 AST_LIST_TRAVERSE_SAFE_END;
13763
13764 if (!dp) {
13765
13766
13767 if ((callno = cache_get_callno_locked(data)) < 0) {
13768 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13769 return NULL;
13770 }
13771 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13772 ast_mutex_unlock(&iaxsl[callno]);
13773 return NULL;
13774 }
13775 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13776 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13777 dp->expiry = ast_tvnow();
13778 dp->orig = dp->expiry;
13779
13780 dp->expiry.tv_sec += iaxdefaultdpcache;
13781 dp->flags = CACHE_FLAG_PENDING;
13782 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13783 dp->waiters[x] = -1;
13784
13785 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13786 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13787
13788 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13789 iax2_dprequest(dp, callno);
13790 ast_mutex_unlock(&iaxsl[callno]);
13791 }
13792
13793
13794 if (dp->flags & CACHE_FLAG_PENDING) {
13795 struct timeval start;
13796 int ms;
13797
13798
13799 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13800
13801 if (dp->waiters[x] < 0)
13802 break;
13803 }
13804 if (x >= ARRAY_LEN(dp->waiters)) {
13805 ast_log(LOG_WARNING, "No more waiter positions available\n");
13806 return NULL;
13807 }
13808 if (pipe(com)) {
13809 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13810 return NULL;
13811 }
13812 dp->waiters[x] = com[1];
13813
13814 timeout = iaxdefaulttimeout * 1000;
13815
13816 AST_LIST_UNLOCK(&dpcache);
13817
13818 if (chan)
13819 old = ast_channel_defer_dtmf(chan);
13820 doabort = 0;
13821 start = ast_tvnow();
13822 while ((ms = ast_remaining_ms(start, timeout))) {
13823 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms);
13824 if (outfd > -1)
13825 break;
13826 if (!c)
13827 continue;
13828 if (!(f = ast_read(c))) {
13829 doabort = 1;
13830 break;
13831 }
13832 ast_frfree(f);
13833 }
13834 if (!ms) {
13835 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13836 }
13837 AST_LIST_LOCK(&dpcache);
13838 dp->waiters[x] = -1;
13839 close(com[1]);
13840 close(com[0]);
13841 if (doabort) {
13842
13843
13844 if (!old && chan)
13845 ast_channel_undefer_dtmf(chan);
13846 return NULL;
13847 }
13848 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13849
13850 if (dp->flags & CACHE_FLAG_PENDING) {
13851
13852
13853 dp->flags &= ~CACHE_FLAG_PENDING;
13854 dp->flags |= CACHE_FLAG_TIMEOUT;
13855
13856
13857 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13858 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13859 if (dp->waiters[x] > -1) {
13860 if (write(dp->waiters[x], "asdf", 4) < 0) {
13861 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13862 }
13863 }
13864 }
13865 }
13866 }
13867
13868 if (!old && chan)
13869 ast_channel_undefer_dtmf(chan);
13870 }
13871 return dp;
13872 }
13873
13874
13875 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13876 {
13877 int res = 0;
13878 struct iax2_dpcache *dp = NULL;
13879 #if 0
13880 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13881 #endif
13882 if ((priority != 1) && (priority != 2))
13883 return 0;
13884
13885 AST_LIST_LOCK(&dpcache);
13886 if ((dp = find_cache(chan, data, context, exten, priority))) {
13887 if (dp->flags & CACHE_FLAG_EXISTS)
13888 res = 1;
13889 } else {
13890 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13891 }
13892 AST_LIST_UNLOCK(&dpcache);
13893
13894 return res;
13895 }
13896
13897
13898 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13899 {
13900 int res = 0;
13901 struct iax2_dpcache *dp = NULL;
13902 #if 0
13903 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13904 #endif
13905 if ((priority != 1) && (priority != 2))
13906 return 0;
13907
13908 AST_LIST_LOCK(&dpcache);
13909 if ((dp = find_cache(chan, data, context, exten, priority))) {
13910 if (dp->flags & CACHE_FLAG_CANEXIST)
13911 res = 1;
13912 } else {
13913 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13914 }
13915 AST_LIST_UNLOCK(&dpcache);
13916
13917 return res;
13918 }
13919
13920
13921 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13922 {
13923 int res = 0;
13924 struct iax2_dpcache *dp = NULL;
13925 #if 0
13926 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13927 #endif
13928 if ((priority != 1) && (priority != 2))
13929 return 0;
13930
13931 AST_LIST_LOCK(&dpcache);
13932 if ((dp = find_cache(chan, data, context, exten, priority))) {
13933 if (dp->flags & CACHE_FLAG_MATCHMORE)
13934 res = 1;
13935 } else {
13936 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13937 }
13938 AST_LIST_UNLOCK(&dpcache);
13939
13940 return res;
13941 }
13942
13943
13944 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13945 {
13946 char odata[256];
13947 char req[256];
13948 char *ncontext;
13949 struct iax2_dpcache *dp = NULL;
13950 struct ast_app *dial = NULL;
13951 #if 0
13952 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);
13953 #endif
13954 if (priority == 2) {
13955
13956 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13957 if (dialstatus) {
13958 dial = pbx_findapp(dialstatus);
13959 if (dial)
13960 pbx_exec(chan, dial, "");
13961 }
13962 return -1;
13963 } else if (priority != 1)
13964 return -1;
13965
13966 AST_LIST_LOCK(&dpcache);
13967 if ((dp = find_cache(chan, data, context, exten, priority))) {
13968 if (dp->flags & CACHE_FLAG_EXISTS) {
13969 ast_copy_string(odata, data, sizeof(odata));
13970 ncontext = strchr(odata, '/');
13971 if (ncontext) {
13972 *ncontext = '\0';
13973 ncontext++;
13974 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13975 } else {
13976 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13977 }
13978 ast_verb(3, "Executing Dial('%s')\n", req);
13979 } else {
13980 AST_LIST_UNLOCK(&dpcache);
13981 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13982 return -1;
13983 }
13984 }
13985 AST_LIST_UNLOCK(&dpcache);
13986
13987 if ((dial = pbx_findapp("Dial")))
13988 return pbx_exec(chan, dial, req);
13989 else
13990 ast_log(LOG_WARNING, "No dial application registered\n");
13991
13992 return -1;
13993 }
13994
13995 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13996 {
13997 struct iax2_peer *peer;
13998 char *peername, *colname;
13999
14000 peername = ast_strdupa(data);
14001
14002
14003 if (!strcmp(peername,"CURRENTCHANNEL")) {
14004 unsigned short callno;
14005 if (chan->tech != &iax2_tech)
14006 return -1;
14007 callno = PTR_TO_CALLNO(chan->tech_pvt);
14008 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
14009 return 0;
14010 }
14011
14012 if ((colname = strchr(peername, ',')))
14013 *colname++ = '\0';
14014 else
14015 colname = "ip";
14016
14017 if (!(peer = find_peer(peername, 1)))
14018 return -1;
14019
14020 if (!strcasecmp(colname, "ip")) {
14021 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
14022 } else if (!strcasecmp(colname, "status")) {
14023 peer_status(peer, buf, len);
14024 } else if (!strcasecmp(colname, "mailbox")) {
14025 ast_copy_string(buf, peer->mailbox, len);
14026 } else if (!strcasecmp(colname, "context")) {
14027 ast_copy_string(buf, peer->context, len);
14028 } else if (!strcasecmp(colname, "expire")) {
14029 snprintf(buf, len, "%d", peer->expire);
14030 } else if (!strcasecmp(colname, "dynamic")) {
14031 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
14032 } else if (!strcasecmp(colname, "callerid_name")) {
14033 ast_copy_string(buf, peer->cid_name, len);
14034 } else if (!strcasecmp(colname, "callerid_num")) {
14035 ast_copy_string(buf, peer->cid_num, len);
14036 } else if (!strcasecmp(colname, "codecs")) {
14037 ast_getformatname_multiple(buf, len -1, peer->capability);
14038 } else if (!strncasecmp(colname, "codec[", 6)) {
14039 char *codecnum, *ptr;
14040 int codec = 0;
14041
14042
14043 codecnum = colname + 5;
14044 *codecnum = '\0';
14045 codecnum++;
14046 if ((ptr = strchr(codecnum, ']'))) {
14047 *ptr = '\0';
14048 }
14049 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
14050 ast_copy_string(buf, ast_getformatname(codec), len);
14051 } else {
14052 buf[0] = '\0';
14053 }
14054 } else {
14055 buf[0] = '\0';
14056 }
14057
14058 peer_unref(peer);
14059
14060 return 0;
14061 }
14062
14063 static struct ast_custom_function iaxpeer_function = {
14064 .name = "IAXPEER",
14065 .read = function_iaxpeer,
14066 };
14067
14068 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
14069 {
14070 struct chan_iax2_pvt *pvt;
14071 unsigned int callno;
14072 int res = 0;
14073
14074 if (!chan || chan->tech != &iax2_tech) {
14075 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14076 return -1;
14077 }
14078
14079 callno = PTR_TO_CALLNO(chan->tech_pvt);
14080 ast_mutex_lock(&iaxsl[callno]);
14081 if (!(pvt = iaxs[callno])) {
14082 ast_mutex_unlock(&iaxsl[callno]);
14083 return -1;
14084 }
14085
14086 if (!strcasecmp(args, "osptoken")) {
14087 ast_copy_string(buf, pvt->osptoken, buflen);
14088 } else if (!strcasecmp(args, "peerip")) {
14089 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
14090 } else if (!strcasecmp(args, "peername")) {
14091 ast_copy_string(buf, pvt->username, buflen);
14092 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14093 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14094 } else {
14095 res = -1;
14096 }
14097
14098 ast_mutex_unlock(&iaxsl[callno]);
14099
14100 return res;
14101 }
14102
14103
14104 static int iax2_devicestate(void *data)
14105 {
14106 struct parsed_dial_string pds;
14107 char *tmp = ast_strdupa(data);
14108 struct iax2_peer *p;
14109 int res = AST_DEVICE_INVALID;
14110
14111 memset(&pds, 0, sizeof(pds));
14112 parse_dial_string(tmp, &pds);
14113
14114 if (ast_strlen_zero(pds.peer)) {
14115 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
14116 return res;
14117 }
14118
14119 ast_debug(3, "Checking device state for device %s\n", pds.peer);
14120
14121
14122 if (!(p = find_peer(pds.peer, 1)))
14123 return res;
14124
14125 res = AST_DEVICE_UNAVAILABLE;
14126 ast_debug(3, "Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
14127 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
14128
14129 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
14130 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14131
14132
14133 if (p->historicms == 0 || p->historicms <= p->maxms)
14134
14135 res = AST_DEVICE_UNKNOWN;
14136 }
14137
14138 peer_unref(p);
14139
14140 return res;
14141 }
14142
14143 static struct ast_switch iax2_switch =
14144 {
14145 .name = "IAX2",
14146 .description = "IAX Remote Dialplan Switch",
14147 .exists = iax2_exists,
14148 .canmatch = iax2_canmatch,
14149 .exec = iax2_exec,
14150 .matchmore = iax2_matchmore,
14151 };
14152
14153
14154
14155
14156
14157
14158
14159
14160
14161
14162
14163
14164
14165
14166
14167
14168
14169
14170
14171
14172
14173
14174
14175
14176
14177
14178
14179
14180
14181
14182
14183
14184
14185
14186
14187
14188
14189
14190
14191
14192
14193
14194
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205
14206
14207
14208
14209
14210
14211
14212
14213
14214
14215
14216
14217
14218
14219
14220
14221
14222
14223
14224
14225
14226
14227
14228
14229
14230
14231
14232
14233
14234
14235
14236
14237
14238
14239
14240
14241
14242
14243
14244
14245
14246
14247
14248
14249
14250
14251
14252
14253
14254
14255
14256
14257 static struct ast_cli_entry cli_iax2[] = {
14258 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14259 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14260 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14261 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14262 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14263 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14264 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14265 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14266 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14267 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14268 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14269 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14270 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14271 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14272 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14273 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14274 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14275 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14276 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14277 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14278 #ifdef IAXTESTS
14279 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14280 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14281 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14282 #endif
14283 };
14284
14285 #ifdef TEST_FRAMEWORK
14286 AST_TEST_DEFINE(test_iax2_peers_get)
14287 {
14288 struct ast_data_query query = {
14289 .path = "/asterisk/channel/iax2/peers",
14290 .search = "peers/peer/name=test_peer_data_provider"
14291 };
14292 struct ast_data *node;
14293 struct iax2_peer *peer;
14294
14295 switch (cmd) {
14296 case TEST_INIT:
14297 info->name = "iax2_peers_get_data_test";
14298 info->category = "/main/data/iax2/peers/";
14299 info->summary = "IAX2 peers data providers unit test";
14300 info->description =
14301 "Tests whether the IAX2 peers data provider implementation works as expected.";
14302 return AST_TEST_NOT_RUN;
14303 case TEST_EXECUTE:
14304 break;
14305 }
14306
14307
14308 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14309 if (!peer) {
14310 return AST_TEST_FAIL;
14311 }
14312 peer->expiry= 1010;
14313 ao2_link(peers, peer);
14314
14315 node = ast_data_get(&query);
14316 if (!node) {
14317 ao2_unlink(peers, peer);
14318 peer_unref(peer);
14319 return AST_TEST_FAIL;
14320 }
14321
14322
14323 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14324 ao2_unlink(peers, peer);
14325 peer_unref(peer);
14326 ast_data_free(node);
14327 return AST_TEST_FAIL;
14328 }
14329
14330 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14331 ao2_unlink(peers, peer);
14332 peer_unref(peer);
14333 ast_data_free(node);
14334 return AST_TEST_FAIL;
14335 }
14336
14337
14338 ast_data_free(node);
14339
14340 ao2_unlink(peers, peer);
14341 peer_unref(peer);
14342
14343 return AST_TEST_PASS;
14344 }
14345
14346 AST_TEST_DEFINE(test_iax2_users_get)
14347 {
14348 struct ast_data_query query = {
14349 .path = "/asterisk/channel/iax2/users",
14350 .search = "users/user/name=test_user_data_provider"
14351 };
14352 struct ast_data *node;
14353 struct iax2_user *user;
14354
14355 switch (cmd) {
14356 case TEST_INIT:
14357 info->name = "iax2_users_get_data_test";
14358 info->category = "/main/data/iax2/users/";
14359 info->summary = "IAX2 users data providers unit test";
14360 info->description =
14361 "Tests whether the IAX2 users data provider implementation works as expected.";
14362 return AST_TEST_NOT_RUN;
14363 case TEST_EXECUTE:
14364 break;
14365 }
14366
14367 user = build_user("test_user_data_provider", NULL, NULL, 0);
14368 if (!user) {
14369 ast_test_status_update(test, "Failed to build a test user\n");
14370 return AST_TEST_FAIL;
14371 }
14372 user->amaflags = 1010;
14373 ao2_link(users, user);
14374
14375 node = ast_data_get(&query);
14376 if (!node) {
14377 ast_test_status_update(test, "The data query to find our test user failed\n");
14378 ao2_unlink(users, user);
14379 user_unref(user);
14380 return AST_TEST_FAIL;
14381 }
14382
14383 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14384 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14385 ao2_unlink(users, user);
14386 user_unref(user);
14387 ast_data_free(node);
14388 return AST_TEST_FAIL;
14389 }
14390
14391 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14392 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"));
14393 ao2_unlink(users, user);
14394 user_unref(user);
14395 ast_data_free(node);
14396 return AST_TEST_FAIL;
14397 }
14398
14399 ast_data_free(node);
14400
14401 ao2_unlink(users, user);
14402 user_unref(user);
14403
14404 return AST_TEST_PASS;
14405 }
14406 #endif
14407
14408 static void cleanup_thread_list(void *head)
14409 {
14410 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14411 struct iax2_thread_list *list_head = head;
14412 struct iax2_thread *thread;
14413
14414 AST_LIST_LOCK(list_head);
14415 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) {
14416 pthread_t thread_id = thread->threadid;
14417
14418 thread->stop = 1;
14419 signal_condition(&thread->lock, &thread->cond);
14420
14421 AST_LIST_UNLOCK(list_head);
14422 pthread_join(thread_id, NULL);
14423 AST_LIST_LOCK(list_head);
14424 }
14425 AST_LIST_UNLOCK(list_head);
14426 }
14427
14428 static int __unload_module(void)
14429 {
14430 struct ast_context *con;
14431 int x;
14432
14433 network_change_event_unsubscribe();
14434
14435 ast_manager_unregister("IAXpeers");
14436 ast_manager_unregister("IAXpeerlist");
14437 ast_manager_unregister("IAXnetstats");
14438 ast_manager_unregister("IAXregistry");
14439 ast_unregister_application(papp);
14440 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14441 ast_unregister_switch(&iax2_switch);
14442 ast_channel_unregister(&iax2_tech);
14443
14444 if (netthreadid != AST_PTHREADT_NULL) {
14445 pthread_cancel(netthreadid);
14446 pthread_kill(netthreadid, SIGURG);
14447 pthread_join(netthreadid, NULL);
14448 }
14449
14450 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14451 if (iaxs[x]) {
14452 iax2_destroy(x);
14453 }
14454 }
14455
14456
14457 cleanup_thread_list(&active_list);
14458 cleanup_thread_list(&dynamic_list);
14459 cleanup_thread_list(&idle_list);
14460
14461 ast_netsock_release(netsock);
14462 ast_netsock_release(outsock);
14463 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14464 if (iaxs[x]) {
14465 iax2_destroy(x);
14466 }
14467 }
14468 ast_manager_unregister( "IAXpeers" );
14469 ast_manager_unregister( "IAXpeerlist" );
14470 ast_manager_unregister( "IAXnetstats" );
14471 ast_manager_unregister( "IAXregistry" );
14472 ast_unregister_application(papp);
14473 #ifdef TEST_FRAMEWORK
14474 AST_TEST_UNREGISTER(test_iax2_peers_get);
14475 AST_TEST_UNREGISTER(test_iax2_users_get);
14476 #endif
14477 ast_data_unregister(NULL);
14478 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14479 ast_unregister_switch(&iax2_switch);
14480 ast_channel_unregister(&iax2_tech);
14481 delete_users();
14482 iax_provision_unload();
14483 reload_firmware(1);
14484
14485 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14486 ast_mutex_destroy(&iaxsl[x]);
14487 }
14488
14489 ao2_ref(peers, -1);
14490 ao2_ref(users, -1);
14491 ao2_ref(iax_peercallno_pvts, -1);
14492 ao2_ref(iax_transfercallno_pvts, -1);
14493 ao2_ref(peercnts, -1);
14494 ao2_ref(callno_limits, -1);
14495 ao2_ref(calltoken_ignores, -1);
14496 ao2_ref(callno_pool, -1);
14497 ao2_ref(callno_pool_trunk, -1);
14498 if (timer) {
14499 ast_timer_close(timer);
14500 timer = NULL;
14501 }
14502 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14503 sched = ast_sched_thread_destroy(sched);
14504
14505 con = ast_context_find(regcontext);
14506 if (con)
14507 ast_context_destroy(con, "IAX2");
14508 ast_unload_realtime("iaxpeers");
14509 return 0;
14510 }
14511
14512 static int unload_module(void)
14513 {
14514 ast_custom_function_unregister(&iaxpeer_function);
14515 ast_custom_function_unregister(&iaxvar_function);
14516 return __unload_module();
14517 }
14518
14519 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14520 {
14521 struct iax2_peer *peer = obj;
14522
14523 if (peer->sockfd < 0)
14524 peer->sockfd = defaultsockfd;
14525
14526 return 0;
14527 }
14528
14529 static int pvt_hash_cb(const void *obj, const int flags)
14530 {
14531 const struct chan_iax2_pvt *pvt = obj;
14532
14533 return pvt->peercallno;
14534 }
14535
14536 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14537 {
14538 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14539
14540
14541
14542
14543 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14544 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14545 }
14546
14547 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14548 {
14549 const struct chan_iax2_pvt *pvt = obj;
14550
14551 return pvt->transfercallno;
14552 }
14553
14554 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14555 {
14556 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14557
14558
14559
14560
14561 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14562 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14563 }
14564
14565 static int load_objects(void)
14566 {
14567 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14568 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14569
14570 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14571 goto container_fail;
14572 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14573 goto container_fail;
14574 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14575 goto container_fail;
14576 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14577 goto container_fail;
14578 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14579 goto container_fail;
14580 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14581 goto container_fail;
14582 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14583 goto container_fail;
14584 } else if (create_callno_pools()) {
14585 goto container_fail;
14586 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14587 goto container_fail;
14588 }
14589
14590 return 0;
14591
14592 container_fail:
14593 if (peers) {
14594 ao2_ref(peers, -1);
14595 }
14596 if (users) {
14597 ao2_ref(users, -1);
14598 }
14599 if (iax_peercallno_pvts) {
14600 ao2_ref(iax_peercallno_pvts, -1);
14601 }
14602 if (iax_transfercallno_pvts) {
14603 ao2_ref(iax_transfercallno_pvts, -1);
14604 }
14605 if (peercnts) {
14606 ao2_ref(peercnts, -1);
14607 }
14608 if (callno_limits) {
14609 ao2_ref(callno_limits, -1);
14610 }
14611 if (calltoken_ignores) {
14612 ao2_ref(calltoken_ignores, -1);
14613 }
14614 if (callno_pool) {
14615 ao2_ref(callno_pool, -1);
14616 }
14617 if (callno_pool_trunk) {
14618 ao2_ref(callno_pool_trunk, -1);
14619 }
14620 return AST_MODULE_LOAD_FAILURE;
14621 }
14622
14623
14624 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14625 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14626 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14627 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14628 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14629 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14630 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14631 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14632 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14633 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14634 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14635 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14636 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14637 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14638 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14639 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14640 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14641 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14642 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14643 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14644 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14645 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14646 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14647 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14648 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14649 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14650
14651 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14652
14653 static int peers_data_provider_get(const struct ast_data_search *search,
14654 struct ast_data *data_root)
14655 {
14656 struct ast_data *data_peer;
14657 struct iax2_peer *peer;
14658 struct ao2_iterator i;
14659 char status[20];
14660 struct ast_str *encmethods = ast_str_alloca(256);
14661
14662 i = ao2_iterator_init(peers, 0);
14663 while ((peer = ao2_iterator_next(&i))) {
14664 data_peer = ast_data_add_node(data_root, "peer");
14665 if (!data_peer) {
14666 peer_unref(peer);
14667 continue;
14668 }
14669
14670 ast_data_add_structure(iax2_peer, data_peer, peer);
14671
14672 ast_data_add_codecs(data_peer, "codecs", peer->capability);
14673
14674 peer_status(peer, status, sizeof(status));
14675 ast_data_add_str(data_peer, "status", status);
14676
14677 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14678
14679 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14680
14681 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14682
14683 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14684
14685 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14686
14687 encmethods_to_str(peer->encmethods, &encmethods);
14688 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14689
14690 peer_unref(peer);
14691
14692 if (!ast_data_search_match(search, data_peer)) {
14693 ast_data_remove_node(data_root, data_peer);
14694 }
14695 }
14696 ao2_iterator_destroy(&i);
14697
14698 return 0;
14699 }
14700
14701 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14702 MEMBER(iax2_user, name, AST_DATA_STRING) \
14703 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14704 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14705 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14706 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14707 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14708 MEMBER(iax2_user, language, AST_DATA_STRING) \
14709 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14710 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14711 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14712 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14713 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14714
14715 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14716
14717 static int users_data_provider_get(const struct ast_data_search *search,
14718 struct ast_data *data_root)
14719 {
14720 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14721 struct iax2_user *user;
14722 struct ao2_iterator i;
14723 char auth[90];
14724 char *pstr = "";
14725
14726 i = ao2_iterator_init(users, 0);
14727 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14728 data_user = ast_data_add_node(data_root, "user");
14729 if (!data_user) {
14730 continue;
14731 }
14732
14733 ast_data_add_structure(iax2_user, data_user, user);
14734
14735 ast_data_add_codecs(data_user, "codecs", user->capability);
14736
14737 if (!ast_strlen_zero(user->secret)) {
14738 ast_copy_string(auth, user->secret, sizeof(auth));
14739 } else if (!ast_strlen_zero(user->inkeys)) {
14740 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14741 } else {
14742 ast_copy_string(auth, "no secret", sizeof(auth));
14743 }
14744 ast_data_add_password(data_user, "secret", auth);
14745
14746 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14747
14748
14749 data_authmethods = ast_data_add_node(data_user, "authmethods");
14750 if (!data_authmethods) {
14751 ast_data_remove_node(data_root, data_user);
14752 continue;
14753 }
14754 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14755 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14756 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14757
14758
14759 data_enum_node = ast_data_add_node(data_user, "amaflags");
14760 if (!data_enum_node) {
14761 ast_data_remove_node(data_root, data_user);
14762 continue;
14763 }
14764 ast_data_add_int(data_enum_node, "value", user->amaflags);
14765 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14766
14767 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14768
14769 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14770 pstr = "REQ only";
14771 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14772 pstr = "disabled";
14773 } else {
14774 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14775 }
14776 ast_data_add_str(data_user, "codec-preferences", pstr);
14777
14778 if (!ast_data_search_match(search, data_user)) {
14779 ast_data_remove_node(data_root, data_user);
14780 }
14781 }
14782 ao2_iterator_destroy(&i);
14783
14784 return 0;
14785 }
14786
14787 static const struct ast_data_handler peers_data_provider = {
14788 .version = AST_DATA_HANDLER_VERSION,
14789 .get = peers_data_provider_get
14790 };
14791
14792 static const struct ast_data_handler users_data_provider = {
14793 .version = AST_DATA_HANDLER_VERSION,
14794 .get = users_data_provider_get
14795 };
14796
14797 static const struct ast_data_entry iax2_data_providers[] = {
14798 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14799 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14800 };
14801
14802
14803 static int load_module(void)
14804 {
14805 static const char config[] = "iax.conf";
14806 int x = 0;
14807 struct iax2_registry *reg = NULL;
14808
14809 if (load_objects()) {
14810 return AST_MODULE_LOAD_FAILURE;
14811 }
14812
14813 memset(iaxs, 0, sizeof(iaxs));
14814
14815 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14816 ast_mutex_init(&iaxsl[x]);
14817 }
14818
14819 if (!(sched = ast_sched_thread_create())) {
14820 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14821 return AST_MODULE_LOAD_FAILURE;
14822 }
14823
14824 if (!(io = io_context_create())) {
14825 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14826 sched = ast_sched_thread_destroy(sched);
14827 return AST_MODULE_LOAD_FAILURE;
14828 }
14829
14830 if (!(netsock = ast_netsock_list_alloc())) {
14831 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14832 io_context_destroy(io);
14833 sched = ast_sched_thread_destroy(sched);
14834 return AST_MODULE_LOAD_FAILURE;
14835 }
14836 ast_netsock_init(netsock);
14837
14838 outsock = ast_netsock_list_alloc();
14839 if (!outsock) {
14840 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14841 io_context_destroy(io);
14842 sched = ast_sched_thread_destroy(sched);
14843 return AST_MODULE_LOAD_FAILURE;
14844 }
14845 ast_netsock_init(outsock);
14846
14847 randomcalltokendata = ast_random();
14848
14849 iax_set_output(iax_debug_output);
14850 iax_set_error(iax_error_output);
14851 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14852
14853 if ((timer = ast_timer_open())) {
14854 ast_timer_set_rate(timer, 1000 / trunkfreq);
14855 }
14856
14857 if (set_config(config, 0) == -1) {
14858 if (timer) {
14859 ast_timer_close(timer);
14860 timer = NULL;
14861 }
14862 return AST_MODULE_LOAD_DECLINE;
14863 }
14864
14865 #ifdef TEST_FRAMEWORK
14866 AST_TEST_REGISTER(test_iax2_peers_get);
14867 AST_TEST_REGISTER(test_iax2_users_get);
14868 #endif
14869
14870
14871 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14872 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14873
14874 ast_register_application_xml(papp, iax2_prov_app);
14875
14876 ast_custom_function_register(&iaxpeer_function);
14877 ast_custom_function_register(&iaxvar_function);
14878
14879 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14880 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14881 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14882 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14883
14884 if (ast_channel_register(&iax2_tech)) {
14885 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14886 __unload_module();
14887 return AST_MODULE_LOAD_FAILURE;
14888 }
14889
14890 if (ast_register_switch(&iax2_switch)) {
14891 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14892 }
14893
14894 if (start_network_thread()) {
14895 ast_log(LOG_ERROR, "Unable to start network thread\n");
14896 __unload_module();
14897 return AST_MODULE_LOAD_FAILURE;
14898 } else {
14899 ast_verb(2, "IAX Ready and Listening\n");
14900 }
14901
14902 AST_LIST_LOCK(®istrations);
14903 AST_LIST_TRAVERSE(®istrations, reg, entry)
14904 iax2_do_register(reg);
14905 AST_LIST_UNLOCK(®istrations);
14906
14907 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14908 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14909
14910
14911 reload_firmware(0);
14912 iax_provision_reload(0);
14913
14914 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14915
14916 network_change_event_subscribe();
14917
14918 return AST_MODULE_LOAD_SUCCESS;
14919 }
14920
14921 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
14922 .load = load_module,
14923 .unload = unload_module,
14924 .reload = reload,
14925 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
14926 .nonoptreq = "res_crypto",
14927 );