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: 354429 $")
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 #define SCHED_MULTITHREADED
00228
00229
00230
00231 #define DEBUG_SCHED_MULTITHREAD
00232
00233
00234 #ifdef SO_NO_CHECK
00235 static int nochecksums = 0;
00236 #endif
00237
00238 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00239 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00240
00241 #define DEFAULT_THREAD_COUNT 10
00242 #define DEFAULT_MAX_THREAD_COUNT 100
00243 #define DEFAULT_RETRY_TIME 1000
00244 #define MEMORY_SIZE 100
00245 #define DEFAULT_DROP 3
00246
00247 #define DEBUG_SUPPORT
00248
00249 #define MIN_REUSE_TIME 60
00250
00251
00252 #define GAMMA (0.01)
00253
00254 static struct ast_codec_pref prefs;
00255
00256 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00257
00258
00259
00260
00261 #define MAX_TRUNK_MTU 1240
00262
00263 static int global_max_trunk_mtu;
00264 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00265
00266 #define DEFAULT_CONTEXT "default"
00267
00268 static char default_parkinglot[AST_MAX_CONTEXT];
00269
00270 static char language[MAX_LANGUAGE] = "";
00271 static char regcontext[AST_MAX_CONTEXT] = "";
00272
00273 static struct ast_event_sub *network_change_event_subscription;
00274 static int network_change_event_sched_id = -1;
00275
00276 static int maxauthreq = 3;
00277 static int max_retries = 4;
00278 static int ping_time = 21;
00279 static int lagrq_time = 10;
00280 static int maxjitterbuffer=1000;
00281 static int resyncthreshold=1000;
00282 static int maxjitterinterps=10;
00283 static int jittertargetextra = 40;
00284
00285 #define MAX_TRUNKDATA 640 * 200
00286
00287 static int trunkfreq = 20;
00288 static int trunkmaxsize = MAX_TRUNKDATA;
00289
00290 static int authdebug = 0;
00291 static int autokill = 0;
00292 static int iaxcompat = 0;
00293 static int last_authmethod = 0;
00294
00295 static int iaxdefaultdpcache=10 * 60;
00296
00297 static int iaxdefaulttimeout = 5;
00298
00299 static struct {
00300 unsigned int tos;
00301 unsigned int cos;
00302 } qos = { 0, 0 };
00303
00304 static int min_reg_expire;
00305 static int max_reg_expire;
00306
00307 static int srvlookup = 0;
00308
00309 static struct ast_timer *timer;
00310
00311 static struct ast_netsock_list *netsock;
00312 static struct ast_netsock_list *outsock;
00313 static int defaultsockfd = -1;
00314
00315 static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00316
00317
00318 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00319
00320 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00321 ~ast_format_id_to_old_bitfield(AST_FORMAT_SLINEAR) & \
00322 ~ast_format_id_to_old_bitfield(AST_FORMAT_SLINEAR16) & \
00323 ~ast_format_id_to_old_bitfield(AST_FORMAT_SIREN7) & \
00324 ~ast_format_id_to_old_bitfield(AST_FORMAT_SIREN14) & \
00325 ~ast_format_id_to_old_bitfield(AST_FORMAT_G719) & \
00326 ~ast_format_id_to_old_bitfield(AST_FORMAT_ULAW) & \
00327 ~ast_format_id_to_old_bitfield(AST_FORMAT_ALAW) & \
00328 ~ast_format_id_to_old_bitfield(AST_FORMAT_G722))
00329
00330 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00331 ~ast_format_id_to_old_bitfield(AST_FORMAT_G726) & \
00332 ~ast_format_id_to_old_bitfield(AST_FORMAT_G726_AAL2) & \
00333 ~ast_format_id_to_old_bitfield(AST_FORMAT_ADPCM))
00334
00335 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00336 ~ast_format_id_to_old_bitfield(AST_FORMAT_G723_1))
00337
00338
00339 #define DEFAULT_MAXMS 2000
00340 #define DEFAULT_FREQ_OK 60 * 1000
00341 #define DEFAULT_FREQ_NOTOK 10 * 1000
00342
00343
00344 #define IAX_CALLENCRYPTED(pvt) \
00345 (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
00346
00347 #define IAX_DEBUGDIGEST(msg, key) do { \
00348 int idx; \
00349 char digest[33] = ""; \
00350 \
00351 if (!iaxdebug) \
00352 break; \
00353 \
00354 for (idx = 0; idx < 16; idx++) \
00355 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00356 \
00357 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00358 } while(0)
00359
00360 static struct io_context *io;
00361 static struct ast_sched_context *sched;
00362
00363 #define DONT_RESCHEDULE -2
00364
00365 static iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00366
00367 static int iaxdebug = 0;
00368
00369 static int iaxtrunkdebug = 0;
00370
00371 static int test_losspct = 0;
00372 #ifdef IAXTESTS
00373 static int test_late = 0;
00374 static int test_resync = 0;
00375 static int test_jit = 0;
00376 static int test_jitpct = 0;
00377 #endif
00378
00379 static char accountcode[AST_MAX_ACCOUNT_CODE];
00380 static char mohinterpret[MAX_MUSICCLASS];
00381 static char mohsuggest[MAX_MUSICCLASS];
00382 static int amaflags = 0;
00383 static int adsi = 0;
00384 static int delayreject = 0;
00385 static int iax2_encryption = 0;
00386
00387 static struct ast_flags64 globalflags = { 0 };
00388
00389 static pthread_t netthreadid = AST_PTHREADT_NULL;
00390
00391 enum iax2_state {
00392 IAX_STATE_STARTED = (1 << 0),
00393 IAX_STATE_AUTHENTICATED = (1 << 1),
00394 IAX_STATE_TBD = (1 << 2),
00395 };
00396
00397 struct iax2_context {
00398 char context[AST_MAX_CONTEXT];
00399 struct iax2_context *next;
00400 };
00401
00402
00403 #define IAX_HASCALLERID (uint64_t)(1 << 0)
00404 #define IAX_DELME (uint64_t)(1 << 1)
00405 #define IAX_TEMPONLY (uint64_t)(1 << 2)
00406 #define IAX_TRUNK (uint64_t)(1 << 3)
00407 #define IAX_NOTRANSFER (uint64_t)(1 << 4)
00408 #define IAX_USEJITTERBUF (uint64_t)(1 << 5)
00409 #define IAX_DYNAMIC (uint64_t)(1 << 6)
00410 #define IAX_SENDANI (uint64_t)(1 << 7)
00411 #define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8)
00412 #define IAX_ALREADYGONE (uint64_t)(1 << 9)
00413 #define IAX_PROVISION (uint64_t)(1 << 10)
00414 #define IAX_QUELCH (uint64_t)(1 << 11)
00415 #define IAX_ENCRYPTED (uint64_t)(1 << 12)
00416 #define IAX_KEYPOPULATED (uint64_t)(1 << 13)
00417 #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14)
00418 #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15)
00419 #define IAX_CODEC_NOCAP (uint64_t)(1 << 16)
00420 #define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17)
00421 #define IAX_RTUPDATE (uint64_t)(1 << 18)
00422 #define IAX_RTAUTOCLEAR (uint64_t)(1 << 19)
00423 #define IAX_FORCEJITTERBUF (uint64_t)(1 << 20)
00424 #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21)
00425 #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22)
00426 #define IAX_TRANSFERMEDIA (uint64_t)(1 << 23)
00427 #define IAX_MAXAUTHREQ (uint64_t)(1 << 24)
00428 #define IAX_DELAYPBXSTART (uint64_t)(1 << 25)
00429 #define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26)
00430 #define IAX_IMMEDIATE (uint64_t)(1 << 27)
00431 #define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28)
00432 #define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29)
00433 #define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30)
00434 #define IAX_SHRINKCALLERID (uint64_t)(1 << 31)
00435 static int global_rtautoclear = 120;
00436
00437 static int reload_config(void);
00438
00439
00440
00441
00442 enum calltoken_peer_enum {
00443
00444 CALLTOKEN_DEFAULT = 0,
00445
00446 CALLTOKEN_YES = 1,
00447
00448
00449 CALLTOKEN_AUTO = 2,
00450
00451 CALLTOKEN_NO = 3,
00452 };
00453
00454 struct iax2_user {
00455 AST_DECLARE_STRING_FIELDS(
00456 AST_STRING_FIELD(name);
00457 AST_STRING_FIELD(secret);
00458 AST_STRING_FIELD(dbsecret);
00459 AST_STRING_FIELD(accountcode);
00460 AST_STRING_FIELD(mohinterpret);
00461 AST_STRING_FIELD(mohsuggest);
00462 AST_STRING_FIELD(inkeys);
00463 AST_STRING_FIELD(language);
00464 AST_STRING_FIELD(cid_num);
00465 AST_STRING_FIELD(cid_name);
00466 AST_STRING_FIELD(parkinglot);
00467 );
00468
00469 int authmethods;
00470 int encmethods;
00471 int amaflags;
00472 int adsi;
00473 uint64_t flags;
00474 iax2_format capability;
00475 int maxauthreq;
00476 int curauthreq;
00477 struct ast_codec_pref prefs;
00478 struct ast_ha *ha;
00479 struct iax2_context *contexts;
00480 struct ast_variable *vars;
00481 enum calltoken_peer_enum calltoken_required;
00482 };
00483
00484 struct iax2_peer {
00485 AST_DECLARE_STRING_FIELDS(
00486 AST_STRING_FIELD(name);
00487 AST_STRING_FIELD(username);
00488 AST_STRING_FIELD(description);
00489 AST_STRING_FIELD(secret);
00490 AST_STRING_FIELD(dbsecret);
00491 AST_STRING_FIELD(outkey);
00492
00493 AST_STRING_FIELD(regexten);
00494 AST_STRING_FIELD(context);
00495 AST_STRING_FIELD(peercontext);
00496 AST_STRING_FIELD(mailbox);
00497 AST_STRING_FIELD(mohinterpret);
00498 AST_STRING_FIELD(mohsuggest);
00499 AST_STRING_FIELD(inkeys);
00500
00501 AST_STRING_FIELD(cid_num);
00502 AST_STRING_FIELD(cid_name);
00503 AST_STRING_FIELD(zonetag);
00504 AST_STRING_FIELD(parkinglot);
00505 );
00506 struct ast_codec_pref prefs;
00507 struct ast_dnsmgr_entry *dnsmgr;
00508 struct ast_sockaddr addr;
00509 int formats;
00510 int sockfd;
00511 struct in_addr mask;
00512 int adsi;
00513 uint64_t flags;
00514
00515
00516 struct sockaddr_in defaddr;
00517 int authmethods;
00518 int encmethods;
00519
00520 int expire;
00521 int expiry;
00522 iax2_format capability;
00523
00524
00525 int callno;
00526 int pokeexpire;
00527 int lastms;
00528 int maxms;
00529
00530 int pokefreqok;
00531 int pokefreqnotok;
00532 int historicms;
00533 int smoothing;
00534 uint16_t maxcallno;
00535
00536 struct ast_event_sub *mwi_event_sub;
00537
00538 struct ast_ha *ha;
00539 enum calltoken_peer_enum calltoken_required;
00540 };
00541
00542 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00543
00544 struct iax2_trunk_peer {
00545 ast_mutex_t lock;
00546 int sockfd;
00547 struct sockaddr_in addr;
00548 struct timeval txtrunktime;
00549 struct timeval rxtrunktime;
00550 struct timeval lasttxtime;
00551 struct timeval trunkact;
00552 unsigned int lastsent;
00553
00554 unsigned char *trunkdata;
00555 unsigned int trunkdatalen;
00556 unsigned int trunkdataalloc;
00557 int trunkmaxmtu;
00558 int trunkerror;
00559 int calls;
00560 AST_LIST_ENTRY(iax2_trunk_peer) list;
00561 };
00562
00563 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00564
00565 struct iax_firmware {
00566 AST_LIST_ENTRY(iax_firmware) list;
00567 int fd;
00568 int mmaplen;
00569 int dead;
00570 struct ast_iax2_firmware_header *fwh;
00571 unsigned char *buf;
00572 };
00573
00574 enum iax_reg_state {
00575 REG_STATE_UNREGISTERED = 0,
00576 REG_STATE_REGSENT,
00577 REG_STATE_AUTHSENT,
00578 REG_STATE_REGISTERED,
00579 REG_STATE_REJECTED,
00580 REG_STATE_TIMEOUT,
00581 REG_STATE_NOAUTH
00582 };
00583
00584 enum iax_transfer_state {
00585 TRANSFER_NONE = 0,
00586 TRANSFER_BEGIN,
00587 TRANSFER_READY,
00588 TRANSFER_RELEASED,
00589 TRANSFER_PASSTHROUGH,
00590 TRANSFER_MBEGIN,
00591 TRANSFER_MREADY,
00592 TRANSFER_MRELEASED,
00593 TRANSFER_MPASSTHROUGH,
00594 TRANSFER_MEDIA,
00595 TRANSFER_MEDIAPASS
00596 };
00597
00598 struct iax2_registry {
00599 struct ast_sockaddr addr;
00600 char username[80];
00601 char secret[80];
00602 int expire;
00603 int refresh;
00604 enum iax_reg_state regstate;
00605 int messages;
00606 int callno;
00607 struct sockaddr_in us;
00608 struct ast_dnsmgr_entry *dnsmgr;
00609 AST_LIST_ENTRY(iax2_registry) entry;
00610 };
00611
00612 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00613
00614
00615 #define MIN_RETRY_TIME 100
00616 #define MAX_RETRY_TIME 10000
00617
00618 #define MAX_JITTER_BUFFER 50
00619 #define MIN_JITTER_BUFFER 10
00620
00621 #define DEFAULT_TRUNKDATA 640 * 10
00622
00623 #define MAX_TIMESTAMP_SKEW 160
00624
00625
00626 #define TS_GAP_FOR_JB_RESYNC 5000
00627
00628
00629 #define MARK_IAX_SUBCLASS_TX 0x8000
00630
00631 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00632 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00633 static int iaxdynamicthreadcount = 0;
00634 static int iaxdynamicthreadnum = 0;
00635 static int iaxactivethreadcount = 0;
00636
00637 struct iax_rr {
00638 int jitter;
00639 int losspct;
00640 int losscnt;
00641 int packets;
00642 int delay;
00643 int dropped;
00644 int ooo;
00645 };
00646
00647 struct iax2_pvt_ref;
00648
00649 struct chan_iax2_pvt {
00650
00651 int sockfd;
00652
00653 iax2_format voiceformat;
00654
00655 iax2_format videoformat;
00656
00657 iax2_format svoiceformat;
00658
00659 iax2_format svideoformat;
00660
00661 iax2_format capability;
00662
00663 unsigned int last;
00664
00665 unsigned int lastsent;
00666
00667 unsigned int lastvsent;
00668
00669 unsigned int nextpred;
00670
00671 int first_iax_message;
00672
00673 int last_iax_message;
00674
00675 unsigned int notsilenttx:1;
00676
00677 unsigned int pingtime;
00678
00679 int maxtime;
00680
00681 struct sockaddr_in addr;
00682
00683 struct ast_codec_pref prefs;
00684
00685 struct ast_codec_pref rprefs;
00686
00687 unsigned short callno;
00688
00689 struct callno_entry *callno_entry;
00690
00691 unsigned short peercallno;
00692
00693
00694
00695 iax2_format chosenformat;
00696
00697 iax2_format peerformat;
00698
00699 iax2_format peercapability;
00700
00701 struct timeval offset;
00702
00703 struct timeval rxcore;
00704
00705 jitterbuf *jb;
00706
00707 int jbid;
00708
00709 int lag;
00710
00711 int error;
00712
00713 struct ast_channel *owner;
00714
00715 struct ast_flags state;
00716
00717 int expiry;
00718
00719 unsigned char oseqno;
00720
00721 unsigned char rseqno;
00722
00723 unsigned char iseqno;
00724
00725 unsigned char aseqno;
00726
00727 AST_DECLARE_STRING_FIELDS(
00728
00729 AST_STRING_FIELD(peer);
00730
00731 AST_STRING_FIELD(context);
00732
00733 AST_STRING_FIELD(cid_num);
00734 AST_STRING_FIELD(cid_name);
00735
00736 AST_STRING_FIELD(ani);
00737
00738 AST_STRING_FIELD(dnid);
00739
00740 AST_STRING_FIELD(rdnis);
00741
00742 AST_STRING_FIELD(exten);
00743
00744 AST_STRING_FIELD(username);
00745
00746 AST_STRING_FIELD(secret);
00747
00748 AST_STRING_FIELD(challenge);
00749
00750 AST_STRING_FIELD(inkeys);
00751
00752 AST_STRING_FIELD(outkey);
00753
00754 AST_STRING_FIELD(language);
00755
00756 AST_STRING_FIELD(host);
00757
00758 AST_STRING_FIELD(dproot);
00759 AST_STRING_FIELD(accountcode);
00760 AST_STRING_FIELD(mohinterpret);
00761 AST_STRING_FIELD(mohsuggest);
00762
00763 AST_STRING_FIELD(osptoken);
00764
00765 AST_STRING_FIELD(parkinglot);
00766 );
00767
00768 int authrej;
00769
00770 int authmethods;
00771
00772 int encmethods;
00773
00774 ast_aes_encrypt_key ecx;
00775
00776 ast_aes_decrypt_key mydcx;
00777
00778 ast_aes_decrypt_key dcx;
00779
00780
00781 int keyrotateid;
00782
00783 unsigned char semirand[32];
00784
00785 struct iax2_registry *reg;
00786
00787 struct iax2_peer *peerpoke;
00788
00789 uint64_t flags;
00790 int adsi;
00791
00792
00793 enum iax_transfer_state transferring;
00794
00795 int transferid;
00796
00797 struct sockaddr_in transfer;
00798
00799 unsigned short transfercallno;
00800
00801 ast_aes_encrypt_key tdcx;
00802
00803
00804 int peeradsicpe;
00805
00806
00807 unsigned short bridgecallno;
00808
00809 int pingid;
00810 int lagid;
00811 int autoid;
00812 int authid;
00813 int authfail;
00814 int initid;
00815 int calling_ton;
00816 int calling_tns;
00817 int calling_pres;
00818 int amaflags;
00819 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00820
00821 struct ast_variable *vars;
00822
00823 struct ast_variable *iaxvars;
00824
00825 struct iax_rr remote_rr;
00826
00827 int min;
00828
00829 int frames_dropped;
00830
00831 int frames_received;
00832
00833 unsigned char calltoken_ie_len;
00834
00835 char hold_signaling;
00836
00837 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00838 };
00839
00840 struct signaling_queue_entry {
00841 struct ast_frame f;
00842 AST_LIST_ENTRY(signaling_queue_entry) next;
00843 };
00844
00845
00846 static struct ao2_container *callno_pool;
00847
00848
00849 static struct ao2_container *callno_pool_trunk;
00850
00851 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862 static AST_LIST_HEAD_NOLOCK(, iax_frame) frame_queue[IAX_MAX_CALLS + 1];
00863
00864 static struct ast_taskprocessor *transmit_processor;
00865
00866 static int randomcalltokendata;
00867
00868 static const time_t MAX_CALLTOKEN_DELAY = 10;
00869
00870
00871
00872
00873
00874
00875
00876
00877 #ifdef LOW_MEMORY
00878 #define MAX_PEER_BUCKETS 17
00879 #else
00880 #define MAX_PEER_BUCKETS 563
00881 #endif
00882 static struct ao2_container *peers;
00883
00884 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00885 static struct ao2_container *users;
00886
00887
00888 static struct ao2_container *peercnts;
00889
00890
00891 static struct ao2_container *callno_limits;
00892
00893
00894 static struct ao2_container *calltoken_ignores;
00895
00896 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00897
00898 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00899
00900 static uint16_t global_maxcallno;
00901
00902
00903 static uint16_t global_maxcallno_nonval;
00904
00905 static uint16_t total_nonval_callno_used = 0;
00906
00907
00908
00909 struct peercnt {
00910
00911 unsigned long addr;
00912
00913 uint16_t cur;
00914
00915 uint16_t limit;
00916
00917
00918 unsigned char reg;
00919 };
00920
00921
00922 struct addr_range {
00923
00924 struct ast_ha ha;
00925
00926 uint16_t limit;
00927
00928 unsigned char delme;
00929 };
00930
00931 struct callno_entry {
00932
00933 uint16_t callno;
00934
00935 unsigned char validated;
00936 };
00937
00938 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00939
00940 enum {
00941
00942 CACHE_FLAG_EXISTS = (1 << 0),
00943
00944 CACHE_FLAG_NONEXISTENT = (1 << 1),
00945
00946 CACHE_FLAG_CANEXIST = (1 << 2),
00947
00948 CACHE_FLAG_PENDING = (1 << 3),
00949
00950 CACHE_FLAG_TIMEOUT = (1 << 4),
00951
00952 CACHE_FLAG_TRANSMITTED = (1 << 5),
00953
00954 CACHE_FLAG_UNKNOWN = (1 << 6),
00955
00956 CACHE_FLAG_MATCHMORE = (1 << 7),
00957 };
00958
00959 struct iax2_dpcache {
00960 char peercontext[AST_MAX_CONTEXT];
00961 char exten[AST_MAX_EXTENSION];
00962 struct timeval orig;
00963 struct timeval expiry;
00964 int flags;
00965 unsigned short callno;
00966 int waiters[256];
00967 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00968 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00969 };
00970
00971 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00972
00973 static void reg_source_db(struct iax2_peer *p);
00974 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00975 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00976
00977 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00978 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags);
00979 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00980
00981 enum iax2_thread_iostate {
00982 IAX_IOSTATE_IDLE,
00983 IAX_IOSTATE_READY,
00984 IAX_IOSTATE_PROCESSING,
00985 IAX_IOSTATE_SCHEDREADY,
00986 };
00987
00988 enum iax2_thread_type {
00989 IAX_THREAD_TYPE_POOL,
00990 IAX_THREAD_TYPE_DYNAMIC,
00991 };
00992
00993 struct iax2_pkt_buf {
00994 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00995 size_t len;
00996 unsigned char buf[1];
00997 };
00998
00999 struct iax2_thread {
01000 AST_LIST_ENTRY(iax2_thread) list;
01001 enum iax2_thread_type type;
01002 enum iax2_thread_iostate iostate;
01003 #ifdef SCHED_MULTITHREADED
01004 void (*schedfunc)(const void *);
01005 const void *scheddata;
01006 #endif
01007 #ifdef DEBUG_SCHED_MULTITHREAD
01008 char curfunc[80];
01009 #endif
01010 int actions;
01011 pthread_t threadid;
01012 int threadnum;
01013 struct sockaddr_in iosin;
01014 unsigned char readbuf[4096];
01015 unsigned char *buf;
01016 ssize_t buf_len;
01017 size_t buf_size;
01018 int iofd;
01019 time_t checktime;
01020 ast_mutex_t lock;
01021 ast_cond_t cond;
01022 ast_mutex_t init_lock;
01023 ast_cond_t init_cond;
01024
01025
01026
01027
01028 struct {
01029 unsigned short callno;
01030 struct sockaddr_in sin;
01031 unsigned char type;
01032 unsigned char csub;
01033 } ffinfo;
01034
01035
01036
01037 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
01038 unsigned char stop;
01039 };
01040
01041
01042 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
01043 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
01044 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
01045
01046 static void *iax2_process_thread(void *data);
01047 static void iax2_destroy(int callno);
01048
01049 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
01050 {
01051 ast_mutex_lock(lock);
01052 ast_cond_signal(cond);
01053 ast_mutex_unlock(lock);
01054 }
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS + 1];
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075 static struct ao2_container *iax_peercallno_pvts;
01076
01077
01078
01079
01080
01081
01082
01083
01084 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
01085
01086
01087
01088
01089
01090
01091 static struct ao2_container *iax_transfercallno_pvts;
01092
01093
01094
01095 #define TRUNK_CALL_START IAX_MAX_CALLS / 2
01096
01097
01098 static struct sockaddr_in debugaddr;
01099
01100 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
01101 {
01102 if (iaxdebug ||
01103 (sin && debugaddr.sin_addr.s_addr &&
01104 (!ntohs(debugaddr.sin_port) ||
01105 debugaddr.sin_port == sin->sin_port) &&
01106 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01107 if (iaxdebug) {
01108 iax_showframe(f, fhi, rx, sin, datalen);
01109 } else {
01110 iaxdebug = 1;
01111 iax_showframe(f, fhi, rx, sin, datalen);
01112 iaxdebug = 0;
01113 }
01114 }
01115 }
01116
01117 static void iax_debug_output(const char *data)
01118 {
01119 if (iaxdebug)
01120 ast_verbose("%s", data);
01121 }
01122
01123 static void iax_error_output(const char *data)
01124 {
01125 ast_log(LOG_WARNING, "%s", data);
01126 }
01127
01128 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
01129 {
01130 va_list args;
01131 char buf[1024];
01132
01133 va_start(args, fmt);
01134 vsnprintf(buf, sizeof(buf), fmt, args);
01135 va_end(args);
01136
01137 ast_log(LOG_ERROR, "%s", buf);
01138 }
01139
01140 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01141 {
01142 va_list args;
01143 char buf[1024];
01144
01145 va_start(args, fmt);
01146 vsnprintf(buf, sizeof(buf), fmt, args);
01147 va_end(args);
01148
01149 ast_log(LOG_WARNING, "%s", buf);
01150 }
01151
01152 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01153 {
01154 va_list args;
01155 char buf[1024];
01156
01157 va_start(args, fmt);
01158 vsnprintf(buf, sizeof(buf), fmt, args);
01159 va_end(args);
01160
01161 ast_verbose("%s", buf);
01162 }
01163
01164 static int maxtrunkcall = TRUNK_CALL_START;
01165 static int maxnontrunkcall = 1;
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, const char *dest, int timeout);
01171 static int iax2_devicestate(const char *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_context *sched, 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, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *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 struct ast_channel_tech iax2_tech = {
01217 .type = "IAX2",
01218 .description = tdesc,
01219 .properties = AST_CHAN_TP_WANTSJITTER,
01220 .requester = iax2_request,
01221 .devicestate = iax2_devicestate,
01222 .send_digit_begin = iax2_digit_begin,
01223 .send_digit_end = iax2_digit_end,
01224 .send_text = iax2_sendtext,
01225 .send_image = iax2_sendimage,
01226 .send_html = iax2_sendhtml,
01227 .call = iax2_call,
01228 .hangup = iax2_hangup,
01229 .answer = iax2_answer,
01230 .read = iax2_read,
01231 .write = iax2_write,
01232 .write_video = iax2_write,
01233 .indicate = iax2_indicate,
01234 .setoption = iax2_setoption,
01235 .queryoption = iax2_queryoption,
01236 .bridge = iax2_bridge,
01237 .transfer = iax2_transfer,
01238 .fixup = iax2_fixup,
01239 .func_channel_read = acf_channel_read,
01240 };
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259 static void iax2_lock_owner(int callno)
01260 {
01261 for (;;) {
01262 if (!iaxs[callno] || !iaxs[callno]->owner) {
01263
01264 break;
01265 }
01266 if (!ast_channel_trylock(iaxs[callno]->owner)) {
01267
01268 break;
01269 }
01270
01271 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01272 }
01273 }
01274
01275 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01276 {
01277
01278
01279
01280 }
01281
01282 static void network_change_event_subscribe(void)
01283 {
01284 if (!network_change_event_subscription) {
01285 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE,
01286 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END);
01287 }
01288 }
01289
01290 static void network_change_event_unsubscribe(void)
01291 {
01292 if (network_change_event_subscription) {
01293 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription);
01294 }
01295 }
01296
01297 static int network_change_event_sched_cb(const void *data)
01298 {
01299 struct iax2_registry *reg;
01300 network_change_event_sched_id = -1;
01301 AST_LIST_LOCK(®istrations);
01302 AST_LIST_TRAVERSE(®istrations, reg, entry) {
01303 iax2_do_register(reg);
01304 }
01305 AST_LIST_UNLOCK(®istrations);
01306
01307 return 0;
01308 }
01309
01310 static void network_change_event_cb(const struct ast_event *event, void *userdata)
01311 {
01312 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n");
01313 if (network_change_event_sched_id == -1) {
01314 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
01315 }
01316
01317 }
01318
01319
01320
01321
01322 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01323 {
01324 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01325 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01326 pvt->owner ? ast_channel_name(pvt->owner) : "",
01327 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01328 }
01329
01330 static struct ast_datastore_info iax2_variable_datastore_info = {
01331 .type = "IAX2_VARIABLE",
01332 .duplicate = iax2_dup_variable_datastore,
01333 .destroy = iax2_free_variable_datastore,
01334 };
01335
01336 static void *iax2_dup_variable_datastore(void *old)
01337 {
01338 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01339 struct ast_var_t *oldvar, *newvar;
01340
01341 newlist = ast_calloc(sizeof(*newlist), 1);
01342 if (!newlist) {
01343 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01344 return NULL;
01345 }
01346
01347 AST_LIST_HEAD_INIT(newlist);
01348 AST_LIST_LOCK(oldlist);
01349 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01350 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01351 if (newvar)
01352 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01353 else
01354 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01355 }
01356 AST_LIST_UNLOCK(oldlist);
01357 return newlist;
01358 }
01359
01360 static void iax2_free_variable_datastore(void *old)
01361 {
01362 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01363 struct ast_var_t *oldvar;
01364
01365 AST_LIST_LOCK(oldlist);
01366 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01367 ast_free(oldvar);
01368 }
01369 AST_LIST_UNLOCK(oldlist);
01370 AST_LIST_HEAD_DESTROY(oldlist);
01371 ast_free(oldlist);
01372 }
01373
01374
01375
01376
01377
01378 static void insert_idle_thread(struct iax2_thread *thread)
01379 {
01380 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01381 AST_LIST_LOCK(&dynamic_list);
01382 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01383 AST_LIST_UNLOCK(&dynamic_list);
01384 } else {
01385 AST_LIST_LOCK(&idle_list);
01386 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01387 AST_LIST_UNLOCK(&idle_list);
01388 }
01389
01390 return;
01391 }
01392
01393 static struct iax2_thread *find_idle_thread(void)
01394 {
01395 struct iax2_thread *thread = NULL;
01396
01397
01398 AST_LIST_LOCK(&idle_list);
01399 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01400 AST_LIST_UNLOCK(&idle_list);
01401
01402
01403 if (thread) {
01404 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01405 return thread;
01406 }
01407
01408
01409 AST_LIST_LOCK(&dynamic_list);
01410 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01411 AST_LIST_UNLOCK(&dynamic_list);
01412
01413
01414 if (thread) {
01415 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01416 return thread;
01417 }
01418
01419
01420 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01421 return NULL;
01422
01423
01424 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01425 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01426 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01427
01428
01429 ast_mutex_init(&thread->lock);
01430 ast_cond_init(&thread->cond, NULL);
01431 ast_mutex_init(&thread->init_lock);
01432 ast_cond_init(&thread->init_cond, NULL);
01433 ast_mutex_lock(&thread->init_lock);
01434
01435
01436 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01437 ast_cond_destroy(&thread->cond);
01438 ast_mutex_destroy(&thread->lock);
01439 ast_mutex_unlock(&thread->init_lock);
01440 ast_cond_destroy(&thread->init_cond);
01441 ast_mutex_destroy(&thread->init_lock);
01442 ast_free(thread);
01443 return NULL;
01444 }
01445
01446
01447
01448 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01449
01450
01451 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01452
01453
01454 ast_mutex_unlock(&thread->init_lock);
01455
01456 return thread;
01457 }
01458
01459 #ifdef SCHED_MULTITHREADED
01460 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01461 {
01462 struct iax2_thread *thread = NULL;
01463 static time_t lasterror;
01464 static time_t t;
01465
01466 thread = find_idle_thread();
01467
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 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01481 lasterror = t;
01482
01483 return -1;
01484 }
01485 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01486 #endif
01487
01488 static int iax2_sched_replace(int id, struct ast_sched_context *con, int when,
01489 ast_sched_cb callback, const void *data)
01490 {
01491 return ast_sched_replace(id, con, when, callback, data);
01492 }
01493
01494 static int iax2_sched_add(struct ast_sched_context *con, int when,
01495 ast_sched_cb callback, const void *data)
01496 {
01497 return ast_sched_add(con, when, callback, data);
01498 }
01499
01500 static int send_ping(const void *data);
01501
01502 static void __send_ping(const void *data)
01503 {
01504 int callno = (long) data;
01505
01506 ast_mutex_lock(&iaxsl[callno]);
01507
01508 if (iaxs[callno]) {
01509 if (iaxs[callno]->peercallno) {
01510 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01511 if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01512 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01513 }
01514 }
01515 } else {
01516 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01517 }
01518
01519 ast_mutex_unlock(&iaxsl[callno]);
01520 }
01521
01522 static int send_ping(const void *data)
01523 {
01524 int callno = (long) data;
01525 ast_mutex_lock(&iaxsl[callno]);
01526 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01527 iaxs[callno]->pingid = -1;
01528 }
01529 ast_mutex_unlock(&iaxsl[callno]);
01530
01531 #ifdef SCHED_MULTITHREADED
01532 if (schedule_action(__send_ping, data))
01533 #endif
01534 __send_ping(data);
01535
01536 return 0;
01537 }
01538
01539 static void encmethods_to_str(int e, struct ast_str *buf)
01540 {
01541 ast_str_set(&buf, 0, "(");
01542 if (e & IAX_ENCRYPT_AES128) {
01543 ast_str_append(&buf, 0, "aes128");
01544 }
01545 if (e & IAX_ENCRYPT_KEYROTATE) {
01546 ast_str_append(&buf, 0, ",keyrotate");
01547 }
01548 if (ast_str_strlen(buf) > 1) {
01549 ast_str_append(&buf, 0, ")");
01550 } else {
01551 ast_str_set(&buf, 0, "No");
01552 }
01553 }
01554
01555 static int get_encrypt_methods(const char *s)
01556 {
01557 int e;
01558 if (!strcasecmp(s, "aes128"))
01559 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01560 else if (ast_true(s))
01561 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01562 else
01563 e = 0;
01564 return e;
01565 }
01566
01567 static int send_lagrq(const void *data);
01568
01569 static void __send_lagrq(const void *data)
01570 {
01571 int callno = (long) data;
01572
01573 ast_mutex_lock(&iaxsl[callno]);
01574
01575 if (iaxs[callno]) {
01576 if (iaxs[callno]->peercallno) {
01577 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01578 if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01579 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01580 }
01581 }
01582 } else {
01583 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01584 }
01585
01586 ast_mutex_unlock(&iaxsl[callno]);
01587 }
01588
01589 static int send_lagrq(const void *data)
01590 {
01591 int callno = (long) data;
01592 ast_mutex_lock(&iaxsl[callno]);
01593 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01594 iaxs[callno]->lagid = -1;
01595 }
01596 ast_mutex_unlock(&iaxsl[callno]);
01597
01598 #ifdef SCHED_MULTITHREADED
01599 if (schedule_action(__send_lagrq, data))
01600 #endif
01601 __send_lagrq(data);
01602 return 0;
01603 }
01604
01605 static unsigned char compress_subclass(iax2_format subclass)
01606 {
01607 int x;
01608 int power=-1;
01609
01610 if (subclass < IAX_FLAG_SC_LOG)
01611 return subclass;
01612
01613 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01614 if (subclass & (1LL << x)) {
01615 if (power > -1) {
01616 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
01617 return 0;
01618 } else
01619 power = x;
01620 }
01621 }
01622 return power | IAX_FLAG_SC_LOG;
01623 }
01624
01625 static iax2_format uncompress_subclass(unsigned char csub)
01626 {
01627
01628 if (csub & IAX_FLAG_SC_LOG) {
01629
01630 if (csub == 0xff)
01631 return -1;
01632 else
01633 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01634 }
01635 else
01636 return csub;
01637 }
01638
01639 static iax2_format iax2_codec_choose(struct ast_codec_pref *pref, iax2_format formats, int find_best)
01640 {
01641 struct ast_format_cap *cap;
01642 struct ast_format tmpfmt;
01643 iax2_format format = 0;
01644 if ((cap = ast_format_cap_alloc_nolock())) {
01645 ast_format_clear(&tmpfmt);
01646 ast_format_cap_from_old_bitfield(cap, formats);
01647 ast_codec_choose(pref, cap, find_best, &tmpfmt);
01648 format = ast_format_to_old_bitfield(&tmpfmt);
01649 cap = ast_format_cap_destroy(cap);
01650 }
01651
01652 return format;
01653 }
01654
01655 static iax2_format iax2_best_codec(iax2_format formats)
01656 {
01657 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01658 struct ast_format tmpfmt;
01659 if (!cap) {
01660 return 0;
01661 }
01662
01663 ast_format_clear(&tmpfmt);
01664 ast_format_cap_from_old_bitfield(cap, formats);
01665 ast_best_codec(cap, &tmpfmt);
01666 cap = ast_format_cap_destroy(cap);
01667 return ast_format_to_old_bitfield(&tmpfmt);
01668 }
01669
01670 const char *iax2_getformatname(iax2_format format)
01671 {
01672 struct ast_format tmpfmt;
01673 if (!(ast_format_from_old_bitfield(&tmpfmt, format))) {
01674 return "Unknown";
01675 }
01676
01677 return ast_getformatname(&tmpfmt);
01678 }
01679
01680 static char *iax2_getformatname_multiple(char *codec_buf, size_t len, iax2_format format)
01681 {
01682 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01683
01684 if (!cap) {
01685 return "(Nothing)";
01686 }
01687 ast_format_cap_from_old_bitfield(cap, format);
01688 ast_getformatname_multiple(codec_buf, len, cap);
01689 cap = ast_format_cap_destroy(cap);
01690
01691 return codec_buf;
01692 }
01693
01694 static int iax2_parse_allow_disallow(struct ast_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
01695 {
01696 int res;
01697 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01698 if (!cap) {
01699 return 1;
01700 }
01701
01702 ast_format_cap_from_old_bitfield(cap, *formats);
01703 res = ast_parse_allow_disallow(pref, cap, list, allowing);
01704 *formats = ast_format_cap_to_old_bitfield(cap);
01705 cap = ast_format_cap_destroy(cap);
01706
01707 return res;
01708 }
01709
01710 static int iax2_data_add_codecs(struct ast_data *root, const char *node_name, iax2_format formats)
01711 {
01712 int res;
01713 struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
01714 if (!cap) {
01715 return -1;
01716 }
01717 ast_format_cap_from_old_bitfield(cap, formats);
01718 res = ast_data_add_codecs(root, node_name, cap);
01719 cap = ast_format_cap_destroy(cap);
01720 return res;
01721 }
01722
01723
01724
01725
01726 static int peer_hash_cb(const void *obj, const int flags)
01727 {
01728 const struct iax2_peer *peer = obj;
01729 const char *name = obj;
01730
01731 return ast_str_hash(flags & OBJ_KEY ? name : peer->name);
01732 }
01733
01734
01735
01736
01737 static int peer_cmp_cb(void *obj, void *arg, int flags)
01738 {
01739 struct iax2_peer *peer = obj, *peer2 = arg;
01740 const char *name = arg;
01741
01742 return !strcmp(peer->name, flags & OBJ_KEY ? name : peer2->name) ?
01743 CMP_MATCH | CMP_STOP : 0;
01744 }
01745
01746
01747
01748
01749 static int user_hash_cb(const void *obj, const int flags)
01750 {
01751 const struct iax2_user *user = obj;
01752 const char *name = obj;
01753
01754 return ast_str_hash(flags & OBJ_KEY ? name : user->name);
01755 }
01756
01757
01758
01759
01760 static int user_cmp_cb(void *obj, void *arg, int flags)
01761 {
01762 struct iax2_user *user = obj, *user2 = arg;
01763 const char *name = arg;
01764
01765 return !strcmp(user->name, flags & OBJ_KEY ? name : user2->name) ?
01766 CMP_MATCH | CMP_STOP : 0;
01767 }
01768
01769
01770
01771
01772
01773 static struct iax2_peer *find_peer(const char *name, int realtime)
01774 {
01775 struct iax2_peer *peer = NULL;
01776
01777 peer = ao2_find(peers, name, OBJ_KEY);
01778
01779
01780 if(!peer && realtime)
01781 peer = realtime_peer(name, NULL);
01782
01783 return peer;
01784 }
01785
01786 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01787 {
01788 ao2_ref(peer, +1);
01789 return peer;
01790 }
01791
01792 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01793 {
01794 ao2_ref(peer, -1);
01795 return NULL;
01796 }
01797
01798 static struct iax2_user *find_user(const char *name)
01799 {
01800 return ao2_find(users, name, OBJ_KEY);
01801 }
01802 static inline struct iax2_user *user_ref(struct iax2_user *user)
01803 {
01804 ao2_ref(user, +1);
01805 return user;
01806 }
01807
01808 static inline struct iax2_user *user_unref(struct iax2_user *user)
01809 {
01810 ao2_ref(user, -1);
01811 return NULL;
01812 }
01813
01814 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01815 {
01816 struct iax2_peer *peer = NULL;
01817 int res = 0;
01818 struct ao2_iterator i;
01819
01820 i = ao2_iterator_init(peers, 0);
01821 while ((peer = ao2_iterator_next(&i))) {
01822 struct sockaddr_in peer_addr;
01823
01824 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
01825
01826 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01827 (peer_addr.sin_port == sin.sin_port)) {
01828 ast_copy_string(host, peer->name, len);
01829 peer_unref(peer);
01830 res = 1;
01831 break;
01832 }
01833 peer_unref(peer);
01834 }
01835 ao2_iterator_destroy(&i);
01836
01837 if (!peer) {
01838 peer = realtime_peer(NULL, &sin);
01839 if (peer) {
01840 ast_copy_string(host, peer->name, len);
01841 peer_unref(peer);
01842 res = 1;
01843 }
01844 }
01845
01846 return res;
01847 }
01848
01849
01850
01851 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01852 {
01853
01854 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
01855 struct iax2_user *user;
01856
01857 user = ao2_find(users, pvt->username, OBJ_KEY);
01858 if (user) {
01859 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01860 user_unref(user);
01861 }
01862
01863 ast_clear_flag64(pvt, IAX_MAXAUTHREQ);
01864 }
01865
01866 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01867 pvt->pingid = DONT_RESCHEDULE;
01868 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01869 pvt->lagid = DONT_RESCHEDULE;
01870 AST_SCHED_DEL(sched, pvt->autoid);
01871 AST_SCHED_DEL(sched, pvt->authid);
01872 AST_SCHED_DEL(sched, pvt->initid);
01873 AST_SCHED_DEL(sched, pvt->jbid);
01874 AST_SCHED_DEL(sched, pvt->keyrotateid);
01875 }
01876
01877 static void iax2_frame_free(struct iax_frame *fr)
01878 {
01879 AST_SCHED_DEL(sched, fr->retrans);
01880 iax_frame_free(fr);
01881 }
01882
01883 static int scheduled_destroy(const void *vid)
01884 {
01885 unsigned short callno = PTR_TO_CALLNO(vid);
01886 ast_mutex_lock(&iaxsl[callno]);
01887 if (iaxs[callno]) {
01888 ast_debug(1, "Really destroying %d now...\n", callno);
01889 iax2_destroy(callno);
01890 }
01891 ast_mutex_unlock(&iaxsl[callno]);
01892 return 0;
01893 }
01894
01895 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01896 {
01897 if (s->f.datalen) {
01898 ast_free(s->f.data.ptr);
01899 }
01900 ast_free(s);
01901 }
01902
01903
01904
01905 static void send_signaling(struct chan_iax2_pvt *pvt)
01906 {
01907 struct signaling_queue_entry *s = NULL;
01908
01909 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01910 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01911 free_signaling_queue_entry(s);
01912 }
01913 pvt->hold_signaling = 0;
01914 }
01915
01916
01917
01918 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01919 {
01920 struct signaling_queue_entry *new;
01921
01922 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01923 return 1;
01924 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01925 return -1;
01926 }
01927
01928 memcpy(&new->f, f, sizeof(new->f));
01929
01930 if (new->f.datalen) {
01931 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01932 free_signaling_queue_entry(new);
01933 return -1;
01934 }
01935 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01936 }
01937 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01938
01939 return 0;
01940 }
01941
01942 static void pvt_destructor(void *obj)
01943 {
01944 struct chan_iax2_pvt *pvt = obj;
01945 struct iax_frame *cur = NULL;
01946 struct signaling_queue_entry *s = NULL;
01947
01948 ast_mutex_lock(&iaxsl[pvt->callno]);
01949
01950 iax2_destroy_helper(pvt);
01951
01952 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01953 pvt->callno_entry = NULL;
01954
01955
01956 ast_set_flag64(pvt, IAX_ALREADYGONE);
01957
01958 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
01959
01960 cur->retries = -1;
01961 }
01962
01963 ast_mutex_unlock(&iaxsl[pvt->callno]);
01964
01965 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01966 free_signaling_queue_entry(s);
01967 }
01968
01969 if (pvt->reg) {
01970 pvt->reg->callno = 0;
01971 }
01972
01973 if (!pvt->owner) {
01974 jb_frame frame;
01975 if (pvt->vars) {
01976 ast_variables_destroy(pvt->vars);
01977 pvt->vars = NULL;
01978 }
01979
01980 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01981 iax2_frame_free(frame.data);
01982 }
01983
01984 jb_destroy(pvt->jb);
01985 ast_string_field_free_memory(pvt);
01986 }
01987 }
01988
01989 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01990 {
01991 struct chan_iax2_pvt *tmp;
01992 jb_conf jbconf;
01993
01994 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01995 return NULL;
01996 }
01997
01998 if (ast_string_field_init(tmp, 32)) {
01999 ao2_ref(tmp, -1);
02000 tmp = NULL;
02001 return NULL;
02002 }
02003
02004 tmp->prefs = prefs;
02005 tmp->pingid = -1;
02006 tmp->lagid = -1;
02007 tmp->autoid = -1;
02008 tmp->authid = -1;
02009 tmp->initid = -1;
02010 tmp->keyrotateid = -1;
02011
02012 ast_string_field_set(tmp,exten, "s");
02013 ast_string_field_set(tmp,host, host);
02014
02015 tmp->jb = jb_new();
02016 tmp->jbid = -1;
02017 jbconf.max_jitterbuf = maxjitterbuffer;
02018 jbconf.resync_threshold = resyncthreshold;
02019 jbconf.max_contig_interp = maxjitterinterps;
02020 jbconf.target_extra = jittertargetextra;
02021 jb_setconf(tmp->jb,&jbconf);
02022
02023 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
02024
02025 tmp->hold_signaling = 1;
02026 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
02027
02028 return tmp;
02029 }
02030
02031 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
02032 {
02033 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
02034 if (new) {
02035 size_t afdatalen = new->afdatalen;
02036 memcpy(new, fr, sizeof(*new));
02037 iax_frame_wrap(new, &fr->af);
02038 new->afdatalen = afdatalen;
02039 new->data = NULL;
02040 new->datalen = 0;
02041 new->direction = DIRECTION_INGRESS;
02042 new->retrans = -1;
02043 }
02044 return new;
02045 }
02046
02047
02048 enum {
02049
02050 NEW_PREVENT = 0,
02051
02052 NEW_ALLOW = 1,
02053
02054 NEW_FORCE = 2,
02055
02056
02057 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
02058 };
02059
02060 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
02061 {
02062 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
02063 (cur->addr.sin_port == sin->sin_port)) {
02064
02065 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
02066 (check_dcallno ? dcallno == cur->callno : 1) ) {
02067
02068 return 1;
02069 }
02070 }
02071 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
02072 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
02073
02074 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
02075 return 1;
02076 }
02077 return 0;
02078 }
02079
02080 static void update_max_trunk(void)
02081 {
02082 int max = TRUNK_CALL_START;
02083 int x;
02084
02085
02086 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
02087 if (iaxs[x]) {
02088 max = x + 1;
02089 }
02090 }
02091
02092 maxtrunkcall = max;
02093 if (iaxdebug)
02094 ast_debug(1, "New max trunk callno is %d\n", max);
02095 }
02096
02097 static void update_max_nontrunk(void)
02098 {
02099 int max = 1;
02100 int x;
02101
02102 for (x=1;x<TRUNK_CALL_START - 1; x++) {
02103 if (iaxs[x])
02104 max = x + 1;
02105 }
02106 maxnontrunkcall = max;
02107 if (iaxdebug)
02108 ast_debug(1, "New max nontrunk callno is %d\n", max);
02109 }
02110
02111 static int make_trunk(unsigned short callno, int locked)
02112 {
02113 int x;
02114 int res= 0;
02115 struct callno_entry *callno_entry;
02116 if (iaxs[callno]->oseqno) {
02117 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02118 return -1;
02119 }
02120 if (callno & TRUNK_CALL_START) {
02121 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02122 return -1;
02123 }
02124
02125 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02126 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02127 return -1;
02128 }
02129
02130 x = callno_entry->callno;
02131 ast_mutex_lock(&iaxsl[x]);
02132
02133
02134
02135
02136
02137 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
02138 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
02139 iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02140 iaxs[x] = iaxs[callno];
02141 iaxs[x]->callno = x;
02142
02143
02144
02145 if (iaxs[x]->callno_entry) {
02146 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02147 }
02148 iaxs[x]->callno_entry = callno_entry;
02149
02150 iaxs[callno] = NULL;
02151
02152 iaxs[x]->pingid = iax2_sched_add(sched,
02153 ping_time * 1000, send_ping, (void *)(long)x);
02154 iaxs[x]->lagid = iax2_sched_add(sched,
02155 lagrq_time * 1000, send_lagrq, (void *)(long)x);
02156
02157 if (locked)
02158 ast_mutex_unlock(&iaxsl[callno]);
02159 res = x;
02160 if (!locked)
02161 ast_mutex_unlock(&iaxsl[x]);
02162
02163 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02164
02165 update_max_trunk();
02166 update_max_nontrunk();
02167 return res;
02168 }
02169
02170 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
02171 {
02172 if (!pvt->transfercallno) {
02173 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02174 return;
02175 }
02176
02177 ao2_link(iax_transfercallno_pvts, pvt);
02178 }
02179
02180 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
02181 {
02182 if (!pvt->transfercallno) {
02183 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02184 return;
02185 }
02186
02187 ao2_unlink(iax_transfercallno_pvts, pvt);
02188 }
02189 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
02190 {
02191 if (!pvt->peercallno) {
02192 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02193 return;
02194 }
02195
02196 ao2_link(iax_peercallno_pvts, pvt);
02197 }
02198
02199 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
02200 {
02201 if (!pvt->peercallno) {
02202 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02203 return;
02204 }
02205
02206 ao2_unlink(iax_peercallno_pvts, pvt);
02207 }
02208
02209 static int addr_range_delme_cb(void *obj, void *arg, int flags)
02210 {
02211 struct addr_range *lim = obj;
02212 lim->delme = 1;
02213 return 0;
02214 }
02215
02216 static int addr_range_hash_cb(const void *obj, const int flags)
02217 {
02218 const struct addr_range *lim = obj;
02219 struct sockaddr_in sin;
02220 ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02221 return abs((int) sin.sin_addr.s_addr);
02222 }
02223
02224 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
02225 {
02226 struct addr_range *lim1 = obj, *lim2 = arg;
02227 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02228 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02229 CMP_MATCH | CMP_STOP : 0;
02230 }
02231
02232 static int peercnt_hash_cb(const void *obj, const int flags)
02233 {
02234 const struct peercnt *peercnt = obj;
02235 return abs((int) peercnt->addr);
02236 }
02237
02238 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
02239 {
02240 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02241 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02242 }
02243
02244 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
02245 {
02246 struct addr_range *addr_range = obj;
02247 struct sockaddr_in *sin = arg;
02248 struct sockaddr_in ha_netmask_sin;
02249 struct sockaddr_in ha_addr_sin;
02250
02251 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02252 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02253
02254 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02255 return CMP_MATCH | CMP_STOP;
02256 }
02257 return 0;
02258 }
02259
02260
02261
02262
02263
02264
02265 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
02266 {
02267 struct addr_range *addr_range;
02268 struct iax2_peer *peer = NULL;
02269 struct iax2_user *user = NULL;
02270
02271 const char *find = S_OR(name, "guest");
02272 int res = 1;
02273 int optional = 0;
02274 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02275
02276
02277
02278
02279
02280
02281
02282 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02283 ao2_ref(addr_range, -1);
02284 optional = 1;
02285 }
02286
02287
02288 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02289 calltoken_required = user->calltoken_required;
02290 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02291 calltoken_required = user->calltoken_required;
02292 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02293 calltoken_required = peer->calltoken_required;
02294 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02295 calltoken_required = peer->calltoken_required;
02296 }
02297
02298 if (peer) {
02299 peer_unref(peer);
02300 }
02301 if (user) {
02302 user_unref(user);
02303 }
02304
02305 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);
02306 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02307 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02308 res = 0;
02309 }
02310
02311 return res;
02312 }
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324 static void set_peercnt_limit(struct peercnt *peercnt)
02325 {
02326 uint16_t limit = global_maxcallno;
02327 struct addr_range *addr_range;
02328 struct sockaddr_in sin = {
02329 .sin_addr.s_addr = peercnt->addr,
02330 };
02331
02332
02333 if (peercnt->reg && peercnt->limit) {
02334 return;
02335 }
02336
02337 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02338 limit = addr_range->limit;
02339 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02340 ao2_ref(addr_range, -1);
02341 }
02342
02343 peercnt->limit = limit;
02344 }
02345
02346
02347
02348
02349
02350 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02351 {
02352 struct peercnt *peercnt = obj;
02353
02354 set_peercnt_limit(peercnt);
02355 ast_debug(1, "Reset limits for peercnts table\n");
02356
02357 return 0;
02358 }
02359
02360
02361
02362
02363
02364 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02365 {
02366 struct addr_range *addr_range = obj;
02367
02368 return addr_range->delme ? CMP_MATCH : 0;
02369 }
02370
02371
02372
02373
02374
02375 static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
02376 {
02377
02378 struct peercnt *peercnt;
02379 struct peercnt tmp = {
02380 .addr = 0,
02381 };
02382 struct sockaddr_in sin;
02383
02384 ast_sockaddr_to_sin(sockaddr, &sin);
02385
02386 tmp.addr = sin.sin_addr.s_addr;
02387
02388 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02389 peercnt->reg = reg;
02390 if (limit) {
02391 peercnt->limit = limit;
02392 } else {
02393 set_peercnt_limit(peercnt);
02394 }
02395 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02396 ao2_ref(peercnt, -1);
02397 }
02398 }
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408 static int peercnt_add(struct sockaddr_in *sin)
02409 {
02410 struct peercnt *peercnt;
02411 unsigned long addr = sin->sin_addr.s_addr;
02412 int res = 0;
02413 struct peercnt tmp = {
02414 .addr = addr,
02415 };
02416
02417
02418
02419
02420
02421
02422
02423 ao2_lock(peercnts);
02424 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02425 ao2_lock(peercnt);
02426 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02427 ao2_lock(peercnt);
02428
02429 peercnt->addr = addr;
02430 set_peercnt_limit(peercnt);
02431
02432
02433 ao2_link(peercnts, peercnt);
02434 } else {
02435 ao2_unlock(peercnts);
02436 return -1;
02437 }
02438
02439
02440 if (peercnt->limit > peercnt->cur) {
02441 peercnt->cur++;
02442 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02443 } else {
02444 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02445 res = -1;
02446 }
02447
02448
02449 ao2_unlock(peercnt);
02450 ao2_unlock(peercnts);
02451 ao2_ref(peercnt, -1);
02452
02453 return res;
02454 }
02455
02456
02457
02458
02459
02460 static void peercnt_remove(struct peercnt *peercnt)
02461 {
02462 struct sockaddr_in sin = {
02463 .sin_addr.s_addr = peercnt->addr,
02464 };
02465
02466 if (peercnt) {
02467
02468
02469
02470 ao2_lock(peercnts);
02471 peercnt->cur--;
02472 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02473
02474 if (peercnt->cur == 0) {
02475 ao2_unlink(peercnts, peercnt);
02476 }
02477 ao2_unlock(peercnts);
02478 }
02479 }
02480
02481
02482
02483
02484
02485 static int peercnt_remove_cb(const void *obj)
02486 {
02487 struct peercnt *peercnt = (struct peercnt *) obj;
02488
02489 peercnt_remove(peercnt);
02490 ao2_ref(peercnt, -1);
02491
02492 return 0;
02493 }
02494
02495
02496
02497
02498
02499 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02500 {
02501 struct peercnt *peercnt;
02502 struct peercnt tmp = {
02503 .addr = sin->sin_addr.s_addr,
02504 };
02505
02506 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02507 peercnt_remove(peercnt);
02508 ao2_ref(peercnt, -1);
02509 }
02510 return 0;
02511 }
02512
02513
02514
02515
02516
02517 static void build_callno_limits(struct ast_variable *v)
02518 {
02519 struct addr_range *addr_range = NULL;
02520 struct addr_range tmp;
02521 struct ast_ha *ha;
02522 int limit;
02523 int error;
02524 int found;
02525
02526 for (; v; v = v->next) {
02527 limit = -1;
02528 error = 0;
02529 found = 0;
02530 ha = ast_append_ha("permit", v->name, NULL, &error);
02531
02532
02533 if (error) {
02534 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02535 continue;
02536 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02537 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02538 ast_free_ha(ha);
02539 continue;
02540 }
02541
02542 ast_copy_ha(ha, &tmp.ha);
02543
02544 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02545 ao2_lock(addr_range);
02546 found = 1;
02547 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02548 ast_free_ha(ha);
02549 return;
02550 }
02551
02552
02553 ast_copy_ha(ha, &addr_range->ha);
02554 ast_free_ha(ha);
02555 addr_range->limit = limit;
02556 addr_range->delme = 0;
02557
02558
02559 if (found) {
02560 ao2_unlock(addr_range);
02561 } else {
02562 ao2_link(callno_limits, addr_range);
02563 }
02564 ao2_ref(addr_range, -1);
02565 }
02566 }
02567
02568
02569
02570
02571
02572 static int add_calltoken_ignore(const char *addr)
02573 {
02574 struct addr_range tmp;
02575 struct addr_range *addr_range = NULL;
02576 struct ast_ha *ha = NULL;
02577 int error = 0;
02578
02579 if (ast_strlen_zero(addr)) {
02580 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02581 return -1;
02582 }
02583
02584 ha = ast_append_ha("permit", addr, NULL, &error);
02585
02586
02587 if (error) {
02588 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02589 return -1;
02590 }
02591
02592 ast_copy_ha(ha, &tmp.ha);
02593
02594 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02595 ao2_lock(addr_range);
02596 addr_range->delme = 0;
02597 ao2_unlock(addr_range);
02598 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02599
02600 ast_copy_ha(ha, &addr_range->ha);
02601 ao2_link(calltoken_ignores, addr_range);
02602 } else {
02603 ast_free_ha(ha);
02604 return -1;
02605 }
02606
02607 ast_free_ha(ha);
02608 ao2_ref(addr_range, -1);
02609
02610 return 0;
02611 }
02612
02613 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02614 {
02615 struct ao2_iterator i;
02616 struct peercnt *peercnt;
02617 struct sockaddr_in sin;
02618 int found = 0;
02619
02620 switch (cmd) {
02621 case CLI_INIT:
02622 e->command = "iax2 show callnumber usage";
02623 e->usage =
02624 "Usage: iax2 show callnumber usage [IP address]\n"
02625 " Shows current IP addresses which are consuming iax2 call numbers\n";
02626 return NULL;
02627 case CLI_GENERATE:
02628 return NULL;
02629 case CLI_HANDLER:
02630 if (a->argc < 4 || a->argc > 5)
02631 return CLI_SHOWUSAGE;
02632
02633 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02634 i = ao2_iterator_init(peercnts, 0);
02635 while ((peercnt = ao2_iterator_next(&i))) {
02636 sin.sin_addr.s_addr = peercnt->addr;
02637 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02638 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02639 ao2_ref(peercnt, -1);
02640 found = 1;
02641 break;
02642 } else {
02643 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02644 }
02645 ao2_ref(peercnt, -1);
02646 }
02647 ao2_iterator_destroy(&i);
02648
02649 if (a->argc == 4) {
02650 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02651 "Non-CallToken Validated Callno Used: %d\n",
02652 global_maxcallno_nonval,
02653 total_nonval_callno_used);
02654
02655 ast_cli(a->fd, "Total Available Callno: %d\n"
02656 "Regular Callno Available: %d\n"
02657 "Trunk Callno Available: %d\n",
02658 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02659 ao2_container_count(callno_pool),
02660 ao2_container_count(callno_pool_trunk));
02661 } else if (a->argc == 5 && !found) {
02662 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02663 }
02664
02665
02666 return CLI_SUCCESS;
02667 default:
02668 return NULL;
02669 }
02670 }
02671
02672 static struct callno_entry *get_unused_callno(int trunk, int validated)
02673 {
02674 struct callno_entry *callno_entry = NULL;
02675 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02676 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02677
02678 return NULL;
02679 }
02680
02681
02682
02683 ao2_lock(callno_pool);
02684
02685
02686
02687
02688 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02689 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02690 ao2_unlock(callno_pool);
02691 return NULL;
02692 }
02693
02694
02695
02696 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02697
02698 if (callno_entry) {
02699 callno_entry->validated = validated;
02700 if (!validated) {
02701 total_nonval_callno_used++;
02702 }
02703 }
02704
02705 ao2_unlock(callno_pool);
02706 return callno_entry;
02707 }
02708
02709 static int replace_callno(const void *obj)
02710 {
02711 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02712
02713
02714
02715 ao2_lock(callno_pool);
02716
02717 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02718 total_nonval_callno_used--;
02719 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02720 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02721 }
02722
02723 if (callno_entry->callno < TRUNK_CALL_START) {
02724 ao2_link(callno_pool, callno_entry);
02725 } else {
02726 ao2_link(callno_pool_trunk, callno_entry);
02727 }
02728 ao2_ref(callno_entry, -1);
02729
02730 ao2_unlock(callno_pool);
02731 return 0;
02732 }
02733
02734 static int callno_hash(const void *obj, const int flags)
02735 {
02736 return abs(ast_random());
02737 }
02738
02739 static int create_callno_pools(void)
02740 {
02741 uint16_t i;
02742
02743 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02744 return -1;
02745 }
02746
02747 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02748 return -1;
02749 }
02750
02751
02752 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02753 struct callno_entry *callno_entry;
02754
02755 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02756 return -1;
02757 }
02758
02759 callno_entry->callno = i;
02760
02761 if (i < TRUNK_CALL_START) {
02762 ao2_link(callno_pool, callno_entry);
02763 } else {
02764 ao2_link(callno_pool_trunk, callno_entry);
02765 }
02766
02767 ao2_ref(callno_entry, -1);
02768 }
02769
02770 return 0;
02771 }
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02782 {
02783 int i;
02784 struct peercnt *peercnt;
02785 struct peercnt tmp = {
02786 .addr = sin->sin_addr.s_addr,
02787 };
02788
02789 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02790
02791 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02792 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02793 if (i == -1) {
02794 ao2_ref(peercnt, -1);
02795 }
02796 }
02797
02798 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02799 }
02800
02801
02802
02803
02804
02805
02806
02807
02808 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02809 {
02810 if (frametype != AST_FRAME_IAX) {
02811 return 0;
02812 }
02813 switch (subclass) {
02814 case IAX_COMMAND_NEW:
02815 case IAX_COMMAND_REGREQ:
02816 case IAX_COMMAND_FWDOWNL:
02817 case IAX_COMMAND_REGREL:
02818 return 1;
02819 case IAX_COMMAND_POKE:
02820 if (!inbound) {
02821 return 1;
02822 }
02823 break;
02824 }
02825 return 0;
02826 }
02827
02828
02829
02830
02831 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02832 {
02833 int res = 0;
02834 int x;
02835
02836
02837 int validated = (new > NEW_ALLOW) ? 1 : 0;
02838 char host[80];
02839
02840 if (new <= NEW_ALLOW) {
02841 if (callno) {
02842 struct chan_iax2_pvt *pvt;
02843 struct chan_iax2_pvt tmp_pvt = {
02844 .callno = dcallno,
02845 .peercallno = callno,
02846 .transfercallno = callno,
02847
02848 .frames_received = check_dcallno,
02849 };
02850
02851 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02852
02853 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02854 if (return_locked) {
02855 ast_mutex_lock(&iaxsl[pvt->callno]);
02856 }
02857 res = pvt->callno;
02858 ao2_ref(pvt, -1);
02859 pvt = NULL;
02860 return res;
02861 }
02862
02863 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02864 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02865 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02866 if (return_locked) {
02867 ast_mutex_lock(&iaxsl[pvt->callno]);
02868 }
02869 res = pvt->callno;
02870 ao2_ref(pvt, -1);
02871 pvt = NULL;
02872 return res;
02873 }
02874 }
02875
02876
02877 if (dcallno) {
02878 ast_mutex_lock(&iaxsl[dcallno]);
02879 }
02880 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02881 iaxs[dcallno]->peercallno = callno;
02882 res = dcallno;
02883 store_by_peercallno(iaxs[dcallno]);
02884 if (!res || !return_locked) {
02885 ast_mutex_unlock(&iaxsl[dcallno]);
02886 }
02887 return res;
02888 }
02889 if (dcallno) {
02890 ast_mutex_unlock(&iaxsl[dcallno]);
02891 }
02892 #ifdef IAX_OLD_FIND
02893
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904 for (x = 1; !res && x < maxnontrunkcall; x++) {
02905 ast_mutex_lock(&iaxsl[x]);
02906 if (iaxs[x]) {
02907
02908 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02909 res = x;
02910 }
02911 }
02912 if (!res || !return_locked)
02913 ast_mutex_unlock(&iaxsl[x]);
02914 }
02915 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02916 ast_mutex_lock(&iaxsl[x]);
02917 if (iaxs[x]) {
02918
02919 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02920 res = x;
02921 }
02922 }
02923 if (!res || !return_locked)
02924 ast_mutex_unlock(&iaxsl[x]);
02925 }
02926 #endif
02927 }
02928 if (!res && (new >= NEW_ALLOW)) {
02929 struct callno_entry *callno_entry;
02930
02931
02932
02933
02934
02935
02936 if (!iax2_getpeername(*sin, host, sizeof(host)))
02937 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02938
02939 if (peercnt_add(sin)) {
02940
02941
02942 return 0;
02943 }
02944
02945 if (!(callno_entry = get_unused_callno(0, validated))) {
02946
02947
02948 peercnt_remove_by_addr(sin);
02949 ast_log(LOG_WARNING, "No more space\n");
02950 return 0;
02951 }
02952 x = callno_entry->callno;
02953 ast_mutex_lock(&iaxsl[x]);
02954
02955 iaxs[x] = new_iax(sin, host);
02956 update_max_nontrunk();
02957 if (iaxs[x]) {
02958 if (iaxdebug)
02959 ast_debug(1, "Creating new call structure %d\n", x);
02960 iaxs[x]->callno_entry = callno_entry;
02961 iaxs[x]->sockfd = sockfd;
02962 iaxs[x]->addr.sin_port = sin->sin_port;
02963 iaxs[x]->addr.sin_family = sin->sin_family;
02964 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02965 iaxs[x]->peercallno = callno;
02966 iaxs[x]->callno = x;
02967 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02968 iaxs[x]->expiry = min_reg_expire;
02969 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02970 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02971 iaxs[x]->amaflags = amaflags;
02972 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02973 ast_string_field_set(iaxs[x], accountcode, accountcode);
02974 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02975 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02976 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02977
02978 if (iaxs[x]->peercallno) {
02979 store_by_peercallno(iaxs[x]);
02980 }
02981 } else {
02982 ast_log(LOG_WARNING, "Out of resources\n");
02983 ast_mutex_unlock(&iaxsl[x]);
02984 replace_callno(callno_entry);
02985 return 0;
02986 }
02987 if (!return_locked)
02988 ast_mutex_unlock(&iaxsl[x]);
02989 res = x;
02990 }
02991 return res;
02992 }
02993
02994 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02995 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02996 }
02997
02998 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02999
03000 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
03001 }
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013 static int iax2_queue_frame(int callno, struct ast_frame *f)
03014 {
03015 iax2_lock_owner(callno);
03016 if (iaxs[callno] && iaxs[callno]->owner) {
03017 ast_queue_frame(iaxs[callno]->owner, f);
03018 ast_channel_unlock(iaxs[callno]->owner);
03019 }
03020 return 0;
03021 }
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036 static int iax2_queue_hangup(int callno)
03037 {
03038 iax2_lock_owner(callno);
03039 if (iaxs[callno] && iaxs[callno]->owner) {
03040 ast_queue_hangup(iaxs[callno]->owner);
03041 ast_channel_unlock(iaxs[callno]->owner);
03042 }
03043 return 0;
03044 }
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059 static int iax2_queue_control_data(int callno,
03060 enum ast_control_frame_type control, const void *data, size_t datalen)
03061 {
03062 iax2_lock_owner(callno);
03063 if (iaxs[callno] && iaxs[callno]->owner) {
03064 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
03065 ast_channel_unlock(iaxs[callno]->owner);
03066 }
03067 return 0;
03068 }
03069 static void destroy_firmware(struct iax_firmware *cur)
03070 {
03071
03072 if (cur->fwh) {
03073 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
03074 }
03075 close(cur->fd);
03076 ast_free(cur);
03077 }
03078
03079 static int try_firmware(char *s)
03080 {
03081 struct stat stbuf;
03082 struct iax_firmware *cur = NULL;
03083 int ifd, fd, res, len, chunk;
03084 struct ast_iax2_firmware_header *fwh, fwh2;
03085 struct MD5Context md5;
03086 unsigned char sum[16], buf[1024];
03087 char *s2, *last;
03088
03089 if (!(s2 = alloca(strlen(s) + 100))) {
03090 ast_log(LOG_WARNING, "Alloca failed!\n");
03091 return -1;
03092 }
03093
03094 last = strrchr(s, '/');
03095 if (last)
03096 last++;
03097 else
03098 last = s;
03099
03100 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03101
03102 if (stat(s, &stbuf) < 0) {
03103 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03104 return -1;
03105 }
03106
03107
03108 if (S_ISDIR(stbuf.st_mode))
03109 return -1;
03110 ifd = open(s, O_RDONLY);
03111 if (ifd < 0) {
03112 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03113 return -1;
03114 }
03115 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03116 if (fd < 0) {
03117 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03118 close(ifd);
03119 return -1;
03120 }
03121
03122 unlink(s2);
03123
03124
03125 len = stbuf.st_size;
03126 while(len) {
03127 chunk = len;
03128 if (chunk > sizeof(buf))
03129 chunk = sizeof(buf);
03130 res = read(ifd, buf, chunk);
03131 if (res != chunk) {
03132 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03133 close(ifd);
03134 close(fd);
03135 return -1;
03136 }
03137 res = write(fd, buf, chunk);
03138 if (res != chunk) {
03139 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03140 close(ifd);
03141 close(fd);
03142 return -1;
03143 }
03144 len -= chunk;
03145 }
03146 close(ifd);
03147
03148 lseek(fd, 0, SEEK_SET);
03149 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03150 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03151 close(fd);
03152 return -1;
03153 }
03154 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03155 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03156 close(fd);
03157 return -1;
03158 }
03159 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03160 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03161 close(fd);
03162 return -1;
03163 }
03164 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03165 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03166 close(fd);
03167 return -1;
03168 }
03169 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
03170 if (fwh == MAP_FAILED) {
03171 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03172 close(fd);
03173 return -1;
03174 }
03175 MD5Init(&md5);
03176 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03177 MD5Final(sum, &md5);
03178 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03179 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03180 munmap((void*)fwh, stbuf.st_size);
03181 close(fd);
03182 return -1;
03183 }
03184
03185 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03186 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03187
03188 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03189
03190 break;
03191
03192
03193 munmap((void*)fwh, stbuf.st_size);
03194 close(fd);
03195 return 0;
03196 }
03197 }
03198
03199 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03200 cur->fd = -1;
03201 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03202 }
03203
03204 if (cur) {
03205 if (cur->fwh)
03206 munmap((void*)cur->fwh, cur->mmaplen);
03207 if (cur->fd > -1)
03208 close(cur->fd);
03209 cur->fwh = fwh;
03210 cur->fd = fd;
03211 cur->mmaplen = stbuf.st_size;
03212 cur->dead = 0;
03213 }
03214
03215 return 0;
03216 }
03217
03218 static int iax_check_version(char *dev)
03219 {
03220 int res = 0;
03221 struct iax_firmware *cur = NULL;
03222
03223 if (ast_strlen_zero(dev))
03224 return 0;
03225
03226 AST_LIST_LOCK(&firmwares);
03227 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03228 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03229 res = ntohs(cur->fwh->version);
03230 break;
03231 }
03232 }
03233 AST_LIST_UNLOCK(&firmwares);
03234
03235 return res;
03236 }
03237
03238 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03239 {
03240 int res = -1;
03241 unsigned int bs = desc & 0xff;
03242 unsigned int start = (desc >> 8) & 0xffffff;
03243 unsigned int bytes;
03244 struct iax_firmware *cur;
03245
03246 if (ast_strlen_zero((char *)dev) || !bs)
03247 return -1;
03248
03249 start *= bs;
03250
03251 AST_LIST_LOCK(&firmwares);
03252 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03253 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03254 continue;
03255 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03256 if (start < ntohl(cur->fwh->datalen)) {
03257 bytes = ntohl(cur->fwh->datalen) - start;
03258 if (bytes > bs)
03259 bytes = bs;
03260 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03261 } else {
03262 bytes = 0;
03263 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03264 }
03265 if (bytes == bs)
03266 res = 0;
03267 else
03268 res = 1;
03269 break;
03270 }
03271 AST_LIST_UNLOCK(&firmwares);
03272
03273 return res;
03274 }
03275
03276
03277 static void reload_firmware(int unload)
03278 {
03279 struct iax_firmware *cur = NULL;
03280 DIR *fwd;
03281 struct dirent *de;
03282 char dir[256], fn[256];
03283
03284 AST_LIST_LOCK(&firmwares);
03285
03286
03287 AST_LIST_TRAVERSE(&firmwares, cur, list)
03288 cur->dead = 1;
03289
03290
03291 if (!unload) {
03292 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03293 fwd = opendir(dir);
03294 if (fwd) {
03295 while((de = readdir(fwd))) {
03296 if (de->d_name[0] != '.') {
03297 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03298 if (!try_firmware(fn)) {
03299 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03300 }
03301 }
03302 }
03303 closedir(fwd);
03304 } else
03305 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03306 }
03307
03308
03309 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03310 if (!cur->dead)
03311 continue;
03312 AST_LIST_REMOVE_CURRENT(list);
03313 destroy_firmware(cur);
03314 }
03315 AST_LIST_TRAVERSE_SAFE_END;
03316
03317 AST_LIST_UNLOCK(&firmwares);
03318 }
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328 static int __do_deliver(void *data)
03329 {
03330
03331
03332 struct iax_frame *fr = data;
03333 fr->retrans = -1;
03334 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03335 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03336 iax2_queue_frame(fr->callno, &fr->af);
03337
03338 iax2_frame_free(fr);
03339
03340 return 0;
03341 }
03342
03343 static int handle_error(void)
03344 {
03345
03346
03347
03348 #if 0
03349 struct sockaddr_in *sin;
03350 int res;
03351 struct msghdr m;
03352 struct sock_extended_err e;
03353 m.msg_name = NULL;
03354 m.msg_namelen = 0;
03355 m.msg_iov = NULL;
03356 m.msg_control = &e;
03357 m.msg_controllen = sizeof(e);
03358 m.msg_flags = 0;
03359 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03360 if (res < 0)
03361 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03362 else {
03363 if (m.msg_controllen) {
03364 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03365 if (sin)
03366 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03367 else
03368 ast_log(LOG_WARNING, "No address detected??\n");
03369 } else {
03370 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03371 }
03372 }
03373 #endif
03374 return 0;
03375 }
03376
03377 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03378 {
03379 int res;
03380 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03381 sizeof(*sin));
03382 if (res < 0) {
03383 ast_debug(1, "Received error: %s\n", strerror(errno));
03384 handle_error();
03385 } else
03386 res = 0;
03387 return res;
03388 }
03389
03390 static int send_packet(struct iax_frame *f)
03391 {
03392 int res;
03393 int callno = f->callno;
03394
03395
03396 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03397 return -1;
03398
03399
03400 if (iaxdebug)
03401 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));
03402
03403 if (f->transfer) {
03404 if (iaxdebug)
03405 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03406 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03407 } else {
03408 if (iaxdebug)
03409 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03410 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03411 }
03412 if (res < 0) {
03413 if (iaxdebug)
03414 ast_debug(1, "Received error: %s\n", strerror(errno));
03415 handle_error();
03416 } else
03417 res = 0;
03418
03419 return res;
03420 }
03421
03422
03423
03424
03425
03426 static int iax2_predestroy(int callno)
03427 {
03428 struct ast_channel *c = NULL;
03429 struct chan_iax2_pvt *pvt = iaxs[callno];
03430
03431 if (!pvt)
03432 return -1;
03433
03434 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03435 iax2_destroy_helper(pvt);
03436 ast_set_flag64(pvt, IAX_ALREADYGONE);
03437 }
03438
03439 if ((c = pvt->owner)) {
03440 c->tech_pvt = NULL;
03441 iax2_queue_hangup(callno);
03442 pvt->owner = NULL;
03443 ast_module_unref(ast_module_info->self);
03444 }
03445
03446 return 0;
03447 }
03448
03449 static void iax2_destroy(int callno)
03450 {
03451 struct chan_iax2_pvt *pvt = NULL;
03452 struct ast_channel *owner = NULL;
03453
03454 retry:
03455 if ((pvt = iaxs[callno])) {
03456 #if 0
03457
03458
03459
03460
03461
03462
03463
03464 iax2_destroy_helper(pvt);
03465 #endif
03466 }
03467
03468 owner = pvt ? pvt->owner : NULL;
03469
03470 if (owner) {
03471 if (ast_channel_trylock(owner)) {
03472 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03473 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03474 goto retry;
03475 }
03476 }
03477
03478 if (!owner) {
03479 iaxs[callno] = NULL;
03480 }
03481
03482 if (pvt) {
03483 if (!owner) {
03484 pvt->owner = NULL;
03485 } else {
03486
03487
03488
03489 ast_queue_hangup(owner);
03490 }
03491
03492 if (pvt->peercallno) {
03493 remove_by_peercallno(pvt);
03494 }
03495
03496 if (pvt->transfercallno) {
03497 remove_by_transfercallno(pvt);
03498 }
03499
03500 if (!owner) {
03501 ao2_ref(pvt, -1);
03502 pvt = NULL;
03503 }
03504 }
03505
03506 if (owner) {
03507 ast_channel_unlock(owner);
03508 }
03509
03510 if (callno & 0x4000) {
03511 update_max_trunk();
03512 }
03513 }
03514
03515 static int update_packet(struct iax_frame *f)
03516 {
03517
03518 struct ast_iax2_full_hdr *fh = f->data;
03519 struct ast_frame af;
03520
03521
03522 if (f->encmethods) {
03523 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03524 }
03525
03526 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03527
03528 f->iseqno = iaxs[f->callno]->iseqno;
03529 fh->iseqno = f->iseqno;
03530
03531
03532 if (f->encmethods) {
03533
03534
03535 build_rand_pad(f->semirand, sizeof(f->semirand));
03536 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03537 }
03538 return 0;
03539 }
03540
03541 static int attempt_transmit(const void *data);
03542 static void __attempt_transmit(const void *data)
03543 {
03544
03545
03546 struct iax_frame *f = (struct iax_frame *)data;
03547 int freeme = 0;
03548 int callno = f->callno;
03549
03550 if (callno)
03551 ast_mutex_lock(&iaxsl[callno]);
03552 if (callno && iaxs[callno]) {
03553 if ((f->retries < 0) ||
03554 (f->retries >= max_retries) ) {
03555
03556 if (f->retries >= max_retries) {
03557 if (f->transfer) {
03558
03559 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03560 } else if (f->final) {
03561 iax2_destroy(callno);
03562 } else {
03563 if (iaxs[callno]->owner)
03564 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),ast_channel_name(iaxs[f->callno]->owner), f->af.frametype, f->af.subclass.integer, f->ts, f->oseqno);
03565 iaxs[callno]->error = ETIMEDOUT;
03566 if (iaxs[callno]->owner) {
03567 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03568
03569 iax2_queue_frame(callno, &fr);
03570
03571 if (iaxs[callno] && iaxs[callno]->owner)
03572 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03573 } else {
03574 if (iaxs[callno]->reg) {
03575 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03576 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03577 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03578 }
03579 iax2_destroy(callno);
03580 }
03581 }
03582
03583 }
03584 freeme = 1;
03585 } else {
03586
03587 update_packet(f);
03588
03589 send_packet(f);
03590 f->retries++;
03591
03592 f->retrytime *= 10;
03593 if (f->retrytime > MAX_RETRY_TIME)
03594 f->retrytime = MAX_RETRY_TIME;
03595
03596 if (f->transfer && (f->retrytime > 1000))
03597 f->retrytime = 1000;
03598 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03599 }
03600 } else {
03601
03602 f->retries = -1;
03603 freeme = 1;
03604 }
03605
03606 if (freeme) {
03607
03608 AST_LIST_REMOVE(&frame_queue[callno], f, list);
03609 ast_mutex_unlock(&iaxsl[callno]);
03610 f->retrans = -1;
03611
03612 iax2_frame_free(f);
03613 } else if (callno) {
03614 ast_mutex_unlock(&iaxsl[callno]);
03615 }
03616 }
03617
03618 static int attempt_transmit(const void *data)
03619 {
03620 #ifdef SCHED_MULTITHREADED
03621 if (schedule_action(__attempt_transmit, data))
03622 #endif
03623 __attempt_transmit(data);
03624 return 0;
03625 }
03626
03627 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03628 {
03629 struct iax2_peer *peer = NULL;
03630 struct iax2_user *user = NULL;
03631 static const char * const choices[] = { "all", NULL };
03632 char *cmplt;
03633
03634 switch (cmd) {
03635 case CLI_INIT:
03636 e->command = "iax2 prune realtime";
03637 e->usage =
03638 "Usage: iax2 prune realtime [<peername>|all]\n"
03639 " Prunes object(s) from the cache\n";
03640 return NULL;
03641 case CLI_GENERATE:
03642 if (a->pos == 3) {
03643 cmplt = ast_cli_complete(a->word, choices, a->n);
03644 if (!cmplt)
03645 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03646 return cmplt;
03647 }
03648 return NULL;
03649 }
03650 if (a->argc != 4)
03651 return CLI_SHOWUSAGE;
03652 if (!strcmp(a->argv[3], "all")) {
03653 prune_users();
03654 prune_peers();
03655 ast_cli(a->fd, "Cache flushed successfully.\n");
03656 return CLI_SUCCESS;
03657 }
03658 peer = find_peer(a->argv[3], 0);
03659 user = find_user(a->argv[3]);
03660 if (peer || user) {
03661 if (peer) {
03662 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03663 ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03664 expire_registry(peer_ref(peer));
03665 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03666 } else {
03667 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03668 }
03669 peer_unref(peer);
03670 }
03671 if (user) {
03672 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03673 ast_set_flag64(user, IAX_RTAUTOCLEAR);
03674 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03675 } else {
03676 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03677 }
03678 ao2_unlink(users,user);
03679 user_unref(user);
03680 }
03681 } else {
03682 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03683 }
03684
03685 return CLI_SUCCESS;
03686 }
03687
03688 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03689 {
03690 switch (cmd) {
03691 case CLI_INIT:
03692 e->command = "iax2 test losspct";
03693 e->usage =
03694 "Usage: iax2 test losspct <percentage>\n"
03695 " For testing, throws away <percentage> percent of incoming packets\n";
03696 return NULL;
03697 case CLI_GENERATE:
03698 return NULL;
03699 }
03700 if (a->argc != 4)
03701 return CLI_SHOWUSAGE;
03702
03703 test_losspct = atoi(a->argv[3]);
03704
03705 return CLI_SUCCESS;
03706 }
03707
03708 #ifdef IAXTESTS
03709 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03710 {
03711 switch (cmd) {
03712 case CLI_INIT:
03713 e->command = "iax2 test late";
03714 e->usage =
03715 "Usage: iax2 test late <ms>\n"
03716 " For testing, count the next frame as <ms> ms late\n";
03717 return NULL;
03718 case CLI_GENERATE:
03719 return NULL;
03720 }
03721
03722 if (a->argc != 4)
03723 return CLI_SHOWUSAGE;
03724
03725 test_late = atoi(a->argv[3]);
03726
03727 return CLI_SUCCESS;
03728 }
03729
03730 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03731 {
03732 switch (cmd) {
03733 case CLI_INIT:
03734 e->command = "iax2 test resync";
03735 e->usage =
03736 "Usage: iax2 test resync <ms>\n"
03737 " For testing, adjust all future frames by <ms> ms\n";
03738 return NULL;
03739 case CLI_GENERATE:
03740 return NULL;
03741 }
03742
03743 if (a->argc != 4)
03744 return CLI_SHOWUSAGE;
03745
03746 test_resync = atoi(a->argv[3]);
03747
03748 return CLI_SUCCESS;
03749 }
03750
03751 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03752 {
03753 switch (cmd) {
03754 case CLI_INIT:
03755 e->command = "iax2 test jitter";
03756 e->usage =
03757 "Usage: iax2 test jitter <ms> <pct>\n"
03758 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03759 " percentage of packets. If <pct> is not specified, adds\n"
03760 " jitter to all packets.\n";
03761 return NULL;
03762 case CLI_GENERATE:
03763 return NULL;
03764 }
03765
03766 if (a->argc < 4 || a->argc > 5)
03767 return CLI_SHOWUSAGE;
03768
03769 test_jit = atoi(a->argv[3]);
03770 if (a->argc == 5)
03771 test_jitpct = atoi(a->argv[4]);
03772
03773 return CLI_SUCCESS;
03774 }
03775 #endif
03776
03777
03778
03779 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03780 {
03781 int res = 0;
03782 if (peer->maxms) {
03783 if (peer->lastms < 0) {
03784 ast_copy_string(status, "UNREACHABLE", statuslen);
03785 } else if (peer->lastms > peer->maxms) {
03786 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03787 res = 1;
03788 } else if (peer->lastms) {
03789 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03790 res = 1;
03791 } else {
03792 ast_copy_string(status, "UNKNOWN", statuslen);
03793 }
03794 } else {
03795 ast_copy_string(status, "Unmonitored", statuslen);
03796 res = -1;
03797 }
03798 return res;
03799 }
03800
03801
03802 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03803 {
03804 char status[30];
03805 char cbuf[256];
03806 struct iax2_peer *peer;
03807 char codec_buf[512];
03808 struct ast_str *encmethods = ast_str_alloca(256);
03809 int x = 0, load_realtime = 0;
03810
03811 switch (cmd) {
03812 case CLI_INIT:
03813 e->command = "iax2 show peer";
03814 e->usage =
03815 "Usage: iax2 show peer <name>\n"
03816 " Display details on specific IAX peer\n";
03817 return NULL;
03818 case CLI_GENERATE:
03819 if (a->pos == 3)
03820 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03821 return NULL;
03822 }
03823
03824 if (a->argc < 4)
03825 return CLI_SHOWUSAGE;
03826
03827 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03828
03829 peer = find_peer(a->argv[3], load_realtime);
03830 if (peer) {
03831 struct sockaddr_in peer_addr;
03832
03833 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03834
03835 encmethods_to_str(peer->encmethods, encmethods);
03836 ast_cli(a->fd, "\n\n");
03837 ast_cli(a->fd, " * Name : %s\n", peer->name);
03838 ast_cli(a->fd, " Description : %s\n", peer->description);
03839 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03840 ast_cli(a->fd, " Context : %s\n", peer->context);
03841 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03842 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03843 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03844 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03845 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03846 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03847 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03848 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03849 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03850 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03851 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));
03852 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03853 ast_cli(a->fd, " Username : %s\n", peer->username);
03854 ast_cli(a->fd, " Codecs : ");
03855 iax2_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03856 ast_cli(a->fd, "%s\n", codec_buf);
03857
03858 ast_cli(a->fd, " Codec Order : (");
03859 for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
03860 struct ast_format tmpfmt;
03861 if(!(ast_codec_pref_index(&peer->prefs, x, &tmpfmt)))
03862 break;
03863 ast_cli(a->fd, "%s", ast_getformatname(&tmpfmt));
03864 if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt))
03865 ast_cli(a->fd, "|");
03866 }
03867
03868 if (!x)
03869 ast_cli(a->fd, "none");
03870 ast_cli(a->fd, ")\n");
03871
03872 ast_cli(a->fd, " Status : ");
03873 peer_status(peer, status, sizeof(status));
03874 ast_cli(a->fd, "%s\n",status);
03875 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");
03876 ast_cli(a->fd, "\n");
03877 peer_unref(peer);
03878 } else {
03879 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03880 ast_cli(a->fd, "\n");
03881 }
03882
03883 return CLI_SUCCESS;
03884 }
03885
03886 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
03887 {
03888 int which = 0;
03889 struct iax2_peer *peer;
03890 char *res = NULL;
03891 int wordlen = strlen(word);
03892 struct ao2_iterator i;
03893
03894 i = ao2_iterator_init(peers, 0);
03895 while ((peer = ao2_iterator_next(&i))) {
03896 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03897 && (!flags || ast_test_flag64(peer, flags))) {
03898 res = ast_strdup(peer->name);
03899 peer_unref(peer);
03900 break;
03901 }
03902 peer_unref(peer);
03903 }
03904 ao2_iterator_destroy(&i);
03905
03906 return res;
03907 }
03908
03909 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03910 {
03911 struct iax_frame *cur;
03912 int cnt = 0, dead = 0, final = 0, i = 0;
03913
03914 switch (cmd) {
03915 case CLI_INIT:
03916 e->command = "iax2 show stats";
03917 e->usage =
03918 "Usage: iax2 show stats\n"
03919 " Display statistics on IAX channel driver.\n";
03920 return NULL;
03921 case CLI_GENERATE:
03922 return NULL;
03923 }
03924
03925 if (a->argc != 3)
03926 return CLI_SHOWUSAGE;
03927
03928 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03929 ast_mutex_lock(&iaxsl[i]);
03930 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03931 if (cur->retries < 0)
03932 dead++;
03933 if (cur->final)
03934 final++;
03935 cnt++;
03936 }
03937 ast_mutex_unlock(&iaxsl[i]);
03938 }
03939
03940 ast_cli(a->fd, " IAX Statistics\n");
03941 ast_cli(a->fd, "---------------------\n");
03942 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03943 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03944 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03945 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03946
03947 trunk_timed = trunk_untimed = 0;
03948 if (trunk_maxmtu > trunk_nmaxmtu)
03949 trunk_nmaxmtu = trunk_maxmtu;
03950
03951 return CLI_SUCCESS;
03952 }
03953
03954
03955 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03956 {
03957 int mtuv;
03958
03959 switch (cmd) {
03960 case CLI_INIT:
03961 e->command = "iax2 set mtu";
03962 e->usage =
03963 "Usage: iax2 set mtu <value>\n"
03964 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03965 " zero to disable. Disabling means that the operating system\n"
03966 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03967 " packet exceeds the UDP payload size. This is substantially\n"
03968 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03969 " greater for G.711 samples.\n";
03970 return NULL;
03971 case CLI_GENERATE:
03972 return NULL;
03973 }
03974
03975 if (a->argc != 4)
03976 return CLI_SHOWUSAGE;
03977 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03978 mtuv = MAX_TRUNK_MTU;
03979 else
03980 mtuv = atoi(a->argv[3]);
03981
03982 if (mtuv == 0) {
03983 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03984 global_max_trunk_mtu = 0;
03985 return CLI_SUCCESS;
03986 }
03987 if (mtuv < 172 || mtuv > 4000) {
03988 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03989 return CLI_SHOWUSAGE;
03990 }
03991 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03992 global_max_trunk_mtu = mtuv;
03993 return CLI_SUCCESS;
03994 }
03995
03996 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03997 {
03998 struct iax2_dpcache *dp = NULL;
03999 char tmp[1024], *pc = NULL;
04000 int s, x, y;
04001 struct timeval now = ast_tvnow();
04002
04003 switch (cmd) {
04004 case CLI_INIT:
04005 e->command = "iax2 show cache";
04006 e->usage =
04007 "Usage: iax2 show cache\n"
04008 " Display currently cached IAX Dialplan results.\n";
04009 return NULL;
04010 case CLI_GENERATE:
04011 return NULL;
04012 }
04013
04014 AST_LIST_LOCK(&dpcache);
04015
04016 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
04017
04018 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
04019 s = dp->expiry.tv_sec - now.tv_sec;
04020 tmp[0] = '\0';
04021 if (dp->flags & CACHE_FLAG_EXISTS)
04022 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
04023 if (dp->flags & CACHE_FLAG_NONEXISTENT)
04024 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
04025 if (dp->flags & CACHE_FLAG_CANEXIST)
04026 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
04027 if (dp->flags & CACHE_FLAG_PENDING)
04028 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
04029 if (dp->flags & CACHE_FLAG_TIMEOUT)
04030 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
04031 if (dp->flags & CACHE_FLAG_TRANSMITTED)
04032 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
04033 if (dp->flags & CACHE_FLAG_MATCHMORE)
04034 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
04035 if (dp->flags & CACHE_FLAG_UNKNOWN)
04036 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
04037
04038 if (!ast_strlen_zero(tmp)) {
04039 tmp[strlen(tmp) - 1] = '\0';
04040 } else {
04041 ast_copy_string(tmp, "(none)", sizeof(tmp));
04042 }
04043 y = 0;
04044 pc = strchr(dp->peercontext, '@');
04045 if (!pc) {
04046 pc = dp->peercontext;
04047 } else {
04048 pc++;
04049 }
04050 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
04051 if (dp->waiters[x] > -1)
04052 y++;
04053 }
04054 if (s > 0) {
04055 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
04056 } else {
04057 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
04058 }
04059 }
04060
04061 AST_LIST_UNLOCK(&dpcache);
04062
04063 return CLI_SUCCESS;
04064 }
04065
04066 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
04067
04068 static void unwrap_timestamp(struct iax_frame *fr)
04069 {
04070
04071
04072 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
04073 const int lower_mask = (1 << ts_shift) - 1;
04074 const int upper_mask = ~lower_mask;
04075 const int last_upper = iaxs[fr->callno]->last & upper_mask;
04076
04077 if ( (fr->ts & upper_mask) == last_upper ) {
04078 const int x = fr->ts - iaxs[fr->callno]->last;
04079 const int threshold = (ts_shift == 15) ? 25000 : 50000;
04080
04081 if (x < -threshold) {
04082
04083
04084
04085
04086 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04087 if (iaxdebug)
04088 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04089 } else if (x > threshold) {
04090
04091
04092
04093
04094 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04095 if (iaxdebug)
04096 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04097 }
04098 }
04099 }
04100
04101 static int get_from_jb(const void *p);
04102
04103 static void update_jbsched(struct chan_iax2_pvt *pvt)
04104 {
04105 int when;
04106
04107 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04108
04109 when = jb_next(pvt->jb) - when;
04110
04111 if (when <= 0) {
04112
04113 when = 1;
04114 }
04115
04116 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
04117 CALLNO_TO_PTR(pvt->callno));
04118 }
04119
04120 static void __get_from_jb(const void *p)
04121 {
04122 int callno = PTR_TO_CALLNO(p);
04123 struct chan_iax2_pvt *pvt = NULL;
04124 struct iax_frame *fr;
04125 jb_frame frame;
04126 int ret;
04127 long ms;
04128 long next;
04129 struct timeval now = ast_tvnow();
04130
04131
04132 ast_mutex_lock(&iaxsl[callno]);
04133 pvt = iaxs[callno];
04134 if (!pvt) {
04135
04136 ast_mutex_unlock(&iaxsl[callno]);
04137 return;
04138 }
04139
04140 pvt->jbid = -1;
04141
04142
04143
04144
04145 now.tv_usec += 1000;
04146
04147 ms = ast_tvdiff_ms(now, pvt->rxcore);
04148
04149 if(ms >= (next = jb_next(pvt->jb))) {
04150 struct ast_format voicefmt;
04151 ast_format_from_old_bitfield(&voicefmt, pvt->voiceformat);
04152 ret = jb_get(pvt->jb, &frame, ms, ast_codec_interp_len(&voicefmt));
04153 switch(ret) {
04154 case JB_OK:
04155 fr = frame.data;
04156 __do_deliver(fr);
04157
04158 pvt = iaxs[callno];
04159 break;
04160 case JB_INTERP:
04161 {
04162 struct ast_frame af = { 0, };
04163
04164
04165 af.frametype = AST_FRAME_VOICE;
04166 ast_format_copy(&af.subclass.format, &voicefmt);
04167 af.samples = frame.ms * (ast_format_rate(&voicefmt) / 1000);
04168 af.src = "IAX2 JB interpolation";
04169 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04170 af.offset = AST_FRIENDLY_OFFSET;
04171
04172
04173
04174 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04175 iax2_queue_frame(callno, &af);
04176
04177 pvt = iaxs[callno];
04178 }
04179 }
04180 break;
04181 case JB_DROP:
04182 iax2_frame_free(frame.data);
04183 break;
04184 case JB_NOFRAME:
04185 case JB_EMPTY:
04186
04187 break;
04188 default:
04189
04190 break;
04191 }
04192 }
04193 if (pvt)
04194 update_jbsched(pvt);
04195 ast_mutex_unlock(&iaxsl[callno]);
04196 }
04197
04198 static int get_from_jb(const void *data)
04199 {
04200 #ifdef SCHED_MULTITHREADED
04201 if (schedule_action(__get_from_jb, data))
04202 #endif
04203 __get_from_jb(data);
04204 return 0;
04205 }
04206
04207
04208
04209
04210
04211
04212
04213 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
04214 {
04215 int type, len;
04216 int ret;
04217 int needfree = 0;
04218 struct ast_channel *owner = NULL;
04219 struct ast_channel *bridge = NULL;
04220
04221
04222 unwrap_timestamp(fr);
04223
04224
04225 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04226 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04227 else {
04228 #if 0
04229 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04230 #endif
04231 fr->af.delivery = ast_tv(0,0);
04232 }
04233
04234 type = JB_TYPE_CONTROL;
04235 len = 0;
04236
04237 if(fr->af.frametype == AST_FRAME_VOICE) {
04238 type = JB_TYPE_VOICE;
04239 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(&fr->af.subclass.format) / 1000);
04240 } else if(fr->af.frametype == AST_FRAME_CNG) {
04241 type = JB_TYPE_SILENCE;
04242 }
04243
04244 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04245 if (tsout)
04246 *tsout = fr->ts;
04247 __do_deliver(fr);
04248 return -1;
04249 }
04250
04251 iax2_lock_owner(fr->callno);
04252 if (!iaxs[fr->callno]) {
04253
04254 iax2_frame_free(fr);
04255 return -1;
04256 }
04257 if ((owner = iaxs[fr->callno]->owner))
04258 bridge = ast_bridged_channel(owner);
04259
04260
04261
04262 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04263 jb_frame frame;
04264
04265 ast_channel_unlock(owner);
04266
04267
04268 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04269 __do_deliver(frame.data);
04270
04271 if (!iaxs[fr->callno])
04272 return -1;
04273 }
04274
04275 jb_reset(iaxs[fr->callno]->jb);
04276
04277 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
04278
04279
04280 if (tsout)
04281 *tsout = fr->ts;
04282 __do_deliver(fr);
04283 return -1;
04284 }
04285 if (owner) {
04286 ast_channel_unlock(owner);
04287 }
04288
04289
04290
04291 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04292 calc_rxstamp(iaxs[fr->callno],fr->ts));
04293 if (ret == JB_DROP) {
04294 needfree++;
04295 } else if (ret == JB_SCHED) {
04296 update_jbsched(iaxs[fr->callno]);
04297 }
04298 if (tsout)
04299 *tsout = fr->ts;
04300 if (needfree) {
04301
04302 iax2_frame_free(fr);
04303 return -1;
04304 }
04305 return 0;
04306 }
04307
04308 static int transmit_frame(void *data)
04309 {
04310 struct iax_frame *fr = data;
04311
04312 ast_mutex_lock(&iaxsl[fr->callno]);
04313
04314 fr->sentyet = 1;
04315
04316 if (iaxs[fr->callno]) {
04317 send_packet(fr);
04318 }
04319
04320 if (fr->retries < 0) {
04321 ast_mutex_unlock(&iaxsl[fr->callno]);
04322
04323 iax_frame_free(fr);
04324 } else {
04325
04326 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04327 fr->retries++;
04328 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04329 ast_mutex_unlock(&iaxsl[fr->callno]);
04330 }
04331
04332 return 0;
04333 }
04334
04335 static int iax2_transmit(struct iax_frame *fr)
04336 {
04337 fr->sentyet = 0;
04338
04339 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04340 }
04341
04342 static int iax2_digit_begin(struct ast_channel *c, char digit)
04343 {
04344 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04345 }
04346
04347 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04348 {
04349 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04350 }
04351
04352 static int iax2_sendtext(struct ast_channel *c, const char *text)
04353 {
04354
04355 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04356 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04357 }
04358
04359 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04360 {
04361 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04362 }
04363
04364 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04365 {
04366 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04367 }
04368
04369 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04370 {
04371 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04372 ast_mutex_lock(&iaxsl[callno]);
04373 if (iaxs[callno])
04374 iaxs[callno]->owner = newchan;
04375 else
04376 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04377 ast_mutex_unlock(&iaxsl[callno]);
04378 return 0;
04379 }
04380
04381
04382
04383
04384
04385 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04386 {
04387 struct ast_variable *var = NULL;
04388 struct ast_variable *tmp;
04389 struct iax2_peer *peer=NULL;
04390 time_t regseconds = 0, nowtime;
04391 int dynamic=0;
04392
04393 if (peername) {
04394 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04395 if (!var && sin)
04396 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04397 } else if (sin) {
04398 char porta[25];
04399 sprintf(porta, "%d", ntohs(sin->sin_port));
04400 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04401 if (var) {
04402
04403 for (tmp = var; tmp; tmp = tmp->next) {
04404 if (!strcasecmp(tmp->name, "name"))
04405 peername = tmp->value;
04406 }
04407 }
04408 }
04409 if (!var && peername) {
04410 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04411
04412
04413
04414
04415
04416
04417 if (var && sin) {
04418 for (tmp = var; tmp; tmp = tmp->next) {
04419 if (!strcasecmp(tmp->name, "host")) {
04420 struct ast_hostent ahp;
04421 struct hostent *hp;
04422 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04423
04424 ast_variables_destroy(var);
04425 var = NULL;
04426 }
04427 break;
04428 }
04429 }
04430 }
04431 }
04432 if (!var)
04433 return NULL;
04434
04435 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04436
04437 if (!peer) {
04438 ast_variables_destroy(var);
04439 return NULL;
04440 }
04441
04442 for (tmp = var; tmp; tmp = tmp->next) {
04443
04444 if (!strcasecmp(tmp->name, "type")) {
04445 if (strcasecmp(tmp->value, "friend") &&
04446 strcasecmp(tmp->value, "peer")) {
04447
04448 peer = peer_unref(peer);
04449 break;
04450 }
04451 } else if (!strcasecmp(tmp->name, "regseconds")) {
04452 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04453 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04454 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE);
04455 } else if (!strcasecmp(tmp->name, "port")) {
04456 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04457 } else if (!strcasecmp(tmp->name, "host")) {
04458 if (!strcasecmp(tmp->value, "dynamic"))
04459 dynamic = 1;
04460 }
04461 }
04462
04463 ast_variables_destroy(var);
04464
04465 if (!peer)
04466 return NULL;
04467
04468 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04469 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04470 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04471 if (peer->expire > -1) {
04472 if (!AST_SCHED_DEL(sched, peer->expire)) {
04473 peer->expire = -1;
04474 peer_unref(peer);
04475 }
04476 }
04477 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04478 if (peer->expire == -1)
04479 peer_unref(peer);
04480 }
04481 ao2_link(peers, peer);
04482 if (ast_test_flag64(peer, IAX_DYNAMIC))
04483 reg_source_db(peer);
04484 } else {
04485 ast_set_flag64(peer, IAX_TEMPONLY);
04486 }
04487
04488 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04489 time(&nowtime);
04490 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04491 memset(&peer->addr, 0, sizeof(peer->addr));
04492 realtime_update_peer(peer->name, &peer->addr, 0);
04493 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04494 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04495 }
04496 else {
04497 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04498 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04499 }
04500 }
04501
04502 return peer;
04503 }
04504
04505 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04506 {
04507 struct ast_variable *var;
04508 struct ast_variable *tmp;
04509 struct iax2_user *user=NULL;
04510
04511 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04512 if (!var)
04513 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04514 if (!var && sin) {
04515 char porta[6];
04516 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04517 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04518 if (!var)
04519 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04520 }
04521 if (!var) {
04522 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04523
04524
04525
04526
04527
04528
04529 if (var) {
04530 for (tmp = var; tmp; tmp = tmp->next) {
04531 if (!strcasecmp(tmp->name, "host")) {
04532 struct ast_hostent ahp;
04533 struct hostent *hp;
04534 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04535
04536 ast_variables_destroy(var);
04537 var = NULL;
04538 }
04539 break;
04540 }
04541 }
04542 }
04543 }
04544 if (!var)
04545 return NULL;
04546
04547 tmp = var;
04548 while(tmp) {
04549
04550 if (!strcasecmp(tmp->name, "type")) {
04551 if (strcasecmp(tmp->value, "friend") &&
04552 strcasecmp(tmp->value, "user")) {
04553 return NULL;
04554 }
04555 }
04556 tmp = tmp->next;
04557 }
04558
04559 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04560
04561 ast_variables_destroy(var);
04562
04563 if (!user)
04564 return NULL;
04565
04566 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04567 ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04568 ao2_link(users, user);
04569 } else {
04570 ast_set_flag64(user, IAX_TEMPONLY);
04571 }
04572
04573 return user;
04574 }
04575
04576 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
04577 {
04578 char port[10];
04579 char regseconds[20];
04580 const char *sysname = ast_config_AST_SYSTEM_NAME;
04581 char *syslabel = NULL;
04582
04583 if (ast_strlen_zero(sysname))
04584 sysname = NULL;
04585 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04586 syslabel = "regserver";
04587
04588 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04589 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04590 ast_update_realtime("iaxpeers", "name", peername,
04591 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port,
04592 "regseconds", regseconds, syslabel, sysname, SENTINEL);
04593 }
04594
04595 struct create_addr_info {
04596 iax2_format capability;
04597 uint64_t flags;
04598 int maxtime;
04599 int encmethods;
04600 int found;
04601 int sockfd;
04602 int adsi;
04603 char username[80];
04604 char secret[80];
04605 char outkey[80];
04606 char timezone[80];
04607 char prefs[32];
04608 char cid_num[80];
04609 char cid_name[80];
04610 char context[AST_MAX_CONTEXT];
04611 char peercontext[AST_MAX_CONTEXT];
04612 char mohinterpret[MAX_MUSICCLASS];
04613 char mohsuggest[MAX_MUSICCLASS];
04614 };
04615
04616 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04617 {
04618 struct iax2_peer *peer;
04619 int res = -1;
04620 struct ast_codec_pref ourprefs;
04621 struct sockaddr_in peer_addr;
04622
04623 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04624 cai->sockfd = defaultsockfd;
04625 cai->maxtime = 0;
04626 sin->sin_family = AF_INET;
04627
04628 if (!(peer = find_peer(peername, 1))) {
04629 struct ast_sockaddr sin_tmp;
04630
04631 cai->found = 0;
04632 sin_tmp.ss.ss_family = AF_INET;
04633 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04634 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04635 return -1;
04636 }
04637 ast_sockaddr_to_sin(&sin_tmp, sin);
04638 if (sin->sin_port == 0) {
04639 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04640 }
04641
04642
04643 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04644 if (c) {
04645 struct ast_format tmpfmt;
04646 ast_format_cap_iter_start(c->nativeformats);
04647 while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
04648 ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
04649 }
04650 ast_format_cap_iter_end(c->nativeformats);
04651 }
04652 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04653 return 0;
04654 }
04655
04656 cai->found = 1;
04657
04658 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04659
04660
04661 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04662 goto return_unref;
04663 }
04664
04665
04666 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04667 goto return_unref;
04668
04669 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04670 cai->maxtime = peer->maxms;
04671 cai->capability = peer->capability;
04672 cai->encmethods = peer->encmethods;
04673 cai->sockfd = peer->sockfd;
04674 cai->adsi = peer->adsi;
04675 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04676
04677 if (c) {
04678 struct ast_format tmpfmt;
04679 ast_format_cap_iter_start(c->nativeformats);
04680 while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
04681 ast_debug(1, "prepending %s to prefs\n", ast_getformatname(&tmpfmt));
04682 ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
04683 }
04684 ast_format_cap_iter_end(c->nativeformats);
04685 }
04686 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04687 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04688 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04689 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04690 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04691 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04692 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04693 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04694 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04695 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04696 if (ast_strlen_zero(peer->dbsecret)) {
04697 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04698 } else {
04699 char *family;
04700 char *key = NULL;
04701
04702 family = ast_strdupa(peer->dbsecret);
04703 key = strchr(family, '/');
04704 if (key)
04705 *key++ = '\0';
04706 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04707 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04708 goto return_unref;
04709 }
04710 }
04711
04712 if (peer_addr.sin_addr.s_addr) {
04713 sin->sin_addr = peer_addr.sin_addr;
04714 sin->sin_port = peer_addr.sin_port;
04715 } else {
04716 sin->sin_addr = peer->defaddr.sin_addr;
04717 sin->sin_port = peer->defaddr.sin_port;
04718 }
04719
04720 res = 0;
04721
04722 return_unref:
04723 peer_unref(peer);
04724
04725 return res;
04726 }
04727
04728 static void __auto_congest(const void *nothing)
04729 {
04730 int callno = PTR_TO_CALLNO(nothing);
04731 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04732 ast_mutex_lock(&iaxsl[callno]);
04733 if (iaxs[callno]) {
04734 iaxs[callno]->initid = -1;
04735 iax2_queue_frame(callno, &f);
04736 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04737 }
04738 ast_mutex_unlock(&iaxsl[callno]);
04739 }
04740
04741 static int auto_congest(const void *data)
04742 {
04743 #ifdef SCHED_MULTITHREADED
04744 if (schedule_action(__auto_congest, data))
04745 #endif
04746 __auto_congest(data);
04747 return 0;
04748 }
04749
04750 static unsigned int iax2_datetime(const char *tz)
04751 {
04752 struct timeval t = ast_tvnow();
04753 struct ast_tm tm;
04754 unsigned int tmp;
04755 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04756 tmp = (tm.tm_sec >> 1) & 0x1f;
04757 tmp |= (tm.tm_min & 0x3f) << 5;
04758 tmp |= (tm.tm_hour & 0x1f) << 11;
04759 tmp |= (tm.tm_mday & 0x1f) << 16;
04760 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04761 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04762 return tmp;
04763 }
04764
04765 struct parsed_dial_string {
04766 char *username;
04767 char *password;
04768 char *key;
04769 char *peer;
04770 char *port;
04771 char *exten;
04772 char *context;
04773 char *options;
04774 };
04775
04776 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04777 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04778 int sockfd, struct iax_ie_data *ied)
04779 {
04780 struct {
04781 struct ast_iax2_full_hdr f;
04782 struct iax_ie_data ied;
04783 } data;
04784 size_t size = sizeof(struct ast_iax2_full_hdr);
04785
04786 if (ied) {
04787 size += ied->pos;
04788 memcpy(&data.ied, ied->buf, ied->pos);
04789 }
04790
04791 data.f.scallno = htons(0x8000 | callno);
04792 data.f.dcallno = htons(dcallno);
04793 data.f.ts = htonl(ts);
04794 data.f.iseqno = seqno;
04795 data.f.oseqno = 0;
04796 data.f.type = AST_FRAME_IAX;
04797 data.f.csub = compress_subclass(command);
04798
04799 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04800 }
04801
04802 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04803 {
04804
04805 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04806 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04807 ied->buf[ied->pos++] = 0;
04808 pvt->calltoken_ie_len = 2;
04809 }
04810 }
04811
04812 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04813 {
04814 struct chan_iax2_pvt *pvt = iaxs[callno];
04815 int frametype = f->af.frametype;
04816 int subclass = f->af.subclass.integer;
04817 struct {
04818 struct ast_iax2_full_hdr fh;
04819 struct iax_ie_data ied;
04820 } data = {
04821 .ied.buf = { 0 },
04822 .ied.pos = 0,
04823 };
04824
04825 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04826
04827 if (!pvt) {
04828 return;
04829 }
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04843 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04844 (f->datalen > sizeof(data))) {
04845
04846 return;
04847 }
04848
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858
04859
04860
04861
04862
04863 memcpy(&data, f->data, f->datalen);
04864 data.ied.pos = ie_data_pos;
04865
04866
04867
04868 data.ied.pos -= pvt->calltoken_ie_len;
04869 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04870
04871
04872 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04873
04874
04875 AST_LIST_REMOVE(&frame_queue[callno], f, list);
04876
04877
04878 iax2_frame_free(f);
04879
04880
04881 pvt->oseqno = 0;
04882 pvt->rseqno = 0;
04883 pvt->iseqno = 0;
04884 pvt->aseqno = 0;
04885 if (pvt->peercallno) {
04886 remove_by_peercallno(pvt);
04887 pvt->peercallno = 0;
04888 }
04889
04890
04891 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04892 }
04893
04894 static void requirecalltoken_mark_auto(const char *name, int subclass)
04895 {
04896 struct iax2_user *user = NULL;
04897 struct iax2_peer *peer = NULL;
04898
04899 if (ast_strlen_zero(name)) {
04900 return;
04901 }
04902
04903 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04904 user->calltoken_required = CALLTOKEN_YES;
04905 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04906 peer->calltoken_required = CALLTOKEN_YES;
04907 }
04908
04909 if (peer) {
04910 peer_unref(peer);
04911 }
04912 if (user) {
04913 user_unref(user);
04914 }
04915 }
04916
04917
04918
04919
04920
04921
04922
04923
04924
04925
04926
04927
04928
04929
04930
04931
04932
04933
04934 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04935 struct sockaddr_in *sin, int fd)
04936 {
04937 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04938 #define CALLTOKEN_IE_FORMAT "%u?%s"
04939 struct ast_str *buf = ast_str_alloca(256);
04940 time_t t = time(NULL);
04941 char hash[41];
04942 int subclass = uncompress_subclass(fh->csub);
04943
04944
04945 if (ies->calltoken && !ies->calltokendata) {
04946 struct iax_ie_data ied = {
04947 .buf = { 0 },
04948 .pos = 0,
04949 };
04950
04951
04952 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04953 ast_sha1_hash(hash, ast_str_buffer(buf));
04954
04955 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04956 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04957 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04958
04959 return 1;
04960
04961
04962 } else if (ies->calltoken && ies->calltokendata) {
04963 char *rec_hash = NULL;
04964 char *rec_ts = NULL;
04965 unsigned int rec_time;
04966
04967
04968 rec_hash = strchr((char *) ies->calltokendata, '?');
04969 if (rec_hash) {
04970 *rec_hash++ = '\0';
04971 rec_ts = (char *) ies->calltokendata;
04972 }
04973
04974
04975 if (!rec_hash || !rec_ts) {
04976 goto reject;
04977 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04978 goto reject;
04979 }
04980
04981
04982 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04983 ast_sha1_hash(hash, ast_str_buffer(buf));
04984
04985
04986 if (strcmp(hash, rec_hash)) {
04987 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04988 goto reject;
04989 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04990 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04991 goto reject;
04992 }
04993
04994
04995
04996 requirecalltoken_mark_auto(ies->username, subclass);
04997 return 0;
04998
04999
05000 } else {
05001 if (calltoken_required(sin, ies->username, subclass)) {
05002 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"));
05003 goto reject;
05004 }
05005 return 0;
05006 }
05007
05008 reject:
05009
05010 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
05011 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
05012 } else {
05013 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
05014 }
05015
05016 return 1;
05017 }
05018
05019
05020
05021
05022
05023
05024
05025
05026
05027
05028
05029
05030
05031
05032
05033
05034
05035
05036
05037 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
05038 {
05039 if (ast_strlen_zero(data))
05040 return;
05041
05042 pds->peer = strsep(&data, "/");
05043 pds->exten = strsep(&data, "/");
05044 pds->options = data;
05045
05046 if (pds->exten) {
05047 data = pds->exten;
05048 pds->exten = strsep(&data, "@");
05049 pds->context = data;
05050 }
05051
05052 if (strchr(pds->peer, '@')) {
05053 data = pds->peer;
05054 pds->username = strsep(&data, "@");
05055 pds->peer = data;
05056 }
05057
05058 if (pds->username) {
05059 data = pds->username;
05060 pds->username = strsep(&data, ":");
05061 pds->password = data;
05062 }
05063
05064 data = pds->peer;
05065 pds->peer = strsep(&data, ":");
05066 pds->port = data;
05067
05068
05069
05070
05071 if (pds->password && (pds->password[0] == '[')) {
05072 pds->key = ast_strip_quoted(pds->password, "[", "]");
05073 pds->password = NULL;
05074 }
05075 }
05076
05077 static int iax2_call(struct ast_channel *c, const char *dest, int timeout)
05078 {
05079 struct sockaddr_in sin;
05080 char *l=NULL, *n=NULL, *tmpstr;
05081 struct iax_ie_data ied;
05082 char *defaultrdest = "s";
05083 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05084 struct parsed_dial_string pds;
05085 struct create_addr_info cai;
05086 struct ast_var_t *var;
05087 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
05088 const char* osp_token_ptr;
05089 unsigned int osp_token_length;
05090 unsigned char osp_block_index;
05091 unsigned int osp_block_length;
05092 unsigned char osp_buffer[256];
05093 iax2_format iax2_tmpfmt;
05094
05095 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05096 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", ast_channel_name(c));
05097 return -1;
05098 }
05099
05100 memset(&cai, 0, sizeof(cai));
05101 cai.encmethods = iax2_encryption;
05102
05103 memset(&pds, 0, sizeof(pds));
05104 tmpstr = ast_strdupa(dest);
05105 parse_dial_string(tmpstr, &pds);
05106
05107 if (ast_strlen_zero(pds.peer)) {
05108 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05109 return -1;
05110 }
05111 if (!pds.exten) {
05112 pds.exten = defaultrdest;
05113 }
05114 if (create_addr(pds.peer, c, &sin, &cai)) {
05115 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05116 return -1;
05117 }
05118 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05119 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05120 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05121 return -1;
05122 }
05123 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05124 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05125 return -1;
05126 }
05127 if (!pds.username && !ast_strlen_zero(cai.username))
05128 pds.username = cai.username;
05129 if (!pds.password && !ast_strlen_zero(cai.secret))
05130 pds.password = cai.secret;
05131 if (!pds.key && !ast_strlen_zero(cai.outkey))
05132 pds.key = cai.outkey;
05133 if (!pds.context && !ast_strlen_zero(cai.peercontext))
05134 pds.context = cai.peercontext;
05135
05136
05137 ast_copy_string(c->context, cai.context, sizeof(c->context));
05138
05139 if (pds.port)
05140 sin.sin_port = htons(atoi(pds.port));
05141
05142 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05143 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05144
05145
05146 memset(&ied, 0, sizeof(ied));
05147
05148
05149 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05150 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05151 if (pds.options && strchr(pds.options, 'a')) {
05152
05153 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05154 }
05155
05156
05157 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05158
05159 if (l) {
05160 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05161 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05162 ast_party_id_presentation(&c->connected.id));
05163 } else if (n) {
05164 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05165 ast_party_id_presentation(&c->connected.id));
05166 } else {
05167 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05168 }
05169
05170 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05171 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05172
05173 if (n)
05174 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05175 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05176 && c->connected.ani.number.valid
05177 && c->connected.ani.number.str) {
05178 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05179 }
05180
05181 if (!ast_strlen_zero(ast_channel_language(c)))
05182 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, ast_channel_language(c));
05183 if (!ast_strlen_zero(c->dialed.number.str)) {
05184 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05185 }
05186 if (c->redirecting.from.number.valid
05187 && !ast_strlen_zero(c->redirecting.from.number.str)) {
05188 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05189 }
05190
05191 if (pds.context)
05192 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05193
05194 if (pds.username)
05195 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05196
05197 if (cai.encmethods)
05198 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05199
05200 ast_mutex_lock(&iaxsl[callno]);
05201
05202 if (!ast_strlen_zero(c->context))
05203 ast_string_field_set(iaxs[callno], context, c->context);
05204
05205 if (pds.username)
05206 ast_string_field_set(iaxs[callno], username, pds.username);
05207
05208 iaxs[callno]->encmethods = cai.encmethods;
05209
05210 iaxs[callno]->adsi = cai.adsi;
05211
05212 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05213 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05214
05215 if (pds.key)
05216 ast_string_field_set(iaxs[callno], outkey, pds.key);
05217 if (pds.password)
05218 ast_string_field_set(iaxs[callno], secret, pds.password);
05219
05220 iax2_tmpfmt = ast_format_cap_to_old_bitfield(c->nativeformats);
05221 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt);
05222 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt);
05223
05224 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05225 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05226 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05227 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05228
05229 if (iaxs[callno]->maxtime) {
05230
05231 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05232 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05233 } else if (autokill) {
05234 iaxs[callno]->pingtime = autokill / 2;
05235 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05236 }
05237
05238
05239 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05240 if (!ast_strlen_zero(osp_token_ptr)) {
05241 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05242 osp_block_index = 0;
05243 while (osp_token_length > 0) {
05244 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05245 osp_buffer[0] = osp_block_index;
05246 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05247 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05248 osp_block_index++;
05249 osp_token_ptr += osp_block_length;
05250 osp_token_length -= osp_block_length;
05251 }
05252 } else
05253 ast_log(LOG_WARNING, "OSP token is too long\n");
05254 } else if (iaxdebug)
05255 ast_debug(1, "OSP token is undefined\n");
05256
05257
05258 iaxs[callno]->sockfd = cai.sockfd;
05259
05260
05261 if (variablestore) {
05262 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05263 ast_debug(1, "Found an IAX variable store on this channel\n");
05264 AST_LIST_LOCK(variablelist);
05265 AST_LIST_TRAVERSE(variablelist, var, entries) {
05266 char tmp[256];
05267 int i;
05268 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05269
05270 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05271 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05272 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05273 }
05274 }
05275 AST_LIST_UNLOCK(variablelist);
05276 }
05277
05278
05279 add_empty_calltoken_ie(iaxs[callno], &ied);
05280 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05281
05282 ast_mutex_unlock(&iaxsl[callno]);
05283 ast_setstate(c, AST_STATE_RINGING);
05284
05285 return 0;
05286 }
05287
05288 static int iax2_hangup(struct ast_channel *c)
05289 {
05290 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05291 struct iax_ie_data ied;
05292 int alreadygone;
05293 memset(&ied, 0, sizeof(ied));
05294 ast_mutex_lock(&iaxsl[callno]);
05295 if (callno && iaxs[callno]) {
05296 ast_debug(1, "We're hanging up %s now...\n", ast_channel_name(c));
05297 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05298
05299 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05300 if (!iaxs[callno]->error && !alreadygone) {
05301 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05302 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05303 }
05304 if (!iaxs[callno]) {
05305 ast_mutex_unlock(&iaxsl[callno]);
05306 return 0;
05307 }
05308 }
05309
05310 iax2_predestroy(callno);
05311
05312 if (iaxs[callno] && alreadygone) {
05313 ast_debug(1, "Really destroying %s now...\n", ast_channel_name(c));
05314 iax2_destroy(callno);
05315 } else if (iaxs[callno]) {
05316 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05317 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05318 iax2_destroy(callno);
05319 }
05320 }
05321 } else if (c->tech_pvt) {
05322
05323
05324
05325
05326 c->tech_pvt = NULL;
05327 }
05328 ast_mutex_unlock(&iaxsl[callno]);
05329 ast_verb(3, "Hungup '%s'\n", ast_channel_name(c));
05330 return 0;
05331 }
05332
05333
05334
05335
05336 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05337 {
05338 unsigned short callno = pvt->callno;
05339
05340 if (!pvt->peercallno) {
05341
05342 int count = 10;
05343 while (count-- && pvt && !pvt->peercallno) {
05344 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05345 pvt = iaxs[callno];
05346 }
05347 if (!pvt->peercallno) {
05348 return -1;
05349 }
05350 }
05351
05352 return 0;
05353 }
05354
05355 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05356 {
05357 struct ast_option_header *h;
05358 int res;
05359
05360 switch (option) {
05361 case AST_OPTION_TXGAIN:
05362 case AST_OPTION_RXGAIN:
05363
05364 errno = ENOSYS;
05365 return -1;
05366 case AST_OPTION_OPRMODE:
05367 errno = EINVAL;
05368 return -1;
05369 case AST_OPTION_SECURE_SIGNALING:
05370 case AST_OPTION_SECURE_MEDIA:
05371 {
05372 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05373 ast_mutex_lock(&iaxsl[callno]);
05374 if ((*(int *) data)) {
05375 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05376 } else {
05377 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05378 }
05379 ast_mutex_unlock(&iaxsl[callno]);
05380 return 0;
05381 }
05382
05383
05384
05385
05386 case AST_OPTION_TONE_VERIFY:
05387 case AST_OPTION_TDD:
05388 case AST_OPTION_RELAXDTMF:
05389 case AST_OPTION_AUDIO_MODE:
05390 case AST_OPTION_DIGIT_DETECT:
05391 case AST_OPTION_FAX_DETECT:
05392 {
05393 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05394 struct chan_iax2_pvt *pvt;
05395
05396 ast_mutex_lock(&iaxsl[callno]);
05397 pvt = iaxs[callno];
05398
05399 if (wait_for_peercallno(pvt)) {
05400 ast_mutex_unlock(&iaxsl[callno]);
05401 return -1;
05402 }
05403
05404 ast_mutex_unlock(&iaxsl[callno]);
05405
05406 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05407 return -1;
05408 }
05409
05410 h->flag = AST_OPTION_FLAG_REQUEST;
05411 h->option = htons(option);
05412 memcpy(h->data, data, datalen);
05413 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05414 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05415 datalen + sizeof(*h), -1);
05416 ast_free(h);
05417 return res;
05418 }
05419 default:
05420 return -1;
05421 }
05422
05423
05424 return -1;
05425 }
05426
05427 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
05428 {
05429 switch (option) {
05430 case AST_OPTION_SECURE_SIGNALING:
05431 case AST_OPTION_SECURE_MEDIA:
05432 {
05433 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05434 ast_mutex_lock(&iaxsl[callno]);
05435 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05436 ast_mutex_unlock(&iaxsl[callno]);
05437 return 0;
05438 }
05439 default:
05440 return -1;
05441 }
05442 }
05443
05444 static struct ast_frame *iax2_read(struct ast_channel *c)
05445 {
05446 ast_debug(1, "I should never be called!\n");
05447 return &ast_null_frame;
05448 }
05449
05450 static int iax2_key_rotate(const void *vpvt)
05451 {
05452 int res = 0;
05453 struct chan_iax2_pvt *pvt = (void *) vpvt;
05454 struct MD5Context md5;
05455 char key[17] = "";
05456 struct iax_ie_data ied = {
05457 .pos = 0,
05458 };
05459
05460 ast_mutex_lock(&iaxsl[pvt->callno]);
05461 pvt->keyrotateid = ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05462
05463 snprintf(key, sizeof(key), "%lX", ast_random());
05464
05465 MD5Init(&md5);
05466 MD5Update(&md5, (unsigned char *) key, strlen(key));
05467 MD5Final((unsigned char *) key, &md5);
05468
05469 IAX_DEBUGDIGEST("Sending", key);
05470
05471 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05472
05473 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05474
05475 build_ecx_key((unsigned char *) key, pvt);
05476
05477 ast_mutex_unlock(&iaxsl[pvt->callno]);
05478
05479 return res;
05480 }
05481
05482 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05483 {
05484 int res;
05485 struct iax_ie_data ied0;
05486 struct iax_ie_data ied1;
05487 unsigned int transferid = (unsigned int)ast_random();
05488
05489 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05490 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05491 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05492 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05493 return 0;
05494 }
05495
05496 memset(&ied0, 0, sizeof(ied0));
05497 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05498 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05499 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05500
05501 memset(&ied1, 0, sizeof(ied1));
05502 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05503 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05504 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05505
05506 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05507 if (res)
05508 return -1;
05509 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05510 if (res)
05511 return -1;
05512 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05513 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05514 return 0;
05515 }
05516
05517 static void lock_both(unsigned short callno0, unsigned short callno1)
05518 {
05519 ast_mutex_lock(&iaxsl[callno0]);
05520 while (ast_mutex_trylock(&iaxsl[callno1])) {
05521 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05522 }
05523 }
05524
05525 static void unlock_both(unsigned short callno0, unsigned short callno1)
05526 {
05527 ast_mutex_unlock(&iaxsl[callno1]);
05528 ast_mutex_unlock(&iaxsl[callno0]);
05529 }
05530
05531 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)
05532 {
05533 struct ast_channel *cs[3];
05534 struct ast_channel *who, *other;
05535 int to = -1;
05536 int res = -1;
05537 int transferstarted=0;
05538 struct ast_frame *f;
05539 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05540 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05541 struct timeval waittimer = {0, 0};
05542
05543
05544 if (timeoutms > 0) {
05545 return AST_BRIDGE_FAILED;
05546 }
05547
05548 timeoutms = -1;
05549
05550 lock_both(callno0, callno1);
05551 if (!iaxs[callno0] || !iaxs[callno1]) {
05552 unlock_both(callno0, callno1);
05553 return AST_BRIDGE_FAILED;
05554 }
05555
05556 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05557 iaxs[callno0]->bridgecallno = callno1;
05558 iaxs[callno1]->bridgecallno = callno0;
05559 }
05560 unlock_both(callno0, callno1);
05561
05562
05563 cs[0] = c0;
05564 cs[1] = c1;
05565 for (;;) {
05566
05567 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05568 ast_verb(3, "Can't masquerade, we're different...\n");
05569
05570 if (c0->tech == &iax2_tech) {
05571 ast_mutex_lock(&iaxsl[callno0]);
05572 iaxs[callno0]->bridgecallno = 0;
05573 ast_mutex_unlock(&iaxsl[callno0]);
05574 }
05575 if (c1->tech == &iax2_tech) {
05576 ast_mutex_lock(&iaxsl[callno1]);
05577 iaxs[callno1]->bridgecallno = 0;
05578 ast_mutex_unlock(&iaxsl[callno1]);
05579 }
05580 return AST_BRIDGE_FAILED_NOWARN;
05581 }
05582 if (!(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) {
05583 char buf0[256];
05584 char buf1[256];
05585 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05586 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05587 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05588
05589 lock_both(callno0, callno1);
05590 if (iaxs[callno0])
05591 iaxs[callno0]->bridgecallno = 0;
05592 if (iaxs[callno1])
05593 iaxs[callno1]->bridgecallno = 0;
05594 unlock_both(callno0, callno1);
05595 return AST_BRIDGE_FAILED_NOWARN;
05596 }
05597
05598 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05599
05600 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05601 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05602 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05603 transferstarted = 1;
05604 }
05605 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05606
05607 struct timeval now = ast_tvnow();
05608 if (ast_tvzero(waittimer)) {
05609 waittimer = now;
05610 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05611 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05612 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05613 *fo = NULL;
05614 *rc = c0;
05615 res = AST_BRIDGE_COMPLETE;
05616 break;
05617 }
05618 }
05619 to = 1000;
05620 who = ast_waitfor_n(cs, 2, &to);
05621 if (timeoutms > -1) {
05622 timeoutms -= (1000 - to);
05623 if (timeoutms < 0)
05624 timeoutms = 0;
05625 }
05626 if (!who) {
05627 if (!timeoutms) {
05628 res = AST_BRIDGE_RETRY;
05629 break;
05630 }
05631 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05632 res = AST_BRIDGE_FAILED;
05633 break;
05634 }
05635 continue;
05636 }
05637 f = ast_read(who);
05638 if (!f) {
05639 *fo = NULL;
05640 *rc = who;
05641 res = AST_BRIDGE_COMPLETE;
05642 break;
05643 }
05644 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05645 *fo = f;
05646 *rc = who;
05647 res = AST_BRIDGE_COMPLETE;
05648 break;
05649 }
05650 other = (who == c0) ? c1 : c0;
05651 if ((f->frametype == AST_FRAME_VOICE) ||
05652 (f->frametype == AST_FRAME_TEXT) ||
05653 (f->frametype == AST_FRAME_VIDEO) ||
05654 (f->frametype == AST_FRAME_IMAGE) ||
05655 (f->frametype == AST_FRAME_DTMF) ||
05656 (f->frametype == AST_FRAME_CONTROL)) {
05657
05658
05659
05660 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05661 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05662 *rc = who;
05663 *fo = f;
05664 res = AST_BRIDGE_COMPLETE;
05665
05666 break;
05667 }
05668
05669 ast_write(other, f);
05670 }
05671 ast_frfree(f);
05672
05673 cs[2] = cs[0];
05674 cs[0] = cs[1];
05675 cs[1] = cs[2];
05676 }
05677 lock_both(callno0, callno1);
05678 if(iaxs[callno0])
05679 iaxs[callno0]->bridgecallno = 0;
05680 if(iaxs[callno1])
05681 iaxs[callno1]->bridgecallno = 0;
05682 unlock_both(callno0, callno1);
05683 return res;
05684 }
05685
05686 static int iax2_answer(struct ast_channel *c)
05687 {
05688 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05689 ast_debug(1, "Answering IAX2 call\n");
05690 ast_mutex_lock(&iaxsl[callno]);
05691 if (iaxs[callno])
05692 iax2_ami_channelupdate(iaxs[callno]);
05693 ast_mutex_unlock(&iaxsl[callno]);
05694 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05695 }
05696
05697 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05698 {
05699 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05700 struct chan_iax2_pvt *pvt;
05701 int res = 0;
05702
05703 if (iaxdebug)
05704 ast_debug(1, "Indicating condition %d\n", condition);
05705
05706 ast_mutex_lock(&iaxsl[callno]);
05707 pvt = iaxs[callno];
05708
05709 if (wait_for_peercallno(pvt)) {
05710 res = -1;
05711 goto done;
05712 }
05713
05714 switch (condition) {
05715 case AST_CONTROL_HOLD:
05716 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05717 ast_moh_start(c, data, pvt->mohinterpret);
05718 goto done;
05719 }
05720 break;
05721 case AST_CONTROL_UNHOLD:
05722 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05723 ast_moh_stop(c);
05724 goto done;
05725 }
05726 break;
05727 case AST_CONTROL_CONNECTED_LINE:
05728 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05729 goto done;
05730 break;
05731 }
05732
05733 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05734
05735 done:
05736 ast_mutex_unlock(&iaxsl[callno]);
05737
05738 return res;
05739 }
05740
05741 static int iax2_transfer(struct ast_channel *c, const char *dest)
05742 {
05743 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05744 struct iax_ie_data ied = { "", };
05745 char tmp[256], *context;
05746 enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05747 ast_copy_string(tmp, dest, sizeof(tmp));
05748 context = strchr(tmp, '@');
05749 if (context) {
05750 *context = '\0';
05751 context++;
05752 }
05753 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05754 if (context)
05755 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05756 ast_debug(1, "Transferring '%s' to '%s'\n", ast_channel_name(c), dest);
05757 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05758 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05759 }
05760
05761 static int iax2_getpeertrunk(struct sockaddr_in sin)
05762 {
05763 struct iax2_peer *peer;
05764 int res = 0;
05765 struct ao2_iterator i;
05766
05767 i = ao2_iterator_init(peers, 0);
05768 while ((peer = ao2_iterator_next(&i))) {
05769 struct sockaddr_in peer_addr;
05770
05771 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05772
05773 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05774 (peer_addr.sin_port == sin.sin_port)) {
05775 res = ast_test_flag64(peer, IAX_TRUNK);
05776 peer_unref(peer);
05777 break;
05778 }
05779 peer_unref(peer);
05780 }
05781 ao2_iterator_destroy(&i);
05782
05783 return res;
05784 }
05785
05786
05787 static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid)
05788 {
05789 struct ast_channel *tmp;
05790 struct chan_iax2_pvt *i;
05791 struct ast_variable *v = NULL;
05792 struct ast_format tmpfmt;
05793
05794 if (!(i = iaxs[callno])) {
05795 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05796 return NULL;
05797 }
05798
05799
05800 ast_mutex_unlock(&iaxsl[callno]);
05801 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);
05802 ast_mutex_lock(&iaxsl[callno]);
05803 if (i != iaxs[callno]) {
05804 if (tmp) {
05805
05806 ast_mutex_unlock(&iaxsl[callno]);
05807 tmp = ast_channel_release(tmp);
05808 ast_mutex_lock(&iaxsl[callno]);
05809 }
05810 return NULL;
05811 }
05812 iax2_ami_channelupdate(i);
05813 if (!tmp)
05814 return NULL;
05815 tmp->tech = &iax2_tech;
05816
05817 ast_format_cap_from_old_bitfield(tmp->nativeformats, capability);
05818 ast_best_codec(tmp->nativeformats, &tmpfmt);
05819
05820 ast_format_copy(&tmp->readformat, &tmpfmt);
05821 ast_format_copy(&tmp->rawreadformat, &tmpfmt);
05822 ast_format_copy(&tmp->writeformat, &tmpfmt);
05823 ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
05824
05825 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05826
05827 if (!ast_strlen_zero(i->parkinglot))
05828 ast_channel_parkinglot_set(tmp, i->parkinglot);
05829
05830
05831 if (!ast_strlen_zero(i->ani)) {
05832 tmp->caller.ani.number.valid = 1;
05833 tmp->caller.ani.number.str = ast_strdup(i->ani);
05834 } else if (!ast_strlen_zero(i->cid_num)) {
05835 tmp->caller.ani.number.valid = 1;
05836 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05837 }
05838 tmp->dialed.number.str = ast_strdup(i->dnid);
05839 if (!ast_strlen_zero(i->rdnis)) {
05840 tmp->redirecting.from.number.valid = 1;
05841 tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05842 }
05843 tmp->caller.id.name.presentation = i->calling_pres;
05844 tmp->caller.id.number.presentation = i->calling_pres;
05845 tmp->caller.id.number.plan = i->calling_ton;
05846 tmp->dialed.transit_network_select = i->calling_tns;
05847 if (!ast_strlen_zero(i->language))
05848 ast_channel_language_set(tmp, i->language);
05849 if (!ast_strlen_zero(i->accountcode))
05850 ast_channel_accountcode_set(tmp, i->accountcode);
05851 if (i->amaflags)
05852 tmp->amaflags = i->amaflags;
05853 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05854 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05855 if (i->adsi)
05856 tmp->adsicpe = i->peeradsicpe;
05857 else
05858 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05859 i->owner = tmp;
05860 i->capability = capability;
05861
05862
05863 if (i->vars) {
05864 for (v = i->vars ; v ; v = v->next)
05865 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05866 }
05867 if (i->iaxvars) {
05868 struct ast_datastore *variablestore;
05869 struct ast_variable *var, *prev = NULL;
05870 AST_LIST_HEAD(, ast_var_t) *varlist;
05871 ast_debug(1, "Loading up the channel with IAXVARs\n");
05872 varlist = ast_calloc(1, sizeof(*varlist));
05873 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05874 if (variablestore && varlist) {
05875 variablestore->data = varlist;
05876 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05877 AST_LIST_HEAD_INIT(varlist);
05878 for (var = i->iaxvars; var; var = var->next) {
05879 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05880 if (prev)
05881 ast_free(prev);
05882 prev = var;
05883 if (!newvar) {
05884
05885 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05886 } else {
05887 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05888 }
05889 }
05890 if (prev)
05891 ast_free(prev);
05892 i->iaxvars = NULL;
05893 ast_channel_datastore_add(i->owner, variablestore);
05894 } else {
05895 if (variablestore) {
05896 ast_datastore_free(variablestore);
05897 }
05898 if (varlist) {
05899 ast_free(varlist);
05900 }
05901 }
05902 }
05903
05904 if (state != AST_STATE_DOWN) {
05905 if (ast_pbx_start(tmp)) {
05906 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));
05907 ast_hangup(tmp);
05908 i->owner = NULL;
05909 return NULL;
05910 }
05911 }
05912
05913 ast_module_ref(ast_module_info->self);
05914 return tmp;
05915 }
05916
05917 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05918 {
05919 unsigned long int mssincetx;
05920 long int ms, pred;
05921
05922 tpeer->trunkact = *now;
05923 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05924 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05925
05926 tpeer->txtrunktime = *now;
05927 tpeer->lastsent = 999999;
05928 }
05929
05930 tpeer->lasttxtime = *now;
05931
05932
05933 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05934
05935 pred = tpeer->lastsent + sampms;
05936 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05937 ms = pred;
05938
05939
05940 if (ms == tpeer->lastsent)
05941 ms = tpeer->lastsent + 1;
05942 tpeer->lastsent = ms;
05943 return ms;
05944 }
05945
05946 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05947 {
05948 long ms;
05949 if (ast_tvzero(iaxs[callno]->rxcore)) {
05950
05951 iaxs[callno]->rxcore = ast_tvnow();
05952
05953 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05954 }
05955
05956 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05957
05958 return ms + ts;
05959 }
05960
05961 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05962 {
05963 int ms;
05964 int voice = 0;
05965 int genuine = 0;
05966 int adjust;
05967 int rate = ast_format_rate(&f->subclass.format) / 1000;
05968 struct timeval *delivery = NULL;
05969
05970
05971
05972
05973
05974
05975
05976
05977 if (f) {
05978 if (f->frametype == AST_FRAME_VOICE) {
05979 voice = 1;
05980 delivery = &f->delivery;
05981 } else if (f->frametype == AST_FRAME_IAX) {
05982 genuine = 1;
05983 } else if (f->frametype == AST_FRAME_CNG) {
05984 p->notsilenttx = 0;
05985 }
05986 }
05987 if (ast_tvzero(p->offset)) {
05988 p->offset = ast_tvnow();
05989
05990 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05991 }
05992
05993 if (ts)
05994 return ts;
05995
05996 if (delivery && !ast_tvzero(*delivery)) {
05997 ms = ast_tvdiff_ms(*delivery, p->offset);
05998 if (ms < 0) {
05999 ms = 0;
06000 }
06001 if (iaxdebug)
06002 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
06003 } else {
06004 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
06005 if (ms < 0)
06006 ms = 0;
06007 if (voice) {
06008
06009 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
06010
06011
06012
06013
06014
06015
06016
06017
06018
06019
06020
06021
06022
06023
06024
06025
06026
06027
06028 adjust = (ms - p->nextpred);
06029 if (adjust < 0)
06030 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
06031 else if (adjust > 0)
06032 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
06033
06034 if (!p->nextpred) {
06035 p->nextpred = ms;
06036 if (p->nextpred <= p->lastsent)
06037 p->nextpred = p->lastsent + 3;
06038 }
06039 ms = p->nextpred;
06040 } else {
06041
06042
06043
06044
06045
06046
06047
06048
06049
06050 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
06051 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
06052 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
06053
06054 if (f->samples >= rate)
06055 {
06056 int diff = ms % (f->samples / rate);
06057 if (diff)
06058 ms += f->samples/rate - diff;
06059 }
06060
06061 p->nextpred = ms;
06062 p->notsilenttx = 1;
06063 }
06064 } else if ( f->frametype == AST_FRAME_VIDEO ) {
06065
06066
06067
06068
06069
06070
06071
06072
06073 if ( (unsigned int)ms < p->lastsent )
06074 ms = p->lastsent;
06075 } else {
06076
06077
06078 if (genuine) {
06079
06080 if (ms <= p->lastsent)
06081 ms = p->lastsent + 3;
06082 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
06083
06084 ms = p->lastsent + 3;
06085 }
06086 }
06087 }
06088 p->lastsent = ms;
06089 if (voice)
06090 p->nextpred = p->nextpred + f->samples / rate;
06091 return ms;
06092 }
06093
06094 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
06095 {
06096
06097
06098 int ms;
06099 #ifdef IAXTESTS
06100 int jit;
06101 #endif
06102
06103 if (ast_tvzero(p->rxcore)) {
06104 p->rxcore = ast_tvnow();
06105 if (iaxdebug)
06106 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06107 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06108 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06109 #if 1
06110 if (iaxdebug)
06111 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06112 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06113 #endif
06114 }
06115
06116 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06117 #ifdef IAXTESTS
06118 if (test_jit) {
06119 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06120 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06121 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06122 jit = -jit;
06123 ms += jit;
06124 }
06125 }
06126 if (test_late) {
06127 ms += test_late;
06128 test_late = 0;
06129 }
06130 #endif
06131 return ms;
06132 }
06133
06134 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
06135 {
06136 struct iax2_trunk_peer *tpeer = NULL;
06137
06138
06139 AST_LIST_LOCK(&tpeers);
06140
06141 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06142 if (!inaddrcmp(&tpeer->addr, sin)) {
06143 ast_mutex_lock(&tpeer->lock);
06144 break;
06145 }
06146 }
06147
06148 if (!tpeer) {
06149 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06150 ast_mutex_init(&tpeer->lock);
06151 tpeer->lastsent = 9999;
06152 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06153 tpeer->trunkact = ast_tvnow();
06154 ast_mutex_lock(&tpeer->lock);
06155 tpeer->sockfd = fd;
06156 #ifdef SO_NO_CHECK
06157 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06158 #endif
06159 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06160 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06161 }
06162 }
06163
06164 AST_LIST_UNLOCK(&tpeers);
06165
06166 return tpeer;
06167 }
06168
06169 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
06170 {
06171 struct ast_frame *f;
06172 struct iax2_trunk_peer *tpeer;
06173 void *tmp, *ptr;
06174 struct timeval now;
06175 struct ast_iax2_meta_trunk_entry *met;
06176 struct ast_iax2_meta_trunk_mini *mtm;
06177
06178 f = &fr->af;
06179 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06180 if (tpeer) {
06181 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06182
06183 if (tpeer->trunkdataalloc < trunkmaxsize) {
06184 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06185 ast_mutex_unlock(&tpeer->lock);
06186 return -1;
06187 }
06188
06189 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06190 tpeer->trunkdata = tmp;
06191 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);
06192 } else {
06193 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));
06194 ast_mutex_unlock(&tpeer->lock);
06195 return -1;
06196 }
06197 }
06198
06199
06200 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06201 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06202 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06203 mtm->len = htons(f->datalen);
06204 mtm->mini.callno = htons(pvt->callno);
06205 mtm->mini.ts = htons(0xffff & fr->ts);
06206 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06207 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06208 } else {
06209 met = (struct ast_iax2_meta_trunk_entry *)ptr;
06210
06211 met->callno = htons(pvt->callno);
06212 met->len = htons(f->datalen);
06213
06214 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06215 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06216 }
06217
06218 memcpy(ptr, f->data.ptr, f->datalen);
06219 tpeer->trunkdatalen += f->datalen;
06220
06221 tpeer->calls++;
06222
06223
06224 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
06225 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
06226
06227
06228 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06229 now = ast_tvnow();
06230 send_trunk(tpeer, &now);
06231 trunk_untimed ++;
06232 }
06233
06234 ast_mutex_unlock(&tpeer->lock);
06235 }
06236 return 0;
06237 }
06238
06239
06240
06241 static void build_rand_pad(unsigned char *buf, ssize_t len)
06242 {
06243 long tmp;
06244 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06245 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06246 buf += sizeof(tmp);
06247 len -= sizeof(tmp);
06248 }
06249 }
06250
06251 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06252 {
06253 build_ecx_key(digest, pvt);
06254 ast_aes_set_decrypt_key(digest, &pvt->dcx);
06255 }
06256
06257 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06258 {
06259
06260
06261
06262 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06263 ast_aes_set_encrypt_key(digest, &pvt->ecx);
06264 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06265 }
06266
06267 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
06268 {
06269 #if 0
06270
06271 int x;
06272 if (len % 16)
06273 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06274 for (x=0;x<len;x++)
06275 dst[x] = src[x] ^ 0xff;
06276 #else
06277 unsigned char lastblock[16] = { 0 };
06278 int x;
06279 while(len > 0) {
06280 ast_aes_decrypt(src, dst, dcx);
06281 for (x=0;x<16;x++)
06282 dst[x] ^= lastblock[x];
06283 memcpy(lastblock, src, sizeof(lastblock));
06284 dst += 16;
06285 src += 16;
06286 len -= 16;
06287 }
06288 #endif
06289 }
06290
06291 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
06292 {
06293 #if 0
06294
06295 int x;
06296 if (len % 16)
06297 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06298 for (x=0;x<len;x++)
06299 dst[x] = src[x] ^ 0xff;
06300 #else
06301 unsigned char curblock[16] = { 0 };
06302 int x;
06303 while(len > 0) {
06304 for (x=0;x<16;x++)
06305 curblock[x] ^= src[x];
06306 ast_aes_encrypt(curblock, dst, ecx);
06307 memcpy(curblock, dst, sizeof(curblock));
06308 dst += 16;
06309 src += 16;
06310 len -= 16;
06311 }
06312 #endif
06313 }
06314
06315 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06316 {
06317 int padding;
06318 unsigned char *workspace;
06319
06320 workspace = alloca(*datalen);
06321 memset(f, 0, sizeof(*f));
06322 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06323 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06324 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06325 return -1;
06326
06327 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06328
06329 padding = 16 + (workspace[15] & 0x0f);
06330 if (iaxdebug)
06331 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06332 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06333 return -1;
06334
06335 *datalen -= padding;
06336 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06337 f->frametype = fh->type;
06338 if (f->frametype == AST_FRAME_VIDEO) {
06339 ast_format_from_old_bitfield(&f->subclass.format, (uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1)));
06340 } else if (f->frametype == AST_FRAME_VOICE) {
06341 ast_format_from_old_bitfield(&f->subclass.format, uncompress_subclass(fh->csub));
06342 } else {
06343 f->subclass.integer = uncompress_subclass(fh->csub);
06344 }
06345 } else {
06346 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06347 if (iaxdebug)
06348 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06349 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06350 return -1;
06351
06352 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06353 padding = 16 + (workspace[15] & 0x0f);
06354 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06355 return -1;
06356 *datalen -= padding;
06357 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06358 }
06359 return 0;
06360 }
06361
06362 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06363 {
06364 int padding;
06365 unsigned char *workspace;
06366 workspace = alloca(*datalen + 32);
06367 if (!workspace)
06368 return -1;
06369 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06370 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06371 if (iaxdebug)
06372 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06373 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06374 padding = 16 + (padding & 0xf);
06375 memcpy(workspace, poo, padding);
06376 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06377 workspace[15] &= 0xf0;
06378 workspace[15] |= (padding & 0xf);
06379 if (iaxdebug)
06380 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06381 *datalen += padding;
06382 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06383 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06384 memcpy(poo, workspace + *datalen - 32, 32);
06385 } else {
06386 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06387 if (iaxdebug)
06388 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06389 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06390 padding = 16 + (padding & 0xf);
06391 memcpy(workspace, poo, padding);
06392 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06393 workspace[15] &= 0xf0;
06394 workspace[15] |= (padding & 0x0f);
06395 *datalen += padding;
06396 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06397 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06398 memcpy(poo, workspace + *datalen - 32, 32);
06399 }
06400 return 0;
06401 }
06402
06403 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06404 {
06405 int res=-1;
06406 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06407
06408 struct MD5Context md5;
06409 unsigned char digest[16];
06410 char *tmppw, *stringp;
06411
06412 tmppw = ast_strdupa(iaxs[callno]->secret);
06413 stringp = tmppw;
06414 while ((tmppw = strsep(&stringp, ";"))) {
06415 MD5Init(&md5);
06416 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06417 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06418 MD5Final(digest, &md5);
06419 build_encryption_keys(digest, iaxs[callno]);
06420 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06421 if (!res) {
06422 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06423 break;
06424 }
06425 }
06426 } else
06427 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06428 return res;
06429 }
06430
06431 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06432 {
06433
06434
06435
06436 struct ast_iax2_full_hdr *fh;
06437 struct ast_iax2_mini_hdr *mh;
06438 struct ast_iax2_video_hdr *vh;
06439 struct {
06440 struct iax_frame fr2;
06441 unsigned char buffer[4096];
06442 } frb;
06443 struct iax_frame *fr;
06444 int res;
06445 int sendmini=0;
06446 unsigned int lastsent;
06447 unsigned int fts;
06448
06449 frb.fr2.afdatalen = sizeof(frb.buffer);
06450
06451 if (!pvt) {
06452 ast_log(LOG_WARNING, "No private structure for packet?\n");
06453 return -1;
06454 }
06455
06456 lastsent = pvt->lastsent;
06457
06458
06459 fts = calc_timestamp(pvt, ts, f);
06460
06461
06462
06463
06464 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06465 return 0;
06466 #if 0
06467 ast_log(LOG_NOTICE,
06468 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06469 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06470 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06471 pvt->keyrotateid != -1 ? "" : "no "
06472 );
06473 #endif
06474 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06475 iax2_key_rotate(pvt);
06476 }
06477
06478 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
06479 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06480 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06481 &&
06482 (f->frametype == AST_FRAME_VOICE)
06483 &&
06484 (f->subclass.format.id == ast_format_id_from_old_bitfield(pvt->svoiceformat))
06485 ) {
06486
06487 now = 1;
06488
06489 sendmini = 1;
06490 }
06491 if ( f->frametype == AST_FRAME_VIDEO ) {
06492
06493
06494
06495
06496
06497 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06498 ((f->subclass.format.id) == ast_format_id_from_old_bitfield(pvt->svideoformat))
06499 ) {
06500 now = 1;
06501 sendmini = 1;
06502 } else {
06503 now = 0;
06504 sendmini = 0;
06505 }
06506 pvt->lastvsent = fts;
06507 }
06508 if (f->frametype == AST_FRAME_IAX) {
06509
06510 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06511 if (!pvt->first_iax_message) {
06512 pvt->first_iax_message = pvt->last_iax_message;
06513 }
06514 }
06515
06516 if (now) {
06517 fr = &frb.fr2;
06518 } else
06519 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));
06520 if (!fr) {
06521 ast_log(LOG_WARNING, "Out of memory\n");
06522 return -1;
06523 }
06524
06525 iax_frame_wrap(fr, f);
06526
06527 fr->ts = fts;
06528 fr->callno = pvt->callno;
06529 fr->transfer = transfer;
06530 fr->final = final;
06531 fr->encmethods = 0;
06532 if (!sendmini) {
06533
06534 if (seqno > -1)
06535 fr->oseqno = seqno;
06536 else
06537 fr->oseqno = pvt->oseqno++;
06538 fr->iseqno = pvt->iseqno;
06539 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06540 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06541 fh->ts = htonl(fr->ts);
06542 fh->oseqno = fr->oseqno;
06543 if (transfer) {
06544 fh->iseqno = 0;
06545 } else
06546 fh->iseqno = fr->iseqno;
06547
06548 if (!transfer)
06549 pvt->aseqno = fr->iseqno;
06550 fh->type = fr->af.frametype & 0xFF;
06551
06552 if (fr->af.frametype == AST_FRAME_VIDEO) {
06553 iax2_format tmpfmt = ast_format_to_old_bitfield(&fr->af.subclass.format);
06554 tmpfmt |= ast_format_get_video_mark(&fr->af.subclass.format) ? 0x1LL : 0;
06555 fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
06556 } else if (fr->af.frametype == AST_FRAME_VOICE) {
06557 fh->csub = compress_subclass(ast_format_to_old_bitfield(&fr->af.subclass.format));
06558 } else {
06559 fh->csub = compress_subclass(fr->af.subclass.integer);
06560 }
06561
06562 if (transfer) {
06563 fr->dcallno = pvt->transfercallno;
06564 } else
06565 fr->dcallno = pvt->peercallno;
06566 fh->dcallno = htons(fr->dcallno);
06567 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06568 fr->data = fh;
06569 fr->retries = 0;
06570
06571 fr->retrytime = pvt->pingtime * 2;
06572 if (fr->retrytime < MIN_RETRY_TIME)
06573 fr->retrytime = MIN_RETRY_TIME;
06574 if (fr->retrytime > MAX_RETRY_TIME)
06575 fr->retrytime = MAX_RETRY_TIME;
06576
06577 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06578 fr->retries = -1;
06579 else if (f->frametype == AST_FRAME_VOICE)
06580 pvt->svoiceformat = ast_format_to_old_bitfield(&f->subclass.format);
06581 else if (f->frametype == AST_FRAME_VIDEO)
06582 pvt->svideoformat = ast_format_to_old_bitfield(&f->subclass.format);
06583 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06584 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06585 if (fr->transfer)
06586 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06587 else
06588 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06589 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06590 fr->encmethods = pvt->encmethods;
06591 fr->ecx = pvt->ecx;
06592 fr->mydcx = pvt->mydcx;
06593 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06594 } else
06595 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06596 }
06597
06598 if (now) {
06599 res = send_packet(fr);
06600 } else
06601 res = iax2_transmit(fr);
06602 } else {
06603 if (ast_test_flag64(pvt, IAX_TRUNK)) {
06604 iax2_trunk_queue(pvt, fr);
06605 res = 0;
06606 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06607
06608 fr->oseqno = -1;
06609 fr->iseqno = -1;
06610 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06611 vh->zeros = 0;
06612 vh->callno = htons(0x8000 | fr->callno);
06613 vh->ts = htons((fr->ts & 0x7FFF) | (ast_format_get_video_mark(&fr->af.subclass.format) ? 0x8000 : 0));
06614 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06615 fr->data = vh;
06616 fr->retries = -1;
06617 res = send_packet(fr);
06618 } else {
06619
06620 fr->oseqno = -1;
06621 fr->iseqno = -1;
06622
06623 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06624 mh->callno = htons(fr->callno);
06625 mh->ts = htons(fr->ts & 0xFFFF);
06626 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06627 fr->data = mh;
06628 fr->retries = -1;
06629 if (pvt->transferring == TRANSFER_MEDIAPASS)
06630 fr->transfer = 1;
06631 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06632 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06633 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06634 } else
06635 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06636 }
06637 res = send_packet(fr);
06638 }
06639 }
06640 return res;
06641 }
06642
06643 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06644 {
06645 regex_t regexbuf;
06646 int havepattern = 0;
06647
06648 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06649 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06650
06651 struct iax2_user *user = NULL;
06652 char auth[90];
06653 char *pstr = "";
06654 struct ao2_iterator i;
06655
06656 switch (cmd) {
06657 case CLI_INIT:
06658 e->command = "iax2 show users [like]";
06659 e->usage =
06660 "Usage: iax2 show users [like <pattern>]\n"
06661 " Lists all known IAX2 users.\n"
06662 " Optional regular expression pattern is used to filter the user list.\n";
06663 return NULL;
06664 case CLI_GENERATE:
06665 return NULL;
06666 }
06667
06668 switch (a->argc) {
06669 case 5:
06670 if (!strcasecmp(a->argv[3], "like")) {
06671 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06672 return CLI_SHOWUSAGE;
06673 havepattern = 1;
06674 } else
06675 return CLI_SHOWUSAGE;
06676 case 3:
06677 break;
06678 default:
06679 return CLI_SHOWUSAGE;
06680 }
06681
06682 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06683 i = ao2_iterator_init(users, 0);
06684 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
06685 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06686 continue;
06687
06688 if (!ast_strlen_zero(user->secret)) {
06689 ast_copy_string(auth,user->secret, sizeof(auth));
06690 } else if (!ast_strlen_zero(user->inkeys)) {
06691 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06692 } else
06693 ast_copy_string(auth, "-no secret-", sizeof(auth));
06694
06695 if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06696 pstr = "REQ Only";
06697 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06698 pstr = "Disabled";
06699 else
06700 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06701
06702 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06703 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06704 user->ha ? "Yes" : "No", pstr);
06705 }
06706 ao2_iterator_destroy(&i);
06707
06708 if (havepattern)
06709 regfree(®exbuf);
06710
06711 return CLI_SUCCESS;
06712 #undef FORMAT
06713 #undef FORMAT2
06714 }
06715
06716 static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
06717 {
06718 regex_t regexbuf;
06719 int havepattern = 0;
06720 int total_peers = 0;
06721 int online_peers = 0;
06722 int offline_peers = 0;
06723 int unmonitored_peers = 0;
06724 struct ao2_iterator i;
06725
06726 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-11s %-32.32s\n"
06727 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-11s %-32.32s\n"
06728
06729 struct iax2_peer *peer = NULL;
06730 char name[256];
06731 struct ast_str *encmethods = ast_str_alloca(256);
06732 int registeredonly=0;
06733 char idtext[256] = "";
06734 switch (argc) {
06735 case 6:
06736 if (!strcasecmp(argv[3], "registered"))
06737 registeredonly = 1;
06738 else
06739 return RESULT_SHOWUSAGE;
06740 if (!strcasecmp(argv[4], "like")) {
06741 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06742 return RESULT_SHOWUSAGE;
06743 havepattern = 1;
06744 } else
06745 return RESULT_SHOWUSAGE;
06746 break;
06747 case 5:
06748 if (!strcasecmp(argv[3], "like")) {
06749 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06750 return RESULT_SHOWUSAGE;
06751 havepattern = 1;
06752 } else
06753 return RESULT_SHOWUSAGE;
06754 break;
06755 case 4:
06756 if (!strcasecmp(argv[3], "registered"))
06757 registeredonly = 1;
06758 else
06759 return RESULT_SHOWUSAGE;
06760 break;
06761 case 3:
06762 break;
06763 default:
06764 return RESULT_SHOWUSAGE;
06765 }
06766
06767
06768 if (!s)
06769 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", "Description");
06770
06771 i = ao2_iterator_init(peers, 0);
06772 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06773 char nm[20];
06774 char status[20];
06775 int retstatus;
06776 struct sockaddr_in peer_addr;
06777
06778 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06779
06780 if (registeredonly && !peer_addr.sin_addr.s_addr) {
06781 continue;
06782 }
06783 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
06784 continue;
06785 }
06786
06787 if (!ast_strlen_zero(peer->username))
06788 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06789 else
06790 ast_copy_string(name, peer->name, sizeof(name));
06791
06792 encmethods_to_str(peer->encmethods, encmethods);
06793 retstatus = peer_status(peer, status, sizeof(status));
06794 if (retstatus > 0)
06795 online_peers++;
06796 else if (!retstatus)
06797 offline_peers++;
06798 else
06799 unmonitored_peers++;
06800
06801 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06802
06803 if (s) {
06804 astman_append(s,
06805 "Event: PeerEntry\r\n%s"
06806 "Channeltype: IAX2\r\n"
06807 "ObjectName: %s\r\n"
06808 "ChanObjectType: peer\r\n"
06809 "IPaddress: %s\r\n"
06810 "IPport: %d\r\n"
06811 "Dynamic: %s\r\n"
06812 "Trunk: %s\r\n"
06813 "Encryption: %s\r\n"
06814 "Status: %s\r\n"
06815 "Description: %s\r\n\r\n",
06816 idtext,
06817 name,
06818 ast_sockaddr_stringify_addr(&peer->addr),
06819 ast_sockaddr_port(&peer->addr),
06820 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06821 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06822 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06823 status,
06824 peer->description);
06825 } else {
06826 ast_cli(fd, FORMAT, name,
06827 ast_sockaddr_stringify_addr(&peer->addr),
06828 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06829 nm,
06830 ast_sockaddr_port(&peer->addr),
06831 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
06832 peer->encmethods ? "(E)" : " ",
06833 status,
06834 peer->description);
06835 }
06836 total_peers++;
06837 }
06838 ao2_iterator_destroy(&i);
06839
06840 if (!s)
06841 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06842 total_peers, online_peers, offline_peers, unmonitored_peers);
06843
06844 if (havepattern)
06845 regfree(®exbuf);
06846
06847 if (total)
06848 *total = total_peers;
06849
06850 return RESULT_SUCCESS;
06851 #undef FORMAT
06852 #undef FORMAT2
06853 }
06854
06855 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06856 {
06857 struct iax2_thread *thread = NULL;
06858 time_t t;
06859 int threadcount = 0, dynamiccount = 0;
06860 char type;
06861
06862 switch (cmd) {
06863 case CLI_INIT:
06864 e->command = "iax2 show threads";
06865 e->usage =
06866 "Usage: iax2 show threads\n"
06867 " Lists status of IAX helper threads\n";
06868 return NULL;
06869 case CLI_GENERATE:
06870 return NULL;
06871 }
06872 if (a->argc != 3)
06873 return CLI_SHOWUSAGE;
06874
06875 ast_cli(a->fd, "IAX2 Thread Information\n");
06876 time(&t);
06877 ast_cli(a->fd, "Idle Threads:\n");
06878 AST_LIST_LOCK(&idle_list);
06879 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06880 #ifdef DEBUG_SCHED_MULTITHREAD
06881 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06882 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06883 #else
06884 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06885 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06886 #endif
06887 threadcount++;
06888 }
06889 AST_LIST_UNLOCK(&idle_list);
06890 ast_cli(a->fd, "Active Threads:\n");
06891 AST_LIST_LOCK(&active_list);
06892 AST_LIST_TRAVERSE(&active_list, thread, list) {
06893 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06894 type = 'D';
06895 else
06896 type = 'P';
06897 #ifdef DEBUG_SCHED_MULTITHREAD
06898 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06899 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06900 #else
06901 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06902 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06903 #endif
06904 threadcount++;
06905 }
06906 AST_LIST_UNLOCK(&active_list);
06907 ast_cli(a->fd, "Dynamic Threads:\n");
06908 AST_LIST_LOCK(&dynamic_list);
06909 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06910 #ifdef DEBUG_SCHED_MULTITHREAD
06911 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06912 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06913 #else
06914 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06915 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06916 #endif
06917 dynamiccount++;
06918 }
06919 AST_LIST_UNLOCK(&dynamic_list);
06920 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06921 return CLI_SUCCESS;
06922 }
06923
06924 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06925 {
06926 struct iax2_peer *p;
06927
06928 switch (cmd) {
06929 case CLI_INIT:
06930 e->command = "iax2 unregister";
06931 e->usage =
06932 "Usage: iax2 unregister <peername>\n"
06933 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06934 return NULL;
06935 case CLI_GENERATE:
06936 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06937 }
06938
06939 if (a->argc != 3)
06940 return CLI_SHOWUSAGE;
06941
06942 p = find_peer(a->argv[2], 1);
06943 if (p) {
06944 if (p->expire > 0) {
06945 struct iax2_peer *peer;
06946
06947 peer = ao2_find(peers, a->argv[2], OBJ_KEY);
06948 if (peer) {
06949 expire_registry(peer_ref(peer));
06950 peer_unref(peer);
06951 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06952 } else {
06953 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06954 }
06955 } else {
06956 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06957 }
06958 } else {
06959 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06960 }
06961 return CLI_SUCCESS;
06962 }
06963
06964 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06965 {
06966 int which = 0;
06967 struct iax2_peer *p = NULL;
06968 char *res = NULL;
06969 int wordlen = strlen(word);
06970
06971
06972 if (pos == 2) {
06973 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06974 while ((p = ao2_iterator_next(&i))) {
06975 if (!strncasecmp(p->name, word, wordlen) &&
06976 ++which > state && p->expire > 0) {
06977 res = ast_strdup(p->name);
06978 peer_unref(p);
06979 break;
06980 }
06981 peer_unref(p);
06982 }
06983 ao2_iterator_destroy(&i);
06984 }
06985
06986 return res;
06987 }
06988
06989 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06990 {
06991 switch (cmd) {
06992 case CLI_INIT:
06993 e->command = "iax2 show peers";
06994 e->usage =
06995 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06996 " Lists all known IAX2 peers.\n"
06997 " Optional 'registered' argument lists only peers with known addresses.\n"
06998 " Optional regular expression pattern is used to filter the peer list.\n";
06999 return NULL;
07000 case CLI_GENERATE:
07001 return NULL;
07002 }
07003
07004 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
07005 case RESULT_SHOWUSAGE:
07006 return CLI_SHOWUSAGE;
07007 case RESULT_FAILURE:
07008 return CLI_FAILURE;
07009 default:
07010 return CLI_SUCCESS;
07011 }
07012 }
07013
07014 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
07015 {
07016 ast_cli_netstats(s, -1, 0);
07017 astman_append(s, "\r\n");
07018 return RESULT_SUCCESS;
07019 }
07020
07021 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07022 {
07023 struct iax_firmware *cur = NULL;
07024
07025 switch (cmd) {
07026 case CLI_INIT:
07027 e->command = "iax2 show firmware";
07028 e->usage =
07029 "Usage: iax2 show firmware\n"
07030 " Lists all known IAX firmware images.\n";
07031 return NULL;
07032 case CLI_GENERATE:
07033 return NULL;
07034 }
07035
07036 if (a->argc != 3 && a->argc != 4)
07037 return CLI_SHOWUSAGE;
07038
07039 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
07040 AST_LIST_LOCK(&firmwares);
07041 AST_LIST_TRAVERSE(&firmwares, cur, list) {
07042 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
07043 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
07044 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
07045 }
07046 }
07047 AST_LIST_UNLOCK(&firmwares);
07048
07049 return CLI_SUCCESS;
07050 }
07051
07052
07053 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
07054 {
07055 static const char * const a[] = { "iax2", "show", "peers" };
07056 const char *id = astman_get_header(m,"ActionID");
07057 char idtext[256] = "";
07058 int total = 0;
07059
07060 if (!ast_strlen_zero(id))
07061 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07062
07063 astman_send_listack(s, m, "Peer status list will follow", "start");
07064
07065 __iax2_show_peers(-1, &total, s, 3, a);
07066
07067 astman_append(s,
07068 "Event: PeerlistComplete\r\n"
07069 "EventList: Complete\r\n"
07070 "ListItems: %d\r\n"
07071 "%s"
07072 "\r\n", total, idtext);
07073 return 0;
07074 }
07075
07076
07077 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
07078 {
07079 struct iax2_peer *peer = NULL;
07080 int peer_count = 0;
07081 char nm[20];
07082 char status[20];
07083 const char *id = astman_get_header(m,"ActionID");
07084 char idtext[256] = "";
07085 struct ast_str *encmethods = ast_str_alloca(256);
07086 struct ao2_iterator i;
07087
07088 if (!ast_strlen_zero(id))
07089 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07090
07091 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
07092
07093
07094 i = ao2_iterator_init(peers, 0);
07095 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
07096 encmethods_to_str(peer->encmethods, encmethods);
07097 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
07098 if (!ast_strlen_zero(peer->username)) {
07099 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07100 } else {
07101 astman_append(s, "ObjectName: %s\r\n", peer->name);
07102 }
07103 astman_append(s, "ChanObjectType: peer\r\n");
07104 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07105 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07106 astman_append(s, "Mask: %s\r\n", nm);
07107 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07108 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07109 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07110 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07111 peer_status(peer, status, sizeof(status));
07112 astman_append(s, "Status: %s\r\n\r\n", status);
07113 peer_count++;
07114 }
07115 ao2_iterator_destroy(&i);
07116
07117 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07118 return RESULT_SUCCESS;
07119 }
07120
07121
07122 static char *regstate2str(int regstate)
07123 {
07124 switch(regstate) {
07125 case REG_STATE_UNREGISTERED:
07126 return "Unregistered";
07127 case REG_STATE_REGSENT:
07128 return "Request Sent";
07129 case REG_STATE_AUTHSENT:
07130 return "Auth. Sent";
07131 case REG_STATE_REGISTERED:
07132 return "Registered";
07133 case REG_STATE_REJECTED:
07134 return "Rejected";
07135 case REG_STATE_TIMEOUT:
07136 return "Timeout";
07137 case REG_STATE_NOAUTH:
07138 return "No Authentication";
07139 default:
07140 return "Unknown";
07141 }
07142 }
07143
07144 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07145 {
07146 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
07147 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
07148 struct iax2_registry *reg = NULL;
07149 char host[80];
07150 char perceived[80];
07151 int counter = 0;
07152
07153 switch (cmd) {
07154 case CLI_INIT:
07155 e->command = "iax2 show registry";
07156 e->usage =
07157 "Usage: iax2 show registry\n"
07158 " Lists all registration requests and status.\n";
07159 return NULL;
07160 case CLI_GENERATE:
07161 return NULL;
07162 }
07163 if (a->argc != 3)
07164 return CLI_SHOWUSAGE;
07165 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07166 AST_LIST_LOCK(®istrations);
07167 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07168 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07169 if (reg->us.sin_addr.s_addr)
07170 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07171 else
07172 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07173 ast_cli(a->fd, FORMAT, host,
07174 (reg->dnsmgr) ? "Y" : "N",
07175 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07176 counter++;
07177 }
07178 AST_LIST_UNLOCK(®istrations);
07179 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07180 return CLI_SUCCESS;
07181 #undef FORMAT
07182 #undef FORMAT2
07183 }
07184
07185 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
07186 {
07187 const char *id = astman_get_header(m, "ActionID");
07188 struct iax2_registry *reg = NULL;
07189 char idtext[256] = "";
07190 char host[80] = "";
07191 char perceived[80] = "";
07192 int total = 0;
07193
07194 if (!ast_strlen_zero(id))
07195 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07196
07197 astman_send_listack(s, m, "Registrations will follow", "start");
07198
07199 AST_LIST_LOCK(®istrations);
07200 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07201 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07202
07203 if (reg->us.sin_addr.s_addr) {
07204 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07205 } else {
07206 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07207 }
07208
07209 astman_append(s,
07210 "Event: RegistryEntry\r\n"
07211 "%s"
07212 "Host: %s\r\n"
07213 "DNSmanager: %s\r\n"
07214 "Username: %s\r\n"
07215 "Perceived: %s\r\n"
07216 "Refresh: %d\r\n"
07217 "State: %s\r\n"
07218 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
07219 reg->refresh, regstate2str(reg->regstate));
07220
07221 total++;
07222 }
07223 AST_LIST_UNLOCK(®istrations);
07224
07225 astman_append(s,
07226 "Event: RegistrationsComplete\r\n"
07227 "EventList: Complete\r\n"
07228 "ListItems: %d\r\n"
07229 "%s"
07230 "\r\n", total, idtext);
07231
07232 return 0;
07233 }
07234
07235 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07236 {
07237 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
07238 #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"
07239 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
07240 int x;
07241 int numchans = 0;
07242 char first_message[10] = { 0, };
07243 char last_message[10] = { 0, };
07244
07245 switch (cmd) {
07246 case CLI_INIT:
07247 e->command = "iax2 show channels";
07248 e->usage =
07249 "Usage: iax2 show channels\n"
07250 " Lists all currently active IAX channels.\n";
07251 return NULL;
07252 case CLI_GENERATE:
07253 return NULL;
07254 }
07255
07256 if (a->argc != 3)
07257 return CLI_SHOWUSAGE;
07258 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07259 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07260 ast_mutex_lock(&iaxsl[x]);
07261 if (iaxs[x]) {
07262 int lag, jitter, localdelay;
07263 jb_info jbinfo;
07264 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07265 jb_getinfo(iaxs[x]->jb, &jbinfo);
07266 jitter = jbinfo.jitter;
07267 localdelay = jbinfo.current - jbinfo.min;
07268 } else {
07269 jitter = -1;
07270 localdelay = 0;
07271 }
07272
07273 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07274 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07275 lag = iaxs[x]->remote_rr.delay;
07276 ast_cli(a->fd, FORMAT,
07277 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
07278 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07279 S_OR(iaxs[x]->username, "(None)"),
07280 iaxs[x]->callno, iaxs[x]->peercallno,
07281 iaxs[x]->oseqno, iaxs[x]->iseqno,
07282 lag,
07283 jitter,
07284 localdelay,
07285 iax2_getformatname(iaxs[x]->voiceformat),
07286 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07287 first_message,
07288 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07289 last_message);
07290 numchans++;
07291 }
07292 ast_mutex_unlock(&iaxsl[x]);
07293 }
07294 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07295 return CLI_SUCCESS;
07296 #undef FORMAT
07297 #undef FORMAT2
07298 #undef FORMATB
07299 }
07300
07301 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07302 {
07303 int x;
07304 int numchans = 0;
07305 char first_message[10] = { 0, };
07306 char last_message[10] = { 0, };
07307 #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"
07308 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07309 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07310 ast_mutex_lock(&iaxsl[x]);
07311 if (iaxs[x]) {
07312 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07313 jb_info jbinfo;
07314 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07315 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07316
07317 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07318 jb_getinfo(iaxs[x]->jb, &jbinfo);
07319 localjitter = jbinfo.jitter;
07320 localdelay = jbinfo.current - jbinfo.min;
07321 locallost = jbinfo.frames_lost;
07322 locallosspct = jbinfo.losspct/1000;
07323 localdropped = jbinfo.frames_dropped;
07324 localooo = jbinfo.frames_ooo;
07325 } else {
07326 localjitter = -1;
07327 localdelay = 0;
07328 locallost = -1;
07329 locallosspct = -1;
07330 localdropped = 0;
07331 localooo = -1;
07332 }
07333 if (s)
07334 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07335 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
07336 iaxs[x]->pingtime,
07337 localjitter,
07338 localdelay,
07339 locallost,
07340 locallosspct,
07341 localdropped,
07342 localooo,
07343 iaxs[x]->frames_received/1000,
07344 iaxs[x]->remote_rr.jitter,
07345 iaxs[x]->remote_rr.delay,
07346 iaxs[x]->remote_rr.losscnt,
07347 iaxs[x]->remote_rr.losspct,
07348 iaxs[x]->remote_rr.dropped,
07349 iaxs[x]->remote_rr.ooo,
07350 iaxs[x]->remote_rr.packets/1000,
07351 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07352 first_message,
07353 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07354 last_message);
07355 else
07356 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07357 iaxs[x]->owner ? ast_channel_name(iaxs[x]->owner) : "(None)",
07358 iaxs[x]->pingtime,
07359 localjitter,
07360 localdelay,
07361 locallost,
07362 locallosspct,
07363 localdropped,
07364 localooo,
07365 iaxs[x]->frames_received/1000,
07366 iaxs[x]->remote_rr.jitter,
07367 iaxs[x]->remote_rr.delay,
07368 iaxs[x]->remote_rr.losscnt,
07369 iaxs[x]->remote_rr.losspct,
07370 iaxs[x]->remote_rr.dropped,
07371 iaxs[x]->remote_rr.ooo,
07372 iaxs[x]->remote_rr.packets/1000,
07373 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07374 first_message,
07375 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07376 last_message);
07377 numchans++;
07378 }
07379 ast_mutex_unlock(&iaxsl[x]);
07380 }
07381
07382 return numchans;
07383 }
07384
07385 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07386 {
07387 int numchans = 0;
07388
07389 switch (cmd) {
07390 case CLI_INIT:
07391 e->command = "iax2 show netstats";
07392 e->usage =
07393 "Usage: iax2 show netstats\n"
07394 " Lists network status for all currently active IAX channels.\n";
07395 return NULL;
07396 case CLI_GENERATE:
07397 return NULL;
07398 }
07399 if (a->argc != 3)
07400 return CLI_SHOWUSAGE;
07401 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07402 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07403 numchans = ast_cli_netstats(NULL, a->fd, 1);
07404 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07405 return CLI_SUCCESS;
07406 }
07407
07408 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07409 {
07410 switch (cmd) {
07411 case CLI_INIT:
07412 e->command = "iax2 set debug {on|off|peer}";
07413 e->usage =
07414 "Usage: iax2 set debug {on|off|peer peername}\n"
07415 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07416 return NULL;
07417 case CLI_GENERATE:
07418 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07419 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07420 return NULL;
07421 }
07422
07423 if (a->argc < e->args || a->argc > e->args + 1)
07424 return CLI_SHOWUSAGE;
07425
07426 if (!strcasecmp(a->argv[3], "peer")) {
07427 struct iax2_peer *peer;
07428 struct sockaddr_in peer_addr;
07429
07430
07431 if (a->argc != e->args + 1)
07432 return CLI_SHOWUSAGE;
07433
07434 peer = find_peer(a->argv[4], 1);
07435
07436 if (!peer) {
07437 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07438 return CLI_FAILURE;
07439 }
07440
07441 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07442
07443 debugaddr.sin_addr = peer_addr.sin_addr;
07444 debugaddr.sin_port = peer_addr.sin_port;
07445
07446 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07447 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07448
07449 ao2_ref(peer, -1);
07450 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07451 iaxdebug = 1;
07452 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07453 } else {
07454 iaxdebug = 0;
07455 memset(&debugaddr, 0, sizeof(debugaddr));
07456 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07457 }
07458 return CLI_SUCCESS;
07459 }
07460
07461 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07462 {
07463 switch (cmd) {
07464 case CLI_INIT:
07465 e->command = "iax2 set debug trunk {on|off}";
07466 e->usage =
07467 "Usage: iax2 set debug trunk {on|off}\n"
07468 " Enables/Disables debugging of IAX trunking\n";
07469 return NULL;
07470 case CLI_GENERATE:
07471 return NULL;
07472 }
07473
07474 if (a->argc != e->args)
07475 return CLI_SHOWUSAGE;
07476
07477 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07478 iaxtrunkdebug = 1;
07479 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07480 } else {
07481 iaxtrunkdebug = 0;
07482 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07483 }
07484 return CLI_SUCCESS;
07485 }
07486
07487 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07488 {
07489 switch (cmd) {
07490 case CLI_INIT:
07491 e->command = "iax2 set debug jb {on|off}";
07492 e->usage =
07493 "Usage: iax2 set debug jb {on|off}\n"
07494 " Enables/Disables jitterbuffer debugging information\n";
07495 return NULL;
07496 case CLI_GENERATE:
07497 return NULL;
07498 }
07499
07500 if (a->argc != e->args)
07501 return CLI_SHOWUSAGE;
07502
07503 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07504 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07505 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07506 } else {
07507 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07508 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07509 }
07510 return CLI_SUCCESS;
07511 }
07512
07513 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07514 {
07515 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07516 int res = -1;
07517 ast_mutex_lock(&iaxsl[callno]);
07518 if (iaxs[callno]) {
07519
07520 if (!iaxs[callno]->error) {
07521 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07522 res = 0;
07523
07524 else if (f->frametype == AST_FRAME_NULL)
07525 res = 0;
07526 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07527 res = 0;
07528 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07529 res = 0;
07530 else
07531
07532 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07533 } else {
07534 ast_debug(1, "Write error: %s\n", strerror(errno));
07535 }
07536 }
07537
07538 ast_mutex_unlock(&iaxsl[callno]);
07539 return res;
07540 }
07541
07542 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07543 int now, int transfer, int final)
07544 {
07545 struct ast_frame f = { 0, };
07546 int res = 0;
07547
07548 f.frametype = type;
07549 f.subclass.integer = command;
07550 f.datalen = datalen;
07551 f.src = __FUNCTION__;
07552 f.data.ptr = (void *) data;
07553
07554 if ((res = queue_signalling(i, &f)) <= 0) {
07555 return res;
07556 }
07557
07558 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07559 }
07560
07561 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07562 {
07563 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07564 }
07565
07566 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07567 {
07568 int res;
07569 ast_mutex_lock(&iaxsl[callno]);
07570 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07571 ast_mutex_unlock(&iaxsl[callno]);
07572 return res;
07573 }
07574
07575
07576
07577
07578
07579
07580 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)
07581 {
07582 int call_num = i->callno;
07583
07584 iax2_predestroy(i->callno);
07585 if (!iaxs[call_num])
07586 return -1;
07587 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07588 }
07589
07590 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)
07591 {
07592 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07593 }
07594
07595 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07596 {
07597 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07598 }
07599
07600 static int apply_context(struct iax2_context *con, const char *context)
07601 {
07602 while(con) {
07603 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07604 return -1;
07605 con = con->next;
07606 }
07607 return 0;
07608 }
07609
07610
07611 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07612 {
07613
07614 int res = -1;
07615 int version = 2;
07616 struct iax2_user *user = NULL, *best = NULL;
07617 int bestscore = 0;
07618 int gotcapability = 0;
07619 struct ast_variable *v = NULL, *tmpvar = NULL;
07620 struct ao2_iterator i;
07621 struct ast_sockaddr addr;
07622
07623 if (!iaxs[callno])
07624 return res;
07625 if (ies->called_number)
07626 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07627 if (ies->calling_number) {
07628 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07629 ast_shrink_phone_number(ies->calling_number);
07630 }
07631 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07632 }
07633 if (ies->calling_name)
07634 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07635 if (ies->calling_ani)
07636 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07637 if (ies->dnid)
07638 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07639 if (ies->rdnis)
07640 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07641 if (ies->called_context)
07642 ast_string_field_set(iaxs[callno], context, ies->called_context);
07643 if (ies->language)
07644 ast_string_field_set(iaxs[callno], language, ies->language);
07645 if (ies->username)
07646 ast_string_field_set(iaxs[callno], username, ies->username);
07647 if (ies->calling_ton > -1)
07648 iaxs[callno]->calling_ton = ies->calling_ton;
07649 if (ies->calling_tns > -1)
07650 iaxs[callno]->calling_tns = ies->calling_tns;
07651 if (ies->calling_pres > -1)
07652 iaxs[callno]->calling_pres = ies->calling_pres;
07653 if (ies->format)
07654 iaxs[callno]->peerformat = ies->format;
07655 if (ies->adsicpe)
07656 iaxs[callno]->peeradsicpe = ies->adsicpe;
07657 if (ies->capability) {
07658 gotcapability = 1;
07659 iaxs[callno]->peercapability = ies->capability;
07660 }
07661 if (ies->version)
07662 version = ies->version;
07663
07664
07665 if (ies->codec_prefs) {
07666 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07667 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07668 }
07669
07670 if (!gotcapability)
07671 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07672 if (version > IAX_PROTO_VERSION) {
07673 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07674 ast_inet_ntoa(sin->sin_addr), version);
07675 return res;
07676 }
07677
07678 ast_sockaddr_from_sin(&addr, sin);
07679 i = ao2_iterator_init(users, 0);
07680 while ((user = ao2_iterator_next(&i))) {
07681 if ((ast_strlen_zero(iaxs[callno]->username) ||
07682 !strcmp(iaxs[callno]->username, user->name))
07683 && ast_apply_ha(user->ha, &addr)
07684 && (ast_strlen_zero(iaxs[callno]->context) ||
07685 apply_context(user->contexts, iaxs[callno]->context))) {
07686 if (!ast_strlen_zero(iaxs[callno]->username)) {
07687
07688 if (best)
07689 user_unref(best);
07690 best = user;
07691 break;
07692 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07693
07694 if (user->ha) {
07695
07696 if (bestscore < 4) {
07697 bestscore = 4;
07698 if (best)
07699 user_unref(best);
07700 best = user;
07701 continue;
07702 }
07703 } else {
07704
07705 if (bestscore < 3) {
07706 bestscore = 3;
07707 if (best)
07708 user_unref(best);
07709 best = user;
07710 continue;
07711 }
07712 }
07713 } else {
07714 if (user->ha) {
07715
07716 if (bestscore < 2) {
07717 bestscore = 2;
07718 if (best)
07719 user_unref(best);
07720 best = user;
07721 continue;
07722 }
07723 } else {
07724
07725 if (bestscore < 1) {
07726 bestscore = 1;
07727 if (best)
07728 user_unref(best);
07729 best = user;
07730 continue;
07731 }
07732 }
07733 }
07734 }
07735 user_unref(user);
07736 }
07737 ao2_iterator_destroy(&i);
07738 user = best;
07739 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07740 user = realtime_user(iaxs[callno]->username, sin);
07741 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07742 !apply_context(user->contexts, iaxs[callno]->context)) {
07743 user = user_unref(user);
07744 }
07745 }
07746 if (user) {
07747
07748
07749 for (v = user->vars ; v ; v = v->next) {
07750 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07751 tmpvar->next = iaxs[callno]->vars;
07752 iaxs[callno]->vars = tmpvar;
07753 }
07754 }
07755
07756 if (user->maxauthreq > 0)
07757 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07758 iaxs[callno]->prefs = user->prefs;
07759 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07760 iaxs[callno]->encmethods = user->encmethods;
07761
07762 if (ast_strlen_zero(iaxs[callno]->username))
07763 ast_string_field_set(iaxs[callno], username, user->name);
07764
07765 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07766 iaxs[callno]->capability = user->capability;
07767
07768 if (ast_strlen_zero(iaxs[callno]->context)) {
07769 if (user->contexts)
07770 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07771 else
07772 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07773 }
07774
07775 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07776
07777 iaxs[callno]->authmethods = user->authmethods;
07778 iaxs[callno]->adsi = user->adsi;
07779
07780 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07781 iaxs[callno]->calling_tns = 0;
07782 iaxs[callno]->calling_ton = 0;
07783 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07784 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07785 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07786 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07787 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07788 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07789 }
07790 if (!ast_strlen_zero(user->accountcode))
07791 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07792 if (!ast_strlen_zero(user->mohinterpret))
07793 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07794 if (!ast_strlen_zero(user->mohsuggest))
07795 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07796 if (!ast_strlen_zero(user->parkinglot))
07797 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07798 if (user->amaflags)
07799 iaxs[callno]->amaflags = user->amaflags;
07800 if (!ast_strlen_zero(user->language))
07801 ast_string_field_set(iaxs[callno], language, user->language);
07802 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07803
07804 if (!ast_strlen_zero(user->dbsecret)) {
07805 char *family, *key=NULL;
07806 char buf[80];
07807 family = ast_strdupa(user->dbsecret);
07808 key = strchr(family, '/');
07809 if (key) {
07810 *key = '\0';
07811 key++;
07812 }
07813 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07814 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07815 else
07816 ast_string_field_set(iaxs[callno], secret, buf);
07817 } else
07818 ast_string_field_set(iaxs[callno], secret, user->secret);
07819 res = 0;
07820 user = user_unref(user);
07821 } else {
07822
07823
07824
07825
07826 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07827 ast_string_field_set(iaxs[callno], secret, "badsecret");
07828 iaxs[callno]->authrej = 1;
07829 if (!ast_strlen_zero(iaxs[callno]->username)) {
07830
07831 res = 0;
07832 }
07833 }
07834 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07835 return res;
07836 }
07837
07838 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07839 {
07840 struct ast_iax2_full_hdr fh;
07841 fh.scallno = htons(src | IAX_FLAG_FULL);
07842 fh.dcallno = htons(dst);
07843 fh.ts = 0;
07844 fh.oseqno = 0;
07845 fh.iseqno = 0;
07846 fh.type = AST_FRAME_IAX;
07847 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07848 iax_outputframe(NULL, &fh, 0, sin, 0);
07849 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07850 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07851 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07852 }
07853
07854 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07855 {
07856
07857 p->encmethods &= enc;
07858 if (p->encmethods) {
07859 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07860 p->keyrotateid = -2;
07861 }
07862 if (p->encmethods & IAX_ENCRYPT_AES128)
07863 p->encmethods = IAX_ENCRYPT_AES128;
07864 else
07865 p->encmethods = 0;
07866 }
07867 }
07868
07869
07870
07871
07872
07873
07874
07875 static int authenticate_request(int call_num)
07876 {
07877 struct iax_ie_data ied;
07878 int res = -1, authreq_restrict = 0;
07879 char challenge[10];
07880 struct chan_iax2_pvt *p = iaxs[call_num];
07881
07882 memset(&ied, 0, sizeof(ied));
07883
07884
07885 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07886 struct iax2_user *user;
07887
07888 user = ao2_find(users, p->username, OBJ_KEY);
07889 if (user) {
07890 if (user->curauthreq == user->maxauthreq)
07891 authreq_restrict = 1;
07892 else
07893 user->curauthreq++;
07894 user = user_unref(user);
07895 }
07896 }
07897
07898
07899 if (authreq_restrict) {
07900 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07901 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07902 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07903 return 0;
07904 }
07905
07906 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07907 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07908 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07909 ast_string_field_set(p, challenge, challenge);
07910
07911 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07912 }
07913 if (p->encmethods)
07914 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07915
07916 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07917
07918 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07919
07920 if (p->encmethods)
07921 ast_set_flag64(p, IAX_ENCRYPTED);
07922
07923 return res;
07924 }
07925
07926 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07927 {
07928 char requeststr[256];
07929 char md5secret[256] = "";
07930 char secret[256] = "";
07931 char rsasecret[256] = "";
07932 int res = -1;
07933 int x;
07934 struct iax2_user *user;
07935
07936 if (p->authrej) {
07937 return res;
07938 }
07939 user = ao2_find(users, p->username, OBJ_KEY);
07940 if (user) {
07941 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07942 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07943 ast_clear_flag64(p, IAX_MAXAUTHREQ);
07944 }
07945 ast_string_field_set(p, host, user->name);
07946 user = user_unref(user);
07947 }
07948 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07949 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07950 return res;
07951 }
07952 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07953 return res;
07954 if (ies->password)
07955 ast_copy_string(secret, ies->password, sizeof(secret));
07956 if (ies->md5_result)
07957 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07958 if (ies->rsa_result)
07959 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07960 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07961 struct ast_key *key;
07962 char *keyn;
07963 char tmpkey[256];
07964 char *stringp=NULL;
07965 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07966 stringp=tmpkey;
07967 keyn = strsep(&stringp, ":");
07968 while(keyn) {
07969 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07970 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07971 res = 0;
07972 break;
07973 } else if (!key)
07974 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07975 keyn = strsep(&stringp, ":");
07976 }
07977 } else if (p->authmethods & IAX_AUTH_MD5) {
07978 struct MD5Context md5;
07979 unsigned char digest[16];
07980 char *tmppw, *stringp;
07981
07982 tmppw = ast_strdupa(p->secret);
07983 stringp = tmppw;
07984 while((tmppw = strsep(&stringp, ";"))) {
07985 MD5Init(&md5);
07986 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07987 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07988 MD5Final(digest, &md5);
07989
07990 for (x=0;x<16;x++)
07991 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07992 if (!strcasecmp(requeststr, md5secret)) {
07993 res = 0;
07994 break;
07995 }
07996 }
07997 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07998 if (!strcmp(secret, p->secret))
07999 res = 0;
08000 }
08001 return res;
08002 }
08003
08004
08005 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
08006 {
08007 char requeststr[256] = "";
08008 char peer[256] = "";
08009 char md5secret[256] = "";
08010 char rsasecret[256] = "";
08011 char secret[256] = "";
08012 struct iax2_peer *p = NULL;
08013 struct ast_key *key;
08014 char *keyn;
08015 int x;
08016 int expire = 0;
08017 int res = -1;
08018 struct ast_sockaddr addr;
08019
08020 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08021
08022 if (ies->username)
08023 ast_copy_string(peer, ies->username, sizeof(peer));
08024 if (ies->password)
08025 ast_copy_string(secret, ies->password, sizeof(secret));
08026 if (ies->md5_result)
08027 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
08028 if (ies->rsa_result)
08029 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
08030 if (ies->refresh)
08031 expire = ies->refresh;
08032
08033 if (ast_strlen_zero(peer)) {
08034 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
08035 return -1;
08036 }
08037
08038
08039 ast_mutex_unlock(&iaxsl[callno]);
08040 p = find_peer(peer, 1);
08041 ast_mutex_lock(&iaxsl[callno]);
08042 if (!p || !iaxs[callno]) {
08043 if (iaxs[callno]) {
08044 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
08045
08046 ast_string_field_set(iaxs[callno], secret, "badsecret");
08047
08048
08049
08050
08051
08052
08053
08054
08055
08056 if (ast_strlen_zero(iaxs[callno]->challenge) &&
08057 !(!ast_strlen_zero(secret) && plaintext)) {
08058
08059 res = 0;
08060 }
08061 }
08062 if (authdebug && !p)
08063 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08064 goto return_unref;
08065 }
08066
08067 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
08068 if (authdebug)
08069 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
08070 goto return_unref;
08071 }
08072
08073 ast_sockaddr_from_sin(&addr, sin);
08074 if (!ast_apply_ha(p->ha, &addr)) {
08075 if (authdebug)
08076 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08077 goto return_unref;
08078 }
08079 ast_string_field_set(iaxs[callno], secret, p->secret);
08080 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
08081
08082 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08083 if (!ast_strlen_zero(p->inkeys)) {
08084 char tmpkeys[256];
08085 char *stringp=NULL;
08086 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
08087 stringp=tmpkeys;
08088 keyn = strsep(&stringp, ":");
08089 while(keyn) {
08090 key = ast_key_get(keyn, AST_KEY_PUBLIC);
08091 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
08092 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08093 break;
08094 } else if (!key)
08095 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08096 keyn = strsep(&stringp, ":");
08097 }
08098 if (!keyn) {
08099 if (authdebug)
08100 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08101 goto return_unref;
08102 }
08103 } else {
08104 if (authdebug)
08105 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08106 goto return_unref;
08107 }
08108 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08109 struct MD5Context md5;
08110 unsigned char digest[16];
08111 char *tmppw, *stringp;
08112
08113 tmppw = ast_strdupa(p->secret);
08114 stringp = tmppw;
08115 while((tmppw = strsep(&stringp, ";"))) {
08116 MD5Init(&md5);
08117 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08118 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08119 MD5Final(digest, &md5);
08120 for (x=0;x<16;x++)
08121 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08122 if (!strcasecmp(requeststr, md5secret))
08123 break;
08124 }
08125 if (tmppw) {
08126 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08127 } else {
08128 if (authdebug)
08129 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08130 goto return_unref;
08131 }
08132 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08133
08134 if (strcmp(secret, p->secret)) {
08135 if (authdebug)
08136 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08137 goto return_unref;
08138 } else
08139 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08140 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08141
08142 goto return_unref;
08143 }
08144 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08145
08146
08147 res = 0;
08148
08149 return_unref:
08150 if (iaxs[callno]) {
08151 ast_string_field_set(iaxs[callno], peer, peer);
08152
08153
08154 if (expire && (expire < iaxs[callno]->expiry)) {
08155 iaxs[callno]->expiry = expire;
08156 }
08157 }
08158
08159 if (p) {
08160 peer_unref(p);
08161 }
08162 return res;
08163 }
08164
08165 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)
08166 {
08167 int res = -1;
08168 int x;
08169 if (!ast_strlen_zero(keyn)) {
08170 if (!(authmethods & IAX_AUTH_RSA)) {
08171 if (ast_strlen_zero(secret))
08172 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));
08173 } else if (ast_strlen_zero(challenge)) {
08174 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08175 } else {
08176 char sig[256];
08177 struct ast_key *key;
08178 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08179 if (!key) {
08180 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08181 } else {
08182 if (ast_sign(key, (char*)challenge, sig)) {
08183 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08184 res = -1;
08185 } else {
08186 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08187 res = 0;
08188 }
08189 }
08190 }
08191 }
08192
08193 if (res && !ast_strlen_zero(secret)) {
08194 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08195 struct MD5Context md5;
08196 unsigned char digest[16];
08197 char digres[128];
08198 MD5Init(&md5);
08199 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08200 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08201 MD5Final(digest, &md5);
08202
08203 for (x=0;x<16;x++)
08204 sprintf(digres + (x << 1), "%2.2x", digest[x]);
08205 if (pvt) {
08206 build_encryption_keys(digest, pvt);
08207 }
08208 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08209 res = 0;
08210 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08211 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08212 res = 0;
08213 } else
08214 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08215 }
08216 return res;
08217 }
08218
08219
08220
08221
08222
08223 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08224 {
08225 struct iax2_peer *peer = NULL;
08226
08227 int res = -1;
08228 int authmethods = 0;
08229 struct iax_ie_data ied;
08230 uint16_t callno = p->callno;
08231
08232 memset(&ied, 0, sizeof(ied));
08233
08234 if (ies->username)
08235 ast_string_field_set(p, username, ies->username);
08236 if (ies->challenge)
08237 ast_string_field_set(p, challenge, ies->challenge);
08238 if (ies->authmethods)
08239 authmethods = ies->authmethods;
08240 if (authmethods & IAX_AUTH_MD5)
08241 merge_encryption(p, ies->encmethods);
08242 else
08243 p->encmethods = 0;
08244
08245
08246 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08247
08248 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08249 } else {
08250 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08251 while ((peer = ao2_iterator_next(&i))) {
08252 struct sockaddr_in peer_addr;
08253
08254 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08255
08256 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08257
08258 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08259
08260 && (!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)))
08261
08262 ) {
08263 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08264 if (!res) {
08265 peer_unref(peer);
08266 break;
08267 }
08268 }
08269 peer_unref(peer);
08270 }
08271 ao2_iterator_destroy(&i);
08272 if (!peer) {
08273
08274
08275 const char *peer_name = ast_strdupa(p->peer);
08276 ast_mutex_unlock(&iaxsl[callno]);
08277 if ((peer = realtime_peer(peer_name, NULL))) {
08278 ast_mutex_lock(&iaxsl[callno]);
08279 if (!(p = iaxs[callno])) {
08280 peer_unref(peer);
08281 return -1;
08282 }
08283 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08284 peer_unref(peer);
08285 }
08286 if (!peer) {
08287 ast_mutex_lock(&iaxsl[callno]);
08288 if (!(p = iaxs[callno]))
08289 return -1;
08290 }
08291 }
08292 }
08293
08294 if (ies->encmethods) {
08295 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08296 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08297 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08298 return -1;
08299 }
08300 if (!res) {
08301 struct ast_datastore *variablestore;
08302 struct ast_variable *var, *prev = NULL;
08303 AST_LIST_HEAD(, ast_var_t) *varlist;
08304 varlist = ast_calloc(1, sizeof(*varlist));
08305 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08306 if (variablestore && varlist && p->owner) {
08307 variablestore->data = varlist;
08308 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08309 AST_LIST_HEAD_INIT(varlist);
08310 for (var = ies->vars; var; var = var->next) {
08311 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08312 if (prev)
08313 ast_free(prev);
08314 prev = var;
08315 if (!newvar) {
08316
08317 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08318 } else {
08319 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08320 }
08321 }
08322 if (prev)
08323 ast_free(prev);
08324 ies->vars = NULL;
08325 ast_channel_datastore_add(p->owner, variablestore);
08326 } else {
08327 if (p->owner)
08328 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08329 if (variablestore)
08330 ast_datastore_free(variablestore);
08331 if (varlist)
08332 ast_free(varlist);
08333 }
08334 }
08335
08336 if (!res)
08337 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08338 return res;
08339 }
08340
08341 static int iax2_do_register(struct iax2_registry *reg);
08342
08343 static void __iax2_do_register_s(const void *data)
08344 {
08345 struct iax2_registry *reg = (struct iax2_registry *)data;
08346 reg->expire = -1;
08347 iax2_do_register(reg);
08348 }
08349
08350 static int iax2_do_register_s(const void *data)
08351 {
08352 #ifdef SCHED_MULTITHREADED
08353 if (schedule_action(__iax2_do_register_s, data))
08354 #endif
08355 __iax2_do_register_s(data);
08356 return 0;
08357 }
08358
08359 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08360 {
08361 int newcall = 0;
08362 char newip[256];
08363 struct iax_ie_data ied;
08364 struct sockaddr_in new;
08365
08366
08367 memset(&ied, 0, sizeof(ied));
08368 if (ies->apparent_addr)
08369 memmove(&new, ies->apparent_addr, sizeof(new));
08370 if (ies->callno)
08371 newcall = ies->callno;
08372 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08373 ast_log(LOG_WARNING, "Invalid transfer request\n");
08374 return -1;
08375 }
08376 pvt->transfercallno = newcall;
08377 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08378 inet_aton(newip, &pvt->transfer.sin_addr);
08379 pvt->transfer.sin_family = AF_INET;
08380 pvt->transferid = ies->transferid;
08381
08382
08383 if (pvt->transferring == TRANSFER_NONE) {
08384 store_by_transfercallno(pvt);
08385 }
08386 pvt->transferring = TRANSFER_BEGIN;
08387
08388 if (ies->transferid)
08389 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08390 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08391 return 0;
08392 }
08393
08394 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08395 {
08396 char exten[256] = "";
08397 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08398 struct iax2_dpcache *dp = NULL;
08399
08400 if (ies->called_number)
08401 ast_copy_string(exten, ies->called_number, sizeof(exten));
08402
08403 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08404 status = CACHE_FLAG_EXISTS;
08405 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08406 status = CACHE_FLAG_CANEXIST;
08407 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08408 status = CACHE_FLAG_NONEXISTENT;
08409
08410 if (ies->refresh)
08411 expiry = ies->refresh;
08412 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08413 matchmore = CACHE_FLAG_MATCHMORE;
08414
08415 AST_LIST_LOCK(&dpcache);
08416 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08417 if (strcmp(dp->exten, exten))
08418 continue;
08419 AST_LIST_REMOVE_CURRENT(peer_list);
08420 dp->callno = 0;
08421 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08422 if (dp->flags & CACHE_FLAG_PENDING) {
08423 dp->flags &= ~CACHE_FLAG_PENDING;
08424 dp->flags |= status;
08425 dp->flags |= matchmore;
08426 }
08427
08428 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08429 if (dp->waiters[x] > -1) {
08430 if (write(dp->waiters[x], "asdf", 4) < 0) {
08431 }
08432 }
08433 }
08434 }
08435 AST_LIST_TRAVERSE_SAFE_END;
08436 AST_LIST_UNLOCK(&dpcache);
08437
08438 return 0;
08439 }
08440
08441 static int complete_transfer(int callno, struct iax_ies *ies)
08442 {
08443 int peercallno = 0;
08444 struct chan_iax2_pvt *pvt = iaxs[callno];
08445 struct iax_frame *cur;
08446 jb_frame frame;
08447
08448 if (ies->callno)
08449 peercallno = ies->callno;
08450
08451 if (peercallno < 1) {
08452 ast_log(LOG_WARNING, "Invalid transfer request\n");
08453 return -1;
08454 }
08455 remove_by_transfercallno(pvt);
08456
08457
08458
08459 peercnt_remove_by_addr(&pvt->addr);
08460 peercnt_add(&pvt->transfer);
08461
08462 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08463 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08464
08465 pvt->oseqno = 0;
08466 pvt->rseqno = 0;
08467 pvt->iseqno = 0;
08468 pvt->aseqno = 0;
08469
08470 if (pvt->peercallno) {
08471 remove_by_peercallno(pvt);
08472 }
08473 pvt->peercallno = peercallno;
08474
08475 store_by_peercallno(pvt);
08476 pvt->transferring = TRANSFER_NONE;
08477 pvt->svoiceformat = -1;
08478 pvt->voiceformat = 0;
08479 pvt->svideoformat = -1;
08480 pvt->videoformat = 0;
08481 pvt->transfercallno = 0;
08482 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08483 memset(&pvt->offset, 0, sizeof(pvt->offset));
08484
08485 while(jb_getall(pvt->jb,&frame) == JB_OK)
08486 iax2_frame_free(frame.data);
08487 jb_reset(pvt->jb);
08488 pvt->lag = 0;
08489 pvt->last = 0;
08490 pvt->lastsent = 0;
08491 pvt->nextpred = 0;
08492 pvt->pingtime = DEFAULT_RETRY_TIME;
08493 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08494
08495
08496
08497 cur->retries = -1;
08498 }
08499 return 0;
08500 }
08501
08502
08503 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08504 {
08505 struct iax2_registry *reg;
08506
08507 char peer[256] = "";
08508 char msgstatus[60];
08509 int refresh = 60;
08510 char ourip[256] = "<Unspecified>";
08511 struct sockaddr_in oldus;
08512 struct sockaddr_in us;
08513 int oldmsgs;
08514 struct sockaddr_in reg_addr;
08515
08516 memset(&us, 0, sizeof(us));
08517 if (ies->apparent_addr) {
08518 memmove(&us, ies->apparent_addr, sizeof(us));
08519 }
08520 if (ies->username) {
08521 ast_copy_string(peer, ies->username, sizeof(peer));
08522 }
08523 if (ies->refresh) {
08524 refresh = ies->refresh;
08525 }
08526 if (ies->calling_number) {
08527
08528 }
08529 reg = iaxs[callno]->reg;
08530 if (!reg) {
08531 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08532 return -1;
08533 }
08534 memcpy(&oldus, ®->us, sizeof(oldus));
08535 oldmsgs = reg->messages;
08536 ast_sockaddr_to_sin(®->addr, ®_addr);
08537 if (inaddrcmp(®_addr, sin)) {
08538 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08539 return -1;
08540 }
08541 memcpy(®->us, &us, sizeof(reg->us));
08542 if (ies->msgcount >= 0) {
08543 reg->messages = ies->msgcount & 0xffff;
08544 }
08545
08546
08547
08548 reg->refresh = refresh;
08549 reg->expire = iax2_sched_replace(reg->expire, sched,
08550 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08551 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08552 if (reg->messages > 255) {
08553 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08554 } else if (reg->messages > 1) {
08555 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08556 } else if (reg->messages > 0) {
08557 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08558 } else {
08559 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08560 }
08561 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08562 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08563 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08564 }
08565 reg->regstate = REG_STATE_REGISTERED;
08566 return 0;
08567 }
08568
08569 static int iax2_append_register(const char *hostname, const char *username,
08570 const char *secret, const char *porta)
08571 {
08572 struct iax2_registry *reg;
08573
08574 if (!(reg = ast_calloc(1, sizeof(*reg))))
08575 return -1;
08576
08577 reg->addr.ss.ss_family = AF_INET;
08578 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08579 ast_free(reg);
08580 return -1;
08581 }
08582
08583 ast_copy_string(reg->username, username, sizeof(reg->username));
08584
08585 if (secret)
08586 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08587
08588 reg->expire = -1;
08589 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08590 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08591
08592 AST_LIST_LOCK(®istrations);
08593 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08594 AST_LIST_UNLOCK(®istrations);
08595
08596 return 0;
08597 }
08598
08599 static int iax2_register(const char *value, int lineno)
08600 {
08601 char copy[256];
08602 char *username, *hostname, *secret;
08603 char *porta;
08604 char *stringp=NULL;
08605
08606 if (!value)
08607 return -1;
08608
08609 ast_copy_string(copy, value, sizeof(copy));
08610 stringp = copy;
08611 username = strsep(&stringp, "@");
08612 hostname = strsep(&stringp, "@");
08613
08614 if (!hostname) {
08615 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08616 return -1;
08617 }
08618
08619 stringp = username;
08620 username = strsep(&stringp, ":");
08621 secret = strsep(&stringp, ":");
08622 stringp = hostname;
08623 hostname = strsep(&stringp, ":");
08624 porta = strsep(&stringp, ":");
08625
08626 if (porta && !atoi(porta)) {
08627 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08628 return -1;
08629 }
08630
08631 return iax2_append_register(hostname, username, secret, porta);
08632 }
08633
08634
08635 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08636 {
08637 char multi[256];
08638 char *stringp, *ext;
08639 if (!ast_strlen_zero(regcontext)) {
08640 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08641 stringp = multi;
08642 while((ext = strsep(&stringp, "&"))) {
08643 if (onoff) {
08644 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08645 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08646 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08647 } else
08648 ast_context_remove_extension(regcontext, ext, 1, NULL);
08649 }
08650 }
08651 }
08652 static void prune_peers(void);
08653
08654 static void unlink_peer(struct iax2_peer *peer)
08655 {
08656 if (peer->expire > -1) {
08657 if (!AST_SCHED_DEL(sched, peer->expire)) {
08658 peer->expire = -1;
08659 peer_unref(peer);
08660 }
08661 }
08662
08663 if (peer->pokeexpire > -1) {
08664 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
08665 peer->pokeexpire = -1;
08666 peer_unref(peer);
08667 }
08668 }
08669
08670 ao2_unlink(peers, peer);
08671 }
08672
08673 static void __expire_registry(const void *data)
08674 {
08675 struct iax2_peer *peer = (struct iax2_peer *) data;
08676
08677 if (!peer)
08678 return;
08679 if (peer->expire == -1) {
08680
08681 return;
08682 }
08683
08684 peer->expire = -1;
08685
08686 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08687 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08688 realtime_update_peer(peer->name, &peer->addr, 0);
08689 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08690
08691 peercnt_modify(0, 0, &peer->addr);
08692
08693 memset(&peer->addr, 0, sizeof(peer->addr));
08694
08695 peer->expiry = min_reg_expire;
08696 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08697 ast_db_del("IAX/Registry", peer->name);
08698 register_peer_exten(peer, 0);
08699 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08700 if (iax2_regfunk)
08701 iax2_regfunk(peer->name, 0);
08702
08703 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08704 unlink_peer(peer);
08705
08706 peer_unref(peer);
08707 }
08708
08709 static int expire_registry(const void *data)
08710 {
08711 #ifdef SCHED_MULTITHREADED
08712 if (schedule_action(__expire_registry, data))
08713 #endif
08714 __expire_registry(data);
08715 return 0;
08716 }
08717
08718 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08719
08720 static void reg_source_db(struct iax2_peer *p)
08721 {
08722 char data[80];
08723 char *expiry;
08724
08725 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08726 return;
08727 }
08728
08729 expiry = strrchr(data, ':');
08730 if (!expiry) {
08731 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08732 }
08733 *expiry++ = '\0';
08734
08735 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08736 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08737 return;
08738 }
08739
08740 p->expiry = atoi(expiry);
08741
08742 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08743 ast_sockaddr_stringify(&p->addr), p->expiry);
08744
08745 iax2_poke_peer(p, 0);
08746 if (p->expire > -1) {
08747 if (!AST_SCHED_DEL(sched, p->expire)) {
08748 p->expire = -1;
08749 peer_unref(p);
08750 }
08751 }
08752
08753 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08754
08755 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08756 if (p->expire == -1) {
08757 peer_unref(p);
08758 }
08759
08760 if (iax2_regfunk) {
08761 iax2_regfunk(p->name, 1);
08762 }
08763
08764 register_peer_exten(p, 1);
08765 }
08766
08767
08768
08769
08770
08771
08772
08773 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08774 {
08775
08776 struct iax_ie_data ied = {
08777 .pos = 0,
08778 };
08779 struct iax2_peer *p;
08780 int msgcount;
08781 char data[80];
08782 int version;
08783 const char *peer_name;
08784 int res = -1;
08785 struct ast_sockaddr sockaddr;
08786
08787 ast_sockaddr_from_sin(&sockaddr, sin);
08788
08789 peer_name = ast_strdupa(iaxs[callno]->peer);
08790
08791
08792 ast_mutex_unlock(&iaxsl[callno]);
08793 if (!(p = find_peer(peer_name, 1))) {
08794 ast_mutex_lock(&iaxsl[callno]);
08795 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08796 return -1;
08797 }
08798 ast_mutex_lock(&iaxsl[callno]);
08799 if (!iaxs[callno])
08800 goto return_unref;
08801
08802 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08803 if (sin->sin_addr.s_addr) {
08804 time_t nowtime;
08805 time(&nowtime);
08806 realtime_update_peer(peer_name, &sockaddr, nowtime);
08807 } else {
08808 realtime_update_peer(peer_name, &sockaddr, 0);
08809 }
08810 }
08811
08812 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08813 if (iax2_regfunk) {
08814 iax2_regfunk(p->name, 1);
08815 }
08816
08817
08818 peercnt_modify(0, 0, &p->addr);
08819
08820
08821 ast_sockaddr_from_sin(&p->addr, sin);
08822
08823 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08824 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08825 ast_db_put("IAX/Registry", p->name, data);
08826 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08827 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08828 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPost: %d\r\n", p->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08829 register_peer_exten(p, 1);
08830 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08831 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08832 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08833 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08834 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08835 register_peer_exten(p, 0);
08836 ast_db_del("IAX/Registry", p->name);
08837 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08838 }
08839
08840
08841 iax2_poke_peer(p, callno);
08842 }
08843
08844
08845 if (p->maxcallno) {
08846 peercnt_modify(1, p->maxcallno, &p->addr);
08847 }
08848
08849
08850 if (!iaxs[callno]) {
08851 res = -1;
08852 goto return_unref;
08853 }
08854
08855
08856 p->sockfd = fd;
08857
08858 if (p->expire > -1) {
08859 if (!AST_SCHED_DEL(sched, p->expire)) {
08860 p->expire = -1;
08861 peer_unref(p);
08862 }
08863 }
08864
08865 if (!refresh)
08866 refresh = min_reg_expire;
08867 if (refresh > max_reg_expire) {
08868 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08869 p->name, max_reg_expire, refresh);
08870 p->expiry = max_reg_expire;
08871 } else if (refresh < min_reg_expire) {
08872 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08873 p->name, min_reg_expire, refresh);
08874 p->expiry = min_reg_expire;
08875 } else {
08876 p->expiry = refresh;
08877 }
08878 if (p->expiry && sin->sin_addr.s_addr) {
08879 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08880 if (p->expire == -1)
08881 peer_unref(p);
08882 }
08883 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08884 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08885 if (sin->sin_addr.s_addr) {
08886 struct sockaddr_in peer_addr;
08887
08888 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08889
08890 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08891 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08892 if (!ast_strlen_zero(p->mailbox)) {
08893 struct ast_event *event;
08894 int new, old;
08895 char *mailbox, *context;
08896
08897 context = mailbox = ast_strdupa(p->mailbox);
08898 strsep(&context, "@");
08899 if (ast_strlen_zero(context))
08900 context = "default";
08901
08902 event = ast_event_get_cached(AST_EVENT_MWI,
08903 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08904 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08905 AST_EVENT_IE_END);
08906 if (event) {
08907 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08908 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08909 ast_event_destroy(event);
08910 } else {
08911 ast_app_inboxcount(p->mailbox, &new, &old);
08912 }
08913
08914 if (new > 255) {
08915 new = 255;
08916 }
08917 if (old > 255) {
08918 old = 255;
08919 }
08920 msgcount = (old << 8) | new;
08921
08922 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08923 }
08924 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08925 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08926 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08927 }
08928 }
08929 version = iax_check_version(devtype);
08930 if (version)
08931 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08932
08933 res = 0;
08934
08935 return_unref:
08936 peer_unref(p);
08937
08938 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08939 }
08940
08941 static int registry_authrequest(int callno)
08942 {
08943 struct iax_ie_data ied;
08944 struct iax2_peer *p;
08945 char challenge[10];
08946 const char *peer_name;
08947 int sentauthmethod;
08948
08949 peer_name = ast_strdupa(iaxs[callno]->peer);
08950
08951
08952 ast_mutex_unlock(&iaxsl[callno]);
08953 if ((p = find_peer(peer_name, 1))) {
08954 last_authmethod = p->authmethods;
08955 }
08956
08957 ast_mutex_lock(&iaxsl[callno]);
08958 if (!iaxs[callno])
08959 goto return_unref;
08960
08961 memset(&ied, 0, sizeof(ied));
08962
08963
08964
08965
08966
08967
08968 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08969 if (!p) {
08970 iaxs[callno]->authmethods = sentauthmethod;
08971 }
08972 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08973 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08974
08975 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08976 ast_string_field_set(iaxs[callno], challenge, challenge);
08977 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08978 }
08979 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08980
08981 return_unref:
08982 if (p) {
08983 peer_unref(p);
08984 }
08985
08986 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08987 }
08988
08989 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08990 {
08991 struct iax2_registry *reg;
08992
08993 struct iax_ie_data ied;
08994 char peer[256] = "";
08995 char challenge[256] = "";
08996 int res;
08997 int authmethods = 0;
08998 if (ies->authmethods)
08999 authmethods = ies->authmethods;
09000 if (ies->username)
09001 ast_copy_string(peer, ies->username, sizeof(peer));
09002 if (ies->challenge)
09003 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
09004 memset(&ied, 0, sizeof(ied));
09005 reg = iaxs[callno]->reg;
09006 if (reg) {
09007 struct sockaddr_in reg_addr;
09008
09009 ast_sockaddr_to_sin(®->addr, ®_addr);
09010
09011 if (inaddrcmp(®_addr, sin)) {
09012 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
09013 return -1;
09014 }
09015 if (ast_strlen_zero(reg->secret)) {
09016 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
09017 reg->regstate = REG_STATE_NOAUTH;
09018 return -1;
09019 }
09020 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
09021 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
09022 if (reg->secret[0] == '[') {
09023 char tmpkey[256];
09024 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
09025 tmpkey[strlen(tmpkey) - 1] = '\0';
09026 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
09027 } else
09028 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
09029 if (!res) {
09030 reg->regstate = REG_STATE_AUTHSENT;
09031 add_empty_calltoken_ie(iaxs[callno], &ied);
09032 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
09033 } else
09034 return -1;
09035 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
09036 } else
09037 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
09038 return -1;
09039 }
09040
09041 static void stop_stuff(int callno)
09042 {
09043 iax2_destroy_helper(iaxs[callno]);
09044 }
09045
09046 static void __auth_reject(const void *nothing)
09047 {
09048
09049 int callno = (int)(long)(nothing);
09050 struct iax_ie_data ied;
09051 ast_mutex_lock(&iaxsl[callno]);
09052 if (iaxs[callno]) {
09053 memset(&ied, 0, sizeof(ied));
09054 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
09055 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
09056 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
09057 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
09058 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
09059 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09060 }
09061 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
09062 }
09063 ast_mutex_unlock(&iaxsl[callno]);
09064 }
09065
09066 static int auth_reject(const void *data)
09067 {
09068 int callno = (int)(long)(data);
09069 ast_mutex_lock(&iaxsl[callno]);
09070 if (iaxs[callno])
09071 iaxs[callno]->authid = -1;
09072 ast_mutex_unlock(&iaxsl[callno]);
09073 #ifdef SCHED_MULTITHREADED
09074 if (schedule_action(__auth_reject, data))
09075 #endif
09076 __auth_reject(data);
09077 return 0;
09078 }
09079
09080 static int auth_fail(int callno, int failcode)
09081 {
09082
09083
09084 if (iaxs[callno]) {
09085 iaxs[callno]->authfail = failcode;
09086 if (delayreject) {
09087 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
09088 sched, 1000, auth_reject, (void *)(long)callno);
09089 } else
09090 auth_reject((void *)(long)callno);
09091 }
09092 return 0;
09093 }
09094
09095 static void __auto_hangup(const void *nothing)
09096 {
09097
09098 int callno = (int)(long)(nothing);
09099 struct iax_ie_data ied;
09100 ast_mutex_lock(&iaxsl[callno]);
09101 if (iaxs[callno]) {
09102 memset(&ied, 0, sizeof(ied));
09103 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09104 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09105 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09106 }
09107 ast_mutex_unlock(&iaxsl[callno]);
09108 }
09109
09110 static int auto_hangup(const void *data)
09111 {
09112 int callno = (int)(long)(data);
09113 ast_mutex_lock(&iaxsl[callno]);
09114 if (iaxs[callno]) {
09115 iaxs[callno]->autoid = -1;
09116 }
09117 ast_mutex_unlock(&iaxsl[callno]);
09118 #ifdef SCHED_MULTITHREADED
09119 if (schedule_action(__auto_hangup, data))
09120 #endif
09121 __auto_hangup(data);
09122 return 0;
09123 }
09124
09125 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09126 {
09127 struct iax_ie_data ied;
09128
09129 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09130 sched, 30000, auto_hangup, (void *)(long)callno);
09131 memset(&ied, 0, sizeof(ied));
09132 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09133 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09134 dp->flags |= CACHE_FLAG_TRANSMITTED;
09135 }
09136
09137 static int iax2_vnak(int callno)
09138 {
09139 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09140 }
09141
09142 static void vnak_retransmit(int callno, int last)
09143 {
09144 struct iax_frame *f;
09145
09146 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09147
09148 if (((unsigned char) (f->oseqno - last) < 128) &&
09149 (f->retries >= 0)) {
09150 send_packet(f);
09151 }
09152 }
09153 }
09154
09155 static void __iax2_poke_peer_s(const void *data)
09156 {
09157 struct iax2_peer *peer = (struct iax2_peer *)data;
09158 iax2_poke_peer(peer, 0);
09159 peer_unref(peer);
09160 }
09161
09162 static int iax2_poke_peer_s(const void *data)
09163 {
09164 struct iax2_peer *peer = (struct iax2_peer *)data;
09165 peer->pokeexpire = -1;
09166 #ifdef SCHED_MULTITHREADED
09167 if (schedule_action(__iax2_poke_peer_s, data))
09168 #endif
09169 __iax2_poke_peer_s(data);
09170 return 0;
09171 }
09172
09173 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09174 {
09175 int res = 0;
09176 struct iax_frame *fr;
09177 struct ast_iax2_meta_hdr *meta;
09178 struct ast_iax2_meta_trunk_hdr *mth;
09179 int calls = 0;
09180
09181
09182 fr = (struct iax_frame *)tpeer->trunkdata;
09183
09184 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09185 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09186 if (tpeer->trunkdatalen) {
09187
09188 meta->zeros = 0;
09189 meta->metacmd = IAX_META_TRUNK;
09190 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09191 meta->cmddata = IAX_META_TRUNK_MINI;
09192 else
09193 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09194 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09195
09196 fr->direction = DIRECTION_OUTGRESS;
09197 fr->retrans = -1;
09198 fr->transfer = 0;
09199
09200 fr->data = fr->afdata;
09201 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09202 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09203 calls = tpeer->calls;
09204 #if 0
09205 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));
09206 #endif
09207
09208 tpeer->trunkdatalen = 0;
09209 tpeer->calls = 0;
09210 }
09211 if (res < 0)
09212 return res;
09213 return calls;
09214 }
09215
09216 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09217 {
09218
09219 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09220 return 1;
09221 return 0;
09222 }
09223
09224 static int timing_read(int *id, int fd, short events, void *cbdata)
09225 {
09226 int res, processed = 0, totalcalls = 0;
09227 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09228 struct timeval now = ast_tvnow();
09229
09230 if (iaxtrunkdebug)
09231 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09232
09233 if (timer) {
09234 ast_timer_ack(timer, 1);
09235 }
09236
09237
09238 AST_LIST_LOCK(&tpeers);
09239 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09240 processed++;
09241 res = 0;
09242 ast_mutex_lock(&tpeer->lock);
09243
09244
09245 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09246
09247
09248 AST_LIST_REMOVE_CURRENT(list);
09249 drop = tpeer;
09250 } else {
09251 res = send_trunk(tpeer, &now);
09252 trunk_timed++;
09253 if (iaxtrunkdebug)
09254 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);
09255 }
09256 totalcalls += res;
09257 res = 0;
09258 ast_mutex_unlock(&tpeer->lock);
09259 }
09260 AST_LIST_TRAVERSE_SAFE_END;
09261 AST_LIST_UNLOCK(&tpeers);
09262
09263 if (drop) {
09264 ast_mutex_lock(&drop->lock);
09265
09266
09267 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09268 if (drop->trunkdata) {
09269 ast_free(drop->trunkdata);
09270 drop->trunkdata = NULL;
09271 }
09272 ast_mutex_unlock(&drop->lock);
09273 ast_mutex_destroy(&drop->lock);
09274 ast_free(drop);
09275 }
09276
09277 if (iaxtrunkdebug)
09278 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09279 iaxtrunkdebug = 0;
09280
09281 return 1;
09282 }
09283
09284 struct dpreq_data {
09285 int callno;
09286 char context[AST_MAX_EXTENSION];
09287 char callednum[AST_MAX_EXTENSION];
09288 char *callerid;
09289 };
09290
09291 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09292 {
09293 unsigned short dpstatus = 0;
09294 struct iax_ie_data ied1;
09295 int mm;
09296
09297 memset(&ied1, 0, sizeof(ied1));
09298 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09299
09300 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09301 dpstatus = IAX_DPSTATUS_EXISTS;
09302 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09303 dpstatus = IAX_DPSTATUS_CANEXIST;
09304 } else {
09305 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09306 }
09307 if (ast_ignore_pattern(context, callednum))
09308 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09309 if (mm)
09310 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09311 if (!skiplock)
09312 ast_mutex_lock(&iaxsl[callno]);
09313 if (iaxs[callno]) {
09314 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09315 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09316 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09317 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09318 }
09319 if (!skiplock)
09320 ast_mutex_unlock(&iaxsl[callno]);
09321 }
09322
09323 static void *dp_lookup_thread(void *data)
09324 {
09325
09326 struct dpreq_data *dpr = data;
09327 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09328 if (dpr->callerid)
09329 ast_free(dpr->callerid);
09330 ast_free(dpr);
09331 return NULL;
09332 }
09333
09334 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09335 {
09336 pthread_t newthread;
09337 struct dpreq_data *dpr;
09338
09339 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09340 return;
09341
09342 dpr->callno = callno;
09343 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09344 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09345 if (callerid)
09346 dpr->callerid = ast_strdup(callerid);
09347 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09348 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09349 }
09350 }
09351
09352 struct iax_dual {
09353 struct ast_channel *chan1;
09354 struct ast_channel *chan2;
09355 char *park_exten;
09356 char *park_context;
09357 };
09358
09359 static void *iax_park_thread(void *stuff)
09360 {
09361 struct iax_dual *d;
09362 int res;
09363 int ext = 0;
09364
09365 d = stuff;
09366
09367 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09368 ast_channel_name(d->chan2), ast_channel_name(d->chan1));
09369
09370 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09371 if (res) {
09372
09373 ast_hangup(d->chan1);
09374 } else {
09375 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09376 }
09377 ast_hangup(d->chan2);
09378
09379 ast_free(d->park_exten);
09380 ast_free(d->park_context);
09381 ast_free(d);
09382 return NULL;
09383 }
09384
09385
09386 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
09387 {
09388 struct iax_dual *d;
09389 struct ast_channel *chan1m, *chan2m;
09390 pthread_t th;
09391
09392 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(chan2), chan1->exten, chan1->context, ast_channel_linkedid(chan1), chan1->amaflags, "Parking/%s", ast_channel_name(chan1));
09393 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, ast_channel_accountcode(chan2), chan2->exten, chan2->context, ast_channel_linkedid(chan2), chan2->amaflags, "IAXPeer/%s", ast_channel_name(chan2));
09394 d = ast_calloc(1, sizeof(*d));
09395 if (!chan1m || !chan2m || !d) {
09396 if (chan1m) {
09397 ast_hangup(chan1m);
09398 }
09399 if (chan2m) {
09400 ast_hangup(chan2m);
09401 }
09402 ast_free(d);
09403 return -1;
09404 }
09405 d->park_exten = ast_strdup(park_exten);
09406 d->park_context = ast_strdup(park_context);
09407 if (!d->park_exten || !d->park_context) {
09408 ast_hangup(chan1m);
09409 ast_hangup(chan2m);
09410 ast_free(d->park_exten);
09411 ast_free(d->park_context);
09412 ast_free(d);
09413 return -1;
09414 }
09415
09416
09417 chan1m->readformat = chan1->readformat;
09418 chan1m->writeformat = chan1->writeformat;
09419
09420
09421 if (ast_channel_masquerade(chan1m, chan1)) {
09422 ast_hangup(chan1m);
09423 ast_hangup(chan2m);
09424 ast_free(d->park_exten);
09425 ast_free(d->park_context);
09426 ast_free(d);
09427 return -1;
09428 }
09429
09430
09431 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09432 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09433 chan1m->priority = chan1->priority;
09434
09435 ast_do_masquerade(chan1m);
09436
09437
09438
09439
09440
09441 chan2m->readformat = chan2->readformat;
09442 chan2m->writeformat = chan2->writeformat;
09443 ast_channel_parkinglot_set(chan2m, ast_channel_parkinglot(chan2));
09444
09445
09446 if (ast_channel_masquerade(chan2m, chan2)) {
09447 ast_hangup(chan1m);
09448 ast_hangup(chan2m);
09449 ast_free(d->park_exten);
09450 ast_free(d->park_context);
09451 ast_free(d);
09452 return -1;
09453 }
09454
09455
09456 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09457 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09458 chan2m->priority = chan2->priority;
09459
09460 ast_do_masquerade(chan2m);
09461
09462 d->chan1 = chan1m;
09463 d->chan2 = chan2m;
09464 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09465
09466 ast_hangup(chan1m);
09467 ast_hangup(chan2m);
09468 ast_free(d->park_exten);
09469 ast_free(d->park_context);
09470 ast_free(d);
09471 return -1;
09472 }
09473 return 0;
09474 }
09475
09476 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09477 {
09478 unsigned int ourver;
09479 char rsi[80];
09480 snprintf(rsi, sizeof(rsi), "si-%s", si);
09481 if (iax_provision_version(&ourver, rsi, 1))
09482 return 0;
09483 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09484 if (ourver != ver)
09485 iax2_provision(sin, sockfd, NULL, rsi, 1);
09486 return 0;
09487 }
09488
09489 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09490 {
09491 jb_info stats;
09492 jb_getinfo(pvt->jb, &stats);
09493
09494 memset(iep, 0, sizeof(*iep));
09495
09496 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09497 if(stats.frames_in == 0) stats.frames_in = 1;
09498 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09499 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09500 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09501 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09502 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09503 }
09504
09505 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09506 {
09507 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09508 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09509 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09510 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09511 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09512 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09513 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09514 }
09515
09516 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09517 {
09518 int i;
09519 unsigned int length, offset = 0;
09520 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09521
09522 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09523 length = ies->ospblocklength[i];
09524 if (length != 0) {
09525 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09526
09527 offset = 0;
09528 break;
09529 } else {
09530 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09531 offset += length;
09532 }
09533 } else {
09534 break;
09535 }
09536 }
09537 *(full_osptoken + offset) = '\0';
09538 if (strlen(full_osptoken) != offset) {
09539
09540 *full_osptoken = '\0';
09541 }
09542
09543 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09544 }
09545
09546 static void log_jitterstats(unsigned short callno)
09547 {
09548 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09549 jb_info jbinfo;
09550
09551 ast_mutex_lock(&iaxsl[callno]);
09552 if (iaxs[callno] && iaxs[callno]->owner && ast_channel_name(iaxs[callno]->owner)) {
09553 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09554 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09555 localjitter = jbinfo.jitter;
09556 localdelay = jbinfo.current - jbinfo.min;
09557 locallost = jbinfo.frames_lost;
09558 locallosspct = jbinfo.losspct/1000;
09559 localdropped = jbinfo.frames_dropped;
09560 localooo = jbinfo.frames_ooo;
09561 localpackets = jbinfo.frames_in;
09562 }
09563 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",
09564 ast_channel_name(iaxs[callno]->owner),
09565 iaxs[callno]->pingtime,
09566 localjitter,
09567 localdelay,
09568 locallost,
09569 locallosspct,
09570 localdropped,
09571 localooo,
09572 localpackets,
09573 iaxs[callno]->remote_rr.jitter,
09574 iaxs[callno]->remote_rr.delay,
09575 iaxs[callno]->remote_rr.losscnt,
09576 iaxs[callno]->remote_rr.losspct/1000,
09577 iaxs[callno]->remote_rr.dropped,
09578 iaxs[callno]->remote_rr.ooo,
09579 iaxs[callno]->remote_rr.packets);
09580 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",
09581 ast_channel_name(iaxs[callno]->owner),
09582 iaxs[callno]->pingtime,
09583 localjitter,
09584 localdelay,
09585 locallost,
09586 locallosspct,
09587 localdropped,
09588 localooo,
09589 localpackets,
09590 iaxs[callno]->remote_rr.jitter,
09591 iaxs[callno]->remote_rr.delay,
09592 iaxs[callno]->remote_rr.losscnt,
09593 iaxs[callno]->remote_rr.losspct/1000,
09594 iaxs[callno]->remote_rr.dropped,
09595 iaxs[callno]->remote_rr.ooo,
09596 iaxs[callno]->remote_rr.packets);
09597 }
09598 ast_mutex_unlock(&iaxsl[callno]);
09599 }
09600
09601 static int socket_process(struct iax2_thread *thread);
09602
09603
09604
09605
09606 static void handle_deferred_full_frames(struct iax2_thread *thread)
09607 {
09608 struct iax2_pkt_buf *pkt_buf;
09609
09610 ast_mutex_lock(&thread->lock);
09611
09612 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09613 ast_mutex_unlock(&thread->lock);
09614
09615 thread->buf = pkt_buf->buf;
09616 thread->buf_len = pkt_buf->len;
09617 thread->buf_size = pkt_buf->len + 1;
09618
09619 socket_process(thread);
09620
09621 thread->buf = NULL;
09622 ast_free(pkt_buf);
09623
09624 ast_mutex_lock(&thread->lock);
09625 }
09626
09627 ast_mutex_unlock(&thread->lock);
09628 }
09629
09630
09631
09632
09633
09634
09635
09636 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09637 {
09638 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09639 struct ast_iax2_full_hdr *fh, *cur_fh;
09640
09641 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09642 return;
09643
09644 pkt_buf->len = from_here->buf_len;
09645 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09646
09647 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09648 ast_mutex_lock(&to_here->lock);
09649 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09650 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09651 if (fh->oseqno < cur_fh->oseqno) {
09652 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09653 break;
09654 }
09655 }
09656 AST_LIST_TRAVERSE_SAFE_END
09657
09658 if (!cur_pkt_buf)
09659 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09660
09661 ast_mutex_unlock(&to_here->lock);
09662 }
09663
09664 static int socket_read(int *id, int fd, short events, void *cbdata)
09665 {
09666 struct iax2_thread *thread;
09667 socklen_t len;
09668 time_t t;
09669 static time_t last_errtime = 0;
09670 struct ast_iax2_full_hdr *fh;
09671
09672 if (!(thread = find_idle_thread())) {
09673 time(&t);
09674 if (t != last_errtime)
09675 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09676 last_errtime = t;
09677 usleep(1);
09678 return 1;
09679 }
09680
09681 len = sizeof(thread->iosin);
09682 thread->iofd = fd;
09683 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09684 thread->buf_size = sizeof(thread->readbuf);
09685 thread->buf = thread->readbuf;
09686 if (thread->buf_len < 0) {
09687 if (errno != ECONNREFUSED && errno != EAGAIN)
09688 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09689 handle_error();
09690 thread->iostate = IAX_IOSTATE_IDLE;
09691 signal_condition(&thread->lock, &thread->cond);
09692 return 1;
09693 }
09694 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09695 thread->iostate = IAX_IOSTATE_IDLE;
09696 signal_condition(&thread->lock, &thread->cond);
09697 return 1;
09698 }
09699
09700
09701
09702
09703 fh = (struct ast_iax2_full_hdr *) thread->buf;
09704 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09705 struct iax2_thread *cur = NULL;
09706 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09707
09708 AST_LIST_LOCK(&active_list);
09709 AST_LIST_TRAVERSE(&active_list, cur, list) {
09710 if ((cur->ffinfo.callno == callno) &&
09711 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09712 break;
09713 }
09714 if (cur) {
09715
09716
09717 defer_full_frame(thread, cur);
09718 AST_LIST_UNLOCK(&active_list);
09719 thread->iostate = IAX_IOSTATE_IDLE;
09720 signal_condition(&thread->lock, &thread->cond);
09721 return 1;
09722 } else {
09723
09724 thread->ffinfo.callno = callno;
09725 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09726 thread->ffinfo.type = fh->type;
09727 thread->ffinfo.csub = fh->csub;
09728 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09729 }
09730 AST_LIST_UNLOCK(&active_list);
09731 }
09732
09733
09734 thread->iostate = IAX_IOSTATE_READY;
09735 #ifdef DEBUG_SCHED_MULTITHREAD
09736 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09737 #endif
09738 signal_condition(&thread->lock, &thread->cond);
09739
09740 return 1;
09741 }
09742
09743 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09744 struct iax_frame *fr)
09745 {
09746 unsigned char metatype;
09747 struct ast_iax2_meta_trunk_mini *mtm;
09748 struct ast_iax2_meta_trunk_hdr *mth;
09749 struct ast_iax2_meta_trunk_entry *mte;
09750 struct iax2_trunk_peer *tpeer;
09751 unsigned int ts;
09752 void *ptr;
09753 struct timeval rxtrunktime;
09754 struct ast_frame f = { 0, };
09755
09756 if (packet_len < sizeof(*meta)) {
09757 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09758 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09759 return 1;
09760 }
09761
09762 if (meta->metacmd != IAX_META_TRUNK)
09763 return 1;
09764
09765 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09766 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09767 (int) (sizeof(*meta) + sizeof(*mth)));
09768 return 1;
09769 }
09770 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09771 ts = ntohl(mth->ts);
09772 metatype = meta->cmddata;
09773 packet_len -= (sizeof(*meta) + sizeof(*mth));
09774 ptr = mth->data;
09775 tpeer = find_tpeer(sin, sockfd);
09776 if (!tpeer) {
09777 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09778 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09779 return 1;
09780 }
09781 tpeer->trunkact = ast_tvnow();
09782 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09783 tpeer->rxtrunktime = tpeer->trunkact;
09784 rxtrunktime = tpeer->rxtrunktime;
09785 ast_mutex_unlock(&tpeer->lock);
09786 while (packet_len >= sizeof(*mte)) {
09787
09788 unsigned short callno, trunked_ts, len;
09789
09790 if (metatype == IAX_META_TRUNK_MINI) {
09791 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09792 ptr += sizeof(*mtm);
09793 packet_len -= sizeof(*mtm);
09794 len = ntohs(mtm->len);
09795 callno = ntohs(mtm->mini.callno);
09796 trunked_ts = ntohs(mtm->mini.ts);
09797 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09798 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09799 ptr += sizeof(*mte);
09800 packet_len -= sizeof(*mte);
09801 len = ntohs(mte->len);
09802 callno = ntohs(mte->callno);
09803 trunked_ts = 0;
09804 } else {
09805 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09806 break;
09807 }
09808
09809 if (len > packet_len)
09810 break;
09811 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09812 if (!fr->callno)
09813 continue;
09814
09815
09816
09817
09818 memset(&f, 0, sizeof(f));
09819 f.frametype = AST_FRAME_VOICE;
09820 if (!iaxs[fr->callno]) {
09821
09822 } else if (iaxs[fr->callno]->voiceformat == 0) {
09823 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09824 iax2_vnak(fr->callno);
09825 } else {
09826 ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
09827 f.datalen = len;
09828 if (f.datalen >= 0) {
09829 if (f.datalen)
09830 f.data.ptr = ptr;
09831 else
09832 f.data.ptr = NULL;
09833 if (trunked_ts)
09834 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09835 else
09836 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09837
09838 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09839 struct iax_frame *duped_fr;
09840
09841
09842 f.src = "IAX2";
09843 f.mallocd = 0;
09844 f.offset = 0;
09845 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09846 f.samples = ast_codec_get_samples(&f);
09847 else
09848 f.samples = 0;
09849 fr->outoforder = 0;
09850 iax_frame_wrap(fr, &f);
09851 duped_fr = iaxfrdup2(fr);
09852 if (duped_fr)
09853 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09854 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09855 iaxs[fr->callno]->last = fr->ts;
09856 }
09857 } else {
09858 ast_log(LOG_WARNING, "Datalen < 0?\n");
09859 }
09860 }
09861 ast_mutex_unlock(&iaxsl[fr->callno]);
09862 ptr += len;
09863 packet_len -= len;
09864 }
09865
09866 return 1;
09867 }
09868
09869 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09870 {
09871 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09872 AST_LIST_HEAD(, ast_var_t) *varlist;
09873 struct ast_var_t *var;
09874
09875 if (!variablestore) {
09876 *buf = '\0';
09877 return 0;
09878 }
09879 varlist = variablestore->data;
09880
09881 AST_LIST_LOCK(varlist);
09882 AST_LIST_TRAVERSE(varlist, var, entries) {
09883 if (strcmp(var->name, data) == 0) {
09884 ast_copy_string(buf, var->value, len);
09885 break;
09886 }
09887 }
09888 AST_LIST_UNLOCK(varlist);
09889 return 0;
09890 }
09891
09892 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09893 {
09894 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09895 AST_LIST_HEAD(, ast_var_t) *varlist;
09896 struct ast_var_t *var;
09897
09898 if (!variablestore) {
09899 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09900 if (!variablestore) {
09901 ast_log(LOG_ERROR, "Memory allocation error\n");
09902 return -1;
09903 }
09904 varlist = ast_calloc(1, sizeof(*varlist));
09905 if (!varlist) {
09906 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09907 return -1;
09908 }
09909
09910 AST_LIST_HEAD_INIT(varlist);
09911 variablestore->data = varlist;
09912 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09913 ast_channel_datastore_add(chan, variablestore);
09914 } else
09915 varlist = variablestore->data;
09916
09917 AST_LIST_LOCK(varlist);
09918 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09919 if (strcmp(var->name, data) == 0) {
09920 AST_LIST_REMOVE_CURRENT(entries);
09921 ast_var_delete(var);
09922 break;
09923 }
09924 }
09925 AST_LIST_TRAVERSE_SAFE_END;
09926 var = ast_var_assign(data, value);
09927 if (var)
09928 AST_LIST_INSERT_TAIL(varlist, var, entries);
09929 else
09930 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09931 AST_LIST_UNLOCK(varlist);
09932 return 0;
09933 }
09934
09935 static struct ast_custom_function iaxvar_function = {
09936 .name = "IAXVAR",
09937 .read = acf_iaxvar_read,
09938 .write = acf_iaxvar_write,
09939 };
09940
09941 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
09942 {
09943 iax2_lock_owner(callno);
09944 if (iaxs[callno] && iaxs[callno]->owner) {
09945 if (causecode) {
09946 iaxs[callno]->owner->hangupcause = causecode;
09947 }
09948 ast_set_hangupsource(iaxs[callno]->owner, ast_channel_name(iaxs[callno]->owner), 0);
09949 ast_channel_unlock(iaxs[callno]->owner);
09950 }
09951 }
09952
09953 static int socket_process(struct iax2_thread *thread)
09954 {
09955 struct sockaddr_in sin;
09956 int res;
09957 int updatehistory=1;
09958 int new = NEW_PREVENT;
09959 int dcallno = 0;
09960 char decrypted = 0;
09961 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09962 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09963 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09964 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09965 struct iax_frame *fr;
09966 struct iax_frame *cur;
09967 struct ast_frame f = { 0, };
09968 struct ast_channel *c = NULL;
09969 struct iax2_dpcache *dp;
09970 struct iax2_peer *peer;
09971 struct iax_ies ies;
09972 struct iax_ie_data ied0, ied1;
09973 iax2_format format;
09974 int fd;
09975 int exists;
09976 int minivid = 0;
09977 char empty[32]="";
09978 struct iax_frame *duped_fr;
09979 char host_pref_buf[128];
09980 char caller_pref_buf[128];
09981 struct ast_codec_pref pref;
09982 char *using_prefs = "mine";
09983
09984
09985 fr = alloca(sizeof(*fr) + 4096);
09986 memset(fr, 0, sizeof(*fr));
09987 fr->afdatalen = 4096;
09988
09989
09990 res = thread->buf_len;
09991 fd = thread->iofd;
09992 memcpy(&sin, &thread->iosin, sizeof(sin));
09993
09994 if (res < sizeof(*mh)) {
09995 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09996 return 1;
09997 }
09998 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09999 if (res < sizeof(*vh)) {
10000 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));
10001 return 1;
10002 }
10003
10004
10005 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
10006 minivid = 1;
10007 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
10008 return socket_process_meta(res, meta, &sin, fd, fr);
10009
10010 #ifdef DEBUG_SUPPORT
10011 if (res >= sizeof(*fh))
10012 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
10013 #endif
10014 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10015 if (res < sizeof(*fh)) {
10016 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));
10017 return 1;
10018 }
10019
10020
10021 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
10022
10023
10024
10025
10026
10027
10028 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
10029 ast_mutex_lock(&iaxsl[fr->callno]);
10030 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
10031 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10032 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10033 ast_mutex_unlock(&iaxsl[fr->callno]);
10034 return 1;
10035 }
10036 decrypted = 1;
10037 }
10038 ast_mutex_unlock(&iaxsl[fr->callno]);
10039 }
10040
10041
10042 f.frametype = fh->type;
10043 if (f.frametype == AST_FRAME_VIDEO) {
10044 ast_format_from_old_bitfield(&f.subclass.format, (uncompress_subclass(fh->csub & ~0x40)));
10045 if ((fh->csub >> 6) & 0x1) {
10046 ast_format_set_video_mark(&f.subclass.format);
10047 }
10048 } else if (f.frametype == AST_FRAME_VOICE) {
10049 ast_format_from_old_bitfield(&f.subclass.format, uncompress_subclass(fh->csub));
10050 } else {
10051 f.subclass.integer = uncompress_subclass(fh->csub);
10052 }
10053
10054
10055 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
10056
10057 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10058 return 1;
10059 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
10060
10061 return 1;
10062 }
10063
10064 f.datalen = res - sizeof(*fh);
10065 if (f.datalen) {
10066 if (f.frametype == AST_FRAME_IAX) {
10067 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
10068 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
10069 ast_variables_destroy(ies.vars);
10070 return 1;
10071 }
10072 f.data.ptr = NULL;
10073 f.datalen = 0;
10074 } else {
10075 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
10076 memset(&ies, 0, sizeof(ies));
10077 }
10078 } else {
10079 if (f.frametype == AST_FRAME_IAX)
10080 f.data.ptr = NULL;
10081 else
10082 f.data.ptr = empty;
10083 memset(&ies, 0, sizeof(ies));
10084 }
10085
10086 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
10087
10088 if (handle_call_token(fh, &ies, &sin, fd)) {
10089 ast_variables_destroy(ies.vars);
10090 return 1;
10091 }
10092
10093 if (ies.calltoken && ies.calltokendata) {
10094
10095
10096
10097
10098 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10099 } else {
10100 new = NEW_ALLOW;
10101 }
10102 }
10103 } else {
10104
10105 f.frametype = AST_FRAME_NULL;
10106 f.subclass.integer = 0;
10107 memset(&ies, 0, sizeof(ies));
10108 }
10109
10110 if (!fr->callno) {
10111 int check_dcallno = 0;
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10122 check_dcallno = 1;
10123 }
10124
10125 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10126 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10127 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10128 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10129 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10130 }
10131 ast_variables_destroy(ies.vars);
10132 return 1;
10133 }
10134 }
10135
10136 if (fr->callno > 0)
10137 ast_mutex_lock(&iaxsl[fr->callno]);
10138
10139 if (!fr->callno || !iaxs[fr->callno]) {
10140
10141
10142 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10143
10144 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10145 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10146 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10147 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10148 (f.frametype != AST_FRAME_IAX))
10149 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10150 fd);
10151 }
10152 if (fr->callno > 0)
10153 ast_mutex_unlock(&iaxsl[fr->callno]);
10154 ast_variables_destroy(ies.vars);
10155 return 1;
10156 }
10157 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10158 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10159 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10160 ast_variables_destroy(ies.vars);
10161 ast_mutex_unlock(&iaxsl[fr->callno]);
10162 return 1;
10163 }
10164 decrypted = 1;
10165 }
10166
10167 #ifdef DEBUG_SUPPORT
10168 if (decrypted) {
10169 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10170 }
10171 #endif
10172
10173
10174
10175 iaxs[fr->callno]->frames_received++;
10176
10177 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10178 f.subclass.integer != IAX_COMMAND_TXCNT &&
10179 f.subclass.integer != IAX_COMMAND_TXACC) {
10180 unsigned short new_peercallno;
10181
10182 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10183 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10184 if (iaxs[fr->callno]->peercallno) {
10185 remove_by_peercallno(iaxs[fr->callno]);
10186 }
10187 iaxs[fr->callno]->peercallno = new_peercallno;
10188 store_by_peercallno(iaxs[fr->callno]);
10189 }
10190 }
10191 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10192 if (iaxdebug)
10193 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10194
10195 fr->oseqno = fh->oseqno;
10196 fr->iseqno = fh->iseqno;
10197 fr->ts = ntohl(fh->ts);
10198 #ifdef IAXTESTS
10199 if (test_resync) {
10200 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10201 fr->ts += test_resync;
10202 }
10203 #endif
10204 #if 0
10205 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10206 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10207 (f.subclass == IAX_COMMAND_NEW ||
10208 f.subclass == IAX_COMMAND_AUTHREQ ||
10209 f.subclass == IAX_COMMAND_ACCEPT ||
10210 f.subclass == IAX_COMMAND_REJECT)) ) )
10211 #endif
10212 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10213 updatehistory = 0;
10214 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10215 (iaxs[fr->callno]->iseqno ||
10216 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10217 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10218 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10219 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10220 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10221 (f.frametype != AST_FRAME_IAX))) {
10222 if (
10223 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10224 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10225 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10226 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10227 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10228 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10229 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10230 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10231 (f.frametype != AST_FRAME_IAX)) {
10232
10233 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10234 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10235
10236
10237 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10238
10239 if ((f.frametype != AST_FRAME_IAX) ||
10240 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10241 ast_debug(1, "Acking anyway\n");
10242
10243
10244 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10245 }
10246 } else {
10247
10248 iax2_vnak(fr->callno);
10249 }
10250 ast_variables_destroy(ies.vars);
10251 ast_mutex_unlock(&iaxsl[fr->callno]);
10252 return 1;
10253 }
10254 } else {
10255
10256 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10257 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10258 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10259 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10260 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10261 (f.frametype != AST_FRAME_IAX))
10262 iaxs[fr->callno]->iseqno++;
10263 }
10264
10265 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10266 if (res < thread->buf_size)
10267 thread->buf[res++] = '\0';
10268 else
10269 thread->buf[res - 1] = '\0';
10270 }
10271
10272
10273
10274 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10275 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10276 (f.frametype != AST_FRAME_IAX))) {
10277 unsigned char x;
10278 int call_to_destroy;
10279
10280 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10281 x = fr->iseqno;
10282 else
10283 x = iaxs[fr->callno]->oseqno;
10284 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10285
10286
10287 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10288
10289 if (iaxdebug)
10290 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10291 call_to_destroy = 0;
10292 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10293
10294 if (x == cur->oseqno) {
10295 cur->retries = -1;
10296
10297 if (cur->final)
10298 call_to_destroy = fr->callno;
10299 }
10300 }
10301 if (call_to_destroy) {
10302 if (iaxdebug)
10303 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10304 ast_mutex_lock(&iaxsl[call_to_destroy]);
10305 iax2_destroy(call_to_destroy);
10306 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10307 }
10308 }
10309
10310 if (iaxs[fr->callno])
10311 iaxs[fr->callno]->rseqno = fr->iseqno;
10312 else {
10313
10314 ast_variables_destroy(ies.vars);
10315 ast_mutex_unlock(&iaxsl[fr->callno]);
10316 return 1;
10317 }
10318 } else {
10319 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10320 }
10321 }
10322 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10323 ((f.frametype != AST_FRAME_IAX) ||
10324 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10325 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10326
10327 ast_variables_destroy(ies.vars);
10328 ast_mutex_unlock(&iaxsl[fr->callno]);
10329 return 1;
10330 }
10331
10332
10333
10334
10335 if ((f.frametype == AST_FRAME_VOICE) ||
10336 (f.frametype == AST_FRAME_VIDEO) ||
10337 (f.frametype == AST_FRAME_IAX)) {
10338 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10339 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10340 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10341 ast_variables_destroy(ies.vars);
10342 ast_mutex_unlock(&iaxsl[fr->callno]);
10343 return 1;
10344 }
10345 }
10346
10347 if (ies.vars) {
10348 struct ast_datastore *variablestore = NULL;
10349 struct ast_variable *var, *prev = NULL;
10350 AST_LIST_HEAD(, ast_var_t) *varlist;
10351
10352 iax2_lock_owner(fr->callno);
10353 if (!iaxs[fr->callno]) {
10354 ast_variables_destroy(ies.vars);
10355 ast_mutex_unlock(&iaxsl[fr->callno]);
10356 return 1;
10357 }
10358 if ((c = iaxs[fr->callno]->owner)) {
10359 varlist = ast_calloc(1, sizeof(*varlist));
10360 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10361
10362 if (variablestore && varlist) {
10363 variablestore->data = varlist;
10364 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10365 AST_LIST_HEAD_INIT(varlist);
10366 ast_debug(1, "I can haz IAX vars?\n");
10367 for (var = ies.vars; var; var = var->next) {
10368 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10369 if (prev) {
10370 ast_free(prev);
10371 }
10372 prev = var;
10373 if (!newvar) {
10374
10375 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10376 } else {
10377 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10378 }
10379 }
10380 if (prev) {
10381 ast_free(prev);
10382 }
10383 ies.vars = NULL;
10384 ast_channel_datastore_add(c, variablestore);
10385 } else {
10386 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10387 if (variablestore) {
10388 ast_datastore_free(variablestore);
10389 }
10390 if (varlist) {
10391 ast_free(varlist);
10392 }
10393 }
10394 ast_channel_unlock(c);
10395 } else {
10396
10397
10398 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10399 for (var = ies.vars; var && var->next; var = var->next);
10400 if (var) {
10401 var->next = iaxs[fr->callno]->iaxvars;
10402 iaxs[fr->callno]->iaxvars = ies.vars;
10403 ies.vars = NULL;
10404 }
10405 }
10406 }
10407
10408 if (ies.vars) {
10409 ast_debug(1, "I have IAX variables, but they were not processed\n");
10410 }
10411 }
10412
10413
10414
10415 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10416 send_signaling(iaxs[fr->callno]);
10417 }
10418
10419 if (f.frametype == AST_FRAME_VOICE) {
10420 if (ast_format_to_old_bitfield(&f.subclass.format) != iaxs[fr->callno]->voiceformat) {
10421 iaxs[fr->callno]->voiceformat = ast_format_to_old_bitfield(&f.subclass.format);
10422 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(&f.subclass.format));
10423 if (iaxs[fr->callno]->owner) {
10424 iax2_lock_owner(fr->callno);
10425 if (iaxs[fr->callno]) {
10426 if (iaxs[fr->callno]->owner) {
10427 struct ast_format_cap *orignative = ast_format_cap_dup(iaxs[fr->callno]->owner->nativeformats);
10428 struct ast_format_cap *native = iaxs[fr->callno]->owner->nativeformats;
10429 if (orignative) {
10430 ast_format_cap_set(native, &f.subclass.format);
10431 if (iaxs[fr->callno]->owner->readformat.id) {
10432 ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
10433 }
10434 ast_format_cap_copy(native, orignative);
10435 ast_channel_unlock(iaxs[fr->callno]->owner);
10436 orignative = ast_format_cap_destroy(orignative);
10437 }
10438 }
10439 } else {
10440 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10441
10442 if (ies.vars) {
10443 ast_variables_destroy(ies.vars);
10444 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10445 ies.vars = NULL;
10446 }
10447 ast_mutex_unlock(&iaxsl[fr->callno]);
10448 return 1;
10449 }
10450 }
10451 }
10452 }
10453 if (f.frametype == AST_FRAME_VIDEO) {
10454 if (f.subclass.format.id != ast_format_id_from_old_bitfield(iaxs[fr->callno]->videoformat)) {
10455 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(&f.subclass.format));
10456 iaxs[fr->callno]->videoformat = ast_format_to_old_bitfield(&f.subclass.format);
10457 }
10458 }
10459 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10460 if (f.subclass.integer == AST_CONTROL_BUSY) {
10461 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10462 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10463 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10464 }
10465 }
10466 if (f.frametype == AST_FRAME_IAX) {
10467 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
10468
10469 if (iaxdebug)
10470 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10471
10472
10473 if (iaxs[fr->callno]->last < fr->ts &&
10474 f.subclass.integer != IAX_COMMAND_ACK &&
10475 f.subclass.integer != IAX_COMMAND_PONG &&
10476 f.subclass.integer != IAX_COMMAND_LAGRP) {
10477 iaxs[fr->callno]->last = fr->ts;
10478 if (iaxdebug)
10479 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10480 }
10481 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10482 if (!iaxs[fr->callno]->first_iax_message) {
10483 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10484 }
10485 switch(f.subclass.integer) {
10486 case IAX_COMMAND_ACK:
10487
10488 break;
10489 case IAX_COMMAND_QUELCH:
10490 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10491
10492 if (iaxs[fr->callno]->owner) {
10493 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10494 "Status: On\r\n"
10495 "Channel: %s\r\n"
10496 "Uniqueid: %s\r\n",
10497 ast_channel_name(iaxs[fr->callno]->owner),
10498 ast_channel_uniqueid(iaxs[fr->callno]->owner));
10499 }
10500
10501 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10502 if (ies.musiconhold) {
10503 iax2_lock_owner(fr->callno);
10504 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10505 break;
10506 }
10507 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10508 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10509
10510
10511
10512
10513
10514 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10515 S_OR(moh_suggest, NULL),
10516 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10517 }
10518 ast_channel_unlock(iaxs[fr->callno]->owner);
10519 }
10520 }
10521 break;
10522 case IAX_COMMAND_UNQUELCH:
10523 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10524 iax2_lock_owner(fr->callno);
10525 if (!iaxs[fr->callno]) {
10526 break;
10527 }
10528
10529 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10530 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10531 "Status: Off\r\n"
10532 "Channel: %s\r\n"
10533 "Uniqueid: %s\r\n",
10534 ast_channel_name(iaxs[fr->callno]->owner),
10535 ast_channel_uniqueid(iaxs[fr->callno]->owner));
10536 }
10537
10538 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10539 if (!iaxs[fr->callno]->owner) {
10540 break;
10541 }
10542 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10543
10544
10545
10546
10547 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10548 }
10549 ast_channel_unlock(iaxs[fr->callno]->owner);
10550 }
10551 break;
10552 case IAX_COMMAND_TXACC:
10553 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10554
10555 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10556
10557 if (cur->transfer) {
10558 cur->retries = -1;
10559 }
10560 }
10561 memset(&ied1, 0, sizeof(ied1));
10562 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10563 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10564 iaxs[fr->callno]->transferring = TRANSFER_READY;
10565 }
10566 break;
10567 case IAX_COMMAND_NEW:
10568
10569 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10570 break;
10571 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10572 ast_mutex_unlock(&iaxsl[fr->callno]);
10573 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10574 ast_mutex_lock(&iaxsl[fr->callno]);
10575 if (!iaxs[fr->callno]) {
10576 break;
10577 }
10578 }
10579
10580 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10581 int new_callno;
10582 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10583 fr->callno = new_callno;
10584 }
10585
10586 if (delayreject)
10587 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10588 if (check_access(fr->callno, &sin, &ies)) {
10589
10590 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10591 if (authdebug)
10592 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);
10593 break;
10594 }
10595 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10596 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10597 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10598 break;
10599 }
10600 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10601 const char *context, *exten, *cid_num;
10602
10603 context = ast_strdupa(iaxs[fr->callno]->context);
10604 exten = ast_strdupa(iaxs[fr->callno]->exten);
10605 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10606
10607
10608 ast_mutex_unlock(&iaxsl[fr->callno]);
10609 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10610 ast_mutex_lock(&iaxsl[fr->callno]);
10611
10612 if (!iaxs[fr->callno]) {
10613 break;
10614 }
10615 } else
10616 exists = 0;
10617
10618 save_osptoken(fr, &ies);
10619 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10620 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10621 memset(&ied0, 0, sizeof(ied0));
10622 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10623 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10624 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10625 if (!iaxs[fr->callno]) {
10626 break;
10627 }
10628 if (authdebug)
10629 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);
10630 } else {
10631
10632
10633 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10634 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10635 using_prefs = "reqonly";
10636 } else {
10637 using_prefs = "disabled";
10638 }
10639 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10640 memset(&pref, 0, sizeof(pref));
10641 strcpy(caller_pref_buf, "disabled");
10642 strcpy(host_pref_buf, "disabled");
10643 } else {
10644 struct ast_format tmpfmt;
10645 using_prefs = "mine";
10646
10647 if (ies.codec_prefs)
10648 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10649 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
10650
10651 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10652 pref = iaxs[fr->callno]->rprefs;
10653 using_prefs = "caller";
10654 } else {
10655 pref = iaxs[fr->callno]->prefs;
10656 }
10657 } else
10658 pref = iaxs[fr->callno]->prefs;
10659
10660 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10661 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10662 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10663 }
10664 if (!format) {
10665 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10666 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10667 if (!format) {
10668 memset(&ied0, 0, sizeof(ied0));
10669 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10670 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10671 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10672 if (!iaxs[fr->callno]) {
10673 break;
10674 }
10675 if (authdebug) {
10676 char tmp[256], tmp2[256], tmp3[256];
10677 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10678 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10679 ast_inet_ntoa(sin.sin_addr),
10680 iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10681 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10682 } else {
10683 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10684 ast_inet_ntoa(sin.sin_addr),
10685 iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10686 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10687 iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10688 }
10689 }
10690 } else {
10691
10692 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10693 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10694 format = 0;
10695 } else {
10696 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10697 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10698 memset(&pref, 0, sizeof(pref));
10699 format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10700 strcpy(caller_pref_buf,"disabled");
10701 strcpy(host_pref_buf,"disabled");
10702 } else {
10703 struct ast_format tmpfmt;
10704 using_prefs = "mine";
10705 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
10706
10707 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10708 pref = iaxs[fr->callno]->prefs;
10709 } else {
10710 pref = iaxs[fr->callno]->rprefs;
10711 using_prefs = "caller";
10712 }
10713 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10714 } else
10715 format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10716 }
10717 }
10718
10719 if (!format) {
10720 char tmp[256], tmp2[256], tmp3[256];
10721 memset(&ied0, 0, sizeof(ied0));
10722 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10723 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10724 ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10725 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10726 if (!iaxs[fr->callno]) {
10727 break;
10728 }
10729 if (authdebug) {
10730 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10731 ast_inet_ntoa(sin.sin_addr),
10732 iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10733 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10734 iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10735 }
10736 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10737 break;
10738 }
10739 }
10740 }
10741 if (format) {
10742
10743 memset(&ied1, 0, sizeof(ied1));
10744 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10745 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10746 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10747 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10748 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10749 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10750 "%srequested format = %s,\n"
10751 "%srequested prefs = %s,\n"
10752 "%sactual format = %s,\n"
10753 "%shost prefs = %s,\n"
10754 "%spriority = %s\n",
10755 ast_inet_ntoa(sin.sin_addr),
10756 VERBOSE_PREFIX_4,
10757 iax2_getformatname(iaxs[fr->callno]->peerformat),
10758 VERBOSE_PREFIX_4,
10759 caller_pref_buf,
10760 VERBOSE_PREFIX_4,
10761 iax2_getformatname(format),
10762 VERBOSE_PREFIX_4,
10763 host_pref_buf,
10764 VERBOSE_PREFIX_4,
10765 using_prefs);
10766
10767 iaxs[fr->callno]->chosenformat = format;
10768 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10769 } else {
10770 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10771
10772 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10773 }
10774 }
10775 }
10776 break;
10777 }
10778 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10779 merge_encryption(iaxs[fr->callno],ies.encmethods);
10780 else
10781 iaxs[fr->callno]->encmethods = 0;
10782 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10783 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10784 break;
10785 case IAX_COMMAND_DPREQ:
10786
10787 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10788 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10789 if (iaxcompat) {
10790
10791 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10792 } else {
10793
10794 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10795 }
10796 }
10797 break;
10798 case IAX_COMMAND_HANGUP:
10799 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10800 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10801
10802 if (iaxs[fr->callno]->owner) {
10803 set_hangup_source_and_cause(fr->callno, ies.causecode);
10804 if (!iaxs[fr->callno]) {
10805 break;
10806 }
10807 }
10808
10809
10810 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10811 iax2_destroy(fr->callno);
10812 break;
10813 case IAX_COMMAND_REJECT:
10814
10815 if (iaxs[fr->callno]->owner) {
10816 set_hangup_source_and_cause(fr->callno, ies.causecode);
10817 if (!iaxs[fr->callno]) {
10818 break;
10819 }
10820 }
10821
10822 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10823 if (iaxs[fr->callno]->owner && authdebug)
10824 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10825 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10826 ies.cause ? ies.cause : "<Unknown>");
10827 ast_debug(1, "Immediately destroying %d, having received reject\n",
10828 fr->callno);
10829 }
10830
10831 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10832 fr->ts, NULL, 0, fr->iseqno);
10833 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10834 iaxs[fr->callno]->error = EPERM;
10835 iax2_destroy(fr->callno);
10836 break;
10837 case IAX_COMMAND_TRANSFER:
10838 {
10839 struct ast_channel *bridged_chan;
10840 struct ast_channel *owner;
10841
10842 iax2_lock_owner(fr->callno);
10843 if (!iaxs[fr->callno]) {
10844
10845 break;
10846 }
10847 owner = iaxs[fr->callno]->owner;
10848 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10849 if (bridged_chan && ies.called_number) {
10850 const char *context;
10851
10852 context = ast_strdupa(iaxs[fr->callno]->context);
10853
10854 ast_channel_ref(owner);
10855 ast_channel_ref(bridged_chan);
10856 ast_channel_unlock(owner);
10857 ast_mutex_unlock(&iaxsl[fr->callno]);
10858
10859
10860 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", ast_channel_name(bridged_chan));
10861 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", ast_channel_name(owner));
10862
10863
10864 if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10865 ast_debug(1, "Parking call '%s'\n", ast_channel_name(bridged_chan));
10866 if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10867 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10868 ast_channel_name(bridged_chan));
10869 }
10870 } else {
10871 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10872 ast_log(LOG_WARNING,
10873 "Async goto of '%s' to '%s@%s' failed\n",
10874 ast_channel_name(bridged_chan), ies.called_number, context);
10875 } else {
10876 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10877 ast_channel_name(bridged_chan), ies.called_number, context);
10878 }
10879 }
10880 ast_channel_unref(owner);
10881 ast_channel_unref(bridged_chan);
10882
10883 ast_mutex_lock(&iaxsl[fr->callno]);
10884 } else {
10885 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10886 if (owner) {
10887 ast_channel_unlock(owner);
10888 }
10889 }
10890
10891 break;
10892 }
10893 case IAX_COMMAND_ACCEPT:
10894
10895 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10896 break;
10897 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10898
10899 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10900 iax2_destroy(fr->callno);
10901 break;
10902 }
10903 if (ies.format) {
10904 iaxs[fr->callno]->peerformat = ies.format;
10905 } else {
10906 if (iaxs[fr->callno]->owner)
10907 iaxs[fr->callno]->peerformat = ast_format_cap_to_old_bitfield(iaxs[fr->callno]->owner->nativeformats);
10908 else
10909 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10910 }
10911 ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iax2_getformatname(iaxs[fr->callno]->peerformat));
10912 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10913 memset(&ied0, 0, sizeof(ied0));
10914 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10915 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10916 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10917 if (!iaxs[fr->callno]) {
10918 break;
10919 }
10920 if (authdebug) {
10921 char tmp1[256], tmp2[256];
10922 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10923 ast_inet_ntoa(sin.sin_addr),
10924 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10925 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10926 }
10927 } else {
10928 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10929 iax2_lock_owner(fr->callno);
10930 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10931 char tmp[256];
10932
10933 ast_format_cap_from_old_bitfield(iaxs[fr->callno]->owner->nativeformats, iaxs[fr->callno]->peerformat);
10934 ast_verb(3, "Format for call is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->owner->nativeformats));
10935
10936
10937 if (iaxs[fr->callno]->owner->writeformat.id)
10938 ast_set_write_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->writeformat);
10939 if (iaxs[fr->callno]->owner->readformat.id)
10940 ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
10941 ast_channel_unlock(iaxs[fr->callno]->owner);
10942 }
10943 }
10944 if (iaxs[fr->callno]) {
10945 AST_LIST_LOCK(&dpcache);
10946 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10947 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10948 iax2_dprequest(dp, fr->callno);
10949 AST_LIST_UNLOCK(&dpcache);
10950 }
10951 break;
10952 case IAX_COMMAND_POKE:
10953
10954 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10955 break;
10956 case IAX_COMMAND_PING:
10957 {
10958 struct iax_ie_data pingied;
10959 construct_rr(iaxs[fr->callno], &pingied);
10960
10961 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10962 }
10963 break;
10964 case IAX_COMMAND_PONG:
10965
10966 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10967
10968 save_rr(fr, &ies);
10969
10970
10971 log_jitterstats(fr->callno);
10972
10973 if (iaxs[fr->callno]->peerpoke) {
10974 peer = iaxs[fr->callno]->peerpoke;
10975 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10976 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10977 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10978 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);
10979 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10980 }
10981 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10982 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10983 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10984 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);
10985 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10986 }
10987 }
10988 peer->lastms = iaxs[fr->callno]->pingtime;
10989 if (peer->smoothing && (peer->lastms > -1))
10990 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10991 else if (peer->smoothing && peer->lastms < 0)
10992 peer->historicms = (0 + peer->historicms) / 2;
10993 else
10994 peer->historicms = iaxs[fr->callno]->pingtime;
10995
10996
10997 if (peer->pokeexpire > -1) {
10998 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
10999 peer_unref(peer);
11000 peer->pokeexpire = -1;
11001 }
11002 }
11003
11004 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
11005 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11006 else
11007 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
11008 if (peer->pokeexpire == -1)
11009 peer_unref(peer);
11010
11011 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11012
11013 iax2_destroy(fr->callno);
11014 peer->callno = 0;
11015 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
11016 }
11017 break;
11018 case IAX_COMMAND_LAGRQ:
11019 case IAX_COMMAND_LAGRP:
11020 f.src = "LAGRQ";
11021 f.mallocd = 0;
11022 f.offset = 0;
11023 f.samples = 0;
11024 iax_frame_wrap(fr, &f);
11025 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
11026
11027 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
11028 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
11029 } else {
11030
11031 unsigned int ts;
11032
11033 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
11034 iaxs[fr->callno]->lag = ts - fr->ts;
11035 if (iaxdebug)
11036 ast_debug(1, "Peer %s lag measured as %dms\n",
11037 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
11038 }
11039 break;
11040 case IAX_COMMAND_AUTHREQ:
11041 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11042 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11043 break;
11044 }
11045 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
11046 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
11047 .subclass.integer = AST_CONTROL_HANGUP,
11048 };
11049 ast_log(LOG_WARNING,
11050 "I don't know how to authenticate %s to %s\n",
11051 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
11052 iax2_queue_frame(fr->callno, &hangup_fr);
11053 }
11054 break;
11055 case IAX_COMMAND_AUTHREP:
11056
11057 if (delayreject)
11058 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11059
11060 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
11061 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11062 break;
11063 }
11064 if (authenticate_verify(iaxs[fr->callno], &ies)) {
11065 if (authdebug)
11066 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);
11067 memset(&ied0, 0, sizeof(ied0));
11068 auth_fail(fr->callno, IAX_COMMAND_REJECT);
11069 break;
11070 }
11071 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
11072
11073 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
11074 } else
11075 exists = 0;
11076 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
11077 if (authdebug)
11078 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);
11079 memset(&ied0, 0, sizeof(ied0));
11080 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11081 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11082 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11083 if (!iaxs[fr->callno]) {
11084 break;
11085 }
11086 } else {
11087
11088 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11089 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11090 using_prefs = "reqonly";
11091 } else {
11092 using_prefs = "disabled";
11093 }
11094 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
11095 memset(&pref, 0, sizeof(pref));
11096 strcpy(caller_pref_buf, "disabled");
11097 strcpy(host_pref_buf, "disabled");
11098 } else {
11099 struct ast_format tmpfmt;
11100 using_prefs = "mine";
11101 if (ies.codec_prefs)
11102 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11103 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11104 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11105 pref = iaxs[fr->callno]->rprefs;
11106 using_prefs = "caller";
11107 } else {
11108 pref = iaxs[fr->callno]->prefs;
11109 }
11110 } else
11111 pref = iaxs[fr->callno]->prefs;
11112 format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11113 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11114 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11115 }
11116 if (!format) {
11117 char tmp1[256], tmp2[256], tmp3[256];
11118 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11119 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11120 iax2_getformatname(iaxs[fr->callno]->peerformat),
11121 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11122 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11123 }
11124 if (!format) {
11125 if (authdebug) {
11126 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11127 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11128 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11129 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11130 } else {
11131 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11132 ast_inet_ntoa(sin.sin_addr),
11133 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11134 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11135 iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11136 }
11137 }
11138 memset(&ied0, 0, sizeof(ied0));
11139 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11140 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11141 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11142 if (!iaxs[fr->callno]) {
11143 break;
11144 }
11145 } else {
11146
11147 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11148 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11149 format = 0;
11150 } else {
11151 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11152 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11153 memset(&pref, 0, sizeof(pref));
11154 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11155 iaxs[fr->callno]->peerformat : iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11156 strcpy(caller_pref_buf,"disabled");
11157 strcpy(host_pref_buf,"disabled");
11158 } else {
11159 struct ast_format tmpfmt;
11160 using_prefs = "mine";
11161 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
11162
11163 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11164 pref = iaxs[fr->callno]->prefs;
11165 } else {
11166 pref = iaxs[fr->callno]->rprefs;
11167 using_prefs = "caller";
11168 }
11169 format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11170 } else
11171 format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11172 }
11173 }
11174 if (!format) {
11175 char tmp1[256], tmp2[256], tmp3[256];
11176 ast_log(LOG_ERROR, "No best format in %s???\n",
11177 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11178 if (authdebug) {
11179 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11180 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11181 ast_inet_ntoa(sin.sin_addr),
11182 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11183 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11184 } else {
11185 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11186 ast_inet_ntoa(sin.sin_addr),
11187 iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11188 iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11189 iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11190 }
11191 }
11192 memset(&ied0, 0, sizeof(ied0));
11193 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11194 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11195 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11196 if (!iaxs[fr->callno]) {
11197 break;
11198 }
11199 }
11200 }
11201 }
11202 if (format) {
11203
11204 memset(&ied1, 0, sizeof(ied1));
11205 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11206 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11207 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11208 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11209 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11210 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11211 "%srequested format = %s,\n"
11212 "%srequested prefs = %s,\n"
11213 "%sactual format = %s,\n"
11214 "%shost prefs = %s,\n"
11215 "%spriority = %s\n",
11216 ast_inet_ntoa(sin.sin_addr),
11217 VERBOSE_PREFIX_4,
11218 iax2_getformatname(iaxs[fr->callno]->peerformat),
11219 VERBOSE_PREFIX_4,
11220 caller_pref_buf,
11221 VERBOSE_PREFIX_4,
11222 iax2_getformatname(format),
11223 VERBOSE_PREFIX_4,
11224 host_pref_buf,
11225 VERBOSE_PREFIX_4,
11226 using_prefs);
11227
11228 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11229 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11230 iax2_destroy(fr->callno);
11231 else if (ies.vars) {
11232 struct ast_datastore *variablestore;
11233 struct ast_variable *var, *prev = NULL;
11234 AST_LIST_HEAD(, ast_var_t) *varlist;
11235 varlist = ast_calloc(1, sizeof(*varlist));
11236 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11237 if (variablestore && varlist) {
11238 variablestore->data = varlist;
11239 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11240 AST_LIST_HEAD_INIT(varlist);
11241 ast_debug(1, "I can haz IAX vars? w00t\n");
11242 for (var = ies.vars; var; var = var->next) {
11243 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11244 if (prev)
11245 ast_free(prev);
11246 prev = var;
11247 if (!newvar) {
11248
11249 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11250 } else {
11251 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11252 }
11253 }
11254 if (prev)
11255 ast_free(prev);
11256 ies.vars = NULL;
11257 ast_channel_datastore_add(c, variablestore);
11258 } else {
11259 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11260 if (variablestore)
11261 ast_datastore_free(variablestore);
11262 if (varlist)
11263 ast_free(varlist);
11264 }
11265 }
11266 } else {
11267 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11268
11269 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11270 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11271 goto immediatedial;
11272 }
11273 }
11274 }
11275 }
11276 break;
11277 case IAX_COMMAND_DIAL:
11278 immediatedial:
11279 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11280 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11281 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11282 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11283 if (authdebug)
11284 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);
11285 memset(&ied0, 0, sizeof(ied0));
11286 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11287 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11288 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11289 if (!iaxs[fr->callno]) {
11290 break;
11291 }
11292 } else {
11293 char tmp[256];
11294 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11295 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11296 ast_inet_ntoa(sin.sin_addr),
11297 iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11298 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11299 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11300 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11301 iax2_destroy(fr->callno);
11302 else if (ies.vars) {
11303 struct ast_datastore *variablestore;
11304 struct ast_variable *var, *prev = NULL;
11305 AST_LIST_HEAD(, ast_var_t) *varlist;
11306 varlist = ast_calloc(1, sizeof(*varlist));
11307 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11308 ast_debug(1, "I can haz IAX vars? w00t\n");
11309 if (variablestore && varlist) {
11310 variablestore->data = varlist;
11311 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11312 AST_LIST_HEAD_INIT(varlist);
11313 for (var = ies.vars; var; var = var->next) {
11314 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11315 if (prev)
11316 ast_free(prev);
11317 prev = var;
11318 if (!newvar) {
11319
11320 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11321 } else {
11322 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11323 }
11324 }
11325 if (prev)
11326 ast_free(prev);
11327 ies.vars = NULL;
11328 ast_channel_datastore_add(c, variablestore);
11329 } else {
11330 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11331 if (variablestore)
11332 ast_datastore_free(variablestore);
11333 if (varlist)
11334 ast_free(varlist);
11335 }
11336 }
11337 }
11338 }
11339 break;
11340 case IAX_COMMAND_INVAL:
11341 iaxs[fr->callno]->error = ENOTCONN;
11342 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11343 iax2_destroy(fr->callno);
11344 ast_debug(1, "Destroying call %d\n", fr->callno);
11345 break;
11346 case IAX_COMMAND_VNAK:
11347 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11348
11349 vnak_retransmit(fr->callno, fr->iseqno);
11350 break;
11351 case IAX_COMMAND_REGREQ:
11352 case IAX_COMMAND_REGREL:
11353
11354 if (delayreject)
11355 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11356 if (register_verify(fr->callno, &sin, &ies)) {
11357 if (!iaxs[fr->callno]) {
11358 break;
11359 }
11360
11361 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11362 break;
11363 }
11364 if (!iaxs[fr->callno]) {
11365 break;
11366 }
11367 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11368 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11369
11370 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11371 memset(&sin, 0, sizeof(sin));
11372 sin.sin_family = AF_INET;
11373 }
11374 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11375 ast_log(LOG_WARNING, "Registry error\n");
11376 }
11377 if (!iaxs[fr->callno]) {
11378 break;
11379 }
11380 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11381 ast_mutex_unlock(&iaxsl[fr->callno]);
11382 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11383 ast_mutex_lock(&iaxsl[fr->callno]);
11384 }
11385 break;
11386 }
11387 registry_authrequest(fr->callno);
11388 break;
11389 case IAX_COMMAND_REGACK:
11390 if (iax2_ack_registry(&ies, &sin, fr->callno))
11391 ast_log(LOG_WARNING, "Registration failure\n");
11392
11393 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11394 iax2_destroy(fr->callno);
11395 break;
11396 case IAX_COMMAND_REGREJ:
11397 if (iaxs[fr->callno]->reg) {
11398 if (authdebug) {
11399 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));
11400 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>");
11401 }
11402 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11403 }
11404
11405 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11406 iax2_destroy(fr->callno);
11407 break;
11408 case IAX_COMMAND_REGAUTH:
11409
11410 if (registry_rerequest(&ies, fr->callno, &sin)) {
11411 memset(&ied0, 0, sizeof(ied0));
11412 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11413 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11414 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11415 }
11416 break;
11417 case IAX_COMMAND_TXREJ:
11418 iaxs[fr->callno]->transferring = 0;
11419 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11420 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11421 if (iaxs[fr->callno]->bridgecallno) {
11422 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11423 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11424 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11425 }
11426 }
11427 break;
11428 case IAX_COMMAND_TXREADY:
11429 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11430 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11431 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11432 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11433 else
11434 iaxs[fr->callno]->transferring = TRANSFER_READY;
11435 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
11436 if (iaxs[fr->callno]->bridgecallno) {
11437 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11438 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11439
11440 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11441 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11442 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
11443
11444 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11445 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11446
11447 memset(&ied0, 0, sizeof(ied0));
11448 memset(&ied1, 0, sizeof(ied1));
11449 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11450 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11451 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11452 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11453 } else {
11454 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
11455 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
11456
11457 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11458 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11459 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11460 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11461
11462
11463 stop_stuff(fr->callno);
11464 stop_stuff(iaxs[fr->callno]->bridgecallno);
11465
11466 memset(&ied0, 0, sizeof(ied0));
11467 memset(&ied1, 0, sizeof(ied1));
11468 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11469 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11470 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11471 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11472 }
11473
11474 }
11475 }
11476 }
11477 break;
11478 case IAX_COMMAND_TXREQ:
11479 try_transfer(iaxs[fr->callno], &ies);
11480 break;
11481 case IAX_COMMAND_TXCNT:
11482 if (iaxs[fr->callno]->transferring)
11483 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11484 break;
11485 case IAX_COMMAND_TXREL:
11486
11487 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11488 complete_transfer(fr->callno, &ies);
11489 stop_stuff(fr->callno);
11490 break;
11491 case IAX_COMMAND_TXMEDIA:
11492 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11493 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11494
11495 if (cur->transfer) {
11496 cur->retries = -1;
11497 }
11498 }
11499
11500 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11501 }
11502 break;
11503 case IAX_COMMAND_RTKEY:
11504 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11505 ast_log(LOG_WARNING,
11506 "we've been told to rotate our encryption key, "
11507 "but this isn't an encrypted call. bad things will happen.\n"
11508 );
11509 break;
11510 }
11511
11512 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11513
11514 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11515 break;
11516 case IAX_COMMAND_DPREP:
11517 complete_dpreply(iaxs[fr->callno], &ies);
11518 break;
11519 case IAX_COMMAND_UNSUPPORT:
11520 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11521 break;
11522 case IAX_COMMAND_FWDOWNL:
11523
11524 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11525 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11526 break;
11527 }
11528 memset(&ied0, 0, sizeof(ied0));
11529 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11530 if (res < 0)
11531 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11532 else if (res > 0)
11533 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11534 else
11535 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11536 break;
11537 case IAX_COMMAND_CALLTOKEN:
11538 {
11539 struct iax_frame *cur;
11540
11541 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11542 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11543 }
11544 break;
11545 }
11546 default:
11547 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11548 memset(&ied0, 0, sizeof(ied0));
11549 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11550 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11551 }
11552
11553 if (ies.vars) {
11554 ast_variables_destroy(ies.vars);
11555 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11556 ies.vars = NULL;
11557 }
11558
11559
11560 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11561 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11562 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11563 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11564 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11565 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11566 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11567 }
11568 ast_mutex_unlock(&iaxsl[fr->callno]);
11569 return 1;
11570 }
11571
11572 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11573 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11574 } else if (minivid) {
11575 f.frametype = AST_FRAME_VIDEO;
11576 if (iaxs[fr->callno]->videoformat > 0) {
11577 if (ntohs(vh->ts) & 0x8000LL) {
11578 ast_format_set_video_mark(&f.subclass.format);
11579 }
11580 ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->videoformat);
11581 } else {
11582 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11583 iax2_vnak(fr->callno);
11584 ast_variables_destroy(ies.vars);
11585 ast_mutex_unlock(&iaxsl[fr->callno]);
11586 return 1;
11587 }
11588 f.datalen = res - sizeof(*vh);
11589 if (f.datalen)
11590 f.data.ptr = thread->buf + sizeof(*vh);
11591 else
11592 f.data.ptr = NULL;
11593 #ifdef IAXTESTS
11594 if (test_resync) {
11595 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11596 } else
11597 #endif
11598 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11599 } else {
11600
11601 f.frametype = AST_FRAME_VOICE;
11602 if (iaxs[fr->callno]->voiceformat > 0)
11603 ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
11604 else {
11605 ast_debug(1, "Received mini frame before first full voice frame\n");
11606 iax2_vnak(fr->callno);
11607 ast_variables_destroy(ies.vars);
11608 ast_mutex_unlock(&iaxsl[fr->callno]);
11609 return 1;
11610 }
11611 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11612 if (f.datalen < 0) {
11613 ast_log(LOG_WARNING, "Datalen < 0?\n");
11614 ast_variables_destroy(ies.vars);
11615 ast_mutex_unlock(&iaxsl[fr->callno]);
11616 return 1;
11617 }
11618 if (f.datalen)
11619 f.data.ptr = thread->buf + sizeof(*mh);
11620 else
11621 f.data.ptr = NULL;
11622 #ifdef IAXTESTS
11623 if (test_resync) {
11624 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11625 } else
11626 #endif
11627 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11628
11629 }
11630
11631 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11632 ast_variables_destroy(ies.vars);
11633 ast_mutex_unlock(&iaxsl[fr->callno]);
11634 return 1;
11635 }
11636
11637 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11638 struct ast_party_connected_line connected;
11639
11640 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11641 ast_variables_destroy(ies.vars);
11642 ast_mutex_unlock(&iaxsl[fr->callno]);
11643 return 1;
11644 }
11645
11646
11647 ast_party_connected_line_init(&connected);
11648 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11649 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11650
11651 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11652 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11653 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11654 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11655
11656 if (iaxs[fr->callno]->owner) {
11657 ast_set_callerid(iaxs[fr->callno]->owner,
11658 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11659 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11660 NULL);
11661 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11662 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11663 }
11664 }
11665 ast_party_connected_line_free(&connected);
11666 }
11667
11668 f.src = "IAX2";
11669 f.mallocd = 0;
11670 f.offset = 0;
11671 f.len = 0;
11672 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11673 f.samples = ast_codec_get_samples(&f);
11674
11675 if (f.subclass.format.id == AST_FORMAT_SLINEAR)
11676 ast_frame_byteswap_be(&f);
11677 } else
11678 f.samples = 0;
11679 iax_frame_wrap(fr, &f);
11680
11681
11682 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11683
11684 fr->outoforder = 0;
11685 } else {
11686 if (iaxdebug && iaxs[fr->callno])
11687 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);
11688 fr->outoforder = -1;
11689 }
11690 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11691 duped_fr = iaxfrdup2(fr);
11692 if (duped_fr) {
11693 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11694 }
11695 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11696 iaxs[fr->callno]->last = fr->ts;
11697 #if 1
11698 if (iaxdebug)
11699 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11700 #endif
11701 }
11702
11703
11704 ast_variables_destroy(ies.vars);
11705 ast_mutex_unlock(&iaxsl[fr->callno]);
11706 return 1;
11707 }
11708
11709
11710 static void iax2_process_thread_cleanup(void *data)
11711 {
11712 struct iax2_thread *thread = data;
11713 ast_mutex_destroy(&thread->lock);
11714 ast_cond_destroy(&thread->cond);
11715 ast_mutex_destroy(&thread->init_lock);
11716 ast_cond_destroy(&thread->init_cond);
11717 ast_free(thread);
11718 ast_atomic_dec_and_test(&iaxactivethreadcount);
11719 }
11720
11721 static void *iax2_process_thread(void *data)
11722 {
11723 struct iax2_thread *thread = data;
11724 struct timeval wait;
11725 struct timespec ts;
11726 int put_into_idle = 0;
11727 int first_time = 1;
11728 int old_state;
11729
11730 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11731
11732 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11733 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11734
11735 for (;;) {
11736
11737 ast_mutex_lock(&thread->lock);
11738
11739 if (thread->stop) {
11740 ast_mutex_unlock(&thread->lock);
11741 break;
11742 }
11743
11744
11745 if (first_time) {
11746 signal_condition(&thread->init_lock, &thread->init_cond);
11747 first_time = 0;
11748 }
11749
11750
11751 if (put_into_idle) {
11752 insert_idle_thread(thread);
11753 }
11754
11755 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11756 struct iax2_thread *t = NULL;
11757
11758 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11759 ts.tv_sec = wait.tv_sec;
11760 ts.tv_nsec = wait.tv_usec * 1000;
11761 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11762
11763
11764 if (!put_into_idle || thread->stop) {
11765 ast_mutex_unlock(&thread->lock);
11766 break;
11767 }
11768 AST_LIST_LOCK(&dynamic_list);
11769
11770 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11771 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11772 AST_LIST_UNLOCK(&dynamic_list);
11773 if (t) {
11774
11775
11776
11777 ast_mutex_unlock(&thread->lock);
11778 break;
11779 }
11780
11781
11782
11783 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11784 ts.tv_sec = wait.tv_sec;
11785 ts.tv_nsec = wait.tv_usec * 1000;
11786 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11787 ast_mutex_unlock(&thread->lock);
11788 break;
11789 }
11790 }
11791 } else {
11792 ast_cond_wait(&thread->cond, &thread->lock);
11793 }
11794
11795
11796 put_into_idle = 1;
11797
11798 ast_mutex_unlock(&thread->lock);
11799
11800 if (thread->stop) {
11801 break;
11802 }
11803
11804 if (thread->iostate == IAX_IOSTATE_IDLE)
11805 continue;
11806
11807
11808 switch (thread->iostate) {
11809 case IAX_IOSTATE_READY:
11810 thread->actions++;
11811 thread->iostate = IAX_IOSTATE_PROCESSING;
11812 socket_process(thread);
11813 handle_deferred_full_frames(thread);
11814 break;
11815 case IAX_IOSTATE_SCHEDREADY:
11816 thread->actions++;
11817 thread->iostate = IAX_IOSTATE_PROCESSING;
11818 #ifdef SCHED_MULTITHREADED
11819 thread->schedfunc(thread->scheddata);
11820 #endif
11821 default:
11822 break;
11823 }
11824 time(&thread->checktime);
11825 thread->iostate = IAX_IOSTATE_IDLE;
11826 #ifdef DEBUG_SCHED_MULTITHREAD
11827 thread->curfunc[0]='\0';
11828 #endif
11829
11830
11831
11832
11833 AST_LIST_LOCK(&active_list);
11834 AST_LIST_REMOVE(&active_list, thread, list);
11835 AST_LIST_UNLOCK(&active_list);
11836
11837
11838 handle_deferred_full_frames(thread);
11839 }
11840
11841
11842
11843
11844
11845
11846 AST_LIST_LOCK(&idle_list);
11847 AST_LIST_REMOVE(&idle_list, thread, list);
11848 AST_LIST_UNLOCK(&idle_list);
11849
11850 AST_LIST_LOCK(&dynamic_list);
11851 AST_LIST_REMOVE(&dynamic_list, thread, list);
11852 AST_LIST_UNLOCK(&dynamic_list);
11853
11854 if (!thread->stop) {
11855
11856 pthread_detach(pthread_self());
11857 }
11858
11859
11860
11861
11862 pthread_cleanup_pop(1);
11863 return NULL;
11864 }
11865
11866 static int iax2_do_register(struct iax2_registry *reg)
11867 {
11868 struct iax_ie_data ied;
11869 if (iaxdebug)
11870 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11871
11872 if (reg->dnsmgr &&
11873 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
11874
11875 ast_dnsmgr_refresh(reg->dnsmgr);
11876 }
11877
11878
11879
11880
11881
11882 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11883 int callno = reg->callno;
11884 ast_mutex_lock(&iaxsl[callno]);
11885 iax2_destroy(callno);
11886 ast_mutex_unlock(&iaxsl[callno]);
11887 reg->callno = 0;
11888 }
11889 if (!ast_sockaddr_ipv4(®->addr)) {
11890 if (iaxdebug)
11891 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11892
11893 reg->expire = iax2_sched_replace(reg->expire, sched,
11894 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11895 return -1;
11896 }
11897
11898 if (!reg->callno) {
11899 struct sockaddr_in reg_addr;
11900
11901 ast_debug(3, "Allocate call number\n");
11902
11903 ast_sockaddr_to_sin(®->addr, ®_addr);
11904
11905 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
11906 if (reg->callno < 1) {
11907 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11908 return -1;
11909 } else
11910 ast_debug(3, "Registration created on call %d\n", reg->callno);
11911 iaxs[reg->callno]->reg = reg;
11912 ast_mutex_unlock(&iaxsl[reg->callno]);
11913 }
11914
11915 reg->expire = iax2_sched_replace(reg->expire, sched,
11916 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11917
11918 memset(&ied, 0, sizeof(ied));
11919 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11920 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11921 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11922 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11923 reg->regstate = REG_STATE_REGSENT;
11924 return 0;
11925 }
11926
11927 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
11928 {
11929
11930
11931 struct iax_ie_data provdata;
11932 struct iax_ie_data ied;
11933 unsigned int sig;
11934 struct sockaddr_in sin;
11935 int callno;
11936 struct create_addr_info cai;
11937
11938 memset(&cai, 0, sizeof(cai));
11939
11940 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11941
11942 if (iax_provision_build(&provdata, &sig, template, force)) {
11943 ast_debug(1, "No provisioning found for template '%s'\n", template);
11944 return 0;
11945 }
11946
11947 if (end) {
11948 memcpy(&sin, end, sizeof(sin));
11949 cai.sockfd = sockfd;
11950 } else if (create_addr(dest, NULL, &sin, &cai))
11951 return -1;
11952
11953
11954 memset(&ied, 0, sizeof(ied));
11955 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11956
11957 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11958 if (!callno)
11959 return -1;
11960
11961 if (iaxs[callno]) {
11962
11963 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11964 sched, 15000, auto_hangup, (void *)(long)callno);
11965 ast_set_flag64(iaxs[callno], IAX_PROVISION);
11966
11967 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11968 }
11969 ast_mutex_unlock(&iaxsl[callno]);
11970
11971 return 1;
11972 }
11973
11974 static char *papp = "IAX2Provision";
11975
11976
11977
11978
11979 static int iax2_prov_app(struct ast_channel *chan, const char *data)
11980 {
11981 int res;
11982 char *sdata;
11983 char *opts;
11984 int force =0;
11985 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11986 if (ast_strlen_zero(data))
11987 data = "default";
11988 sdata = ast_strdupa(data);
11989 opts = strchr(sdata, '|');
11990 if (opts)
11991 *opts='\0';
11992
11993 if (chan->tech != &iax2_tech) {
11994 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11995 return -1;
11996 }
11997 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11998 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11999 return -1;
12000 }
12001 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
12002 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
12003 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
12004 sdata, res);
12005 return res;
12006 }
12007
12008 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
12009 {
12010 int force = 0;
12011 int res;
12012
12013 switch (cmd) {
12014 case CLI_INIT:
12015 e->command = "iax2 provision";
12016 e->usage =
12017 "Usage: iax2 provision <host> <template> [forced]\n"
12018 " Provisions the given peer or IP address using a template\n"
12019 " matching either 'template' or '*' if the template is not\n"
12020 " found. If 'forced' is specified, even empty provisioning\n"
12021 " fields will be provisioned as empty fields.\n";
12022 return NULL;
12023 case CLI_GENERATE:
12024 if (a->pos == 3)
12025 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
12026 return NULL;
12027 }
12028
12029 if (a->argc < 4)
12030 return CLI_SHOWUSAGE;
12031 if (a->argc > 4) {
12032 if (!strcasecmp(a->argv[4], "forced"))
12033 force = 1;
12034 else
12035 return CLI_SHOWUSAGE;
12036 }
12037 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
12038 if (res < 0)
12039 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
12040 else if (res < 1)
12041 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
12042 else
12043 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
12044 return CLI_SUCCESS;
12045 }
12046
12047 static void __iax2_poke_noanswer(const void *data)
12048 {
12049 struct iax2_peer *peer = (struct iax2_peer *)data;
12050 int callno;
12051
12052 if (peer->lastms > -1) {
12053 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
12054 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
12055 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
12056 }
12057 if ((callno = peer->callno) > 0) {
12058 ast_mutex_lock(&iaxsl[callno]);
12059 iax2_destroy(callno);
12060 ast_mutex_unlock(&iaxsl[callno]);
12061 }
12062 peer->callno = 0;
12063 peer->lastms = -1;
12064
12065 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
12066 if (peer->pokeexpire == -1)
12067 peer_unref(peer);
12068 }
12069
12070 static int iax2_poke_noanswer(const void *data)
12071 {
12072 struct iax2_peer *peer = (struct iax2_peer *)data;
12073 peer->pokeexpire = -1;
12074 #ifdef SCHED_MULTITHREADED
12075 if (schedule_action(__iax2_poke_noanswer, data))
12076 #endif
12077 __iax2_poke_noanswer(data);
12078 peer_unref(peer);
12079 return 0;
12080 }
12081
12082 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
12083 {
12084 struct iax2_peer *peer = obj;
12085
12086 iax2_poke_peer(peer, 0);
12087
12088 return 0;
12089 }
12090
12091 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
12092 {
12093 int callno;
12094 struct sockaddr_in peer_addr;
12095
12096 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
12097
12098
12099 peer->lastms = 0;
12100 peer->historicms = 0;
12101 peer->pokeexpire = -1;
12102 peer->callno = 0;
12103 return 0;
12104 }
12105
12106 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12107
12108
12109 if ((callno = peer->callno) > 0) {
12110 ast_log(LOG_NOTICE, "Still have a callno...\n");
12111 ast_mutex_lock(&iaxsl[callno]);
12112 iax2_destroy(callno);
12113 ast_mutex_unlock(&iaxsl[callno]);
12114 }
12115 if (heldcall)
12116 ast_mutex_unlock(&iaxsl[heldcall]);
12117 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12118 if (heldcall)
12119 ast_mutex_lock(&iaxsl[heldcall]);
12120 if (peer->callno < 1) {
12121 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12122 return -1;
12123 }
12124
12125
12126 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12127 iaxs[peer->callno]->peerpoke = peer;
12128
12129 if (peer->pokeexpire > -1) {
12130 if (!AST_SCHED_DEL(sched, peer->pokeexpire)) {
12131 peer->pokeexpire = -1;
12132 peer_unref(peer);
12133 }
12134 }
12135
12136
12137
12138 if (peer->lastms < 0)
12139 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12140 else
12141 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12142
12143 if (peer->pokeexpire == -1)
12144 peer_unref(peer);
12145
12146
12147 ast_mutex_lock(&iaxsl[callno]);
12148 if (iaxs[callno]) {
12149 struct iax_ie_data ied = {
12150 .buf = { 0 },
12151 .pos = 0,
12152 };
12153 add_empty_calltoken_ie(iaxs[callno], &ied);
12154 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12155 }
12156 ast_mutex_unlock(&iaxsl[callno]);
12157
12158 return 0;
12159 }
12160
12161 static void free_context(struct iax2_context *con)
12162 {
12163 struct iax2_context *conl;
12164 while(con) {
12165 conl = con;
12166 con = con->next;
12167 ast_free(conl);
12168 }
12169 }
12170
12171 static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
12172 {
12173 int callno;
12174 int res;
12175 struct sockaddr_in sin;
12176 struct ast_channel *c;
12177 struct parsed_dial_string pds;
12178 struct create_addr_info cai;
12179 char *tmpstr;
12180
12181 memset(&pds, 0, sizeof(pds));
12182 tmpstr = ast_strdupa(data);
12183 parse_dial_string(tmpstr, &pds);
12184
12185 if (ast_strlen_zero(pds.peer)) {
12186 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
12187 return NULL;
12188 }
12189 memset(&cai, 0, sizeof(cai));
12190 cai.capability = iax2_capability;
12191
12192 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12193
12194
12195 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12196 *cause = AST_CAUSE_UNREGISTERED;
12197 return NULL;
12198 }
12199
12200 if (pds.port)
12201 sin.sin_port = htons(atoi(pds.port));
12202
12203 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12204 if (callno < 1) {
12205 ast_log(LOG_WARNING, "Unable to create call\n");
12206 *cause = AST_CAUSE_CONGESTION;
12207 return NULL;
12208 }
12209
12210
12211 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12212 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12213 int new_callno;
12214 if ((new_callno = make_trunk(callno, 1)) != -1)
12215 callno = new_callno;
12216 }
12217 iaxs[callno]->maxtime = cai.maxtime;
12218 if (cai.found)
12219 ast_string_field_set(iaxs[callno], host, pds.peer);
12220
12221 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL);
12222
12223 ast_mutex_unlock(&iaxsl[callno]);
12224
12225 if (c) {
12226 struct ast_format_cap *joint;
12227
12228
12229 if ((joint = ast_format_cap_joint(c->nativeformats, cap))) {
12230 ast_format_cap_copy(c->nativeformats, joint);
12231 joint = ast_format_cap_destroy(joint);
12232 } else {
12233 struct ast_format best_fmt_cap;
12234 struct ast_format best_fmt_native;
12235 res = ast_translator_best_choice(cap, c->nativeformats, &best_fmt_cap, &best_fmt_native);
12236 if (res < 0) {
12237 char tmp[256];
12238 char tmp2[256];
12239 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12240 ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_channel_name(c));
12241 ast_hangup(c);
12242 return NULL;
12243 }
12244 ast_format_cap_set(c->nativeformats, &best_fmt_native);
12245 }
12246 ast_best_codec(c->nativeformats, &c->readformat);
12247 ast_format_copy(&c->writeformat, &c->readformat);
12248 }
12249
12250 return c;
12251 }
12252
12253 static void *network_thread(void *ignore)
12254 {
12255 if (timer) {
12256 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12257 }
12258
12259 for (;;) {
12260 pthread_testcancel();
12261
12262
12263
12264 ast_io_wait(io, 1000);
12265 }
12266
12267 return NULL;
12268 }
12269
12270 static int start_network_thread(void)
12271 {
12272 struct iax2_thread *thread;
12273 int threadcount = 0;
12274 int x;
12275 for (x = 0; x < iaxthreadcount; x++) {
12276 thread = ast_calloc(1, sizeof(*thread));
12277 if (thread) {
12278 thread->type = IAX_THREAD_TYPE_POOL;
12279 thread->threadnum = ++threadcount;
12280 ast_mutex_init(&thread->lock);
12281 ast_cond_init(&thread->cond, NULL);
12282 ast_mutex_init(&thread->init_lock);
12283 ast_cond_init(&thread->init_cond, NULL);
12284 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12285 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12286 ast_mutex_destroy(&thread->lock);
12287 ast_cond_destroy(&thread->cond);
12288 ast_mutex_destroy(&thread->init_lock);
12289 ast_cond_destroy(&thread->init_cond);
12290 ast_free(thread);
12291 thread = NULL;
12292 continue;
12293 }
12294 AST_LIST_LOCK(&idle_list);
12295 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12296 AST_LIST_UNLOCK(&idle_list);
12297 }
12298 }
12299 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12300 ast_verb(2, "%d helper threads started\n", threadcount);
12301 return 0;
12302 }
12303
12304 static struct iax2_context *build_context(const char *context)
12305 {
12306 struct iax2_context *con;
12307
12308 if ((con = ast_calloc(1, sizeof(*con))))
12309 ast_copy_string(con->context, context, sizeof(con->context));
12310
12311 return con;
12312 }
12313
12314 static int get_auth_methods(const char *value)
12315 {
12316 int methods = 0;
12317 if (strstr(value, "rsa"))
12318 methods |= IAX_AUTH_RSA;
12319 if (strstr(value, "md5"))
12320 methods |= IAX_AUTH_MD5;
12321 if (strstr(value, "plaintext"))
12322 methods |= IAX_AUTH_PLAINTEXT;
12323 return methods;
12324 }
12325
12326
12327
12328
12329
12330 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12331 {
12332 int sd;
12333 int res;
12334
12335 sd = socket(AF_INET, SOCK_DGRAM, 0);
12336 if (sd < 0) {
12337 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12338 return -1;
12339 }
12340
12341 res = bind(sd, sa, salen);
12342 if (res < 0) {
12343 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12344 close(sd);
12345 return 1;
12346 }
12347
12348 close(sd);
12349 return 0;
12350 }
12351
12352
12353
12354
12355 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12356 {
12357 struct sockaddr_in sin;
12358 struct ast_sockaddr sin_tmp;
12359 int nonlocal = 1;
12360 int port = IAX_DEFAULT_PORTNO;
12361 int sockfd = defaultsockfd;
12362 char *tmp;
12363 char *addr;
12364 char *portstr;
12365
12366 if (!(tmp = ast_strdupa(srcaddr)))
12367 return -1;
12368
12369 addr = strsep(&tmp, ":");
12370 portstr = tmp;
12371
12372 if (portstr) {
12373 port = atoi(portstr);
12374 if (port < 1)
12375 port = IAX_DEFAULT_PORTNO;
12376 }
12377
12378 sin_tmp.ss.ss_family = AF_INET;
12379 if (!ast_get_ip(&sin_tmp, addr)) {
12380 struct ast_netsock *sock;
12381 int res;
12382
12383 ast_sockaddr_to_sin(&sin_tmp, &sin);
12384 sin.sin_port = 0;
12385 sin.sin_family = AF_INET;
12386 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12387 if (res == 0) {
12388
12389 sin.sin_port = htons(port);
12390 if (!(sock = ast_netsock_find(netsock, &sin)))
12391 sock = ast_netsock_find(outsock, &sin);
12392 if (sock) {
12393 sockfd = ast_netsock_sockfd(sock);
12394 nonlocal = 0;
12395 } else {
12396 unsigned int orig_saddr = sin.sin_addr.s_addr;
12397
12398 sin.sin_addr.s_addr = INADDR_ANY;
12399 if (ast_netsock_find(netsock, &sin)) {
12400 sin.sin_addr.s_addr = orig_saddr;
12401 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12402 if (sock) {
12403 sockfd = ast_netsock_sockfd(sock);
12404 ast_netsock_unref(sock);
12405 nonlocal = 0;
12406 } else {
12407 nonlocal = 2;
12408 }
12409 }
12410 }
12411 }
12412 }
12413
12414 peer->sockfd = sockfd;
12415
12416 if (nonlocal == 1) {
12417 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12418 srcaddr, peer->name);
12419 return -1;
12420 } else if (nonlocal == 2) {
12421 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12422 srcaddr, peer->name);
12423 return -1;
12424 } else {
12425 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12426 return 0;
12427 }
12428 }
12429
12430 static void peer_destructor(void *obj)
12431 {
12432 struct iax2_peer *peer = obj;
12433 int callno = peer->callno;
12434
12435 ast_free_ha(peer->ha);
12436
12437 if (callno > 0) {
12438 ast_mutex_lock(&iaxsl[callno]);
12439 iax2_destroy(callno);
12440 ast_mutex_unlock(&iaxsl[callno]);
12441 }
12442
12443 register_peer_exten(peer, 0);
12444
12445 if (peer->dnsmgr)
12446 ast_dnsmgr_release(peer->dnsmgr);
12447
12448 if (peer->mwi_event_sub)
12449 ast_event_unsubscribe(peer->mwi_event_sub);
12450
12451 ast_string_field_free_memory(peer);
12452 }
12453
12454
12455 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12456 {
12457 struct iax2_peer *peer = NULL;
12458 struct ast_ha *oldha = NULL;
12459 int maskfound = 0;
12460 int found = 0;
12461 int firstpass = 1;
12462
12463 if (!temponly) {
12464 peer = ao2_find(peers, name, OBJ_KEY);
12465 if (peer && !ast_test_flag64(peer, IAX_DELME))
12466 firstpass = 0;
12467 }
12468
12469 if (peer) {
12470 found++;
12471 if (firstpass) {
12472 oldha = peer->ha;
12473 peer->ha = NULL;
12474 }
12475 unlink_peer(peer);
12476 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12477 peer->expire = -1;
12478 peer->pokeexpire = -1;
12479 peer->sockfd = defaultsockfd;
12480 peer->addr.ss.ss_family = AF_INET;
12481 if (ast_string_field_init(peer, 32))
12482 peer = peer_unref(peer);
12483 }
12484
12485 if (peer) {
12486 if (firstpass) {
12487 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12488 peer->encmethods = iax2_encryption;
12489 peer->adsi = adsi;
12490 ast_string_field_set(peer,secret,"");
12491 if (!found) {
12492 ast_string_field_set(peer, name, name);
12493 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12494 peer->expiry = min_reg_expire;
12495 }
12496 peer->prefs = prefs;
12497 peer->capability = iax2_capability;
12498 peer->smoothing = 0;
12499 peer->pokefreqok = DEFAULT_FREQ_OK;
12500 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12501 peer->maxcallno = 0;
12502 peercnt_modify(0, 0, &peer->addr);
12503 peer->calltoken_required = CALLTOKEN_DEFAULT;
12504 ast_string_field_set(peer,context,"");
12505 ast_string_field_set(peer,peercontext,"");
12506 ast_clear_flag64(peer, IAX_HASCALLERID);
12507 ast_string_field_set(peer, cid_name, "");
12508 ast_string_field_set(peer, cid_num, "");
12509 ast_string_field_set(peer, mohinterpret, mohinterpret);
12510 ast_string_field_set(peer, mohsuggest, mohsuggest);
12511 }
12512
12513 if (!v) {
12514 v = alt;
12515 alt = NULL;
12516 }
12517 while(v) {
12518 if (!strcasecmp(v->name, "secret")) {
12519 ast_string_field_set(peer, secret, v->value);
12520 } else if (!strcasecmp(v->name, "mailbox")) {
12521 ast_string_field_set(peer, mailbox, v->value);
12522 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12523 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12524 ast_string_field_set(peer, mailbox, name);
12525 }
12526 } else if (!strcasecmp(v->name, "mohinterpret")) {
12527 ast_string_field_set(peer, mohinterpret, v->value);
12528 } else if (!strcasecmp(v->name, "mohsuggest")) {
12529 ast_string_field_set(peer, mohsuggest, v->value);
12530 } else if (!strcasecmp(v->name, "dbsecret")) {
12531 ast_string_field_set(peer, dbsecret, v->value);
12532 } else if (!strcasecmp(v->name, "description")) {
12533 ast_string_field_set(peer, description, v->value);
12534 } else if (!strcasecmp(v->name, "trunk")) {
12535 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12536 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12537 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12538 ast_clear_flag64(peer, IAX_TRUNK);
12539 }
12540 } else if (!strcasecmp(v->name, "auth")) {
12541 peer->authmethods = get_auth_methods(v->value);
12542 } else if (!strcasecmp(v->name, "encryption")) {
12543 peer->encmethods |= get_encrypt_methods(v->value);
12544 if (!peer->encmethods) {
12545 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12546 }
12547 } else if (!strcasecmp(v->name, "forceencryption")) {
12548 if (ast_false(v->value)) {
12549 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12550 } else {
12551 peer->encmethods |= get_encrypt_methods(v->value);
12552 if (peer->encmethods) {
12553 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12554 }
12555 }
12556 } else if (!strcasecmp(v->name, "transfer")) {
12557 if (!strcasecmp(v->value, "mediaonly")) {
12558 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12559 } else if (ast_true(v->value)) {
12560 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12561 } else
12562 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12563 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12564 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12565 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12566 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12567 } else if (!strcasecmp(v->name, "host")) {
12568 if (!strcasecmp(v->value, "dynamic")) {
12569
12570 ast_set_flag64(peer, IAX_DYNAMIC);
12571 if (!found) {
12572
12573
12574 if (ast_sockaddr_port(&peer->addr)) {
12575 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12576 }
12577 ast_sockaddr_setnull(&peer->addr);
12578 }
12579 } else {
12580
12581 AST_SCHED_DEL(sched, peer->expire);
12582 ast_clear_flag64(peer, IAX_DYNAMIC);
12583 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12584 return peer_unref(peer);
12585 if (!ast_sockaddr_port(&peer->addr)) {
12586 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12587 }
12588 }
12589 if (!maskfound)
12590 inet_aton("255.255.255.255", &peer->mask);
12591 } else if (!strcasecmp(v->name, "defaultip")) {
12592 struct ast_sockaddr peer_defaddr_tmp;
12593
12594 peer_defaddr_tmp.ss.ss_family = AF_INET;
12595 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12596 return peer_unref(peer);
12597 }
12598 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12599 &peer->defaddr);
12600 } else if (!strcasecmp(v->name, "sourceaddress")) {
12601 peer_set_srcaddr(peer, v->value);
12602 } else if (!strcasecmp(v->name, "permit") ||
12603 !strcasecmp(v->name, "deny")) {
12604 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12605 } else if (!strcasecmp(v->name, "mask")) {
12606 maskfound++;
12607 inet_aton(v->value, &peer->mask);
12608 } else if (!strcasecmp(v->name, "context")) {
12609 ast_string_field_set(peer, context, v->value);
12610 } else if (!strcasecmp(v->name, "regexten")) {
12611 ast_string_field_set(peer, regexten, v->value);
12612 } else if (!strcasecmp(v->name, "peercontext")) {
12613 ast_string_field_set(peer, peercontext, v->value);
12614 } else if (!strcasecmp(v->name, "port")) {
12615 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12616 peer->defaddr.sin_port = htons(atoi(v->value));
12617 } else {
12618 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12619 }
12620 } else if (!strcasecmp(v->name, "username")) {
12621 ast_string_field_set(peer, username, v->value);
12622 } else if (!strcasecmp(v->name, "allow")) {
12623 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12624 } else if (!strcasecmp(v->name, "disallow")) {
12625 iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12626 } else if (!strcasecmp(v->name, "callerid")) {
12627 if (!ast_strlen_zero(v->value)) {
12628 char name2[80];
12629 char num2[80];
12630 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12631 ast_string_field_set(peer, cid_name, name2);
12632 ast_string_field_set(peer, cid_num, num2);
12633 } else {
12634 ast_string_field_set(peer, cid_name, "");
12635 ast_string_field_set(peer, cid_num, "");
12636 }
12637 ast_set_flag64(peer, IAX_HASCALLERID);
12638 } else if (!strcasecmp(v->name, "fullname")) {
12639 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12640 ast_set_flag64(peer, IAX_HASCALLERID);
12641 } else if (!strcasecmp(v->name, "cid_number")) {
12642 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12643 ast_set_flag64(peer, IAX_HASCALLERID);
12644 } else if (!strcasecmp(v->name, "sendani")) {
12645 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12646 } else if (!strcasecmp(v->name, "inkeys")) {
12647 ast_string_field_set(peer, inkeys, v->value);
12648 } else if (!strcasecmp(v->name, "outkey")) {
12649 ast_string_field_set(peer, outkey, v->value);
12650 } else if (!strcasecmp(v->name, "qualify")) {
12651 if (!strcasecmp(v->value, "no")) {
12652 peer->maxms = 0;
12653 } else if (!strcasecmp(v->value, "yes")) {
12654 peer->maxms = DEFAULT_MAXMS;
12655 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12656 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);
12657 peer->maxms = 0;
12658 }
12659 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12660 peer->smoothing = ast_true(v->value);
12661 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12662 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12663 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);
12664 }
12665 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12666 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12667 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);
12668 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12669 } else if (!strcasecmp(v->name, "timezone")) {
12670 ast_string_field_set(peer, zonetag, v->value);
12671 } else if (!strcasecmp(v->name, "adsi")) {
12672 peer->adsi = ast_true(v->value);
12673 } else if (!strcasecmp(v->name, "connectedline")) {
12674 if (ast_true(v->value)) {
12675 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12676 } else if (!strcasecmp(v->value, "send")) {
12677 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12678 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12679 } else if (!strcasecmp(v->value, "receive")) {
12680 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12681 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12682 } else {
12683 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12684 }
12685 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12686 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12687 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12688 } else {
12689 peercnt_modify(1, peer->maxcallno, &peer->addr);
12690 }
12691 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12692
12693 if (ast_false(v->value)) {
12694 peer->calltoken_required = CALLTOKEN_NO;
12695 } else if (!strcasecmp(v->value, "auto")) {
12696 peer->calltoken_required = CALLTOKEN_AUTO;
12697 } else if (ast_true(v->value)) {
12698 peer->calltoken_required = CALLTOKEN_YES;
12699 } else {
12700 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12701 }
12702 }
12703
12704 v = v->next;
12705 if (!v) {
12706 v = alt;
12707 alt = NULL;
12708 }
12709 }
12710 if (!peer->authmethods)
12711 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12712 ast_clear_flag64(peer, IAX_DELME);
12713 }
12714
12715 if (oldha)
12716 ast_free_ha(oldha);
12717
12718 if (!ast_strlen_zero(peer->mailbox)) {
12719 char *mailbox, *context;
12720 context = mailbox = ast_strdupa(peer->mailbox);
12721 strsep(&context, "@");
12722 if (ast_strlen_zero(context))
12723 context = "default";
12724 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12725 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12726 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12727 AST_EVENT_IE_END);
12728 }
12729
12730 return peer;
12731 }
12732
12733 static void user_destructor(void *obj)
12734 {
12735 struct iax2_user *user = obj;
12736
12737 ast_free_ha(user->ha);
12738 free_context(user->contexts);
12739 if(user->vars) {
12740 ast_variables_destroy(user->vars);
12741 user->vars = NULL;
12742 }
12743 ast_string_field_free_memory(user);
12744 }
12745
12746
12747 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12748 {
12749 struct iax2_user *user = NULL;
12750 struct iax2_context *con, *conl = NULL;
12751 struct ast_ha *oldha = NULL;
12752 struct iax2_context *oldcon = NULL;
12753 int format;
12754 int firstpass=1;
12755 int oldcurauthreq = 0;
12756 char *varname = NULL, *varval = NULL;
12757 struct ast_variable *tmpvar = NULL;
12758
12759 if (!temponly) {
12760 user = ao2_find(users, name, OBJ_KEY);
12761 if (user && !ast_test_flag64(user, IAX_DELME))
12762 firstpass = 0;
12763 }
12764
12765 if (user) {
12766 if (firstpass) {
12767 oldcurauthreq = user->curauthreq;
12768 oldha = user->ha;
12769 oldcon = user->contexts;
12770 user->ha = NULL;
12771 user->contexts = NULL;
12772 }
12773
12774 ao2_unlink(users, user);
12775 } else {
12776 user = ao2_alloc(sizeof(*user), user_destructor);
12777 }
12778
12779 if (user) {
12780 if (firstpass) {
12781 ast_string_field_free_memory(user);
12782 memset(user, 0, sizeof(struct iax2_user));
12783 if (ast_string_field_init(user, 32)) {
12784 user = user_unref(user);
12785 goto cleanup;
12786 }
12787 user->maxauthreq = maxauthreq;
12788 user->curauthreq = oldcurauthreq;
12789 user->prefs = prefs;
12790 user->capability = iax2_capability;
12791 user->encmethods = iax2_encryption;
12792 user->adsi = adsi;
12793 user->calltoken_required = CALLTOKEN_DEFAULT;
12794 ast_string_field_set(user, name, name);
12795 ast_string_field_set(user, language, language);
12796 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);
12797 ast_clear_flag64(user, IAX_HASCALLERID);
12798 ast_string_field_set(user, cid_name, "");
12799 ast_string_field_set(user, cid_num, "");
12800 ast_string_field_set(user, accountcode, accountcode);
12801 ast_string_field_set(user, mohinterpret, mohinterpret);
12802 ast_string_field_set(user, mohsuggest, mohsuggest);
12803 }
12804 if (!v) {
12805 v = alt;
12806 alt = NULL;
12807 }
12808 while(v) {
12809 if (!strcasecmp(v->name, "context")) {
12810 con = build_context(v->value);
12811 if (con) {
12812 if (conl)
12813 conl->next = con;
12814 else
12815 user->contexts = con;
12816 conl = con;
12817 }
12818 } else if (!strcasecmp(v->name, "permit") ||
12819 !strcasecmp(v->name, "deny")) {
12820 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12821 } else if (!strcasecmp(v->name, "setvar")) {
12822 varname = ast_strdupa(v->value);
12823 if (varname && (varval = strchr(varname,'='))) {
12824 *varval = '\0';
12825 varval++;
12826 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12827 tmpvar->next = user->vars;
12828 user->vars = tmpvar;
12829 }
12830 }
12831 } else if (!strcasecmp(v->name, "allow")) {
12832 iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12833 } else if (!strcasecmp(v->name, "disallow")) {
12834 iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12835 } else if (!strcasecmp(v->name, "trunk")) {
12836 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
12837 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12838 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12839 ast_clear_flag64(user, IAX_TRUNK);
12840 }
12841 } else if (!strcasecmp(v->name, "auth")) {
12842 user->authmethods = get_auth_methods(v->value);
12843 } else if (!strcasecmp(v->name, "encryption")) {
12844 user->encmethods |= get_encrypt_methods(v->value);
12845 if (!user->encmethods) {
12846 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12847 }
12848 } else if (!strcasecmp(v->name, "forceencryption")) {
12849 if (ast_false(v->value)) {
12850 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12851 } else {
12852 user->encmethods |= get_encrypt_methods(v->value);
12853 if (user->encmethods) {
12854 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12855 }
12856 }
12857 } else if (!strcasecmp(v->name, "transfer")) {
12858 if (!strcasecmp(v->value, "mediaonly")) {
12859 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12860 } else if (ast_true(v->value)) {
12861 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12862 } else
12863 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12864 } else if (!strcasecmp(v->name, "codecpriority")) {
12865 if(!strcasecmp(v->value, "caller"))
12866 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12867 else if(!strcasecmp(v->value, "disabled"))
12868 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12869 else if(!strcasecmp(v->value, "reqonly")) {
12870 ast_set_flag64(user, IAX_CODEC_NOCAP);
12871 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12872 }
12873 } else if (!strcasecmp(v->name, "immediate")) {
12874 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12875 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12876 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12877 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12878 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12879 } else if (!strcasecmp(v->name, "dbsecret")) {
12880 ast_string_field_set(user, dbsecret, v->value);
12881 } else if (!strcasecmp(v->name, "secret")) {
12882 if (!ast_strlen_zero(user->secret)) {
12883 char *old = ast_strdupa(user->secret);
12884
12885 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12886 } else
12887 ast_string_field_set(user, secret, v->value);
12888 } else if (!strcasecmp(v->name, "callerid")) {
12889 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12890 char name2[80];
12891 char num2[80];
12892 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12893 ast_string_field_set(user, cid_name, name2);
12894 ast_string_field_set(user, cid_num, num2);
12895 ast_set_flag64(user, IAX_HASCALLERID);
12896 } else {
12897 ast_clear_flag64(user, IAX_HASCALLERID);
12898 ast_string_field_set(user, cid_name, "");
12899 ast_string_field_set(user, cid_num, "");
12900 }
12901 } else if (!strcasecmp(v->name, "fullname")) {
12902 if (!ast_strlen_zero(v->value)) {
12903 ast_string_field_set(user, cid_name, v->value);
12904 ast_set_flag64(user, IAX_HASCALLERID);
12905 } else {
12906 ast_string_field_set(user, cid_name, "");
12907 if (ast_strlen_zero(user->cid_num))
12908 ast_clear_flag64(user, IAX_HASCALLERID);
12909 }
12910 } else if (!strcasecmp(v->name, "cid_number")) {
12911 if (!ast_strlen_zero(v->value)) {
12912 ast_string_field_set(user, cid_num, v->value);
12913 ast_set_flag64(user, IAX_HASCALLERID);
12914 } else {
12915 ast_string_field_set(user, cid_num, "");
12916 if (ast_strlen_zero(user->cid_name))
12917 ast_clear_flag64(user, IAX_HASCALLERID);
12918 }
12919 } else if (!strcasecmp(v->name, "accountcode")) {
12920 ast_string_field_set(user, accountcode, v->value);
12921 } else if (!strcasecmp(v->name, "mohinterpret")) {
12922 ast_string_field_set(user, mohinterpret, v->value);
12923 } else if (!strcasecmp(v->name, "mohsuggest")) {
12924 ast_string_field_set(user, mohsuggest, v->value);
12925 } else if (!strcasecmp(v->name, "parkinglot")) {
12926 ast_string_field_set(user, parkinglot, v->value);
12927 } else if (!strcasecmp(v->name, "language")) {
12928 ast_string_field_set(user, language, v->value);
12929 } else if (!strcasecmp(v->name, "amaflags")) {
12930 format = ast_cdr_amaflags2int(v->value);
12931 if (format < 0) {
12932 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12933 } else {
12934 user->amaflags = format;
12935 }
12936 } else if (!strcasecmp(v->name, "inkeys")) {
12937 ast_string_field_set(user, inkeys, v->value);
12938 } else if (!strcasecmp(v->name, "maxauthreq")) {
12939 user->maxauthreq = atoi(v->value);
12940 if (user->maxauthreq < 0)
12941 user->maxauthreq = 0;
12942 } else if (!strcasecmp(v->name, "adsi")) {
12943 user->adsi = ast_true(v->value);
12944 } else if (!strcasecmp(v->name, "connectedline")) {
12945 if (ast_true(v->value)) {
12946 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12947 } else if (!strcasecmp(v->value, "send")) {
12948 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12949 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12950 } else if (!strcasecmp(v->value, "receive")) {
12951 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12952 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12953 } else {
12954 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12955 }
12956 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12957
12958 if (ast_false(v->value)) {
12959 user->calltoken_required = CALLTOKEN_NO;
12960 } else if (!strcasecmp(v->value, "auto")) {
12961 user->calltoken_required = CALLTOKEN_AUTO;
12962 } else if (ast_true(v->value)) {
12963 user->calltoken_required = CALLTOKEN_YES;
12964 } else {
12965 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12966 }
12967 }
12968
12969 v = v->next;
12970 if (!v) {
12971 v = alt;
12972 alt = NULL;
12973 }
12974 }
12975 if (!user->authmethods) {
12976 if (!ast_strlen_zero(user->secret)) {
12977 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12978 if (!ast_strlen_zero(user->inkeys))
12979 user->authmethods |= IAX_AUTH_RSA;
12980 } else if (!ast_strlen_zero(user->inkeys)) {
12981 user->authmethods = IAX_AUTH_RSA;
12982 } else {
12983 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12984 }
12985 }
12986 ast_clear_flag64(user, IAX_DELME);
12987 }
12988 cleanup:
12989 if (oldha)
12990 ast_free_ha(oldha);
12991 if (oldcon)
12992 free_context(oldcon);
12993 return user;
12994 }
12995
12996 static int peer_delme_cb(void *obj, void *arg, int flags)
12997 {
12998 struct iax2_peer *peer = obj;
12999
13000 ast_set_flag64(peer, IAX_DELME);
13001
13002 return 0;
13003 }
13004
13005 static int user_delme_cb(void *obj, void *arg, int flags)
13006 {
13007 struct iax2_user *user = obj;
13008
13009 ast_set_flag64(user, IAX_DELME);
13010
13011 return 0;
13012 }
13013
13014 static void delete_users(void)
13015 {
13016 struct iax2_registry *reg;
13017
13018 ao2_callback(users, 0, user_delme_cb, NULL);
13019
13020 AST_LIST_LOCK(®istrations);
13021 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
13022 if (sched) {
13023 AST_SCHED_DEL(sched, reg->expire);
13024 }
13025 if (reg->callno) {
13026 int callno = reg->callno;
13027 ast_mutex_lock(&iaxsl[callno]);
13028 if (iaxs[callno]) {
13029 iaxs[callno]->reg = NULL;
13030 iax2_destroy(callno);
13031 }
13032 ast_mutex_unlock(&iaxsl[callno]);
13033 }
13034 if (reg->dnsmgr)
13035 ast_dnsmgr_release(reg->dnsmgr);
13036 ast_free(reg);
13037 }
13038 AST_LIST_UNLOCK(®istrations);
13039
13040 ao2_callback(peers, 0, peer_delme_cb, NULL);
13041 }
13042
13043 static void prune_users(void)
13044 {
13045 struct iax2_user *user;
13046 struct ao2_iterator i;
13047
13048 i = ao2_iterator_init(users, 0);
13049 while ((user = ao2_iterator_next(&i))) {
13050 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
13051 ao2_unlink(users, user);
13052 }
13053 user_unref(user);
13054 }
13055 ao2_iterator_destroy(&i);
13056 }
13057
13058
13059 static void prune_peers(void)
13060 {
13061 struct iax2_peer *peer;
13062 struct ao2_iterator i;
13063
13064 i = ao2_iterator_init(peers, 0);
13065 while ((peer = ao2_iterator_next(&i))) {
13066 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
13067 unlink_peer(peer);
13068 }
13069 peer_unref(peer);
13070 }
13071 ao2_iterator_destroy(&i);
13072 }
13073
13074 static void set_config_destroy(void)
13075 {
13076 strcpy(accountcode, "");
13077 strcpy(language, "");
13078 strcpy(mohinterpret, "default");
13079 strcpy(mohsuggest, "");
13080 trunkmaxsize = MAX_TRUNKDATA;
13081 amaflags = 0;
13082 delayreject = 0;
13083 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
13084 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13085 delete_users();
13086 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
13087 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
13088 }
13089
13090
13091 static int set_config(const char *config_file, int reload)
13092 {
13093 struct ast_config *cfg, *ucfg;
13094 iax2_format capability = iax2_capability;
13095 struct ast_variable *v;
13096 char *cat;
13097 const char *utype;
13098 const char *tosval;
13099 int format;
13100 int portno = IAX_DEFAULT_PORTNO;
13101 int x;
13102 int mtuv;
13103 int subscribe_network_change = 1;
13104 struct iax2_user *user;
13105 struct iax2_peer *peer;
13106 struct ast_netsock *ns;
13107 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13108 #if 0
13109 static unsigned short int last_port=0;
13110 #endif
13111
13112 cfg = ast_config_load(config_file, config_flags);
13113
13114 if (!cfg) {
13115 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13116 return -1;
13117 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13118 ucfg = ast_config_load("users.conf", config_flags);
13119 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13120 return 0;
13121
13122 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13123 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13124 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13125 ast_config_destroy(ucfg);
13126 return 0;
13127 }
13128 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13129 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13130 return 0;
13131 } else {
13132 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13133 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13134 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
13135 ast_config_destroy(cfg);
13136 return 0;
13137 }
13138 }
13139
13140 if (reload) {
13141 set_config_destroy();
13142 }
13143
13144
13145 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13146
13147
13148 memset(&globalflags, 0, sizeof(globalflags));
13149 ast_set_flag64(&globalflags, IAX_RTUPDATE);
13150 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13151
13152 #ifdef SO_NO_CHECK
13153 nochecksums = 0;
13154 #endif
13155
13156 default_parkinglot[0] = '\0';
13157
13158 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13159 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13160 global_max_trunk_mtu = MAX_TRUNK_MTU;
13161 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13162 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13163
13164 maxauthreq = 3;
13165
13166 srvlookup = 0;
13167
13168 v = ast_variable_browse(cfg, "general");
13169
13170
13171 tosval = ast_variable_retrieve(cfg, "general", "tos");
13172 if (tosval) {
13173 if (ast_str2tos(tosval, &qos.tos))
13174 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13175 }
13176
13177 tosval = ast_variable_retrieve(cfg, "general", "cos");
13178 if (tosval) {
13179 if (ast_str2cos(tosval, &qos.cos))
13180 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13181 }
13182 while(v) {
13183 if (!strcasecmp(v->name, "bindport")){
13184 if (reload)
13185 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13186 else
13187 portno = atoi(v->value);
13188 } else if (!strcasecmp(v->name, "pingtime"))
13189 ping_time = atoi(v->value);
13190 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13191 if (reload) {
13192 if (atoi(v->value) != iaxthreadcount)
13193 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13194 } else {
13195 iaxthreadcount = atoi(v->value);
13196 if (iaxthreadcount < 1) {
13197 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13198 iaxthreadcount = 1;
13199 } else if (iaxthreadcount > 256) {
13200 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13201 iaxthreadcount = 256;
13202 }
13203 }
13204 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13205 if (reload) {
13206 AST_LIST_LOCK(&dynamic_list);
13207 iaxmaxthreadcount = atoi(v->value);
13208 AST_LIST_UNLOCK(&dynamic_list);
13209 } else {
13210 iaxmaxthreadcount = atoi(v->value);
13211 if (iaxmaxthreadcount < 0) {
13212 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13213 iaxmaxthreadcount = 0;
13214 } else if (iaxmaxthreadcount > 256) {
13215 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13216 iaxmaxthreadcount = 256;
13217 }
13218 }
13219 } else if (!strcasecmp(v->name, "nochecksums")) {
13220 #ifdef SO_NO_CHECK
13221 if (ast_true(v->value))
13222 nochecksums = 1;
13223 else
13224 nochecksums = 0;
13225 #else
13226 if (ast_true(v->value))
13227 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13228 #endif
13229 }
13230 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13231 maxjitterbuffer = atoi(v->value);
13232 else if (!strcasecmp(v->name, "resyncthreshold"))
13233 resyncthreshold = atoi(v->value);
13234 else if (!strcasecmp(v->name, "maxjitterinterps"))
13235 maxjitterinterps = atoi(v->value);
13236 else if (!strcasecmp(v->name, "jittertargetextra"))
13237 jittertargetextra = atoi(v->value);
13238 else if (!strcasecmp(v->name, "lagrqtime"))
13239 lagrq_time = atoi(v->value);
13240 else if (!strcasecmp(v->name, "maxregexpire"))
13241 max_reg_expire = atoi(v->value);
13242 else if (!strcasecmp(v->name, "minregexpire"))
13243 min_reg_expire = atoi(v->value);
13244 else if (!strcasecmp(v->name, "bindaddr")) {
13245 if (reload) {
13246 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13247 } else {
13248 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13249 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13250 } else {
13251 if (strchr(v->value, ':'))
13252 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13253 else
13254 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13255 if (defaultsockfd < 0)
13256 defaultsockfd = ast_netsock_sockfd(ns);
13257 ast_netsock_unref(ns);
13258 }
13259 }
13260 } else if (!strcasecmp(v->name, "authdebug")) {
13261 authdebug = ast_true(v->value);
13262 } else if (!strcasecmp(v->name, "encryption")) {
13263 iax2_encryption |= get_encrypt_methods(v->value);
13264 if (!iax2_encryption) {
13265 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13266 }
13267 } else if (!strcasecmp(v->name, "forceencryption")) {
13268 if (ast_false(v->value)) {
13269 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13270 } else {
13271 iax2_encryption |= get_encrypt_methods(v->value);
13272 if (iax2_encryption) {
13273 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13274 }
13275 }
13276 } else if (!strcasecmp(v->name, "transfer")) {
13277 if (!strcasecmp(v->value, "mediaonly")) {
13278 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13279 } else if (ast_true(v->value)) {
13280 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13281 } else
13282 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13283 } else if (!strcasecmp(v->name, "codecpriority")) {
13284 if(!strcasecmp(v->value, "caller"))
13285 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13286 else if(!strcasecmp(v->value, "disabled"))
13287 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13288 else if(!strcasecmp(v->value, "reqonly")) {
13289 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13290 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13291 }
13292 } else if (!strcasecmp(v->name, "jitterbuffer"))
13293 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13294 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13295 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13296 else if (!strcasecmp(v->name, "delayreject"))
13297 delayreject = ast_true(v->value);
13298 else if (!strcasecmp(v->name, "allowfwdownload"))
13299 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13300 else if (!strcasecmp(v->name, "rtcachefriends"))
13301 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13302 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13303 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13304 else if (!strcasecmp(v->name, "rtupdate"))
13305 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13306 else if (!strcasecmp(v->name, "rtsavesysname"))
13307 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13308 else if (!strcasecmp(v->name, "trunktimestamps"))
13309 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13310 else if (!strcasecmp(v->name, "rtautoclear")) {
13311 int i = atoi(v->value);
13312 if(i > 0)
13313 global_rtautoclear = i;
13314 else
13315 i = 0;
13316 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13317 } else if (!strcasecmp(v->name, "trunkfreq")) {
13318 trunkfreq = atoi(v->value);
13319 if (trunkfreq < 10)
13320 trunkfreq = 10;
13321 } else if (!strcasecmp(v->name, "trunkmtu")) {
13322 mtuv = atoi(v->value);
13323 if (mtuv == 0 )
13324 global_max_trunk_mtu = 0;
13325 else if (mtuv >= 172 && mtuv < 4000)
13326 global_max_trunk_mtu = mtuv;
13327 else
13328 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13329 mtuv, v->lineno);
13330 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13331 trunkmaxsize = atoi(v->value);
13332 if (trunkmaxsize == 0)
13333 trunkmaxsize = MAX_TRUNKDATA;
13334 } else if (!strcasecmp(v->name, "autokill")) {
13335 if (sscanf(v->value, "%30d", &x) == 1) {
13336 if (x >= 0)
13337 autokill = x;
13338 else
13339 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13340 } else if (ast_true(v->value)) {
13341 autokill = DEFAULT_MAXMS;
13342 } else {
13343 autokill = 0;
13344 }
13345 } else if (!strcasecmp(v->name, "bandwidth")) {
13346 if (!strcasecmp(v->value, "low")) {
13347 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13348 } else if (!strcasecmp(v->value, "medium")) {
13349 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13350 } else if (!strcasecmp(v->value, "high")) {
13351 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13352 } else
13353 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13354 } else if (!strcasecmp(v->name, "allow")) {
13355 iax2_parse_allow_disallow(&prefs, &capability, v->value, 1);
13356 } else if (!strcasecmp(v->name, "disallow")) {
13357 iax2_parse_allow_disallow(&prefs, &capability, v->value, 0);
13358 } else if (!strcasecmp(v->name, "register")) {
13359 iax2_register(v->value, v->lineno);
13360 } else if (!strcasecmp(v->name, "iaxcompat")) {
13361 iaxcompat = ast_true(v->value);
13362 } else if (!strcasecmp(v->name, "regcontext")) {
13363 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13364
13365 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13366 } else if (!strcasecmp(v->name, "tos")) {
13367 if (ast_str2tos(v->value, &qos.tos))
13368 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13369 } else if (!strcasecmp(v->name, "cos")) {
13370 if (ast_str2cos(v->value, &qos.cos))
13371 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13372 } else if (!strcasecmp(v->name, "parkinglot")) {
13373 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13374 } else if (!strcasecmp(v->name, "accountcode")) {
13375 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13376 } else if (!strcasecmp(v->name, "mohinterpret")) {
13377 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13378 } else if (!strcasecmp(v->name, "mohsuggest")) {
13379 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13380 } else if (!strcasecmp(v->name, "amaflags")) {
13381 format = ast_cdr_amaflags2int(v->value);
13382 if (format < 0) {
13383 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13384 } else {
13385 amaflags = format;
13386 }
13387 } else if (!strcasecmp(v->name, "language")) {
13388 ast_copy_string(language, v->value, sizeof(language));
13389 } else if (!strcasecmp(v->name, "maxauthreq")) {
13390 maxauthreq = atoi(v->value);
13391 if (maxauthreq < 0)
13392 maxauthreq = 0;
13393 } else if (!strcasecmp(v->name, "adsi")) {
13394 adsi = ast_true(v->value);
13395 } else if (!strcasecmp(v->name, "srvlookup")) {
13396 srvlookup = ast_true(v->value);
13397 } else if (!strcasecmp(v->name, "connectedline")) {
13398 if (ast_true(v->value)) {
13399 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13400 } else if (!strcasecmp(v->value, "send")) {
13401 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13402 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13403 } else if (!strcasecmp(v->value, "receive")) {
13404 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13405 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13406 } else {
13407 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13408 }
13409 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13410 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13411 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13412 }
13413 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13414 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13415 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);
13416 }
13417 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13418 if (add_calltoken_ignore(v->value)) {
13419 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13420 }
13421 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13422 if (ast_true(v->value)) {
13423 subscribe_network_change = 1;
13424 } else if (ast_false(v->value)) {
13425 subscribe_network_change = 0;
13426 } else {
13427 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13428 }
13429 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13430 if (ast_true(v->value)) {
13431 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13432 } else if (ast_false(v->value)) {
13433 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13434 } else {
13435 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13436 }
13437 }
13438
13439 v = v->next;
13440 }
13441
13442 if (subscribe_network_change) {
13443 network_change_event_subscribe();
13444 } else {
13445 network_change_event_unsubscribe();
13446 }
13447
13448 if (defaultsockfd < 0) {
13449 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13450 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13451 } else {
13452 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13453 defaultsockfd = ast_netsock_sockfd(ns);
13454 ast_netsock_unref(ns);
13455 }
13456 }
13457 if (reload) {
13458 ast_netsock_release(outsock);
13459 outsock = ast_netsock_list_alloc();
13460 if (!outsock) {
13461 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13462 return -1;
13463 }
13464 ast_netsock_init(outsock);
13465 }
13466
13467 if (min_reg_expire > max_reg_expire) {
13468 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13469 min_reg_expire, max_reg_expire, max_reg_expire);
13470 min_reg_expire = max_reg_expire;
13471 }
13472 iax2_capability = capability;
13473
13474 if (ucfg) {
13475 struct ast_variable *gen;
13476 int genhasiax;
13477 int genregisteriax;
13478 const char *hasiax, *registeriax;
13479
13480 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13481 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13482 gen = ast_variable_browse(ucfg, "general");
13483 cat = ast_category_browse(ucfg, NULL);
13484 while (cat) {
13485 if (strcasecmp(cat, "general")) {
13486 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13487 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13488 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13489
13490 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13491 if (user) {
13492 ao2_link(users, user);
13493 user = user_unref(user);
13494 }
13495 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13496 if (peer) {
13497 if (ast_test_flag64(peer, IAX_DYNAMIC))
13498 reg_source_db(peer);
13499 ao2_link(peers, peer);
13500 peer = peer_unref(peer);
13501 }
13502 }
13503 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13504 char tmp[256];
13505 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13506 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13507 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13508 if (!host)
13509 host = ast_variable_retrieve(ucfg, "general", "host");
13510 if (!username)
13511 username = ast_variable_retrieve(ucfg, "general", "username");
13512 if (!secret)
13513 secret = ast_variable_retrieve(ucfg, "general", "secret");
13514 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13515 if (!ast_strlen_zero(secret))
13516 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13517 else
13518 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13519 iax2_register(tmp, 0);
13520 }
13521 }
13522 }
13523 cat = ast_category_browse(ucfg, cat);
13524 }
13525 ast_config_destroy(ucfg);
13526 }
13527
13528 cat = ast_category_browse(cfg, NULL);
13529 while(cat) {
13530 if (strcasecmp(cat, "general")) {
13531 utype = ast_variable_retrieve(cfg, cat, "type");
13532 if (!strcasecmp(cat, "callnumberlimits")) {
13533 build_callno_limits(ast_variable_browse(cfg, cat));
13534 } else if (utype) {
13535 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13536 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13537 if (user) {
13538 ao2_link(users, user);
13539 user = user_unref(user);
13540 }
13541 }
13542 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13543 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13544 if (peer) {
13545 if (ast_test_flag64(peer, IAX_DYNAMIC))
13546 reg_source_db(peer);
13547 ao2_link(peers, peer);
13548 peer = peer_unref(peer);
13549 }
13550 } else if (strcasecmp(utype, "user")) {
13551 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13552 }
13553 } else
13554 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13555 }
13556 cat = ast_category_browse(cfg, cat);
13557 }
13558 ast_config_destroy(cfg);
13559 return 1;
13560 }
13561
13562 static void poke_all_peers(void)
13563 {
13564 struct ao2_iterator i;
13565 struct iax2_peer *peer;
13566
13567 i = ao2_iterator_init(peers, 0);
13568 while ((peer = ao2_iterator_next(&i))) {
13569 iax2_poke_peer(peer, 0);
13570 peer_unref(peer);
13571 }
13572 ao2_iterator_destroy(&i);
13573 }
13574 static int reload_config(void)
13575 {
13576 static const char config[] = "iax.conf";
13577 struct iax2_registry *reg;
13578
13579 if (set_config(config, 1) > 0) {
13580 prune_peers();
13581 prune_users();
13582 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13583 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13584 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13585 trunk_timed = trunk_untimed = 0;
13586 trunk_nmaxmtu = trunk_maxmtu = 0;
13587 memset(&debugaddr, '\0', sizeof(debugaddr));
13588
13589 AST_LIST_LOCK(®istrations);
13590 AST_LIST_TRAVERSE(®istrations, reg, entry)
13591 iax2_do_register(reg);
13592 AST_LIST_UNLOCK(®istrations);
13593
13594
13595 poke_all_peers();
13596 }
13597
13598 reload_firmware(0);
13599 iax_provision_reload(1);
13600 ast_unload_realtime("iaxpeers");
13601
13602 return 0;
13603 }
13604
13605 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13606 {
13607 switch (cmd) {
13608 case CLI_INIT:
13609 e->command = "iax2 reload";
13610 e->usage =
13611 "Usage: iax2 reload\n"
13612 " Reloads IAX configuration from iax.conf\n";
13613 return NULL;
13614 case CLI_GENERATE:
13615 return NULL;
13616 }
13617
13618 reload_config();
13619
13620 return CLI_SUCCESS;
13621 }
13622
13623 static int reload(void)
13624 {
13625 return reload_config();
13626 }
13627
13628 static int cache_get_callno_locked(const char *data)
13629 {
13630 struct sockaddr_in sin;
13631 int x;
13632 int callno;
13633 struct iax_ie_data ied;
13634 struct create_addr_info cai;
13635 struct parsed_dial_string pds;
13636 char *tmpstr;
13637
13638 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13639
13640
13641 if (!ast_mutex_trylock(&iaxsl[x])) {
13642 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13643 return x;
13644 ast_mutex_unlock(&iaxsl[x]);
13645 }
13646 }
13647
13648
13649
13650 memset(&cai, 0, sizeof(cai));
13651 memset(&ied, 0, sizeof(ied));
13652 memset(&pds, 0, sizeof(pds));
13653
13654 tmpstr = ast_strdupa(data);
13655 parse_dial_string(tmpstr, &pds);
13656
13657 if (ast_strlen_zero(pds.peer)) {
13658 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13659 return -1;
13660 }
13661
13662
13663 if (create_addr(pds.peer, NULL, &sin, &cai))
13664 return -1;
13665
13666 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13667 pds.peer, pds.username, pds.password, pds.context);
13668
13669 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13670 if (callno < 1) {
13671 ast_log(LOG_WARNING, "Unable to create call\n");
13672 return -1;
13673 }
13674
13675 ast_string_field_set(iaxs[callno], dproot, data);
13676 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13677
13678 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13679 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13680
13681
13682
13683 if (pds.exten)
13684 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13685 if (pds.username)
13686 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13687 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13688 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13689
13690 if (pds.password)
13691 ast_string_field_set(iaxs[callno], secret, pds.password);
13692 if (pds.key)
13693 ast_string_field_set(iaxs[callno], outkey, pds.key);
13694
13695 add_empty_calltoken_ie(iaxs[callno], &ied);
13696 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13697
13698 return callno;
13699 }
13700
13701 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13702 {
13703 struct iax2_dpcache *dp = NULL;
13704 struct timeval now = ast_tvnow();
13705 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13706 struct ast_channel *c = NULL;
13707 struct ast_frame *f = NULL;
13708
13709 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13710 if (ast_tvcmp(now, dp->expiry) > 0) {
13711 AST_LIST_REMOVE_CURRENT(cache_list);
13712 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13713 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13714 else
13715 ast_free(dp);
13716 continue;
13717 }
13718 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13719 break;
13720 }
13721 AST_LIST_TRAVERSE_SAFE_END;
13722
13723 if (!dp) {
13724
13725
13726 if ((callno = cache_get_callno_locked(data)) < 0) {
13727 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13728 return NULL;
13729 }
13730 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13731 ast_mutex_unlock(&iaxsl[callno]);
13732 return NULL;
13733 }
13734 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13735 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13736 dp->expiry = ast_tvnow();
13737 dp->orig = dp->expiry;
13738
13739 dp->expiry.tv_sec += iaxdefaultdpcache;
13740 dp->flags = CACHE_FLAG_PENDING;
13741 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13742 dp->waiters[x] = -1;
13743
13744 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13745 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13746
13747 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13748 iax2_dprequest(dp, callno);
13749 ast_mutex_unlock(&iaxsl[callno]);
13750 }
13751
13752
13753 if (dp->flags & CACHE_FLAG_PENDING) {
13754
13755
13756 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13757
13758 if (dp->waiters[x] < 0)
13759 break;
13760 }
13761 if (x >= ARRAY_LEN(dp->waiters)) {
13762 ast_log(LOG_WARNING, "No more waiter positions available\n");
13763 return NULL;
13764 }
13765 if (pipe(com)) {
13766 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13767 return NULL;
13768 }
13769 dp->waiters[x] = com[1];
13770
13771 timeout = iaxdefaulttimeout * 1000;
13772
13773 AST_LIST_UNLOCK(&dpcache);
13774
13775 if (chan)
13776 old = ast_channel_defer_dtmf(chan);
13777 doabort = 0;
13778 while(timeout) {
13779 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13780 if (outfd > -1)
13781 break;
13782 if (!c)
13783 continue;
13784 if (!(f = ast_read(c))) {
13785 doabort = 1;
13786 break;
13787 }
13788 ast_frfree(f);
13789 }
13790 if (!timeout) {
13791 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13792 }
13793 AST_LIST_LOCK(&dpcache);
13794 dp->waiters[x] = -1;
13795 close(com[1]);
13796 close(com[0]);
13797 if (doabort) {
13798
13799
13800 if (!old && chan)
13801 ast_channel_undefer_dtmf(chan);
13802 return NULL;
13803 }
13804 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13805
13806 if (dp->flags & CACHE_FLAG_PENDING) {
13807
13808
13809 dp->flags &= ~CACHE_FLAG_PENDING;
13810 dp->flags |= CACHE_FLAG_TIMEOUT;
13811
13812
13813 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13814 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13815 if (dp->waiters[x] > -1) {
13816 if (write(dp->waiters[x], "asdf", 4) < 0) {
13817 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13818 }
13819 }
13820 }
13821 }
13822 }
13823
13824 if (!old && chan)
13825 ast_channel_undefer_dtmf(chan);
13826 }
13827 return dp;
13828 }
13829
13830
13831 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13832 {
13833 int res = 0;
13834 struct iax2_dpcache *dp = NULL;
13835 #if 0
13836 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13837 #endif
13838 if ((priority != 1) && (priority != 2))
13839 return 0;
13840
13841 AST_LIST_LOCK(&dpcache);
13842 if ((dp = find_cache(chan, data, context, exten, priority))) {
13843 if (dp->flags & CACHE_FLAG_EXISTS)
13844 res = 1;
13845 } else {
13846 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13847 }
13848 AST_LIST_UNLOCK(&dpcache);
13849
13850 return res;
13851 }
13852
13853
13854 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13855 {
13856 int res = 0;
13857 struct iax2_dpcache *dp = NULL;
13858 #if 0
13859 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13860 #endif
13861 if ((priority != 1) && (priority != 2))
13862 return 0;
13863
13864 AST_LIST_LOCK(&dpcache);
13865 if ((dp = find_cache(chan, data, context, exten, priority))) {
13866 if (dp->flags & CACHE_FLAG_CANEXIST)
13867 res = 1;
13868 } else {
13869 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13870 }
13871 AST_LIST_UNLOCK(&dpcache);
13872
13873 return res;
13874 }
13875
13876
13877 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13878 {
13879 int res = 0;
13880 struct iax2_dpcache *dp = NULL;
13881 #if 0
13882 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13883 #endif
13884 if ((priority != 1) && (priority != 2))
13885 return 0;
13886
13887 AST_LIST_LOCK(&dpcache);
13888 if ((dp = find_cache(chan, data, context, exten, priority))) {
13889 if (dp->flags & CACHE_FLAG_MATCHMORE)
13890 res = 1;
13891 } else {
13892 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13893 }
13894 AST_LIST_UNLOCK(&dpcache);
13895
13896 return res;
13897 }
13898
13899
13900 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13901 {
13902 char odata[256];
13903 char req[256];
13904 char *ncontext;
13905 struct iax2_dpcache *dp = NULL;
13906 struct ast_app *dial = NULL;
13907 #if 0
13908 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);
13909 #endif
13910 if (priority == 2) {
13911
13912 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13913 if (dialstatus) {
13914 dial = pbx_findapp(dialstatus);
13915 if (dial)
13916 pbx_exec(chan, dial, "");
13917 }
13918 return -1;
13919 } else if (priority != 1)
13920 return -1;
13921
13922 AST_LIST_LOCK(&dpcache);
13923 if ((dp = find_cache(chan, data, context, exten, priority))) {
13924 if (dp->flags & CACHE_FLAG_EXISTS) {
13925 ast_copy_string(odata, data, sizeof(odata));
13926 ncontext = strchr(odata, '/');
13927 if (ncontext) {
13928 *ncontext = '\0';
13929 ncontext++;
13930 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13931 } else {
13932 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13933 }
13934 ast_verb(3, "Executing Dial('%s')\n", req);
13935 } else {
13936 AST_LIST_UNLOCK(&dpcache);
13937 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13938 return -1;
13939 }
13940 }
13941 AST_LIST_UNLOCK(&dpcache);
13942
13943 if ((dial = pbx_findapp("Dial")))
13944 return pbx_exec(chan, dial, req);
13945 else
13946 ast_log(LOG_WARNING, "No dial application registered\n");
13947
13948 return -1;
13949 }
13950
13951 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13952 {
13953 struct iax2_peer *peer;
13954 char *peername, *colname;
13955
13956 peername = ast_strdupa(data);
13957
13958
13959 if (!strcmp(peername,"CURRENTCHANNEL")) {
13960 unsigned short callno;
13961 if (chan->tech != &iax2_tech)
13962 return -1;
13963 callno = PTR_TO_CALLNO(chan->tech_pvt);
13964 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13965 return 0;
13966 }
13967
13968 if ((colname = strchr(peername, ',')))
13969 *colname++ = '\0';
13970 else
13971 colname = "ip";
13972
13973 if (!(peer = find_peer(peername, 1)))
13974 return -1;
13975
13976 if (!strcasecmp(colname, "ip")) {
13977 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13978 } else if (!strcasecmp(colname, "status")) {
13979 peer_status(peer, buf, len);
13980 } else if (!strcasecmp(colname, "mailbox")) {
13981 ast_copy_string(buf, peer->mailbox, len);
13982 } else if (!strcasecmp(colname, "context")) {
13983 ast_copy_string(buf, peer->context, len);
13984 } else if (!strcasecmp(colname, "expire")) {
13985 snprintf(buf, len, "%d", peer->expire);
13986 } else if (!strcasecmp(colname, "dynamic")) {
13987 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13988 } else if (!strcasecmp(colname, "callerid_name")) {
13989 ast_copy_string(buf, peer->cid_name, len);
13990 } else if (!strcasecmp(colname, "callerid_num")) {
13991 ast_copy_string(buf, peer->cid_num, len);
13992 } else if (!strcasecmp(colname, "codecs")) {
13993 iax2_getformatname_multiple(buf, len -1, peer->capability);
13994 } else if (!strncasecmp(colname, "codec[", 6)) {
13995 char *codecnum, *ptr;
13996 struct ast_format tmpfmt;
13997 codecnum = strchr(colname, '[');
13998 *codecnum = '\0';
13999 codecnum++;
14000 if ((ptr = strchr(codecnum, ']'))) {
14001 *ptr = '\0';
14002 }
14003 if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
14004 ast_copy_string(buf, ast_getformatname(&tmpfmt), len);
14005 } else {
14006 buf[0] = '\0';
14007 }
14008 } else {
14009 buf[0] = '\0';
14010 }
14011
14012 peer_unref(peer);
14013
14014 return 0;
14015 }
14016
14017 static struct ast_custom_function iaxpeer_function = {
14018 .name = "IAXPEER",
14019 .read = function_iaxpeer,
14020 };
14021
14022 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
14023 {
14024 struct chan_iax2_pvt *pvt;
14025 unsigned int callno;
14026 int res = 0;
14027
14028 if (!chan || chan->tech != &iax2_tech) {
14029 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
14030 return -1;
14031 }
14032
14033 callno = PTR_TO_CALLNO(chan->tech_pvt);
14034 ast_mutex_lock(&iaxsl[callno]);
14035 if (!(pvt = iaxs[callno])) {
14036 ast_mutex_unlock(&iaxsl[callno]);
14037 return -1;
14038 }
14039
14040 if (!strcasecmp(args, "osptoken")) {
14041 ast_copy_string(buf, pvt->osptoken, buflen);
14042 } else if (!strcasecmp(args, "peerip")) {
14043 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
14044 } else if (!strcasecmp(args, "peername")) {
14045 ast_copy_string(buf, pvt->username, buflen);
14046 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
14047 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
14048 } else {
14049 res = -1;
14050 }
14051
14052 ast_mutex_unlock(&iaxsl[callno]);
14053
14054 return res;
14055 }
14056
14057
14058 static int iax2_devicestate(const char *data)
14059 {
14060 struct parsed_dial_string pds;
14061 char *tmp = ast_strdupa(data);
14062 struct iax2_peer *p;
14063 int res = AST_DEVICE_INVALID;
14064
14065 memset(&pds, 0, sizeof(pds));
14066 parse_dial_string(tmp, &pds);
14067
14068 if (ast_strlen_zero(pds.peer)) {
14069 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
14070 return res;
14071 }
14072
14073 ast_debug(3, "Checking device state for device %s\n", pds.peer);
14074
14075
14076 if (!(p = find_peer(pds.peer, 1)))
14077 return res;
14078
14079 res = AST_DEVICE_UNAVAILABLE;
14080 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
14081 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
14082
14083 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
14084 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
14085
14086
14087 if (p->historicms == 0 || p->historicms <= p->maxms)
14088
14089 res = AST_DEVICE_UNKNOWN;
14090 }
14091
14092 peer_unref(p);
14093
14094 return res;
14095 }
14096
14097 static struct ast_switch iax2_switch =
14098 {
14099 name: "IAX2",
14100 description: "IAX Remote Dialplan Switch",
14101 exists: iax2_exists,
14102 canmatch: iax2_canmatch,
14103 exec: iax2_exec,
14104 matchmore: iax2_matchmore,
14105 };
14106
14107
14108
14109
14110
14111
14112
14113
14114
14115
14116
14117
14118
14119
14120
14121
14122
14123
14124
14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143
14144
14145
14146
14147
14148
14149
14150
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 static struct ast_cli_entry cli_iax2[] = {
14212 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14213 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14214 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14215 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14216 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14217 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14218 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14219 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14220 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14221 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14222 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14223 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14224 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14225 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14226 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14227 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14228 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14229 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14230 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14231 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14232 #ifdef IAXTESTS
14233 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14234 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14235 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14236 #endif
14237 };
14238
14239 #ifdef TEST_FRAMEWORK
14240 AST_TEST_DEFINE(test_iax2_peers_get)
14241 {
14242 struct ast_data_query query = {
14243 .path = "/asterisk/channel/iax2/peers",
14244 .search = "peers/peer/name=test_peer_data_provider"
14245 };
14246 struct ast_data *node;
14247 struct iax2_peer *peer;
14248
14249 switch (cmd) {
14250 case TEST_INIT:
14251 info->name = "iax2_peers_get_data_test";
14252 info->category = "/main/data/iax2/peers/";
14253 info->summary = "IAX2 peers data providers unit test";
14254 info->description =
14255 "Tests whether the IAX2 peers data provider implementation works as expected.";
14256 return AST_TEST_NOT_RUN;
14257 case TEST_EXECUTE:
14258 break;
14259 }
14260
14261
14262 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14263 if (!peer) {
14264 return AST_TEST_FAIL;
14265 }
14266 peer->expiry= 1010;
14267 ao2_link(peers, peer);
14268
14269 node = ast_data_get(&query);
14270 if (!node) {
14271 ao2_unlink(peers, peer);
14272 peer_unref(peer);
14273 return AST_TEST_FAIL;
14274 }
14275
14276
14277 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14278 ao2_unlink(peers, peer);
14279 peer_unref(peer);
14280 ast_data_free(node);
14281 return AST_TEST_FAIL;
14282 }
14283
14284 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14285 ao2_unlink(peers, peer);
14286 peer_unref(peer);
14287 ast_data_free(node);
14288 return AST_TEST_FAIL;
14289 }
14290
14291
14292 ast_data_free(node);
14293
14294 ao2_unlink(peers, peer);
14295 peer_unref(peer);
14296
14297 return AST_TEST_PASS;
14298 }
14299
14300 AST_TEST_DEFINE(test_iax2_users_get)
14301 {
14302 struct ast_data_query query = {
14303 .path = "/asterisk/channel/iax2/users",
14304 .search = "users/user/name=test_user_data_provider"
14305 };
14306 struct ast_data *node;
14307 struct iax2_user *user;
14308
14309 switch (cmd) {
14310 case TEST_INIT:
14311 info->name = "iax2_users_get_data_test";
14312 info->category = "/main/data/iax2/users/";
14313 info->summary = "IAX2 users data providers unit test";
14314 info->description =
14315 "Tests whether the IAX2 users data provider implementation works as expected.";
14316 return AST_TEST_NOT_RUN;
14317 case TEST_EXECUTE:
14318 break;
14319 }
14320
14321 user = build_user("test_user_data_provider", NULL, NULL, 0);
14322 if (!user) {
14323 ast_test_status_update(test, "Failed to build a test user\n");
14324 return AST_TEST_FAIL;
14325 }
14326 user->amaflags = 1010;
14327 ao2_link(users, user);
14328
14329 node = ast_data_get(&query);
14330 if (!node) {
14331 ast_test_status_update(test, "The data query to find our test user failed\n");
14332 ao2_unlink(users, user);
14333 user_unref(user);
14334 return AST_TEST_FAIL;
14335 }
14336
14337 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14338 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14339 ao2_unlink(users, user);
14340 user_unref(user);
14341 ast_data_free(node);
14342 return AST_TEST_FAIL;
14343 }
14344
14345 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14346 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"));
14347 ao2_unlink(users, user);
14348 user_unref(user);
14349 ast_data_free(node);
14350 return AST_TEST_FAIL;
14351 }
14352
14353 ast_data_free(node);
14354
14355 ao2_unlink(users, user);
14356 user_unref(user);
14357
14358 return AST_TEST_PASS;
14359 }
14360 #endif
14361
14362 static void cleanup_thread_list(void *head)
14363 {
14364 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14365 struct iax2_thread_list *list_head = head;
14366 struct iax2_thread *thread;
14367
14368 AST_LIST_LOCK(list_head);
14369 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14370 pthread_t thread_id = thread->threadid;
14371
14372 thread->stop = 1;
14373 signal_condition(&thread->lock, &thread->cond);
14374
14375 AST_LIST_UNLOCK(list_head);
14376 pthread_join(thread_id, NULL);
14377 AST_LIST_LOCK(list_head);
14378 }
14379 AST_LIST_UNLOCK(list_head);
14380 }
14381
14382 static int __unload_module(void)
14383 {
14384 struct ast_context *con;
14385 int x;
14386
14387 network_change_event_unsubscribe();
14388
14389 ast_manager_unregister("IAXpeers");
14390 ast_manager_unregister("IAXpeerlist");
14391 ast_manager_unregister("IAXnetstats");
14392 ast_manager_unregister("IAXregistry");
14393 ast_unregister_application(papp);
14394 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14395 ast_unregister_switch(&iax2_switch);
14396 ast_channel_unregister(&iax2_tech);
14397
14398 if (netthreadid != AST_PTHREADT_NULL) {
14399 pthread_cancel(netthreadid);
14400 pthread_kill(netthreadid, SIGURG);
14401 pthread_join(netthreadid, NULL);
14402 }
14403
14404 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14405 if (iaxs[x]) {
14406 iax2_destroy(x);
14407 }
14408 }
14409
14410
14411 cleanup_thread_list(&idle_list);
14412 cleanup_thread_list(&active_list);
14413 cleanup_thread_list(&dynamic_list);
14414
14415 ast_netsock_release(netsock);
14416 ast_netsock_release(outsock);
14417 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14418 if (iaxs[x]) {
14419 iax2_destroy(x);
14420 }
14421 }
14422 ast_manager_unregister( "IAXpeers" );
14423 ast_manager_unregister( "IAXpeerlist" );
14424 ast_manager_unregister( "IAXnetstats" );
14425 ast_manager_unregister( "IAXregistry" );
14426 ast_unregister_application(papp);
14427 #ifdef TEST_FRAMEWORK
14428 AST_TEST_UNREGISTER(test_iax2_peers_get);
14429 AST_TEST_UNREGISTER(test_iax2_users_get);
14430 #endif
14431 ast_data_unregister(NULL);
14432 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14433 ast_unregister_switch(&iax2_switch);
14434 ast_channel_unregister(&iax2_tech);
14435 delete_users();
14436 iax_provision_unload();
14437 reload_firmware(1);
14438
14439 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14440 ast_mutex_destroy(&iaxsl[x]);
14441 }
14442
14443 ao2_ref(peers, -1);
14444 ao2_ref(users, -1);
14445 ao2_ref(iax_peercallno_pvts, -1);
14446 ao2_ref(iax_transfercallno_pvts, -1);
14447 ao2_ref(peercnts, -1);
14448 ao2_ref(callno_limits, -1);
14449 ao2_ref(calltoken_ignores, -1);
14450 ao2_ref(callno_pool, -1);
14451 ao2_ref(callno_pool_trunk, -1);
14452 if (timer) {
14453 ast_timer_close(timer);
14454 }
14455 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14456 ast_sched_context_destroy(sched);
14457 sched = NULL;
14458
14459 con = ast_context_find(regcontext);
14460 if (con)
14461 ast_context_destroy(con, "IAX2");
14462 ast_unload_realtime("iaxpeers");
14463
14464 iax2_tech.capabilities = ast_format_cap_destroy(iax2_tech.capabilities);
14465 return 0;
14466 }
14467
14468 static int unload_module(void)
14469 {
14470 ast_custom_function_unregister(&iaxpeer_function);
14471 ast_custom_function_unregister(&iaxvar_function);
14472 return __unload_module();
14473 }
14474
14475 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14476 {
14477 struct iax2_peer *peer = obj;
14478
14479 if (peer->sockfd < 0)
14480 peer->sockfd = defaultsockfd;
14481
14482 return 0;
14483 }
14484
14485 static int pvt_hash_cb(const void *obj, const int flags)
14486 {
14487 const struct chan_iax2_pvt *pvt = obj;
14488
14489 return pvt->peercallno;
14490 }
14491
14492 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14493 {
14494 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14495
14496
14497
14498
14499 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14500 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14501 }
14502
14503 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14504 {
14505 const struct chan_iax2_pvt *pvt = obj;
14506
14507 return pvt->transfercallno;
14508 }
14509
14510 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14511 {
14512 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14513
14514
14515
14516
14517 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14518 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14519 }
14520
14521 static int load_objects(void)
14522 {
14523 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14524 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14525
14526 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14527 goto container_fail;
14528 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14529 goto container_fail;
14530 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14531 goto container_fail;
14532 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14533 goto container_fail;
14534 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14535 goto container_fail;
14536 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14537 goto container_fail;
14538 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14539 goto container_fail;
14540 } else if (create_callno_pools()) {
14541 goto container_fail;
14542 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14543 goto container_fail;
14544 }
14545
14546 return 0;
14547
14548 container_fail:
14549 if (peers) {
14550 ao2_ref(peers, -1);
14551 }
14552 if (users) {
14553 ao2_ref(users, -1);
14554 }
14555 if (iax_peercallno_pvts) {
14556 ao2_ref(iax_peercallno_pvts, -1);
14557 }
14558 if (iax_transfercallno_pvts) {
14559 ao2_ref(iax_transfercallno_pvts, -1);
14560 }
14561 if (peercnts) {
14562 ao2_ref(peercnts, -1);
14563 }
14564 if (callno_limits) {
14565 ao2_ref(callno_limits, -1);
14566 }
14567 if (calltoken_ignores) {
14568 ao2_ref(calltoken_ignores, -1);
14569 }
14570 if (callno_pool) {
14571 ao2_ref(callno_pool, -1);
14572 }
14573 if (callno_pool_trunk) {
14574 ao2_ref(callno_pool_trunk, -1);
14575 }
14576 return AST_MODULE_LOAD_FAILURE;
14577 }
14578
14579
14580 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14581 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14582 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14583 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14584 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14585 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14586 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14587 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14588 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14589 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14590 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14591 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14592 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14593 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14594 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14595 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14596 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14597 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14598 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14599 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14600 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14601 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14602 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14603 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14604 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14605 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14606
14607 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14608
14609 static int peers_data_provider_get(const struct ast_data_search *search,
14610 struct ast_data *data_root)
14611 {
14612 struct ast_data *data_peer;
14613 struct iax2_peer *peer;
14614 struct ao2_iterator i;
14615 char status[20];
14616 struct ast_str *encmethods = ast_str_alloca(256);
14617
14618 i = ao2_iterator_init(peers, 0);
14619 while ((peer = ao2_iterator_next(&i))) {
14620 data_peer = ast_data_add_node(data_root, "peer");
14621 if (!data_peer) {
14622 peer_unref(peer);
14623 continue;
14624 }
14625
14626 ast_data_add_structure(iax2_peer, data_peer, peer);
14627
14628 iax2_data_add_codecs(data_peer, "codecs", peer->capability);
14629
14630 peer_status(peer, status, sizeof(status));
14631 ast_data_add_str(data_peer, "status", status);
14632
14633 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14634
14635 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14636
14637 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14638
14639 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14640
14641 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14642
14643 encmethods_to_str(peer->encmethods, encmethods);
14644 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14645
14646 peer_unref(peer);
14647
14648 if (!ast_data_search_match(search, data_peer)) {
14649 ast_data_remove_node(data_root, data_peer);
14650 }
14651 }
14652 ao2_iterator_destroy(&i);
14653
14654 return 0;
14655 }
14656
14657 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14658 MEMBER(iax2_user, name, AST_DATA_STRING) \
14659 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14660 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14661 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14662 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14663 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14664 MEMBER(iax2_user, language, AST_DATA_STRING) \
14665 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14666 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14667 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14668 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14669 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14670
14671 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14672
14673 static int users_data_provider_get(const struct ast_data_search *search,
14674 struct ast_data *data_root)
14675 {
14676 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14677 struct iax2_user *user;
14678 struct ao2_iterator i;
14679 char auth[90];
14680 char *pstr = "";
14681
14682 i = ao2_iterator_init(users, 0);
14683 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14684 data_user = ast_data_add_node(data_root, "user");
14685 if (!data_user) {
14686 continue;
14687 }
14688
14689 ast_data_add_structure(iax2_user, data_user, user);
14690
14691 iax2_data_add_codecs(data_user, "codecs", user->capability);
14692
14693 if (!ast_strlen_zero(user->secret)) {
14694 ast_copy_string(auth, user->secret, sizeof(auth));
14695 } else if (!ast_strlen_zero(user->inkeys)) {
14696 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14697 } else {
14698 ast_copy_string(auth, "no secret", sizeof(auth));
14699 }
14700 ast_data_add_password(data_user, "secret", auth);
14701
14702 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14703
14704
14705 data_authmethods = ast_data_add_node(data_user, "authmethods");
14706 if (!data_authmethods) {
14707 ast_data_remove_node(data_root, data_user);
14708 continue;
14709 }
14710 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14711 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14712 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14713
14714
14715 data_enum_node = ast_data_add_node(data_user, "amaflags");
14716 if (!data_enum_node) {
14717 ast_data_remove_node(data_root, data_user);
14718 continue;
14719 }
14720 ast_data_add_int(data_enum_node, "value", user->amaflags);
14721 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14722
14723 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14724
14725 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14726 pstr = "REQ only";
14727 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14728 pstr = "disabled";
14729 } else {
14730 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14731 }
14732 ast_data_add_str(data_user, "codec-preferences", pstr);
14733
14734 if (!ast_data_search_match(search, data_user)) {
14735 ast_data_remove_node(data_root, data_user);
14736 }
14737 }
14738 ao2_iterator_destroy(&i);
14739
14740 return 0;
14741 }
14742
14743 static const struct ast_data_handler peers_data_provider = {
14744 .version = AST_DATA_HANDLER_VERSION,
14745 .get = peers_data_provider_get
14746 };
14747
14748 static const struct ast_data_handler users_data_provider = {
14749 .version = AST_DATA_HANDLER_VERSION,
14750 .get = users_data_provider_get
14751 };
14752
14753 static const struct ast_data_entry iax2_data_providers[] = {
14754 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14755 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14756 };
14757
14758
14759 static int load_module(void)
14760 {
14761 static const char config[] = "iax.conf";
14762 int x = 0;
14763 struct iax2_registry *reg = NULL;
14764
14765 if (!(iax2_tech.capabilities = ast_format_cap_alloc())) {
14766 return AST_MODULE_LOAD_FAILURE;
14767 }
14768 ast_format_cap_add_all(iax2_tech.capabilities);
14769
14770 if (load_objects()) {
14771 return AST_MODULE_LOAD_FAILURE;
14772 }
14773
14774 memset(iaxs, 0, sizeof(iaxs));
14775
14776 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14777 ast_mutex_init(&iaxsl[x]);
14778 }
14779
14780 if (!(sched = ast_sched_context_create())) {
14781 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14782 return AST_MODULE_LOAD_FAILURE;
14783 }
14784
14785 if (ast_sched_start_thread(sched)) {
14786 ast_sched_context_destroy(sched);
14787 sched = NULL;
14788 return AST_MODULE_LOAD_FAILURE;
14789 }
14790
14791 if (!(io = io_context_create())) {
14792 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14793 ast_sched_context_destroy(sched);
14794 sched = NULL;
14795 return AST_MODULE_LOAD_FAILURE;
14796 }
14797
14798 if (!(netsock = ast_netsock_list_alloc())) {
14799 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14800 io_context_destroy(io);
14801 ast_sched_context_destroy(sched);
14802 sched = NULL;
14803 return AST_MODULE_LOAD_FAILURE;
14804 }
14805 ast_netsock_init(netsock);
14806
14807 outsock = ast_netsock_list_alloc();
14808 if (!outsock) {
14809 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14810 io_context_destroy(io);
14811 ast_sched_context_destroy(sched);
14812 sched = NULL;
14813 return AST_MODULE_LOAD_FAILURE;
14814 }
14815 ast_netsock_init(outsock);
14816
14817 randomcalltokendata = ast_random();
14818
14819 iax_set_output(iax_debug_output);
14820 iax_set_error(iax_error_output);
14821 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14822
14823 if ((timer = ast_timer_open())) {
14824 ast_timer_set_rate(timer, trunkfreq);
14825 }
14826
14827 if (set_config(config, 0) == -1) {
14828 if (timer) {
14829 ast_timer_close(timer);
14830 }
14831 return AST_MODULE_LOAD_DECLINE;
14832 }
14833
14834 #ifdef TEST_FRAMEWORK
14835 AST_TEST_REGISTER(test_iax2_peers_get);
14836 AST_TEST_REGISTER(test_iax2_users_get);
14837 #endif
14838
14839
14840 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14841 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14842
14843 ast_register_application_xml(papp, iax2_prov_app);
14844
14845 ast_custom_function_register(&iaxpeer_function);
14846 ast_custom_function_register(&iaxvar_function);
14847
14848 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14849 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14850 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14851 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14852
14853 if (ast_channel_register(&iax2_tech)) {
14854 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14855 __unload_module();
14856 return AST_MODULE_LOAD_FAILURE;
14857 }
14858
14859 if (ast_register_switch(&iax2_switch)) {
14860 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14861 }
14862
14863 if (start_network_thread()) {
14864 ast_log(LOG_ERROR, "Unable to start network thread\n");
14865 __unload_module();
14866 return AST_MODULE_LOAD_FAILURE;
14867 } else {
14868 ast_verb(2, "IAX Ready and Listening\n");
14869 }
14870
14871 AST_LIST_LOCK(®istrations);
14872 AST_LIST_TRAVERSE(®istrations, reg, entry)
14873 iax2_do_register(reg);
14874 AST_LIST_UNLOCK(®istrations);
14875
14876 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14877 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14878
14879
14880 reload_firmware(0);
14881 iax_provision_reload(0);
14882
14883 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14884
14885 network_change_event_subscribe();
14886
14887 return AST_MODULE_LOAD_SUCCESS;
14888 }
14889
14890 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
14891 .load = load_module,
14892 .unload = unload_module,
14893 .reload = reload,
14894 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
14895 .nonoptreq = "res_crypto",
14896 );