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 #include "asterisk.h"
00037
00038 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 201997 $")
00039
00040 #include <sys/mman.h>
00041 #include <dirent.h>
00042 #include <sys/socket.h>
00043 #include <netinet/in.h>
00044 #include <arpa/inet.h>
00045 #include <netinet/in_systm.h>
00046 #include <netinet/ip.h>
00047 #include <sys/time.h>
00048 #include <sys/signal.h>
00049 #include <signal.h>
00050 #include <strings.h>
00051 #include <netdb.h>
00052 #include <fcntl.h>
00053 #include <sys/stat.h>
00054 #include <regex.h>
00055 #include <sys/ioctl.h>
00056 #if defined(HAVE_DAHDI)
00057 #include <dahdi/user.h>
00058 #endif
00059
00060 #include "asterisk/paths.h"
00061
00062 #include "asterisk/lock.h"
00063 #include "asterisk/frame.h"
00064 #include "asterisk/channel.h"
00065 #include "asterisk/module.h"
00066 #include "asterisk/pbx.h"
00067 #include "asterisk/sched.h"
00068 #include "asterisk/io.h"
00069 #include "asterisk/config.h"
00070 #include "asterisk/cli.h"
00071 #include "asterisk/translate.h"
00072 #include "asterisk/md5.h"
00073 #include "asterisk/cdr.h"
00074 #include "asterisk/crypto.h"
00075 #include "asterisk/acl.h"
00076 #include "asterisk/manager.h"
00077 #include "asterisk/callerid.h"
00078 #include "asterisk/app.h"
00079 #include "asterisk/astdb.h"
00080 #include "asterisk/musiconhold.h"
00081 #include "asterisk/features.h"
00082 #include "asterisk/utils.h"
00083 #include "asterisk/causes.h"
00084 #include "asterisk/localtime.h"
00085 #include "asterisk/aes.h"
00086 #include "asterisk/dnsmgr.h"
00087 #include "asterisk/devicestate.h"
00088 #include "asterisk/netsock.h"
00089 #include "asterisk/stringfields.h"
00090 #include "asterisk/linkedlists.h"
00091 #include "asterisk/event.h"
00092 #include "asterisk/astobj2.h"
00093
00094 #include "iax2.h"
00095 #include "iax2-parser.h"
00096 #include "iax2-provision.h"
00097 #include "jitterbuf.h"
00098
00099
00100
00101 #define SCHED_MULTITHREADED
00102
00103
00104
00105 #define DEBUG_SCHED_MULTITHREAD
00106
00107
00108 #ifdef SO_NO_CHECK
00109 static int nochecksums = 0;
00110 #endif
00111
00112
00113 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00114 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00115
00116 #define DEFAULT_THREAD_COUNT 10
00117 #define DEFAULT_MAX_THREAD_COUNT 100
00118 #define DEFAULT_RETRY_TIME 1000
00119 #define MEMORY_SIZE 100
00120 #define DEFAULT_DROP 3
00121
00122 #define DEBUG_SUPPORT
00123
00124 #define MIN_REUSE_TIME 60
00125
00126
00127 #define GAMMA (0.01)
00128
00129 static struct ast_codec_pref prefs;
00130
00131 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00132
00133
00134
00135
00136 #define MAX_TRUNK_MTU 1240
00137
00138 static int global_max_trunk_mtu;
00139 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00140
00141
00142 static char context[80] = "default";
00143
00144 static char language[MAX_LANGUAGE] = "";
00145 static char regcontext[AST_MAX_CONTEXT] = "";
00146
00147 static int maxauthreq = 3;
00148 static int max_retries = 4;
00149 static int ping_time = 21;
00150 static int lagrq_time = 10;
00151 static int maxjitterbuffer=1000;
00152 static int resyncthreshold=1000;
00153 static int maxjitterinterps=10;
00154 static int jittertargetextra = 40;
00155
00156 #define MAX_TRUNKDATA 640 * 200
00157
00158 static int trunkfreq = 20;
00159 static int trunkmaxsize = MAX_TRUNKDATA;
00160
00161 static int authdebug = 1;
00162 static int autokill = 0;
00163 static int iaxcompat = 0;
00164 static int last_authmethod = 0;
00165
00166 static int iaxdefaultdpcache=10 * 60;
00167
00168 static int iaxdefaulttimeout = 5;
00169
00170 static unsigned int tos = 0;
00171
00172 static unsigned int cos = 0;
00173
00174 static int min_reg_expire;
00175 static int max_reg_expire;
00176
00177 static int srvlookup = 0;
00178
00179 static int timingfd = -1;
00180
00181 static struct ast_netsock_list *netsock;
00182 static struct ast_netsock_list *outsock;
00183 static int defaultsockfd = -1;
00184
00185 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00186
00187
00188 #define IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
00189
00190 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00191 ~AST_FORMAT_SLINEAR & \
00192 ~AST_FORMAT_SLINEAR16 & \
00193 ~AST_FORMAT_ULAW & \
00194 ~AST_FORMAT_ALAW & \
00195 ~AST_FORMAT_G722)
00196
00197 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00198 ~AST_FORMAT_G726 & \
00199 ~AST_FORMAT_G726_AAL2 & \
00200 ~AST_FORMAT_ADPCM)
00201
00202 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00203 ~AST_FORMAT_G723_1)
00204
00205
00206 #define DEFAULT_MAXMS 2000
00207 #define DEFAULT_FREQ_OK 60 * 1000
00208 #define DEFAULT_FREQ_NOTOK 10 * 1000
00209
00210 static struct io_context *io;
00211 static struct sched_context *sched;
00212
00213 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00214
00215 static int iaxdebug = 0;
00216
00217 static int iaxtrunkdebug = 0;
00218
00219 static int test_losspct = 0;
00220 #ifdef IAXTESTS
00221 static int test_late = 0;
00222 static int test_resync = 0;
00223 static int test_jit = 0;
00224 static int test_jitpct = 0;
00225 #endif
00226
00227 static char accountcode[AST_MAX_ACCOUNT_CODE];
00228 static char mohinterpret[MAX_MUSICCLASS];
00229 static char mohsuggest[MAX_MUSICCLASS];
00230 static int amaflags = 0;
00231 static int adsi = 0;
00232 static int delayreject = 0;
00233 static int iax2_encryption = 0;
00234
00235 static struct ast_flags globalflags = { 0 };
00236
00237 static pthread_t netthreadid = AST_PTHREADT_NULL;
00238 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00239 AST_MUTEX_DEFINE_STATIC(sched_lock);
00240 static ast_cond_t sched_cond;
00241
00242 enum iax2_state {
00243 IAX_STATE_STARTED = (1 << 0),
00244 IAX_STATE_AUTHENTICATED = (1 << 1),
00245 IAX_STATE_TBD = (1 << 2),
00246 };
00247
00248 struct iax2_context {
00249 char context[AST_MAX_CONTEXT];
00250 struct iax2_context *next;
00251 };
00252
00253 enum iax2_flags {
00254 IAX_HASCALLERID = (1 << 0),
00255 IAX_DELME = (1 << 1),
00256 IAX_TEMPONLY = (1 << 2),
00257 IAX_TRUNK = (1 << 3),
00258 IAX_NOTRANSFER = (1 << 4),
00259 IAX_USEJITTERBUF = (1 << 5),
00260 IAX_DYNAMIC = (1 << 6),
00261 IAX_SENDANI = (1 << 7),
00262
00263 IAX_ALREADYGONE = (1 << 9),
00264 IAX_PROVISION = (1 << 10),
00265 IAX_QUELCH = (1 << 11),
00266 IAX_ENCRYPTED = (1 << 12),
00267 IAX_KEYPOPULATED = (1 << 13),
00268 IAX_CODEC_USER_FIRST = (1 << 14),
00269 IAX_CODEC_NOPREFS = (1 << 15),
00270 IAX_CODEC_NOCAP = (1 << 16),
00271 IAX_RTCACHEFRIENDS = (1 << 17),
00272 IAX_RTUPDATE = (1 << 18),
00273 IAX_RTAUTOCLEAR = (1 << 19),
00274 IAX_FORCEJITTERBUF = (1 << 20),
00275 IAX_RTIGNOREREGEXPIRE = (1 << 21),
00276 IAX_TRUNKTIMESTAMPS = (1 << 22),
00277 IAX_TRANSFERMEDIA = (1 << 23),
00278 IAX_MAXAUTHREQ = (1 << 24),
00279 IAX_DELAYPBXSTART = (1 << 25),
00280
00281
00282 IAX_ALLOWFWDOWNLOAD = (1 << 26),
00283 };
00284
00285 static int global_rtautoclear = 120;
00286
00287 static int reload_config(void);
00288
00289 struct iax2_user {
00290 AST_DECLARE_STRING_FIELDS(
00291 AST_STRING_FIELD(name);
00292 AST_STRING_FIELD(secret);
00293 AST_STRING_FIELD(dbsecret);
00294 AST_STRING_FIELD(accountcode);
00295 AST_STRING_FIELD(mohinterpret);
00296 AST_STRING_FIELD(mohsuggest);
00297 AST_STRING_FIELD(inkeys);
00298 AST_STRING_FIELD(language);
00299 AST_STRING_FIELD(cid_num);
00300 AST_STRING_FIELD(cid_name);
00301 );
00302
00303 int authmethods;
00304 int encmethods;
00305 int amaflags;
00306 int adsi;
00307 unsigned int flags;
00308 int capability;
00309 int maxauthreq;
00310 int curauthreq;
00311 struct ast_codec_pref prefs;
00312 struct ast_ha *ha;
00313 struct iax2_context *contexts;
00314 struct ast_variable *vars;
00315 };
00316
00317 struct iax2_peer {
00318 AST_DECLARE_STRING_FIELDS(
00319 AST_STRING_FIELD(name);
00320 AST_STRING_FIELD(username);
00321 AST_STRING_FIELD(secret);
00322 AST_STRING_FIELD(dbsecret);
00323 AST_STRING_FIELD(outkey);
00324
00325 AST_STRING_FIELD(regexten);
00326 AST_STRING_FIELD(context);
00327 AST_STRING_FIELD(peercontext);
00328 AST_STRING_FIELD(mailbox);
00329 AST_STRING_FIELD(mohinterpret);
00330 AST_STRING_FIELD(mohsuggest);
00331 AST_STRING_FIELD(inkeys);
00332
00333 AST_STRING_FIELD(cid_num);
00334 AST_STRING_FIELD(cid_name);
00335 AST_STRING_FIELD(zonetag);
00336 );
00337 struct ast_codec_pref prefs;
00338 struct ast_dnsmgr_entry *dnsmgr;
00339 struct sockaddr_in addr;
00340 int formats;
00341 int sockfd;
00342 struct in_addr mask;
00343 int adsi;
00344 unsigned int flags;
00345
00346
00347 struct sockaddr_in defaddr;
00348 int authmethods;
00349 int encmethods;
00350
00351 int expire;
00352 int expiry;
00353 int capability;
00354
00355
00356 int callno;
00357 int pokeexpire;
00358 int lastms;
00359 int maxms;
00360
00361 int pokefreqok;
00362 int pokefreqnotok;
00363 int historicms;
00364 int smoothing;
00365
00366 struct ast_event_sub *mwi_event_sub;
00367
00368 struct ast_ha *ha;
00369 };
00370
00371 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00372
00373 struct iax2_trunk_peer {
00374 ast_mutex_t lock;
00375 int sockfd;
00376 struct sockaddr_in addr;
00377 struct timeval txtrunktime;
00378 struct timeval rxtrunktime;
00379 struct timeval lasttxtime;
00380 struct timeval trunkact;
00381 unsigned int lastsent;
00382
00383 unsigned char *trunkdata;
00384 unsigned int trunkdatalen;
00385 unsigned int trunkdataalloc;
00386 int trunkmaxmtu;
00387 int trunkerror;
00388 int calls;
00389 AST_LIST_ENTRY(iax2_trunk_peer) list;
00390 };
00391
00392 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00393
00394 struct iax_firmware {
00395 AST_LIST_ENTRY(iax_firmware) list;
00396 int fd;
00397 int mmaplen;
00398 int dead;
00399 struct ast_iax2_firmware_header *fwh;
00400 unsigned char *buf;
00401 };
00402
00403 enum iax_reg_state {
00404 REG_STATE_UNREGISTERED = 0,
00405 REG_STATE_REGSENT,
00406 REG_STATE_AUTHSENT,
00407 REG_STATE_REGISTERED,
00408 REG_STATE_REJECTED,
00409 REG_STATE_TIMEOUT,
00410 REG_STATE_NOAUTH
00411 };
00412
00413 enum iax_transfer_state {
00414 TRANSFER_NONE = 0,
00415 TRANSFER_BEGIN,
00416 TRANSFER_READY,
00417 TRANSFER_RELEASED,
00418 TRANSFER_PASSTHROUGH,
00419 TRANSFER_MBEGIN,
00420 TRANSFER_MREADY,
00421 TRANSFER_MRELEASED,
00422 TRANSFER_MPASSTHROUGH,
00423 TRANSFER_MEDIA,
00424 TRANSFER_MEDIAPASS
00425 };
00426
00427 struct iax2_registry {
00428 struct sockaddr_in addr;
00429 char username[80];
00430 char secret[80];
00431 int expire;
00432 int refresh;
00433 enum iax_reg_state regstate;
00434 int messages;
00435 int callno;
00436 struct sockaddr_in us;
00437 struct ast_dnsmgr_entry *dnsmgr;
00438 AST_LIST_ENTRY(iax2_registry) entry;
00439 };
00440
00441 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00442
00443
00444 #define MIN_RETRY_TIME 100
00445 #define MAX_RETRY_TIME 10000
00446
00447 #define MAX_JITTER_BUFFER 50
00448 #define MIN_JITTER_BUFFER 10
00449
00450 #define DEFAULT_TRUNKDATA 640 * 10
00451
00452 #define MAX_TIMESTAMP_SKEW 160
00453
00454
00455 #define TS_GAP_FOR_JB_RESYNC 5000
00456
00457
00458 #define MARK_IAX_SUBCLASS_TX 0x8000
00459
00460 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00461 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00462 static int iaxdynamicthreadcount = 0;
00463 static int iaxdynamicthreadnum = 0;
00464 static int iaxactivethreadcount = 0;
00465
00466 struct iax_rr {
00467 int jitter;
00468 int losspct;
00469 int losscnt;
00470 int packets;
00471 int delay;
00472 int dropped;
00473 int ooo;
00474 };
00475
00476 struct iax2_pvt_ref;
00477
00478 struct chan_iax2_pvt {
00479
00480 int sockfd;
00481
00482 int voiceformat;
00483
00484 int videoformat;
00485
00486 int svoiceformat;
00487
00488 int svideoformat;
00489
00490 int capability;
00491
00492 unsigned int last;
00493
00494 unsigned int lastsent;
00495
00496 unsigned int lastvsent;
00497
00498 unsigned int nextpred;
00499
00500 int first_iax_message;
00501
00502 int last_iax_message;
00503
00504 unsigned int notsilenttx:1;
00505
00506 unsigned int pingtime;
00507
00508 int maxtime;
00509
00510 struct sockaddr_in addr;
00511
00512 struct ast_codec_pref prefs;
00513
00514 struct ast_codec_pref rprefs;
00515
00516 unsigned short callno;
00517
00518 unsigned short peercallno;
00519
00520
00521
00522 int chosenformat;
00523
00524 int peerformat;
00525
00526 int peercapability;
00527
00528 struct timeval offset;
00529
00530 struct timeval rxcore;
00531
00532 jitterbuf *jb;
00533
00534 int jbid;
00535
00536 int lag;
00537
00538 int error;
00539
00540 struct ast_channel *owner;
00541
00542 struct ast_flags state;
00543
00544 int expiry;
00545
00546 unsigned char oseqno;
00547
00548 unsigned char rseqno;
00549
00550 unsigned char iseqno;
00551
00552 unsigned char aseqno;
00553
00554 AST_DECLARE_STRING_FIELDS(
00555
00556 AST_STRING_FIELD(peer);
00557
00558 AST_STRING_FIELD(context);
00559
00560 AST_STRING_FIELD(cid_num);
00561 AST_STRING_FIELD(cid_name);
00562
00563 AST_STRING_FIELD(ani);
00564
00565 AST_STRING_FIELD(dnid);
00566
00567 AST_STRING_FIELD(rdnis);
00568
00569 AST_STRING_FIELD(exten);
00570
00571 AST_STRING_FIELD(username);
00572
00573 AST_STRING_FIELD(secret);
00574
00575 AST_STRING_FIELD(challenge);
00576
00577 AST_STRING_FIELD(inkeys);
00578
00579 AST_STRING_FIELD(outkey);
00580
00581 AST_STRING_FIELD(language);
00582
00583 AST_STRING_FIELD(host);
00584
00585 AST_STRING_FIELD(dproot);
00586 AST_STRING_FIELD(accountcode);
00587 AST_STRING_FIELD(mohinterpret);
00588 AST_STRING_FIELD(mohsuggest);
00589
00590 AST_STRING_FIELD(osptoken);
00591 );
00592
00593 int authrej;
00594
00595 int authmethods;
00596
00597 int encmethods;
00598
00599 ast_aes_encrypt_key ecx;
00600
00601 ast_aes_decrypt_key mydcx;
00602
00603 ast_aes_decrypt_key dcx;
00604
00605 unsigned char semirand[32];
00606
00607 struct iax2_registry *reg;
00608
00609 struct iax2_peer *peerpoke;
00610
00611 unsigned int flags;
00612 int adsi;
00613
00614
00615 enum iax_transfer_state transferring;
00616
00617 int transferid;
00618
00619 struct sockaddr_in transfer;
00620
00621 unsigned short transfercallno;
00622
00623 ast_aes_encrypt_key tdcx;
00624
00625
00626 int peeradsicpe;
00627
00628
00629 unsigned short bridgecallno;
00630
00631 int pingid;
00632 int lagid;
00633 int autoid;
00634 int authid;
00635 int authfail;
00636 int initid;
00637 int calling_ton;
00638 int calling_tns;
00639 int calling_pres;
00640 int amaflags;
00641 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00642
00643 struct ast_variable *vars;
00644
00645 struct ast_variable *iaxvars;
00646
00647 struct iax_rr remote_rr;
00648
00649 int min;
00650
00651 int frames_dropped;
00652
00653 int frames_received;
00654 };
00655
00656
00657
00658
00659
00660
00661
00662
00663 static AST_LIST_HEAD_STATIC(frame_queue, iax_frame);
00664
00665
00666
00667
00668
00669
00670
00671
00672 #ifdef LOW_MEMORY
00673 #define MAX_PEER_BUCKETS 17
00674 #else
00675 #define MAX_PEER_BUCKETS 563
00676 #endif
00677 static struct ao2_container *peers;
00678
00679 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00680 static struct ao2_container *users;
00681
00682 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00683
00684 enum {
00685
00686 CACHE_FLAG_EXISTS = (1 << 0),
00687
00688 CACHE_FLAG_NONEXISTENT = (1 << 1),
00689
00690 CACHE_FLAG_CANEXIST = (1 << 2),
00691
00692 CACHE_FLAG_PENDING = (1 << 3),
00693
00694 CACHE_FLAG_TIMEOUT = (1 << 4),
00695
00696 CACHE_FLAG_TRANSMITTED = (1 << 5),
00697
00698 CACHE_FLAG_UNKNOWN = (1 << 6),
00699
00700 CACHE_FLAG_MATCHMORE = (1 << 7),
00701 };
00702
00703 struct iax2_dpcache {
00704 char peercontext[AST_MAX_CONTEXT];
00705 char exten[AST_MAX_EXTENSION];
00706 struct timeval orig;
00707 struct timeval expiry;
00708 int flags;
00709 unsigned short callno;
00710 int waiters[256];
00711 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00712 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00713 };
00714
00715 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00716
00717 static void reg_source_db(struct iax2_peer *p);
00718 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00719
00720 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00721 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state);
00722 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00723
00724 enum iax2_thread_iostate {
00725 IAX_IOSTATE_IDLE,
00726 IAX_IOSTATE_READY,
00727 IAX_IOSTATE_PROCESSING,
00728 IAX_IOSTATE_SCHEDREADY,
00729 };
00730
00731 enum iax2_thread_type {
00732 IAX_THREAD_TYPE_POOL,
00733 IAX_THREAD_TYPE_DYNAMIC,
00734 };
00735
00736 struct iax2_pkt_buf {
00737 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00738 size_t len;
00739 unsigned char buf[1];
00740 };
00741
00742 struct iax2_thread {
00743 AST_LIST_ENTRY(iax2_thread) list;
00744 enum iax2_thread_type type;
00745 enum iax2_thread_iostate iostate;
00746 #ifdef SCHED_MULTITHREADED
00747 void (*schedfunc)(const void *);
00748 const void *scheddata;
00749 #endif
00750 #ifdef DEBUG_SCHED_MULTITHREAD
00751 char curfunc[80];
00752 #endif
00753 int actions;
00754 pthread_t threadid;
00755 int threadnum;
00756 struct sockaddr_in iosin;
00757 unsigned char readbuf[4096];
00758 unsigned char *buf;
00759 ssize_t buf_len;
00760 size_t buf_size;
00761 int iofd;
00762 time_t checktime;
00763 ast_mutex_t lock;
00764 ast_cond_t cond;
00765 unsigned int ready_for_signal:1;
00766
00767
00768
00769
00770 struct {
00771 unsigned short callno;
00772 struct sockaddr_in sin;
00773 unsigned char type;
00774 unsigned char csub;
00775 } ffinfo;
00776
00777
00778
00779 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00780 };
00781
00782
00783 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00784 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00785 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00786
00787 static void *iax2_process_thread(void *data);
00788 static void iax2_destroy(int callno);
00789
00790 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00791 {
00792 ast_mutex_lock(lock);
00793 ast_cond_signal(cond);
00794 ast_mutex_unlock(lock);
00795 }
00796
00797 static void iax_debug_output(const char *data)
00798 {
00799 if (iaxdebug)
00800 ast_verbose("%s", data);
00801 }
00802
00803 static void iax_error_output(const char *data)
00804 {
00805 ast_log(LOG_WARNING, "%s", data);
00806 }
00807
00808 static void __attribute__((format (printf, 1, 2))) jb_error_output(const char *fmt, ...)
00809 {
00810 va_list args;
00811 char buf[1024];
00812
00813 va_start(args, fmt);
00814 vsnprintf(buf, sizeof(buf), fmt, args);
00815 va_end(args);
00816
00817 ast_log(LOG_ERROR, "%s", buf);
00818 }
00819
00820 static void __attribute__((format (printf, 1, 2))) jb_warning_output(const char *fmt, ...)
00821 {
00822 va_list args;
00823 char buf[1024];
00824
00825 va_start(args, fmt);
00826 vsnprintf(buf, sizeof(buf), fmt, args);
00827 va_end(args);
00828
00829 ast_log(LOG_WARNING, "%s", buf);
00830 }
00831
00832 static void __attribute__((format (printf, 1, 2))) jb_debug_output(const char *fmt, ...)
00833 {
00834 va_list args;
00835 char buf[1024];
00836
00837 va_start(args, fmt);
00838 vsnprintf(buf, sizeof(buf), fmt, args);
00839 va_end(args);
00840
00841 ast_verbose("%s", buf);
00842 }
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 static struct ao2_container *iax_peercallno_pvts;
00864
00865
00866
00867
00868
00869
00870
00871
00872 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893 static struct timeval lastused[ARRAY_LEN(iaxs)];
00894
00895
00896
00897
00898
00899
00900 static struct ao2_container *iax_transfercallno_pvts;
00901
00902
00903
00904 #define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2
00905
00906 static int maxtrunkcall = TRUNK_CALL_START;
00907 static int maxnontrunkcall = 1;
00908
00909 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);
00910 static int expire_registry(const void *data);
00911 static int iax2_answer(struct ast_channel *c);
00912 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00913 static int iax2_devicestate(void *data);
00914 static int iax2_digit_begin(struct ast_channel *c, char digit);
00915 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00916 static int iax2_do_register(struct iax2_registry *reg);
00917 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00918 static int iax2_hangup(struct ast_channel *c);
00919 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00920 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00921 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00922 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00923 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00924 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00925 static int iax2_sendtext(struct ast_channel *c, const char *text);
00926 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00927 static int iax2_transfer(struct ast_channel *c, const char *dest);
00928 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00929 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
00930 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00931 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00932 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00933 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00934 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00935 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00936 static struct ast_frame *iax2_read(struct ast_channel *c);
00937 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00938 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00939 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00940 static void *iax2_dup_variable_datastore(void *);
00941 static void prune_peers(void);
00942 static void prune_users(void);
00943 static void iax2_free_variable_datastore(void *);
00944
00945 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
00946 static int acf_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value);
00947 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
00948 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
00949 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
00950 static void build_rand_pad(unsigned char *buf, ssize_t len);
00951
00952 static const struct ast_channel_tech iax2_tech = {
00953 .type = "IAX2",
00954 .description = tdesc,
00955 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00956 .properties = AST_CHAN_TP_WANTSJITTER,
00957 .requester = iax2_request,
00958 .devicestate = iax2_devicestate,
00959 .send_digit_begin = iax2_digit_begin,
00960 .send_digit_end = iax2_digit_end,
00961 .send_text = iax2_sendtext,
00962 .send_image = iax2_sendimage,
00963 .send_html = iax2_sendhtml,
00964 .call = iax2_call,
00965 .hangup = iax2_hangup,
00966 .answer = iax2_answer,
00967 .read = iax2_read,
00968 .write = iax2_write,
00969 .write_video = iax2_write,
00970 .indicate = iax2_indicate,
00971 .setoption = iax2_setoption,
00972 .bridge = iax2_bridge,
00973 .transfer = iax2_transfer,
00974 .fixup = iax2_fixup,
00975 .func_channel_read = acf_channel_read,
00976 .func_channel_write = acf_channel_write,
00977 };
00978
00979 static void mwi_event_cb(const struct ast_event *event, void *userdata)
00980 {
00981
00982
00983
00984 }
00985
00986
00987
00988 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
00989 {
00990 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
00991 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
00992 pvt->owner ? pvt->owner->name : "",
00993 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
00994 }
00995
00996
00997 static struct ast_datastore_info iax2_variable_datastore_info = {
00998 .type = "IAX2_VARIABLE",
00999 .duplicate = iax2_dup_variable_datastore,
01000 .destroy = iax2_free_variable_datastore,
01001 };
01002
01003 static void *iax2_dup_variable_datastore(void *old)
01004 {
01005 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01006 struct ast_var_t *oldvar, *newvar;
01007
01008 newlist = ast_calloc(sizeof(*newlist), 1);
01009 if (!newlist) {
01010 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01011 return NULL;
01012 }
01013
01014 AST_LIST_HEAD_INIT(newlist);
01015 AST_LIST_LOCK(oldlist);
01016 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01017 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01018 if (newvar)
01019 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01020 else
01021 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01022 }
01023 AST_LIST_UNLOCK(oldlist);
01024 return newlist;
01025 }
01026
01027 static void iax2_free_variable_datastore(void *old)
01028 {
01029 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01030 struct ast_var_t *oldvar;
01031
01032 AST_LIST_LOCK(oldlist);
01033 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01034 ast_free(oldvar);
01035 }
01036 AST_LIST_UNLOCK(oldlist);
01037 AST_LIST_HEAD_DESTROY(oldlist);
01038 ast_free(oldlist);
01039 }
01040
01041
01042
01043
01044
01045 static void insert_idle_thread(struct iax2_thread *thread)
01046 {
01047 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01048 AST_LIST_LOCK(&dynamic_list);
01049 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01050 AST_LIST_UNLOCK(&dynamic_list);
01051 } else {
01052 AST_LIST_LOCK(&idle_list);
01053 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01054 AST_LIST_UNLOCK(&idle_list);
01055 }
01056
01057 return;
01058 }
01059
01060 static struct iax2_thread *find_idle_thread(void)
01061 {
01062 struct iax2_thread *thread = NULL;
01063
01064
01065 AST_LIST_LOCK(&idle_list);
01066 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01067 AST_LIST_UNLOCK(&idle_list);
01068
01069
01070 if (thread) {
01071 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01072 return thread;
01073 }
01074
01075
01076 AST_LIST_LOCK(&dynamic_list);
01077 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01078 AST_LIST_UNLOCK(&dynamic_list);
01079
01080
01081 if (thread) {
01082 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01083 return thread;
01084 }
01085
01086
01087 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01088 return NULL;
01089
01090
01091 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01092 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01093 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01094
01095
01096 ast_mutex_init(&thread->lock);
01097 ast_cond_init(&thread->cond, NULL);
01098
01099
01100 if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01101 ast_cond_destroy(&thread->cond);
01102 ast_mutex_destroy(&thread->lock);
01103 ast_free(thread);
01104 return NULL;
01105 }
01106
01107
01108
01109 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01110
01111
01112 while (!thread->ready_for_signal)
01113 usleep(1);
01114
01115 return thread;
01116 }
01117
01118 #ifdef SCHED_MULTITHREADED
01119 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01120 {
01121 struct iax2_thread *thread = NULL;
01122 static time_t lasterror;
01123 static time_t t;
01124
01125 thread = find_idle_thread();
01126
01127 if (thread != NULL) {
01128 thread->schedfunc = func;
01129 thread->scheddata = data;
01130 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01131 #ifdef DEBUG_SCHED_MULTITHREAD
01132 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01133 #endif
01134 signal_condition(&thread->lock, &thread->cond);
01135 return 0;
01136 }
01137 time(&t);
01138 if (t != lasterror)
01139 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01140 lasterror = t;
01141
01142 return -1;
01143 }
01144 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01145 #endif
01146
01147 static int iax2_sched_replace(int id, struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01148 {
01149 AST_SCHED_REPLACE(id, con, when, callback, data);
01150 signal_condition(&sched_lock, &sched_cond);
01151
01152 return id;
01153 }
01154
01155 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01156 {
01157 int res;
01158
01159 res = ast_sched_add(con, when, callback, data);
01160 signal_condition(&sched_lock, &sched_cond);
01161
01162 return res;
01163 }
01164
01165 static int send_ping(const void *data);
01166
01167 static void __send_ping(const void *data)
01168 {
01169 int callno = (long) data;
01170
01171 ast_mutex_lock(&iaxsl[callno]);
01172
01173 if (iaxs[callno]) {
01174 if (iaxs[callno]->peercallno) {
01175 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01176 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01177 } else {
01178
01179 iaxs[callno]->pingid = -1;
01180 }
01181 } else {
01182 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01183 }
01184
01185 ast_mutex_unlock(&iaxsl[callno]);
01186 }
01187
01188 static int send_ping(const void *data)
01189 {
01190 #ifdef SCHED_MULTITHREADED
01191 if (schedule_action(__send_ping, data))
01192 #endif
01193 __send_ping(data);
01194
01195 return 0;
01196 }
01197
01198 static int get_encrypt_methods(const char *s)
01199 {
01200 int e;
01201 if (!strcasecmp(s, "aes128"))
01202 e = IAX_ENCRYPT_AES128;
01203 else if (ast_true(s))
01204 e = IAX_ENCRYPT_AES128;
01205 else
01206 e = 0;
01207 return e;
01208 }
01209
01210 static int send_lagrq(const void *data);
01211
01212 static void __send_lagrq(const void *data)
01213 {
01214 int callno = (long) data;
01215
01216 ast_mutex_lock(&iaxsl[callno]);
01217
01218 if (iaxs[callno]) {
01219 if (iaxs[callno]->peercallno) {
01220 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01221 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01222 } else {
01223
01224 iaxs[callno]->lagid = -1;
01225 }
01226 } else {
01227 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01228 }
01229
01230 ast_mutex_unlock(&iaxsl[callno]);
01231 }
01232
01233 static int send_lagrq(const void *data)
01234 {
01235 #ifdef SCHED_MULTITHREADED
01236 if (schedule_action(__send_lagrq, data))
01237 #endif
01238 __send_lagrq(data);
01239
01240 return 0;
01241 }
01242
01243 static unsigned char compress_subclass(int subclass)
01244 {
01245 int x;
01246 int power=-1;
01247
01248 if (subclass < IAX_FLAG_SC_LOG)
01249 return subclass;
01250
01251 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01252 if (subclass & (1 << x)) {
01253 if (power > -1) {
01254 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01255 return 0;
01256 } else
01257 power = x;
01258 }
01259 }
01260 return power | IAX_FLAG_SC_LOG;
01261 }
01262
01263 static int uncompress_subclass(unsigned char csub)
01264 {
01265
01266 if (csub & IAX_FLAG_SC_LOG) {
01267
01268 if (csub == 0xff)
01269 return -1;
01270 else
01271 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01272 }
01273 else
01274 return csub;
01275 }
01276
01277
01278
01279
01280 static int peer_hash_cb(const void *obj, const int flags)
01281 {
01282 const struct iax2_peer *peer = obj;
01283
01284 return ast_str_hash(peer->name);
01285 }
01286
01287
01288
01289
01290 static int peer_cmp_cb(void *obj, void *arg, int flags)
01291 {
01292 struct iax2_peer *peer = obj, *peer2 = arg;
01293
01294 return !strcmp(peer->name, peer2->name) ? CMP_MATCH : 0;
01295 }
01296
01297
01298
01299
01300 static int user_hash_cb(const void *obj, const int flags)
01301 {
01302 const struct iax2_user *user = obj;
01303
01304 return ast_str_hash(user->name);
01305 }
01306
01307
01308
01309
01310 static int user_cmp_cb(void *obj, void *arg, int flags)
01311 {
01312 struct iax2_user *user = obj, *user2 = arg;
01313
01314 return !strcmp(user->name, user2->name) ? CMP_MATCH : 0;
01315 }
01316
01317
01318
01319
01320
01321 static struct iax2_peer *find_peer(const char *name, int realtime)
01322 {
01323 struct iax2_peer *peer = NULL;
01324 struct iax2_peer tmp_peer = {
01325 .name = name,
01326 };
01327
01328 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01329
01330
01331 if(!peer && realtime)
01332 peer = realtime_peer(name, NULL);
01333
01334 return peer;
01335 }
01336
01337 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01338 {
01339 ao2_ref(peer, +1);
01340 return peer;
01341 }
01342
01343 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01344 {
01345 ao2_ref(peer, -1);
01346 return NULL;
01347 }
01348
01349 static struct iax2_user *find_user(const char *name)
01350 {
01351 struct iax2_user tmp_user = {
01352 .name = name,
01353 };
01354
01355 return ao2_find(users, &tmp_user, OBJ_POINTER);
01356 }
01357 static inline struct iax2_user *user_ref(struct iax2_user *user)
01358 {
01359 ao2_ref(user, +1);
01360 return user;
01361 }
01362
01363 static inline struct iax2_user *user_unref(struct iax2_user *user)
01364 {
01365 ao2_ref(user, -1);
01366 return NULL;
01367 }
01368
01369 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01370 {
01371 struct iax2_peer *peer = NULL;
01372 int res = 0;
01373 struct ao2_iterator i;
01374
01375 i = ao2_iterator_init(peers, 0);
01376 while ((peer = ao2_iterator_next(&i))) {
01377 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01378 (peer->addr.sin_port == sin.sin_port)) {
01379 ast_copy_string(host, peer->name, len);
01380 peer_unref(peer);
01381 res = 1;
01382 break;
01383 }
01384 peer_unref(peer);
01385 }
01386
01387 if (!peer) {
01388 peer = realtime_peer(NULL, &sin);
01389 if (peer) {
01390 ast_copy_string(host, peer->name, len);
01391 peer_unref(peer);
01392 res = 1;
01393 }
01394 }
01395
01396 return res;
01397 }
01398
01399 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01400 {
01401
01402 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01403 struct iax2_user *user;
01404 struct iax2_user tmp_user = {
01405 .name = pvt->username,
01406 };
01407
01408 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01409 if (user) {
01410 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01411 user_unref(user);
01412 }
01413
01414 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01415 }
01416
01417 AST_SCHED_DEL(sched, pvt->pingid);
01418 AST_SCHED_DEL(sched, pvt->lagid);
01419 AST_SCHED_DEL(sched, pvt->autoid);
01420 AST_SCHED_DEL(sched, pvt->authid);
01421 AST_SCHED_DEL(sched, pvt->initid);
01422 AST_SCHED_DEL(sched, pvt->jbid);
01423 }
01424
01425 static void iax2_frame_free(struct iax_frame *fr)
01426 {
01427 AST_SCHED_DEL(sched, fr->retrans);
01428 iax_frame_free(fr);
01429 }
01430
01431 static int scheduled_destroy(const void *vid)
01432 {
01433 short callno = PTR_TO_CALLNO(vid);
01434 ast_mutex_lock(&iaxsl[callno]);
01435 if (iaxs[callno]) {
01436 if (option_debug) {
01437 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01438 }
01439 iax2_destroy(callno);
01440 }
01441 ast_mutex_unlock(&iaxsl[callno]);
01442 return 0;
01443 }
01444
01445 static void pvt_destructor(void *obj)
01446 {
01447 struct chan_iax2_pvt *pvt = obj;
01448 struct iax_frame *cur = NULL;
01449
01450 iax2_destroy_helper(pvt);
01451
01452
01453 ast_set_flag(pvt, IAX_ALREADYGONE);
01454
01455 AST_LIST_LOCK(&frame_queue);
01456 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01457
01458 if (cur->callno == pvt->callno) {
01459 cur->retries = -1;
01460 }
01461 }
01462 AST_LIST_UNLOCK(&frame_queue);
01463
01464 if (pvt->reg) {
01465 pvt->reg->callno = 0;
01466 }
01467
01468 if (!pvt->owner) {
01469 jb_frame frame;
01470 if (pvt->vars) {
01471 ast_variables_destroy(pvt->vars);
01472 pvt->vars = NULL;
01473 }
01474
01475 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01476 iax2_frame_free(frame.data);
01477 }
01478
01479 jb_destroy(pvt->jb);
01480 ast_string_field_free_memory(pvt);
01481 }
01482 }
01483
01484 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01485 {
01486 struct chan_iax2_pvt *tmp;
01487 jb_conf jbconf;
01488
01489 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01490 return NULL;
01491 }
01492
01493 if (ast_string_field_init(tmp, 32)) {
01494 ao2_ref(tmp, -1);
01495 tmp = NULL;
01496 return NULL;
01497 }
01498
01499 tmp->prefs = prefs;
01500 tmp->pingid = -1;
01501 tmp->lagid = -1;
01502 tmp->autoid = -1;
01503 tmp->authid = -1;
01504 tmp->initid = -1;
01505
01506 ast_string_field_set(tmp,exten, "s");
01507 ast_string_field_set(tmp,host, host);
01508
01509 tmp->jb = jb_new();
01510 tmp->jbid = -1;
01511 jbconf.max_jitterbuf = maxjitterbuffer;
01512 jbconf.resync_threshold = resyncthreshold;
01513 jbconf.max_contig_interp = maxjitterinterps;
01514 jbconf.target_extra = jittertargetextra;
01515 jb_setconf(tmp->jb,&jbconf);
01516
01517 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01518
01519 return tmp;
01520 }
01521
01522 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01523 {
01524 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01525 if (new) {
01526 size_t afdatalen = new->afdatalen;
01527 memcpy(new, fr, sizeof(*new));
01528 iax_frame_wrap(new, &fr->af);
01529 new->afdatalen = afdatalen;
01530 new->data = NULL;
01531 new->datalen = 0;
01532 new->direction = DIRECTION_INGRESS;
01533 new->retrans = -1;
01534 }
01535 return new;
01536 }
01537
01538 #define NEW_PREVENT 0
01539 #define NEW_ALLOW 1
01540 #define NEW_FORCE 2
01541
01542 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01543 {
01544 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01545 (cur->addr.sin_port == sin->sin_port)) {
01546
01547 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01548 (check_dcallno ? dcallno == cur->callno : 1) ) {
01549
01550 return 1;
01551 }
01552 }
01553 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01554 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01555
01556 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01557 return 1;
01558 }
01559 return 0;
01560 }
01561
01562 static void update_max_trunk(void)
01563 {
01564 int max = TRUNK_CALL_START;
01565 int x;
01566
01567
01568 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01569 if (iaxs[x]) {
01570 max = x + 1;
01571 }
01572 }
01573
01574 maxtrunkcall = max;
01575 if (iaxdebug)
01576 ast_debug(1, "New max trunk callno is %d\n", max);
01577 }
01578
01579 static void update_max_nontrunk(void)
01580 {
01581 int max = 1;
01582 int x;
01583
01584 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01585 if (iaxs[x])
01586 max = x + 1;
01587 }
01588 maxnontrunkcall = max;
01589 if (iaxdebug)
01590 ast_debug(1, "New max nontrunk callno is %d\n", max);
01591 }
01592
01593 static int make_trunk(unsigned short callno, int locked)
01594 {
01595 int x;
01596 int res= 0;
01597 struct timeval now = ast_tvnow();
01598 if (iaxs[callno]->oseqno) {
01599 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01600 return -1;
01601 }
01602 if (callno & TRUNK_CALL_START) {
01603 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01604 return -1;
01605 }
01606 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01607 ast_mutex_lock(&iaxsl[x]);
01608 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01609
01610
01611
01612
01613 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01614 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01615 iaxs[x] = iaxs[callno];
01616 iaxs[x]->callno = x;
01617 iaxs[callno] = NULL;
01618
01619 iaxs[x]->pingid = iax2_sched_add(sched,
01620 ping_time * 1000, send_ping, (void *)(long)x);
01621 iaxs[x]->lagid = iax2_sched_add(sched,
01622 lagrq_time * 1000, send_lagrq, (void *)(long)x);
01623 if (locked)
01624 ast_mutex_unlock(&iaxsl[callno]);
01625 res = x;
01626 if (!locked)
01627 ast_mutex_unlock(&iaxsl[x]);
01628 break;
01629 }
01630 ast_mutex_unlock(&iaxsl[x]);
01631 }
01632 if (x >= ARRAY_LEN(iaxs) - 1) {
01633 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01634 return -1;
01635 }
01636 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01637
01638 update_max_trunk();
01639 update_max_nontrunk();
01640 return res;
01641 }
01642
01643 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01644 {
01645 if (!pvt->transfercallno) {
01646 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01647 return;
01648 }
01649
01650 ao2_link(iax_transfercallno_pvts, pvt);
01651 }
01652
01653 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01654 {
01655 if (!pvt->transfercallno) {
01656 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01657 return;
01658 }
01659
01660 ao2_unlink(iax_transfercallno_pvts, pvt);
01661 }
01662 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01663 {
01664 if (!pvt->peercallno) {
01665 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01666 return;
01667 }
01668
01669 ao2_link(iax_peercallno_pvts, pvt);
01670 }
01671
01672 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01673 {
01674 if (!pvt->peercallno) {
01675 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01676 return;
01677 }
01678
01679 ao2_unlink(iax_peercallno_pvts, pvt);
01680 }
01681
01682
01683
01684
01685 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01686 {
01687 int res = 0;
01688 int x;
01689 struct timeval now;
01690 char host[80];
01691
01692 if (new <= NEW_ALLOW) {
01693 if (callno) {
01694 struct chan_iax2_pvt *pvt;
01695 struct chan_iax2_pvt tmp_pvt = {
01696 .callno = dcallno,
01697 .peercallno = callno,
01698 .transfercallno = callno,
01699
01700 .frames_received = check_dcallno,
01701 };
01702
01703 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01704
01705 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01706 if (return_locked) {
01707 ast_mutex_lock(&iaxsl[pvt->callno]);
01708 }
01709 res = pvt->callno;
01710 ao2_ref(pvt, -1);
01711 pvt = NULL;
01712 return res;
01713 }
01714
01715 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
01716 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr));
01717 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01718 if (return_locked) {
01719 ast_mutex_lock(&iaxsl[pvt->callno]);
01720 }
01721 res = pvt->callno;
01722 ao2_ref(pvt, -1);
01723 pvt = NULL;
01724 return res;
01725 }
01726 }
01727
01728
01729 if (dcallno) {
01730 ast_mutex_lock(&iaxsl[dcallno]);
01731 }
01732 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
01733 iaxs[dcallno]->peercallno = callno;
01734 res = dcallno;
01735 store_by_peercallno(iaxs[dcallno]);
01736 if (!res || !return_locked) {
01737 ast_mutex_unlock(&iaxsl[dcallno]);
01738 }
01739 return res;
01740 }
01741 if (dcallno) {
01742 ast_mutex_unlock(&iaxsl[dcallno]);
01743 }
01744 #ifdef IAX_OLD_FIND
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756 for (x = 1; !res && x < maxnontrunkcall; x++) {
01757 ast_mutex_lock(&iaxsl[x]);
01758 if (iaxs[x]) {
01759
01760 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01761 res = x;
01762 }
01763 }
01764 if (!res || !return_locked)
01765 ast_mutex_unlock(&iaxsl[x]);
01766 }
01767 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01768 ast_mutex_lock(&iaxsl[x]);
01769 if (iaxs[x]) {
01770
01771 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01772 res = x;
01773 }
01774 }
01775 if (!res || !return_locked)
01776 ast_mutex_unlock(&iaxsl[x]);
01777 }
01778 #endif
01779 }
01780 if (!res && (new >= NEW_ALLOW)) {
01781 int start, found = 0;
01782
01783
01784
01785
01786
01787
01788
01789 if (!iax2_getpeername(*sin, host, sizeof(host)))
01790 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01791
01792 now = ast_tvnow();
01793 start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01794 for (x = start; 1; x++) {
01795 if (x == TRUNK_CALL_START) {
01796 x = 1;
01797 continue;
01798 }
01799
01800
01801 ast_mutex_lock(&iaxsl[x]);
01802 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01803 found = 1;
01804 break;
01805 }
01806 ast_mutex_unlock(&iaxsl[x]);
01807
01808 if (x == start - 1) {
01809 break;
01810 }
01811 }
01812
01813 if (x == start - 1 && !found) {
01814 ast_log(LOG_WARNING, "No more space\n");
01815 return 0;
01816 }
01817 iaxs[x] = new_iax(sin, host);
01818 update_max_nontrunk();
01819 if (iaxs[x]) {
01820 if (iaxdebug)
01821 ast_debug(1, "Creating new call structure %d\n", x);
01822 iaxs[x]->sockfd = sockfd;
01823 iaxs[x]->addr.sin_port = sin->sin_port;
01824 iaxs[x]->addr.sin_family = sin->sin_family;
01825 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01826 iaxs[x]->peercallno = callno;
01827 iaxs[x]->callno = x;
01828 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01829 iaxs[x]->expiry = min_reg_expire;
01830 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01831 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01832 iaxs[x]->amaflags = amaflags;
01833 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01834
01835 ast_string_field_set(iaxs[x], accountcode, accountcode);
01836 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01837 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01838
01839 if (iaxs[x]->peercallno) {
01840 store_by_peercallno(iaxs[x]);
01841 }
01842 } else {
01843 ast_log(LOG_WARNING, "Out of resources\n");
01844 ast_mutex_unlock(&iaxsl[x]);
01845 return 0;
01846 }
01847 if (!return_locked)
01848 ast_mutex_unlock(&iaxsl[x]);
01849 res = x;
01850 }
01851 return res;
01852 }
01853
01854 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01855
01856 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01857 }
01858
01859 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01860
01861 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01862 }
01863
01864
01865
01866
01867
01868
01869
01870
01871
01872
01873
01874 static int iax2_queue_frame(int callno, struct ast_frame *f)
01875 {
01876 for (;;) {
01877 if (iaxs[callno] && iaxs[callno]->owner) {
01878 if (ast_channel_trylock(iaxs[callno]->owner)) {
01879
01880 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01881 } else {
01882 ast_queue_frame(iaxs[callno]->owner, f);
01883 ast_channel_unlock(iaxs[callno]->owner);
01884 break;
01885 }
01886 } else
01887 break;
01888 }
01889 return 0;
01890 }
01891
01892
01893
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905 static int iax2_queue_hangup(int callno)
01906 {
01907 for (;;) {
01908 if (iaxs[callno] && iaxs[callno]->owner) {
01909 if (ast_channel_trylock(iaxs[callno]->owner)) {
01910
01911 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01912 } else {
01913 ast_queue_hangup(iaxs[callno]->owner);
01914 ast_channel_unlock(iaxs[callno]->owner);
01915 break;
01916 }
01917 } else
01918 break;
01919 }
01920 return 0;
01921 }
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936 static int iax2_queue_control_data(int callno,
01937 enum ast_control_frame_type control, const void *data, size_t datalen)
01938 {
01939 for (;;) {
01940 if (iaxs[callno] && iaxs[callno]->owner) {
01941 if (ast_channel_trylock(iaxs[callno]->owner)) {
01942
01943 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01944 } else {
01945 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01946 ast_channel_unlock(iaxs[callno]->owner);
01947 break;
01948 }
01949 } else
01950 break;
01951 }
01952 return 0;
01953 }
01954 static void destroy_firmware(struct iax_firmware *cur)
01955 {
01956
01957 if (cur->fwh) {
01958 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01959 }
01960 close(cur->fd);
01961 ast_free(cur);
01962 }
01963
01964 static int try_firmware(char *s)
01965 {
01966 struct stat stbuf;
01967 struct iax_firmware *cur = NULL;
01968 int ifd, fd, res, len, chunk;
01969 struct ast_iax2_firmware_header *fwh, fwh2;
01970 struct MD5Context md5;
01971 unsigned char sum[16], buf[1024];
01972 char *s2, *last;
01973
01974 if (!(s2 = alloca(strlen(s) + 100))) {
01975 ast_log(LOG_WARNING, "Alloca failed!\n");
01976 return -1;
01977 }
01978
01979 last = strrchr(s, '/');
01980 if (last)
01981 last++;
01982 else
01983 last = s;
01984
01985 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01986
01987 if ((res = stat(s, &stbuf) < 0)) {
01988 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01989 return -1;
01990 }
01991
01992
01993 if (S_ISDIR(stbuf.st_mode))
01994 return -1;
01995 ifd = open(s, O_RDONLY);
01996 if (ifd < 0) {
01997 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01998 return -1;
01999 }
02000 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02001 if (fd < 0) {
02002 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02003 close(ifd);
02004 return -1;
02005 }
02006
02007 unlink(s2);
02008
02009
02010 len = stbuf.st_size;
02011 while(len) {
02012 chunk = len;
02013 if (chunk > sizeof(buf))
02014 chunk = sizeof(buf);
02015 res = read(ifd, buf, chunk);
02016 if (res != chunk) {
02017 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02018 close(ifd);
02019 close(fd);
02020 return -1;
02021 }
02022 res = write(fd, buf, chunk);
02023 if (res != chunk) {
02024 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02025 close(ifd);
02026 close(fd);
02027 return -1;
02028 }
02029 len -= chunk;
02030 }
02031 close(ifd);
02032
02033 lseek(fd, 0, SEEK_SET);
02034 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02035 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02036 close(fd);
02037 return -1;
02038 }
02039 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02040 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02041 close(fd);
02042 return -1;
02043 }
02044 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02045 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02046 close(fd);
02047 return -1;
02048 }
02049 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02050 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02051 close(fd);
02052 return -1;
02053 }
02054 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
02055 if (fwh == MAP_FAILED) {
02056 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02057 close(fd);
02058 return -1;
02059 }
02060 MD5Init(&md5);
02061 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02062 MD5Final(sum, &md5);
02063 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02064 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02065 munmap((void*)fwh, stbuf.st_size);
02066 close(fd);
02067 return -1;
02068 }
02069
02070 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02071 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02072
02073 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02074
02075 break;
02076
02077
02078 munmap((void*)fwh, stbuf.st_size);
02079 close(fd);
02080 return 0;
02081 }
02082 }
02083
02084 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02085 cur->fd = -1;
02086 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02087 }
02088
02089 if (cur) {
02090 if (cur->fwh)
02091 munmap((void*)cur->fwh, cur->mmaplen);
02092 if (cur->fd > -1)
02093 close(cur->fd);
02094 cur->fwh = fwh;
02095 cur->fd = fd;
02096 cur->mmaplen = stbuf.st_size;
02097 cur->dead = 0;
02098 }
02099
02100 return 0;
02101 }
02102
02103 static int iax_check_version(char *dev)
02104 {
02105 int res = 0;
02106 struct iax_firmware *cur = NULL;
02107
02108 if (ast_strlen_zero(dev))
02109 return 0;
02110
02111 AST_LIST_LOCK(&firmwares);
02112 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02113 if (!strcmp(dev, (char *)cur->fwh->devname)) {
02114 res = ntohs(cur->fwh->version);
02115 break;
02116 }
02117 }
02118 AST_LIST_UNLOCK(&firmwares);
02119
02120 return res;
02121 }
02122
02123 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02124 {
02125 int res = -1;
02126 unsigned int bs = desc & 0xff;
02127 unsigned int start = (desc >> 8) & 0xffffff;
02128 unsigned int bytes;
02129 struct iax_firmware *cur;
02130
02131 if (ast_strlen_zero((char *)dev) || !bs)
02132 return -1;
02133
02134 start *= bs;
02135
02136 AST_LIST_LOCK(&firmwares);
02137 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02138 if (strcmp((char *)dev, (char *)cur->fwh->devname))
02139 continue;
02140 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02141 if (start < ntohl(cur->fwh->datalen)) {
02142 bytes = ntohl(cur->fwh->datalen) - start;
02143 if (bytes > bs)
02144 bytes = bs;
02145 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02146 } else {
02147 bytes = 0;
02148 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02149 }
02150 if (bytes == bs)
02151 res = 0;
02152 else
02153 res = 1;
02154 break;
02155 }
02156 AST_LIST_UNLOCK(&firmwares);
02157
02158 return res;
02159 }
02160
02161
02162 static void reload_firmware(int unload)
02163 {
02164 struct iax_firmware *cur = NULL;
02165 DIR *fwd;
02166 struct dirent *de;
02167 char dir[256], fn[256];
02168
02169 AST_LIST_LOCK(&firmwares);
02170
02171
02172 AST_LIST_TRAVERSE(&firmwares, cur, list)
02173 cur->dead = 1;
02174
02175
02176 if (!unload) {
02177 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
02178 fwd = opendir(dir);
02179 if (fwd) {
02180 while((de = readdir(fwd))) {
02181 if (de->d_name[0] != '.') {
02182 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02183 if (!try_firmware(fn)) {
02184 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
02185 }
02186 }
02187 }
02188 closedir(fwd);
02189 } else
02190 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02191 }
02192
02193
02194 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
02195 if (!cur->dead)
02196 continue;
02197 AST_LIST_REMOVE_CURRENT(list);
02198 destroy_firmware(cur);
02199 }
02200 AST_LIST_TRAVERSE_SAFE_END;
02201
02202 AST_LIST_UNLOCK(&firmwares);
02203 }
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213 static int __do_deliver(void *data)
02214 {
02215
02216
02217 struct iax_frame *fr = data;
02218 fr->retrans = -1;
02219 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02220 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02221 iax2_queue_frame(fr->callno, &fr->af);
02222
02223 iax2_frame_free(fr);
02224
02225 return 0;
02226 }
02227
02228 static int handle_error(void)
02229 {
02230
02231
02232
02233 #if 0
02234 struct sockaddr_in *sin;
02235 int res;
02236 struct msghdr m;
02237 struct sock_extended_err e;
02238 m.msg_name = NULL;
02239 m.msg_namelen = 0;
02240 m.msg_iov = NULL;
02241 m.msg_control = &e;
02242 m.msg_controllen = sizeof(e);
02243 m.msg_flags = 0;
02244 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02245 if (res < 0)
02246 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02247 else {
02248 if (m.msg_controllen) {
02249 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02250 if (sin)
02251 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02252 else
02253 ast_log(LOG_WARNING, "No address detected??\n");
02254 } else {
02255 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02256 }
02257 }
02258 #endif
02259 return 0;
02260 }
02261
02262 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02263 {
02264 int res;
02265 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02266 sizeof(*sin));
02267 if (res < 0) {
02268 ast_debug(1, "Received error: %s\n", strerror(errno));
02269 handle_error();
02270 } else
02271 res = 0;
02272 return res;
02273 }
02274
02275 static int send_packet(struct iax_frame *f)
02276 {
02277 int res;
02278 int callno = f->callno;
02279
02280
02281 if (!callno || !iaxs[callno] || iaxs[callno]->error)
02282 return -1;
02283
02284
02285 if (iaxdebug)
02286 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));
02287 if (f->transfer) {
02288 if (iaxdebug)
02289 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02290 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02291 sizeof(iaxs[callno]->transfer));
02292 } else {
02293 if (iaxdebug)
02294 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02295 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02296 sizeof(iaxs[callno]->addr));
02297 }
02298 if (res < 0) {
02299 if (iaxdebug)
02300 ast_debug(1, "Received error: %s\n", strerror(errno));
02301 handle_error();
02302 } else
02303 res = 0;
02304 return res;
02305 }
02306
02307
02308
02309
02310
02311 static int iax2_predestroy(int callno)
02312 {
02313 struct ast_channel *c = NULL;
02314 struct chan_iax2_pvt *pvt = iaxs[callno];
02315
02316 if (!pvt)
02317 return -1;
02318
02319 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02320 iax2_destroy_helper(pvt);
02321 ast_set_flag(pvt, IAX_ALREADYGONE);
02322 }
02323
02324 if ((c = pvt->owner)) {
02325 c->tech_pvt = NULL;
02326 iax2_queue_hangup(callno);
02327 pvt->owner = NULL;
02328 ast_module_unref(ast_module_info->self);
02329 }
02330
02331 return 0;
02332 }
02333
02334 static void iax2_destroy(int callno)
02335 {
02336 struct chan_iax2_pvt *pvt = NULL;
02337 struct ast_channel *owner = NULL;
02338
02339 retry:
02340 pvt = iaxs[callno];
02341 lastused[callno] = ast_tvnow();
02342
02343 owner = pvt ? pvt->owner : NULL;
02344
02345 if (owner) {
02346 if (ast_channel_trylock(owner)) {
02347 ast_debug(3, "Avoiding IAX destroy deadlock\n");
02348 ast_mutex_unlock(&iaxsl[callno]);
02349 usleep(1);
02350 ast_mutex_lock(&iaxsl[callno]);
02351 goto retry;
02352 }
02353 }
02354
02355 if (!owner) {
02356 iaxs[callno] = NULL;
02357 }
02358
02359 if (pvt) {
02360 if (!owner) {
02361 pvt->owner = NULL;
02362 } else {
02363
02364
02365
02366 ast_queue_hangup(owner);
02367 }
02368
02369 if (pvt->peercallno) {
02370 remove_by_peercallno(pvt);
02371 }
02372
02373 if (pvt->transfercallno) {
02374 remove_by_transfercallno(pvt);
02375 }
02376
02377 if (!owner) {
02378 ao2_ref(pvt, -1);
02379 pvt = NULL;
02380 }
02381 }
02382
02383 if (owner) {
02384 ast_channel_unlock(owner);
02385 }
02386
02387 if (callno & 0x4000) {
02388 update_max_trunk();
02389 }
02390 }
02391
02392 static int update_packet(struct iax_frame *f)
02393 {
02394
02395 struct ast_iax2_full_hdr *fh = f->data;
02396 struct ast_frame af;
02397
02398
02399 if (f->encmethods) {
02400 decode_frame(&f->mydcx, fh, &af, &f->datalen);
02401 }
02402
02403 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02404
02405 f->iseqno = iaxs[f->callno]->iseqno;
02406 fh->iseqno = f->iseqno;
02407
02408
02409 if (f->encmethods) {
02410
02411
02412 build_rand_pad(f->semirand, sizeof(f->semirand));
02413 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
02414 }
02415 return 0;
02416 }
02417
02418 static int attempt_transmit(const void *data);
02419 static void __attempt_transmit(const void *data)
02420 {
02421
02422
02423 struct iax_frame *f = (struct iax_frame *)data;
02424 int freeme = 0;
02425 int callno = f->callno;
02426
02427 if (callno)
02428 ast_mutex_lock(&iaxsl[callno]);
02429 if (callno && iaxs[callno]) {
02430 if ((f->retries < 0) ||
02431 (f->retries >= max_retries) ) {
02432
02433 if (f->retries >= max_retries) {
02434 if (f->transfer) {
02435
02436 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02437 } else if (f->final) {
02438 if (f->final)
02439 iax2_destroy(callno);
02440 } else {
02441 if (iaxs[callno]->owner)
02442 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
02443 iaxs[callno]->error = ETIMEDOUT;
02444 if (iaxs[callno]->owner) {
02445 struct ast_frame fr = { 0, };
02446
02447 fr.frametype = AST_FRAME_CONTROL;
02448 fr.subclass = AST_CONTROL_HANGUP;
02449 iax2_queue_frame(callno, &fr);
02450
02451 if (iaxs[callno] && iaxs[callno]->owner)
02452 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02453 } else {
02454 if (iaxs[callno]->reg) {
02455 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02456 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02457 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02458 }
02459 iax2_destroy(callno);
02460 }
02461 }
02462
02463 }
02464 freeme = 1;
02465 } else {
02466
02467 update_packet(f);
02468
02469 send_packet(f);
02470 f->retries++;
02471
02472 f->retrytime *= 10;
02473 if (f->retrytime > MAX_RETRY_TIME)
02474 f->retrytime = MAX_RETRY_TIME;
02475
02476 if (f->transfer && (f->retrytime > 1000))
02477 f->retrytime = 1000;
02478 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02479 }
02480 } else {
02481
02482 f->retries = -1;
02483 freeme = 1;
02484 }
02485 if (callno)
02486 ast_mutex_unlock(&iaxsl[callno]);
02487
02488 if (freeme) {
02489
02490 AST_LIST_LOCK(&frame_queue);
02491 AST_LIST_REMOVE(&frame_queue, f, list);
02492 AST_LIST_UNLOCK(&frame_queue);
02493 f->retrans = -1;
02494
02495 iax2_frame_free(f);
02496 }
02497 }
02498
02499 static int attempt_transmit(const void *data)
02500 {
02501 #ifdef SCHED_MULTITHREADED
02502 if (schedule_action(__attempt_transmit, data))
02503 #endif
02504 __attempt_transmit(data);
02505 return 0;
02506 }
02507
02508 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02509 {
02510 struct iax2_peer *peer = NULL;
02511 struct iax2_user *user = NULL;
02512
02513 switch (cmd) {
02514 case CLI_INIT:
02515 e->command = "iax2 prune realtime";
02516 e->usage =
02517 "Usage: iax2 prune realtime [<peername>|all]\n"
02518 " Prunes object(s) from the cache\n";
02519 return NULL;
02520 case CLI_GENERATE:
02521 return complete_iax2_show_peer(a->line, a->word, a->pos, a->n);
02522 }
02523 if (a->argc != 4)
02524 return CLI_SHOWUSAGE;
02525 if (!strcmp(a->argv[3], "all")) {
02526 prune_users();
02527 prune_peers();
02528 ast_cli(a->fd, "Cache flushed successfully.\n");
02529 return CLI_SUCCESS;
02530 }
02531 peer = find_peer(a->argv[3], 0);
02532 user = find_user(a->argv[3]);
02533 if (peer || user) {
02534 if (peer) {
02535 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02536 ast_set_flag(peer, IAX_RTAUTOCLEAR);
02537 expire_registry(peer_ref(peer));
02538 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
02539 } else {
02540 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
02541 }
02542 peer_unref(peer);
02543 }
02544 if (user) {
02545 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
02546 ast_set_flag(user, IAX_RTAUTOCLEAR);
02547 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
02548 } else {
02549 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
02550 }
02551 ao2_unlink(users,user);
02552 user_unref(user);
02553 }
02554 } else {
02555 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
02556 }
02557
02558 return CLI_SUCCESS;
02559 }
02560
02561 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02562 {
02563 switch (cmd) {
02564 case CLI_INIT:
02565 e->command = "iax2 test losspct";
02566 e->usage =
02567 "Usage: iax2 test losspct <percentage>\n"
02568 " For testing, throws away <percentage> percent of incoming packets\n";
02569 return NULL;
02570 case CLI_GENERATE:
02571 return NULL;
02572 }
02573 if (a->argc != 4)
02574 return CLI_SHOWUSAGE;
02575
02576 test_losspct = atoi(a->argv[3]);
02577
02578 return CLI_SUCCESS;
02579 }
02580
02581 #ifdef IAXTESTS
02582 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02583 {
02584 switch (cmd) {
02585 case CLI_INIT:
02586 e->command = "iax2 test late";
02587 e->usage =
02588 "Usage: iax2 test late <ms>\n"
02589 " For testing, count the next frame as <ms> ms late\n";
02590 return NULL;
02591 case CLI_GENERATE:
02592 return NULL;
02593 }
02594
02595 if (a->argc != 4)
02596 return CLI_SHOWUSAGE;
02597
02598 test_late = atoi(a->argv[3]);
02599
02600 return CLI_SUCCESS;
02601 }
02602
02603 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02604 {
02605 switch (cmd) {
02606 case CLI_INIT:
02607 e->command = "iax2 test resync";
02608 e->usage =
02609 "Usage: iax2 test resync <ms>\n"
02610 " For testing, adjust all future frames by <ms> ms\n";
02611 return NULL;
02612 case CLI_GENERATE:
02613 return NULL;
02614 }
02615
02616 if (a->argc != 4)
02617 return CLI_SHOWUSAGE;
02618
02619 test_resync = atoi(a->argv[3]);
02620
02621 return CLI_SUCCESS;
02622 }
02623
02624 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02625 {
02626 switch (cmd) {
02627 case CLI_INIT:
02628 e->command = "iax2 test jitter";
02629 e->usage =
02630 "Usage: iax2 test jitter <ms> <pct>\n"
02631 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
02632 " percentage of packets. If <pct> is not specified, adds\n"
02633 " jitter to all packets.\n";
02634 return NULL;
02635 case CLI_GENERATE:
02636 return NULL;
02637 }
02638
02639 if (a->argc < 4 || a->argc > 5)
02640 return CLI_SHOWUSAGE;
02641
02642 test_jit = atoi(a->argv[3]);
02643 if (a->argc == 5)
02644 test_jitpct = atoi(a->argv[4]);
02645
02646 return CLI_SUCCESS;
02647 }
02648 #endif
02649
02650
02651
02652 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02653 {
02654 int res = 0;
02655 if (peer->maxms) {
02656 if (peer->lastms < 0) {
02657 ast_copy_string(status, "UNREACHABLE", statuslen);
02658 } else if (peer->lastms > peer->maxms) {
02659 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02660 res = 1;
02661 } else if (peer->lastms) {
02662 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02663 res = 1;
02664 } else {
02665 ast_copy_string(status, "UNKNOWN", statuslen);
02666 }
02667 } else {
02668 ast_copy_string(status, "Unmonitored", statuslen);
02669 res = -1;
02670 }
02671 return res;
02672 }
02673
02674
02675 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02676 {
02677 char status[30];
02678 char cbuf[256];
02679 struct iax2_peer *peer;
02680 char codec_buf[512];
02681 int x = 0, codec = 0, load_realtime = 0;
02682
02683 switch (cmd) {
02684 case CLI_INIT:
02685 e->command = "iax2 show peer";
02686 e->usage =
02687 "Usage: iax2 show peer <name>\n"
02688 " Display details on specific IAX peer\n";
02689 return NULL;
02690 case CLI_GENERATE:
02691 return complete_iax2_show_peer(a->line, a->word, a->pos, a->n);
02692 }
02693
02694 if (a->argc < 4)
02695 return CLI_SHOWUSAGE;
02696
02697 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
02698
02699 peer = find_peer(a->argv[3], load_realtime);
02700 if (peer) {
02701 ast_cli(a->fd, "\n\n");
02702 ast_cli(a->fd, " * Name : %s\n", peer->name);
02703 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
02704 ast_cli(a->fd, " Context : %s\n", peer->context);
02705 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
02706 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
02707 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No");
02708 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02709 ast_cli(a->fd, " Expire : %d\n", peer->expire);
02710 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
02711 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));
02712 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02713 ast_cli(a->fd, " Username : %s\n", peer->username);
02714 ast_cli(a->fd, " Codecs : ");
02715 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02716 ast_cli(a->fd, "%s\n", codec_buf);
02717
02718 ast_cli(a->fd, " Codec Order : (");
02719 for(x = 0; x < 32 ; x++) {
02720 codec = ast_codec_pref_index(&peer->prefs,x);
02721 if(!codec)
02722 break;
02723 ast_cli(a->fd, "%s", ast_getformatname(codec));
02724 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02725 ast_cli(a->fd, "|");
02726 }
02727
02728 if (!x)
02729 ast_cli(a->fd, "none");
02730 ast_cli(a->fd, ")\n");
02731
02732 ast_cli(a->fd, " Status : ");
02733 peer_status(peer, status, sizeof(status));
02734 ast_cli(a->fd, "%s\n",status);
02735 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");
02736 ast_cli(a->fd, "\n");
02737 peer_unref(peer);
02738 } else {
02739 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
02740 ast_cli(a->fd, "\n");
02741 }
02742
02743 return CLI_SUCCESS;
02744 }
02745
02746 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02747 {
02748 int which = 0;
02749 struct iax2_peer *peer;
02750 char *res = NULL;
02751 int wordlen = strlen(word);
02752 struct ao2_iterator i;
02753
02754
02755 if (pos != 3)
02756 return NULL;
02757
02758 i = ao2_iterator_init(peers, 0);
02759 while ((peer = ao2_iterator_next(&i))) {
02760 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02761 res = ast_strdup(peer->name);
02762 peer_unref(peer);
02763 break;
02764 }
02765 peer_unref(peer);
02766 }
02767
02768 return res;
02769 }
02770
02771 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02772 {
02773 struct iax_frame *cur;
02774 int cnt = 0, dead = 0, final = 0;
02775
02776 switch (cmd) {
02777 case CLI_INIT:
02778 e->command = "iax2 show stats";
02779 e->usage =
02780 "Usage: iax2 show stats\n"
02781 " Display statistics on IAX channel driver.\n";
02782 return NULL;
02783 case CLI_GENERATE:
02784 return NULL;
02785 }
02786
02787 if (a->argc != 3)
02788 return CLI_SHOWUSAGE;
02789
02790 AST_LIST_LOCK(&frame_queue);
02791 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
02792 if (cur->retries < 0)
02793 dead++;
02794 if (cur->final)
02795 final++;
02796 cnt++;
02797 }
02798 AST_LIST_UNLOCK(&frame_queue);
02799
02800 ast_cli(a->fd, " IAX Statistics\n");
02801 ast_cli(a->fd, "---------------------\n");
02802 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02803 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
02804 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
02805 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02806
02807 trunk_timed = trunk_untimed = 0;
02808 if (trunk_maxmtu > trunk_nmaxmtu)
02809 trunk_nmaxmtu = trunk_maxmtu;
02810
02811 return CLI_SUCCESS;
02812 }
02813
02814
02815 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02816 {
02817 int mtuv;
02818
02819 switch (cmd) {
02820 case CLI_INIT:
02821 e->command = "iax2 set mtu";
02822 e->usage =
02823 "Usage: iax2 set mtu <value>\n"
02824 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
02825 " zero to disable. Disabling means that the operating system\n"
02826 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
02827 " packet exceeds the UDP payload size. This is substantially\n"
02828 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
02829 " greater for G.711 samples.\n";
02830 return NULL;
02831 case CLI_GENERATE:
02832 return NULL;
02833 }
02834
02835 if (a->argc != 4)
02836 return CLI_SHOWUSAGE;
02837 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
02838 mtuv = MAX_TRUNK_MTU;
02839 else
02840 mtuv = atoi(a->argv[3]);
02841
02842 if (mtuv == 0) {
02843 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
02844 global_max_trunk_mtu = 0;
02845 return CLI_SUCCESS;
02846 }
02847 if (mtuv < 172 || mtuv > 4000) {
02848 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
02849 return CLI_SHOWUSAGE;
02850 }
02851 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
02852 global_max_trunk_mtu = mtuv;
02853 return CLI_SUCCESS;
02854 }
02855
02856 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02857 {
02858 struct iax2_dpcache *dp = NULL;
02859 char tmp[1024], *pc = NULL;
02860 int s, x, y;
02861 struct timeval tv = ast_tvnow();
02862
02863 switch (cmd) {
02864 case CLI_INIT:
02865 e->command = "iax2 show cache";
02866 e->usage =
02867 "Usage: iax2 show cache\n"
02868 " Display currently cached IAX Dialplan results.\n";
02869 return NULL;
02870 case CLI_GENERATE:
02871 return NULL;
02872 }
02873
02874 AST_LIST_LOCK(&dpcache);
02875
02876 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02877
02878 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
02879 s = dp->expiry.tv_sec - tv.tv_sec;
02880 tmp[0] = '\0';
02881 if (dp->flags & CACHE_FLAG_EXISTS)
02882 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02883 if (dp->flags & CACHE_FLAG_NONEXISTENT)
02884 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02885 if (dp->flags & CACHE_FLAG_CANEXIST)
02886 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02887 if (dp->flags & CACHE_FLAG_PENDING)
02888 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02889 if (dp->flags & CACHE_FLAG_TIMEOUT)
02890 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02891 if (dp->flags & CACHE_FLAG_TRANSMITTED)
02892 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02893 if (dp->flags & CACHE_FLAG_MATCHMORE)
02894 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02895 if (dp->flags & CACHE_FLAG_UNKNOWN)
02896 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02897
02898 if (!ast_strlen_zero(tmp)) {
02899 tmp[strlen(tmp) - 1] = '\0';
02900 } else {
02901 ast_copy_string(tmp, "(none)", sizeof(tmp));
02902 }
02903 y = 0;
02904 pc = strchr(dp->peercontext, '@');
02905 if (!pc) {
02906 pc = dp->peercontext;
02907 } else {
02908 pc++;
02909 }
02910 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
02911 if (dp->waiters[x] > -1)
02912 y++;
02913 }
02914 if (s > 0) {
02915 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02916 } else {
02917 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02918 }
02919 }
02920
02921 AST_LIST_LOCK(&dpcache);
02922
02923 return CLI_SUCCESS;
02924 }
02925
02926 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02927
02928 static void unwrap_timestamp(struct iax_frame *fr)
02929 {
02930
02931
02932 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
02933 const int lower_mask = (1 << ts_shift) - 1;
02934 const int upper_mask = ~lower_mask;
02935 const int last_upper = iaxs[fr->callno]->last & upper_mask;
02936
02937 if ( (fr->ts & upper_mask) == last_upper ) {
02938 const int x = fr->ts - iaxs[fr->callno]->last;
02939 const int threshold = (ts_shift == 15) ? 25000 : 50000;
02940
02941 if (x < -threshold) {
02942
02943
02944
02945
02946 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
02947 if (iaxdebug)
02948 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
02949 } else if (x > threshold) {
02950
02951
02952
02953
02954 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
02955 if (iaxdebug)
02956 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
02957 }
02958 }
02959 }
02960
02961 static int get_from_jb(const void *p);
02962
02963 static void update_jbsched(struct chan_iax2_pvt *pvt)
02964 {
02965 int when;
02966
02967 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02968
02969 when = jb_next(pvt->jb) - when;
02970
02971 if (when <= 0) {
02972
02973 when = 1;
02974 }
02975
02976 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
02977 CALLNO_TO_PTR(pvt->callno));
02978 }
02979
02980 static void __get_from_jb(const void *p)
02981 {
02982 int callno = PTR_TO_CALLNO(p);
02983 struct chan_iax2_pvt *pvt = NULL;
02984 struct iax_frame *fr;
02985 jb_frame frame;
02986 int ret;
02987 long now;
02988 long next;
02989 struct timeval tv = ast_tvnow();
02990
02991
02992 ast_mutex_lock(&iaxsl[callno]);
02993 pvt = iaxs[callno];
02994 if (!pvt) {
02995
02996 ast_mutex_unlock(&iaxsl[callno]);
02997 return;
02998 }
02999
03000 pvt->jbid = -1;
03001
03002
03003
03004
03005 tv.tv_usec += 1000;
03006
03007 now = ast_tvdiff_ms(tv, pvt->rxcore);
03008
03009 if(now >= (next = jb_next(pvt->jb))) {
03010 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
03011 switch(ret) {
03012 case JB_OK:
03013 fr = frame.data;
03014 __do_deliver(fr);
03015
03016 pvt = iaxs[callno];
03017 break;
03018 case JB_INTERP:
03019 {
03020 struct ast_frame af = { 0, };
03021
03022
03023 af.frametype = AST_FRAME_VOICE;
03024 af.subclass = pvt->voiceformat;
03025 af.samples = frame.ms * 8;
03026 af.src = "IAX2 JB interpolation";
03027 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03028 af.offset = AST_FRIENDLY_OFFSET;
03029
03030
03031
03032 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03033 iax2_queue_frame(callno, &af);
03034
03035 pvt = iaxs[callno];
03036 }
03037 }
03038 break;
03039 case JB_DROP:
03040 iax2_frame_free(frame.data);
03041 break;
03042 case JB_NOFRAME:
03043 case JB_EMPTY:
03044
03045 break;
03046 default:
03047
03048 break;
03049 }
03050 }
03051 if (pvt)
03052 update_jbsched(pvt);
03053 ast_mutex_unlock(&iaxsl[callno]);
03054 }
03055
03056 static int get_from_jb(const void *data)
03057 {
03058 #ifdef SCHED_MULTITHREADED
03059 if (schedule_action(__get_from_jb, data))
03060 #endif
03061 __get_from_jb(data);
03062 return 0;
03063 }
03064
03065
03066
03067
03068
03069
03070
03071 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03072 {
03073 int type, len;
03074 int ret;
03075 int needfree = 0;
03076 struct ast_channel *owner = NULL;
03077 struct ast_channel *bridge = NULL;
03078
03079
03080 unwrap_timestamp(fr);
03081
03082
03083 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03084 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03085 else {
03086 #if 0
03087 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03088 #endif
03089 fr->af.delivery = ast_tv(0,0);
03090 }
03091
03092 type = JB_TYPE_CONTROL;
03093 len = 0;
03094
03095 if(fr->af.frametype == AST_FRAME_VOICE) {
03096 type = JB_TYPE_VOICE;
03097 len = ast_codec_get_samples(&fr->af) / 8;
03098 } else if(fr->af.frametype == AST_FRAME_CNG) {
03099 type = JB_TYPE_SILENCE;
03100 }
03101
03102 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03103 if (tsout)
03104 *tsout = fr->ts;
03105 __do_deliver(fr);
03106 return -1;
03107 }
03108
03109 if ((owner = iaxs[fr->callno]->owner))
03110 bridge = ast_bridged_channel(owner);
03111
03112
03113
03114 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03115 jb_frame frame;
03116
03117
03118 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03119 __do_deliver(frame.data);
03120
03121 if (!iaxs[fr->callno])
03122 return -1;
03123 }
03124
03125 jb_reset(iaxs[fr->callno]->jb);
03126
03127 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03128
03129
03130 if (tsout)
03131 *tsout = fr->ts;
03132 __do_deliver(fr);
03133 return -1;
03134 }
03135
03136
03137
03138 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03139 calc_rxstamp(iaxs[fr->callno],fr->ts));
03140 if (ret == JB_DROP) {
03141 needfree++;
03142 } else if (ret == JB_SCHED) {
03143 update_jbsched(iaxs[fr->callno]);
03144 }
03145 if (tsout)
03146 *tsout = fr->ts;
03147 if (needfree) {
03148
03149 iax2_frame_free(fr);
03150 return -1;
03151 }
03152 return 0;
03153 }
03154
03155 static int iax2_transmit(struct iax_frame *fr)
03156 {
03157
03158
03159
03160 fr->sentyet = 0;
03161 AST_LIST_LOCK(&frame_queue);
03162 AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
03163 AST_LIST_UNLOCK(&frame_queue);
03164
03165 if (netthreadid != AST_PTHREADT_NULL)
03166 pthread_kill(netthreadid, SIGURG);
03167 signal_condition(&sched_lock, &sched_cond);
03168 return 0;
03169 }
03170
03171
03172
03173 static int iax2_digit_begin(struct ast_channel *c, char digit)
03174 {
03175 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03176 }
03177
03178 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
03179 {
03180 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03181 }
03182
03183 static int iax2_sendtext(struct ast_channel *c, const char *text)
03184 {
03185
03186 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03187 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03188 }
03189
03190 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
03191 {
03192 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
03193 }
03194
03195 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
03196 {
03197 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03198 }
03199
03200 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
03201 {
03202 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03203 ast_mutex_lock(&iaxsl[callno]);
03204 if (iaxs[callno])
03205 iaxs[callno]->owner = newchan;
03206 else
03207 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
03208 ast_mutex_unlock(&iaxsl[callno]);
03209 return 0;
03210 }
03211
03212
03213
03214
03215
03216 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
03217 {
03218 struct ast_variable *var = NULL;
03219 struct ast_variable *tmp;
03220 struct iax2_peer *peer=NULL;
03221 time_t regseconds = 0, nowtime;
03222 int dynamic=0;
03223
03224 if (peername) {
03225 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
03226 if (!var && sin)
03227 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03228 } else if (sin) {
03229 char porta[25];
03230 sprintf(porta, "%d", ntohs(sin->sin_port));
03231 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03232 if (var) {
03233
03234 for (tmp = var; tmp; tmp = tmp->next) {
03235 if (!strcasecmp(tmp->name, "name"))
03236 peername = tmp->value;
03237 }
03238 }
03239 }
03240 if (!var && peername) {
03241 var = ast_load_realtime("iaxpeers", "name", peername, NULL);
03242
03243
03244
03245
03246
03247
03248 if (var && sin) {
03249 for (tmp = var; tmp; tmp = tmp->next) {
03250 if (!strcasecmp(tmp->name, "host")) {
03251 struct ast_hostent ahp;
03252 struct hostent *hp;
03253 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03254
03255 ast_variables_destroy(var);
03256 var = NULL;
03257 }
03258 break;
03259 }
03260 }
03261 }
03262 }
03263 if (!var)
03264 return NULL;
03265
03266 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
03267
03268 if (!peer) {
03269 ast_variables_destroy(var);
03270 return NULL;
03271 }
03272
03273 for (tmp = var; tmp; tmp = tmp->next) {
03274
03275 if (!strcasecmp(tmp->name, "type")) {
03276 if (strcasecmp(tmp->value, "friend") &&
03277 strcasecmp(tmp->value, "peer")) {
03278
03279 peer = peer_unref(peer);
03280 break;
03281 }
03282 } else if (!strcasecmp(tmp->name, "regseconds")) {
03283 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
03284 } else if (!strcasecmp(tmp->name, "ipaddr")) {
03285 inet_aton(tmp->value, &(peer->addr.sin_addr));
03286 } else if (!strcasecmp(tmp->name, "port")) {
03287 peer->addr.sin_port = htons(atoi(tmp->value));
03288 } else if (!strcasecmp(tmp->name, "host")) {
03289 if (!strcasecmp(tmp->value, "dynamic"))
03290 dynamic = 1;
03291 }
03292 }
03293
03294 ast_variables_destroy(var);
03295
03296 if (!peer)
03297 return NULL;
03298
03299 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03300 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
03301 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
03302 if (peer->expire > -1) {
03303 if (!ast_sched_del(sched, peer->expire)) {
03304 peer->expire = -1;
03305 peer_unref(peer);
03306 }
03307 }
03308 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
03309 if (peer->expire == -1)
03310 peer_unref(peer);
03311 }
03312 ao2_link(peers, peer);
03313 if (ast_test_flag(peer, IAX_DYNAMIC))
03314 reg_source_db(peer);
03315 } else {
03316 ast_set_flag(peer, IAX_TEMPONLY);
03317 }
03318
03319 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
03320 time(&nowtime);
03321 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
03322 memset(&peer->addr, 0, sizeof(peer->addr));
03323 realtime_update_peer(peer->name, &peer->addr, 0);
03324 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
03325 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03326 }
03327 else {
03328 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
03329 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03330 }
03331 }
03332
03333 return peer;
03334 }
03335
03336 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
03337 {
03338 struct ast_variable *var;
03339 struct ast_variable *tmp;
03340 struct iax2_user *user=NULL;
03341
03342 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
03343 if (!var)
03344 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
03345 if (!var && sin) {
03346 char porta[6];
03347 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
03348 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03349 if (!var)
03350 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
03351 }
03352 if (!var) {
03353 var = ast_load_realtime("iaxusers", "name", username, NULL);
03354
03355
03356
03357
03358
03359
03360 if (var) {
03361 for (tmp = var; tmp; tmp = tmp->next) {
03362 if (!strcasecmp(tmp->name, "host")) {
03363 struct ast_hostent ahp;
03364 struct hostent *hp;
03365 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03366
03367 ast_variables_destroy(var);
03368 var = NULL;
03369 }
03370 break;
03371 }
03372 }
03373 }
03374 }
03375 if (!var)
03376 return NULL;
03377
03378 tmp = var;
03379 while(tmp) {
03380
03381 if (!strcasecmp(tmp->name, "type")) {
03382 if (strcasecmp(tmp->value, "friend") &&
03383 strcasecmp(tmp->value, "user")) {
03384 return NULL;
03385 }
03386 }
03387 tmp = tmp->next;
03388 }
03389
03390 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03391
03392 ast_variables_destroy(var);
03393
03394 if (!user)
03395 return NULL;
03396
03397 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03398 ast_set_flag(user, IAX_RTCACHEFRIENDS);
03399 ao2_link(users, user);
03400 } else {
03401 ast_set_flag(user, IAX_TEMPONLY);
03402 }
03403
03404 return user;
03405 }
03406
03407 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
03408 {
03409 char port[10];
03410 char regseconds[20];
03411
03412 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03413 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03414 ast_update_realtime("iaxpeers", "name", peername,
03415 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
03416 "regseconds", regseconds, NULL);
03417 }
03418
03419 struct create_addr_info {
03420 int capability;
03421 unsigned int flags;
03422 int maxtime;
03423 int encmethods;
03424 int found;
03425 int sockfd;
03426 int adsi;
03427 char username[80];
03428 char secret[80];
03429 char outkey[80];
03430 char timezone[80];
03431 char prefs[32];
03432 char context[AST_MAX_CONTEXT];
03433 char peercontext[AST_MAX_CONTEXT];
03434 char mohinterpret[MAX_MUSICCLASS];
03435 char mohsuggest[MAX_MUSICCLASS];
03436 };
03437
03438 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03439 {
03440 struct iax2_peer *peer;
03441 int res = -1;
03442 struct ast_codec_pref ourprefs;
03443
03444 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03445 cai->sockfd = defaultsockfd;
03446 cai->maxtime = 0;
03447 sin->sin_family = AF_INET;
03448
03449 if (!(peer = find_peer(peername, 1))) {
03450 cai->found = 0;
03451 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
03452 ast_log(LOG_WARNING, "No such host: %s\n", peername);
03453 return -1;
03454 }
03455 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03456
03457
03458 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03459 if (c)
03460 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03461 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03462 return 0;
03463 }
03464
03465 cai->found = 1;
03466
03467
03468 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03469 goto return_unref;
03470
03471
03472 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03473 goto return_unref;
03474
03475 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03476 cai->maxtime = peer->maxms;
03477 cai->capability = peer->capability;
03478 cai->encmethods = peer->encmethods;
03479 cai->sockfd = peer->sockfd;
03480 cai->adsi = peer->adsi;
03481 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03482
03483 if (c) {
03484 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03485 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03486 }
03487 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03488 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03489 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03490 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03491 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03492 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03493 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03494 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03495 if (ast_strlen_zero(peer->dbsecret)) {
03496 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03497 } else {
03498 char *family;
03499 char *key = NULL;
03500
03501 family = ast_strdupa(peer->dbsecret);
03502 key = strchr(family, '/');
03503 if (key)
03504 *key++ = '\0';
03505 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03506 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03507 goto return_unref;
03508 }
03509 }
03510
03511 if (peer->addr.sin_addr.s_addr) {
03512 sin->sin_addr = peer->addr.sin_addr;
03513 sin->sin_port = peer->addr.sin_port;
03514 } else {
03515 sin->sin_addr = peer->defaddr.sin_addr;
03516 sin->sin_port = peer->defaddr.sin_port;
03517 }
03518
03519 res = 0;
03520
03521 return_unref:
03522 peer_unref(peer);
03523
03524 return res;
03525 }
03526
03527 static void __auto_congest(const void *nothing)
03528 {
03529 int callno = PTR_TO_CALLNO(nothing);
03530 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03531 ast_mutex_lock(&iaxsl[callno]);
03532 if (iaxs[callno]) {
03533 iaxs[callno]->initid = -1;
03534 iax2_queue_frame(callno, &f);
03535 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03536 }
03537 ast_mutex_unlock(&iaxsl[callno]);
03538 }
03539
03540 static int auto_congest(const void *data)
03541 {
03542 #ifdef SCHED_MULTITHREADED
03543 if (schedule_action(__auto_congest, data))
03544 #endif
03545 __auto_congest(data);
03546 return 0;
03547 }
03548
03549 static unsigned int iax2_datetime(const char *tz)
03550 {
03551 struct timeval t = ast_tvnow();
03552 struct ast_tm tm;
03553 unsigned int tmp;
03554 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
03555 tmp = (tm.tm_sec >> 1) & 0x1f;
03556 tmp |= (tm.tm_min & 0x3f) << 5;
03557 tmp |= (tm.tm_hour & 0x1f) << 11;
03558 tmp |= (tm.tm_mday & 0x1f) << 16;
03559 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
03560 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
03561 return tmp;
03562 }
03563
03564 struct parsed_dial_string {
03565 char *username;
03566 char *password;
03567 char *key;
03568 char *peer;
03569 char *port;
03570 char *exten;
03571 char *context;
03572 char *options;
03573 };
03574
03575 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03576 {
03577 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03578 .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX,
03579 .csub = compress_subclass(command) };
03580
03581 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03582 }
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601
03602 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03603 {
03604 if (ast_strlen_zero(data))
03605 return;
03606
03607 pds->peer = strsep(&data, "/");
03608 pds->exten = strsep(&data, "/");
03609 pds->options = data;
03610
03611 if (pds->exten) {
03612 data = pds->exten;
03613 pds->exten = strsep(&data, "@");
03614 pds->context = data;
03615 }
03616
03617 if (strchr(pds->peer, '@')) {
03618 data = pds->peer;
03619 pds->username = strsep(&data, "@");
03620 pds->peer = data;
03621 }
03622
03623 if (pds->username) {
03624 data = pds->username;
03625 pds->username = strsep(&data, ":");
03626 pds->password = data;
03627 }
03628
03629 data = pds->peer;
03630 pds->peer = strsep(&data, ":");
03631 pds->port = data;
03632
03633
03634
03635
03636 if (pds->password && (pds->password[0] == '[')) {
03637 pds->key = ast_strip_quoted(pds->password, "[", "]");
03638 pds->password = NULL;
03639 }
03640 }
03641
03642 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03643 {
03644 struct sockaddr_in sin;
03645 char *l=NULL, *n=NULL, *tmpstr;
03646 struct iax_ie_data ied;
03647 char *defaultrdest = "s";
03648 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03649 struct parsed_dial_string pds;
03650 struct create_addr_info cai;
03651 struct ast_var_t *var;
03652 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
03653 const char* osp_token_ptr;
03654 unsigned int osp_token_length;
03655 unsigned char osp_block_index;
03656 unsigned int osp_block_length;
03657 unsigned char osp_buffer[256];
03658
03659 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03660 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03661 return -1;
03662 }
03663
03664 memset(&cai, 0, sizeof(cai));
03665 cai.encmethods = iax2_encryption;
03666
03667 memset(&pds, 0, sizeof(pds));
03668 tmpstr = ast_strdupa(dest);
03669 parse_dial_string(tmpstr, &pds);
03670
03671 if (ast_strlen_zero(pds.peer)) {
03672 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03673 return -1;
03674 }
03675
03676 if (!pds.exten) {
03677 pds.exten = defaultrdest;
03678 }
03679
03680 if (create_addr(pds.peer, c, &sin, &cai)) {
03681 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03682 return -1;
03683 }
03684
03685 if (!pds.username && !ast_strlen_zero(cai.username))
03686 pds.username = cai.username;
03687 if (!pds.password && !ast_strlen_zero(cai.secret))
03688 pds.password = cai.secret;
03689 if (!pds.key && !ast_strlen_zero(cai.outkey))
03690 pds.key = cai.outkey;
03691 if (!pds.context && !ast_strlen_zero(cai.peercontext))
03692 pds.context = cai.peercontext;
03693
03694
03695 ast_copy_string(c->context, cai.context, sizeof(c->context));
03696
03697 if (pds.port)
03698 sin.sin_port = htons(atoi(pds.port));
03699
03700 l = c->cid.cid_num;
03701 n = c->cid.cid_name;
03702
03703
03704 memset(&ied, 0, sizeof(ied));
03705
03706
03707 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03708 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03709 if (pds.options && strchr(pds.options, 'a')) {
03710
03711 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03712 }
03713
03714 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03715
03716 if (l) {
03717 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03718 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03719 } else {
03720 if (n)
03721 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03722 else
03723 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03724 }
03725
03726 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03727 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03728
03729 if (n)
03730 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03731 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03732 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03733
03734 if (!ast_strlen_zero(c->language))
03735 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03736 if (!ast_strlen_zero(c->cid.cid_dnid))
03737 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03738 if (!ast_strlen_zero(c->cid.cid_rdnis))
03739 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03740
03741 if (pds.context)
03742 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03743
03744 if (pds.username)
03745 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03746
03747 if (cai.encmethods)
03748 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03749
03750 ast_mutex_lock(&iaxsl[callno]);
03751
03752 if (!ast_strlen_zero(c->context))
03753 ast_string_field_set(iaxs[callno], context, c->context);
03754
03755 if (pds.username)
03756 ast_string_field_set(iaxs[callno], username, pds.username);
03757
03758 iaxs[callno]->encmethods = cai.encmethods;
03759
03760 iaxs[callno]->adsi = cai.adsi;
03761
03762 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03763 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03764
03765 if (pds.key)
03766 ast_string_field_set(iaxs[callno], outkey, pds.key);
03767 if (pds.password)
03768 ast_string_field_set(iaxs[callno], secret, pds.password);
03769
03770 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03771 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03772 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03773 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03774
03775 if (iaxs[callno]->maxtime) {
03776
03777 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03778 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03779 } else if (autokill) {
03780 iaxs[callno]->pingtime = autokill / 2;
03781 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03782 }
03783
03784
03785 osp_token_ptr = iaxs[callno]->osptoken;
03786 if (!ast_strlen_zero(osp_token_ptr)) {
03787 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
03788 osp_block_index = 0;
03789 while (osp_token_length > 0) {
03790 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
03791 osp_buffer[0] = osp_block_index;
03792 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
03793 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
03794 osp_block_index++;
03795 osp_token_ptr += osp_block_length;
03796 osp_token_length -= osp_block_length;
03797 }
03798 } else
03799 ast_log(LOG_WARNING, "OSP token is too long\n");
03800 } else if (iaxdebug)
03801 ast_debug(1, "OSP token is undefined\n");
03802
03803
03804 iaxs[callno]->sockfd = cai.sockfd;
03805
03806
03807 if (variablestore) {
03808 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
03809 ast_debug(1, "Found an IAX variable store on this channel\n");
03810 AST_LIST_LOCK(variablelist);
03811 AST_LIST_TRAVERSE(variablelist, var, entries) {
03812 char tmp[256];
03813 int i;
03814 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
03815
03816 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
03817 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
03818 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
03819 }
03820 }
03821 AST_LIST_UNLOCK(variablelist);
03822 }
03823
03824
03825 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03826
03827 ast_mutex_unlock(&iaxsl[callno]);
03828 ast_setstate(c, AST_STATE_RINGING);
03829
03830 return 0;
03831 }
03832
03833 static int iax2_hangup(struct ast_channel *c)
03834 {
03835 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03836 struct iax_ie_data ied;
03837 int alreadygone;
03838 memset(&ied, 0, sizeof(ied));
03839 ast_mutex_lock(&iaxsl[callno]);
03840 if (callno && iaxs[callno]) {
03841 ast_debug(1, "We're hanging up %s now...\n", c->name);
03842 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03843
03844 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03845 if (!iaxs[callno]->error && !alreadygone) {
03846 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
03847 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
03848 }
03849 if (!iaxs[callno]) {
03850 ast_mutex_unlock(&iaxsl[callno]);
03851 return 0;
03852 }
03853 }
03854
03855 iax2_predestroy(callno);
03856
03857 if (iaxs[callno] && alreadygone) {
03858 ast_debug(1, "Really destroying %s now...\n", c->name);
03859 iax2_destroy(callno);
03860 } else if (iaxs[callno]) {
03861 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
03862 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
03863 iax2_destroy(callno);
03864 }
03865 }
03866 } else if (c->tech_pvt) {
03867
03868
03869
03870
03871 c->tech_pvt = NULL;
03872 }
03873 ast_mutex_unlock(&iaxsl[callno]);
03874 ast_verb(3, "Hungup '%s'\n", c->name);
03875 return 0;
03876 }
03877
03878
03879
03880
03881 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
03882 {
03883 unsigned short callno = pvt->callno;
03884
03885 if (!pvt->peercallno) {
03886
03887 int count = 10;
03888 while (count-- && pvt && !pvt->peercallno) {
03889 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03890 pvt = iaxs[callno];
03891 }
03892 if (!pvt->peercallno) {
03893 return -1;
03894 }
03895 }
03896
03897 return 0;
03898 }
03899
03900 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03901 {
03902 struct ast_option_header *h;
03903 int res;
03904
03905 switch (option) {
03906 case AST_OPTION_TXGAIN:
03907 case AST_OPTION_RXGAIN:
03908
03909 errno = ENOSYS;
03910 return -1;
03911 default:
03912 {
03913 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03914 struct chan_iax2_pvt *pvt;
03915
03916 ast_mutex_lock(&iaxsl[callno]);
03917 pvt = iaxs[callno];
03918
03919 if (wait_for_peercallno(pvt)) {
03920 ast_mutex_unlock(&iaxsl[callno]);
03921 return -1;
03922 }
03923
03924 ast_mutex_unlock(&iaxsl[callno]);
03925
03926 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
03927 return -1;
03928 }
03929
03930 h->flag = AST_OPTION_FLAG_REQUEST;
03931 h->option = htons(option);
03932 memcpy(h->data, data, datalen);
03933 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03934 AST_CONTROL_OPTION, 0, (unsigned char *) h,
03935 datalen + sizeof(*h), -1);
03936 ast_free(h);
03937 return res;
03938 }
03939 }
03940 }
03941
03942 static struct ast_frame *iax2_read(struct ast_channel *c)
03943 {
03944 ast_log(LOG_NOTICE, "I should never be called!\n");
03945 return &ast_null_frame;
03946 }
03947
03948 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03949 {
03950 int res;
03951 struct iax_ie_data ied0;
03952 struct iax_ie_data ied1;
03953 unsigned int transferid = (unsigned int)ast_random();
03954 memset(&ied0, 0, sizeof(ied0));
03955 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03956 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03957 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03958
03959 memset(&ied1, 0, sizeof(ied1));
03960 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03961 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03962 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03963
03964 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03965 if (res)
03966 return -1;
03967 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03968 if (res)
03969 return -1;
03970 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03971 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03972 return 0;
03973 }
03974
03975 static void lock_both(unsigned short callno0, unsigned short callno1)
03976 {
03977 ast_mutex_lock(&iaxsl[callno0]);
03978 while (ast_mutex_trylock(&iaxsl[callno1])) {
03979 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03980 }
03981 }
03982
03983 static void unlock_both(unsigned short callno0, unsigned short callno1)
03984 {
03985 ast_mutex_unlock(&iaxsl[callno1]);
03986 ast_mutex_unlock(&iaxsl[callno0]);
03987 }
03988
03989 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)
03990 {
03991 struct ast_channel *cs[3];
03992 struct ast_channel *who, *other;
03993 int to = -1;
03994 int res = -1;
03995 int transferstarted=0;
03996 struct ast_frame *f;
03997 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03998 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03999 struct timeval waittimer = {0, 0}, tv;
04000
04001
04002 if (timeoutms > 0) {
04003 return AST_BRIDGE_FAILED;
04004 }
04005
04006 timeoutms = -1;
04007
04008 lock_both(callno0, callno1);
04009 if (!iaxs[callno0] || !iaxs[callno1]) {
04010 unlock_both(callno0, callno1);
04011 return AST_BRIDGE_FAILED;
04012 }
04013
04014 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
04015 iaxs[callno0]->bridgecallno = callno1;
04016 iaxs[callno1]->bridgecallno = callno0;
04017 }
04018
04019 if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) {
04020 transferstarted = 1;
04021 }
04022 unlock_both(callno0, callno1);
04023
04024
04025 cs[0] = c0;
04026 cs[1] = c1;
04027 for (;;) {
04028
04029 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
04030 ast_verb(3, "Can't masquerade, we're different...\n");
04031
04032 if (c0->tech == &iax2_tech) {
04033 ast_mutex_lock(&iaxsl[callno0]);
04034 iaxs[callno0]->bridgecallno = 0;
04035 ast_mutex_unlock(&iaxsl[callno0]);
04036 }
04037 if (c1->tech == &iax2_tech) {
04038 ast_mutex_lock(&iaxsl[callno1]);
04039 iaxs[callno1]->bridgecallno = 0;
04040 ast_mutex_unlock(&iaxsl[callno1]);
04041 }
04042 return AST_BRIDGE_FAILED_NOWARN;
04043 }
04044 if (c0->nativeformats != c1->nativeformats) {
04045 char buf0[255];
04046 char buf1[255];
04047 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
04048 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
04049 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
04050
04051 lock_both(callno0, callno1);
04052 if (iaxs[callno0])
04053 iaxs[callno0]->bridgecallno = 0;
04054 if (iaxs[callno1])
04055 iaxs[callno1]->bridgecallno = 0;
04056 unlock_both(callno0, callno1);
04057 return AST_BRIDGE_FAILED_NOWARN;
04058 }
04059
04060 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
04061
04062 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
04063 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
04064 ast_log(LOG_WARNING, "Unable to start the transfer\n");
04065 transferstarted = 1;
04066 }
04067 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
04068
04069 tv = ast_tvnow();
04070 if (ast_tvzero(waittimer)) {
04071 waittimer = tv;
04072 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
04073 c0->_softhangup |= AST_SOFTHANGUP_DEV;
04074 c1->_softhangup |= AST_SOFTHANGUP_DEV;
04075 *fo = NULL;
04076 *rc = c0;
04077 res = AST_BRIDGE_COMPLETE;
04078 break;
04079 }
04080 }
04081 to = 1000;
04082 who = ast_waitfor_n(cs, 2, &to);
04083 if (timeoutms > -1) {
04084 timeoutms -= (1000 - to);
04085 if (timeoutms < 0)
04086 timeoutms = 0;
04087 }
04088 if (!who) {
04089 if (!timeoutms) {
04090 res = AST_BRIDGE_RETRY;
04091 break;
04092 }
04093 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
04094 res = AST_BRIDGE_FAILED;
04095 break;
04096 }
04097 continue;
04098 }
04099 f = ast_read(who);
04100 if (!f) {
04101 *fo = NULL;
04102 *rc = who;
04103 res = AST_BRIDGE_COMPLETE;
04104 break;
04105 }
04106 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
04107 *fo = f;
04108 *rc = who;
04109 res = AST_BRIDGE_COMPLETE;
04110 break;
04111 }
04112 other = (who == c0) ? c1 : c0;
04113 if ((f->frametype == AST_FRAME_VOICE) ||
04114 (f->frametype == AST_FRAME_TEXT) ||
04115 (f->frametype == AST_FRAME_VIDEO) ||
04116 (f->frametype == AST_FRAME_IMAGE) ||
04117 (f->frametype == AST_FRAME_DTMF) ||
04118 (f->frametype == AST_FRAME_CONTROL)) {
04119
04120
04121
04122 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
04123 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
04124 *rc = who;
04125 *fo = f;
04126 res = AST_BRIDGE_COMPLETE;
04127
04128 break;
04129 }
04130
04131 ast_write(other, f);
04132 }
04133 ast_frfree(f);
04134
04135 cs[2] = cs[0];
04136 cs[0] = cs[1];
04137 cs[1] = cs[2];
04138 }
04139 lock_both(callno0, callno1);
04140 if(iaxs[callno0])
04141 iaxs[callno0]->bridgecallno = 0;
04142 if(iaxs[callno1])
04143 iaxs[callno1]->bridgecallno = 0;
04144 unlock_both(callno0, callno1);
04145 return res;
04146 }
04147
04148 static int iax2_answer(struct ast_channel *c)
04149 {
04150 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04151 ast_debug(1, "Answering IAX2 call\n");
04152 ast_mutex_lock(&iaxsl[callno]);
04153 if (iaxs[callno])
04154 iax2_ami_channelupdate(iaxs[callno]);
04155 ast_mutex_unlock(&iaxsl[callno]);
04156 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
04157 }
04158
04159 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
04160 {
04161 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04162 struct chan_iax2_pvt *pvt;
04163 int res = 0;
04164
04165 if (iaxdebug)
04166 ast_debug(1, "Indicating condition %d\n", condition);
04167
04168 ast_mutex_lock(&iaxsl[callno]);
04169 pvt = iaxs[callno];
04170
04171 if (wait_for_peercallno(pvt)) {
04172 res = -1;
04173 goto done;
04174 }
04175
04176 switch (condition) {
04177 case AST_CONTROL_HOLD:
04178 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04179 ast_moh_start(c, data, pvt->mohinterpret);
04180 goto done;
04181 }
04182 break;
04183 case AST_CONTROL_UNHOLD:
04184 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04185 ast_moh_stop(c);
04186 goto done;
04187 }
04188 }
04189
04190 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
04191
04192 done:
04193 ast_mutex_unlock(&iaxsl[callno]);
04194
04195 return res;
04196 }
04197
04198 static int iax2_transfer(struct ast_channel *c, const char *dest)
04199 {
04200 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04201 struct iax_ie_data ied = { "", };
04202 char tmp[256], *context;
04203 ast_copy_string(tmp, dest, sizeof(tmp));
04204 context = strchr(tmp, '@');
04205 if (context) {
04206 *context = '\0';
04207 context++;
04208 }
04209 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
04210 if (context)
04211 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
04212 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
04213 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
04214 }
04215
04216 static int iax2_getpeertrunk(struct sockaddr_in sin)
04217 {
04218 struct iax2_peer *peer;
04219 int res = 0;
04220 struct ao2_iterator i;
04221
04222 i = ao2_iterator_init(peers, 0);
04223 while ((peer = ao2_iterator_next(&i))) {
04224 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
04225 (peer->addr.sin_port == sin.sin_port)) {
04226 res = ast_test_flag(peer, IAX_TRUNK);
04227 peer_unref(peer);
04228 break;
04229 }
04230 peer_unref(peer);
04231 }
04232
04233 return res;
04234 }
04235
04236
04237 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
04238 {
04239 struct ast_channel *tmp;
04240 struct chan_iax2_pvt *i;
04241 struct ast_variable *v = NULL;
04242
04243 if (!(i = iaxs[callno])) {
04244 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
04245 return NULL;
04246 }
04247
04248
04249 ast_mutex_unlock(&iaxsl[callno]);
04250 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
04251 ast_mutex_lock(&iaxsl[callno]);
04252 if (i != iaxs[callno]) {
04253 if (tmp) {
04254
04255 ast_mutex_unlock(&iaxsl[callno]);
04256 ast_channel_free(tmp);
04257 ast_mutex_lock(&iaxsl[callno]);
04258 }
04259 return NULL;
04260 }
04261 iax2_ami_channelupdate(i);
04262 if (!tmp)
04263 return NULL;
04264 tmp->tech = &iax2_tech;
04265
04266 tmp->nativeformats = capability;
04267 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
04268 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
04269 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
04270
04271
04272
04273 if (!ast_strlen_zero(i->ani))
04274 tmp->cid.cid_ani = ast_strdup(i->ani);
04275 else
04276 tmp->cid.cid_ani = ast_strdup(i->cid_num);
04277 tmp->cid.cid_dnid = ast_strdup(i->dnid);
04278 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04279 tmp->cid.cid_pres = i->calling_pres;
04280 tmp->cid.cid_ton = i->calling_ton;
04281 tmp->cid.cid_tns = i->calling_tns;
04282 if (!ast_strlen_zero(i->language))
04283 ast_string_field_set(tmp, language, i->language);
04284 if (!ast_strlen_zero(i->accountcode))
04285 ast_string_field_set(tmp, accountcode, i->accountcode);
04286 if (i->amaflags)
04287 tmp->amaflags = i->amaflags;
04288 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04289 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
04290 if (i->adsi)
04291 tmp->adsicpe = i->peeradsicpe;
04292 else
04293 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04294 i->owner = tmp;
04295 i->capability = capability;
04296
04297
04298 if (i->vars) {
04299 for (v = i->vars ; v ; v = v->next)
04300 pbx_builtin_setvar_helper(tmp, v->name, v->value);
04301 }
04302 if (i->iaxvars) {
04303 struct ast_datastore *variablestore;
04304 struct ast_variable *var, *prev = NULL;
04305 AST_LIST_HEAD(, ast_var_t) *varlist;
04306 ast_debug(1, "Loading up the channel with IAXVARs\n");
04307 varlist = ast_calloc(1, sizeof(*varlist));
04308 variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
04309 if (variablestore && varlist) {
04310 variablestore->data = varlist;
04311 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
04312 AST_LIST_HEAD_INIT(varlist);
04313 for (var = i->iaxvars; var; var = var->next) {
04314 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
04315 if (prev)
04316 ast_free(prev);
04317 prev = var;
04318 if (!newvar) {
04319
04320 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
04321 } else {
04322 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
04323 }
04324 }
04325 if (prev)
04326 ast_free(prev);
04327 i->iaxvars = NULL;
04328 ast_channel_datastore_add(i->owner, variablestore);
04329 } else {
04330 if (variablestore) {
04331 ast_channel_datastore_free(variablestore);
04332 }
04333 if (varlist) {
04334 ast_free(varlist);
04335 }
04336 }
04337 }
04338
04339 if (state != AST_STATE_DOWN) {
04340 if (ast_pbx_start(tmp)) {
04341 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04342 ast_hangup(tmp);
04343 i->owner = NULL;
04344 return NULL;
04345 }
04346 }
04347
04348 ast_module_ref(ast_module_info->self);
04349 return tmp;
04350 }
04351
04352 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
04353 {
04354 unsigned long int mssincetx;
04355 long int ms, pred;
04356
04357 tpeer->trunkact = *tv;
04358 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
04359 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
04360
04361 tpeer->txtrunktime = *tv;
04362 tpeer->lastsent = 999999;
04363 }
04364
04365 tpeer->lasttxtime = *tv;
04366
04367
04368 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
04369
04370 pred = tpeer->lastsent + sampms;
04371 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
04372 ms = pred;
04373
04374
04375 if (ms == tpeer->lastsent)
04376 ms = tpeer->lastsent + 1;
04377 tpeer->lastsent = ms;
04378 return ms;
04379 }
04380
04381 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
04382 {
04383 long ms;
04384 if (ast_tvzero(iaxs[callno]->rxcore)) {
04385
04386 iaxs[callno]->rxcore = ast_tvnow();
04387
04388 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
04389 }
04390
04391 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
04392
04393 return ms + ts;
04394 }
04395
04396 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
04397 {
04398 int ms;
04399 int voice = 0;
04400 int genuine = 0;
04401 int adjust;
04402 struct timeval *delivery = NULL;
04403
04404
04405
04406
04407
04408
04409
04410
04411 if (f) {
04412 if (f->frametype == AST_FRAME_VOICE) {
04413 voice = 1;
04414 delivery = &f->delivery;
04415 } else if (f->frametype == AST_FRAME_IAX) {
04416 genuine = 1;
04417 } else if (f->frametype == AST_FRAME_CNG) {
04418 p->notsilenttx = 0;
04419 }
04420 }
04421 if (ast_tvzero(p->offset)) {
04422 p->offset = ast_tvnow();
04423
04424 p->offset.tv_usec -= p->offset.tv_usec % 20000;
04425 }
04426
04427 if (ts)
04428 return ts;
04429
04430 if (delivery && !ast_tvzero(*delivery)) {
04431 ms = ast_tvdiff_ms(*delivery, p->offset);
04432 if (ms < 0) {
04433 ms = 0;
04434 }
04435 if (iaxdebug)
04436 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
04437 } else {
04438 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
04439 if (ms < 0)
04440 ms = 0;
04441 if (voice) {
04442
04443 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455
04456
04457
04458
04459
04460
04461
04462 adjust = (ms - p->nextpred);
04463 if (adjust < 0)
04464 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
04465 else if (adjust > 0)
04466 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
04467
04468 if (!p->nextpred) {
04469 p->nextpred = ms;
04470 if (p->nextpred <= p->lastsent)
04471 p->nextpred = p->lastsent + 3;
04472 }
04473 ms = p->nextpred;
04474 } else {
04475
04476
04477
04478
04479
04480
04481
04482
04483
04484 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
04485 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
04486 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
04487
04488 if (f->samples >= 8)
04489 {
04490 int diff = ms % (f->samples / 8);
04491 if (diff)
04492 ms += f->samples/8 - diff;
04493 }
04494
04495 p->nextpred = ms;
04496 p->notsilenttx = 1;
04497 }
04498 } else if ( f->frametype == AST_FRAME_VIDEO ) {
04499
04500
04501
04502
04503
04504
04505
04506
04507 if ( (unsigned int)ms < p->lastsent )
04508 ms = p->lastsent;
04509 } else {
04510
04511
04512 if (genuine) {
04513
04514 if (ms <= p->lastsent)
04515 ms = p->lastsent + 3;
04516 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
04517
04518 ms = p->lastsent + 3;
04519 }
04520 }
04521 }
04522 p->lastsent = ms;
04523 if (voice)
04524 p->nextpred = p->nextpred + f->samples / 8;
04525 return ms;
04526 }
04527
04528 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
04529 {
04530
04531
04532 int ms;
04533 #ifdef IAXTESTS
04534 int jit;
04535 #endif
04536
04537 if (ast_tvzero(p->rxcore)) {
04538 p->rxcore = ast_tvnow();
04539 if (iaxdebug)
04540 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04541 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04542 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04543 #if 1
04544 if (iaxdebug)
04545 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04546 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04547 #endif
04548 }
04549
04550 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04551 #ifdef IAXTESTS
04552 if (test_jit) {
04553 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04554 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04555 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04556 jit = -jit;
04557 ms += jit;
04558 }
04559 }
04560 if (test_late) {
04561 ms += test_late;
04562 test_late = 0;
04563 }
04564 #endif
04565 return ms;
04566 }
04567
04568 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04569 {
04570 struct iax2_trunk_peer *tpeer = NULL;
04571
04572
04573 AST_LIST_LOCK(&tpeers);
04574
04575 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
04576 if (!inaddrcmp(&tpeer->addr, sin)) {
04577 ast_mutex_lock(&tpeer->lock);
04578 break;
04579 }
04580 }
04581
04582 if (!tpeer) {
04583 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04584 ast_mutex_init(&tpeer->lock);
04585 tpeer->lastsent = 9999;
04586 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04587 tpeer->trunkact = ast_tvnow();
04588 ast_mutex_lock(&tpeer->lock);
04589 tpeer->sockfd = fd;
04590 #ifdef SO_NO_CHECK
04591 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04592 #endif
04593 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04594 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
04595 }
04596 }
04597
04598 AST_LIST_UNLOCK(&tpeers);
04599
04600 return tpeer;
04601 }
04602
04603 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04604 {
04605 struct ast_frame *f;
04606 struct iax2_trunk_peer *tpeer;
04607 void *tmp, *ptr;
04608 struct timeval now;
04609 int res;
04610 struct ast_iax2_meta_trunk_entry *met;
04611 struct ast_iax2_meta_trunk_mini *mtm;
04612
04613 f = &fr->af;
04614 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04615 if (tpeer) {
04616 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04617
04618 if (tpeer->trunkdataalloc < trunkmaxsize) {
04619 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04620 ast_mutex_unlock(&tpeer->lock);
04621 return -1;
04622 }
04623
04624 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04625 tpeer->trunkdata = tmp;
04626 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);
04627 } else {
04628 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));
04629 ast_mutex_unlock(&tpeer->lock);
04630 return -1;
04631 }
04632 }
04633
04634
04635 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04636 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04637 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04638 mtm->len = htons(f->datalen);
04639 mtm->mini.callno = htons(pvt->callno);
04640 mtm->mini.ts = htons(0xffff & fr->ts);
04641 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04642 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04643 } else {
04644 met = (struct ast_iax2_meta_trunk_entry *)ptr;
04645
04646 met->callno = htons(pvt->callno);
04647 met->len = htons(f->datalen);
04648
04649 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04650 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04651 }
04652
04653 memcpy(ptr, f->data, f->datalen);
04654 tpeer->trunkdatalen += f->datalen;
04655
04656 tpeer->calls++;
04657
04658
04659 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
04660 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
04661
04662
04663 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
04664 now = ast_tvnow();
04665 res = send_trunk(tpeer, &now);
04666 trunk_untimed ++;
04667 }
04668
04669 ast_mutex_unlock(&tpeer->lock);
04670 }
04671 return 0;
04672 }
04673
04674
04675
04676 static void build_rand_pad(unsigned char *buf, ssize_t len)
04677 {
04678 long tmp;
04679 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
04680 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
04681 buf += sizeof(tmp);
04682 len -= sizeof(tmp);
04683 }
04684 }
04685
04686 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04687 {
04688 build_ecx_key(digest, pvt);
04689 ast_aes_decrypt_key(digest, &pvt->dcx);
04690 }
04691
04692 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04693 {
04694
04695
04696
04697 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
04698 ast_aes_encrypt_key(digest, &pvt->ecx);
04699 ast_aes_decrypt_key(digest, &pvt->mydcx);
04700 }
04701
04702 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
04703 {
04704 #if 0
04705
04706 int x;
04707 if (len % 16)
04708 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04709 for (x=0;x<len;x++)
04710 dst[x] = src[x] ^ 0xff;
04711 #else
04712 unsigned char lastblock[16] = { 0 };
04713 int x;
04714 while(len > 0) {
04715 ast_aes_decrypt(src, dst, dcx);
04716 for (x=0;x<16;x++)
04717 dst[x] ^= lastblock[x];
04718 memcpy(lastblock, src, sizeof(lastblock));
04719 dst += 16;
04720 src += 16;
04721 len -= 16;
04722 }
04723 #endif
04724 }
04725
04726 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
04727 {
04728 #if 0
04729
04730 int x;
04731 if (len % 16)
04732 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04733 for (x=0;x<len;x++)
04734 dst[x] = src[x] ^ 0xff;
04735 #else
04736 unsigned char curblock[16] = { 0 };
04737 int x;
04738 while(len > 0) {
04739 for (x=0;x<16;x++)
04740 curblock[x] ^= src[x];
04741 ast_aes_encrypt(curblock, dst, ecx);
04742 memcpy(curblock, dst, sizeof(curblock));
04743 dst += 16;
04744 src += 16;
04745 len -= 16;
04746 }
04747 #endif
04748 }
04749
04750 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04751 {
04752 int padding;
04753 unsigned char *workspace;
04754
04755 workspace = alloca(*datalen);
04756 memset(f, 0, sizeof(*f));
04757 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04758 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04759 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04760 return -1;
04761
04762 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04763
04764 padding = 16 + (workspace[15] & 0x0f);
04765 if (iaxdebug)
04766 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04767 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04768 return -1;
04769
04770 *datalen -= padding;
04771 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04772 f->frametype = fh->type;
04773 if (f->frametype == AST_FRAME_VIDEO) {
04774 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04775 } else {
04776 f->subclass = uncompress_subclass(fh->csub);
04777 }
04778 } else {
04779 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04780 if (iaxdebug)
04781 ast_debug(1, "Decoding mini with length %d\n", *datalen);
04782 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04783 return -1;
04784
04785 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04786 padding = 16 + (workspace[15] & 0x0f);
04787 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04788 return -1;
04789 *datalen -= padding;
04790 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04791 }
04792 return 0;
04793 }
04794
04795 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04796 {
04797 int padding;
04798 unsigned char *workspace;
04799 workspace = alloca(*datalen + 32);
04800 if (!workspace)
04801 return -1;
04802 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04803 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04804 if (iaxdebug)
04805 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04806 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04807 padding = 16 + (padding & 0xf);
04808 memcpy(workspace, poo, padding);
04809 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04810 workspace[15] &= 0xf0;
04811 workspace[15] |= (padding & 0xf);
04812 if (iaxdebug)
04813 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
04814 *datalen += padding;
04815 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04816 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04817 memcpy(poo, workspace + *datalen - 32, 32);
04818 } else {
04819 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04820 if (iaxdebug)
04821 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
04822 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04823 padding = 16 + (padding & 0xf);
04824 memcpy(workspace, poo, padding);
04825 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04826 workspace[15] &= 0xf0;
04827 workspace[15] |= (padding & 0x0f);
04828 *datalen += padding;
04829 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04830 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04831 memcpy(poo, workspace + *datalen - 32, 32);
04832 }
04833 return 0;
04834 }
04835
04836 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04837 {
04838 int res=-1;
04839 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04840
04841 struct MD5Context md5;
04842 unsigned char digest[16];
04843 char *tmppw, *stringp;
04844
04845 tmppw = ast_strdupa(iaxs[callno]->secret);
04846 stringp = tmppw;
04847 while ((tmppw = strsep(&stringp, ";"))) {
04848 MD5Init(&md5);
04849 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04850 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04851 MD5Final(digest, &md5);
04852 build_encryption_keys(digest, iaxs[callno]);
04853 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04854 if (!res) {
04855 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04856 break;
04857 }
04858 }
04859 } else
04860 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04861 return res;
04862 }
04863
04864 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04865 {
04866
04867
04868
04869 struct ast_iax2_full_hdr *fh;
04870 struct ast_iax2_mini_hdr *mh;
04871 struct ast_iax2_video_hdr *vh;
04872 struct {
04873 struct iax_frame fr2;
04874 unsigned char buffer[4096];
04875 } frb;
04876 struct iax_frame *fr;
04877 int res;
04878 int sendmini=0;
04879 unsigned int lastsent;
04880 unsigned int fts;
04881
04882 frb.fr2.afdatalen = sizeof(frb.buffer);
04883
04884 if (!pvt) {
04885 ast_log(LOG_WARNING, "No private structure for packet?\n");
04886 return -1;
04887 }
04888
04889 lastsent = pvt->lastsent;
04890
04891
04892 fts = calc_timestamp(pvt, ts, f);
04893
04894
04895
04896
04897 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04898 return 0;
04899
04900
04901 if ((ast_test_flag(pvt, IAX_TRUNK) ||
04902 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04903 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04904 &&
04905 (f->frametype == AST_FRAME_VOICE)
04906 &&
04907 (f->subclass == pvt->svoiceformat)
04908 ) {
04909
04910 now = 1;
04911
04912 sendmini = 1;
04913 }
04914 if ( f->frametype == AST_FRAME_VIDEO ) {
04915
04916
04917
04918
04919
04920 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04921 ((f->subclass & ~0x1) == pvt->svideoformat)
04922 ) {
04923 now = 1;
04924 sendmini = 1;
04925 } else {
04926 now = 0;
04927 sendmini = 0;
04928 }
04929 pvt->lastvsent = fts;
04930 }
04931 if (f->frametype == AST_FRAME_IAX) {
04932
04933 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX;
04934 if (!pvt->first_iax_message) {
04935 pvt->first_iax_message = pvt->last_iax_message;
04936 }
04937 }
04938
04939 if (now) {
04940 fr = &frb.fr2;
04941 } else
04942 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
04943 if (!fr) {
04944 ast_log(LOG_WARNING, "Out of memory\n");
04945 return -1;
04946 }
04947
04948 iax_frame_wrap(fr, f);
04949
04950 fr->ts = fts;
04951 fr->callno = pvt->callno;
04952 fr->transfer = transfer;
04953 fr->final = final;
04954 fr->encmethods = 0;
04955 if (!sendmini) {
04956
04957 if (seqno > -1)
04958 fr->oseqno = seqno;
04959 else
04960 fr->oseqno = pvt->oseqno++;
04961 fr->iseqno = pvt->iseqno;
04962 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04963 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04964 fh->ts = htonl(fr->ts);
04965 fh->oseqno = fr->oseqno;
04966 if (transfer) {
04967 fh->iseqno = 0;
04968 } else
04969 fh->iseqno = fr->iseqno;
04970
04971 if (!transfer)
04972 pvt->aseqno = fr->iseqno;
04973 fh->type = fr->af.frametype & 0xFF;
04974 if (fr->af.frametype == AST_FRAME_VIDEO)
04975 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04976 else
04977 fh->csub = compress_subclass(fr->af.subclass);
04978 if (transfer) {
04979 fr->dcallno = pvt->transfercallno;
04980 } else
04981 fr->dcallno = pvt->peercallno;
04982 fh->dcallno = htons(fr->dcallno);
04983 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04984 fr->data = fh;
04985 fr->retries = 0;
04986
04987 fr->retrytime = pvt->pingtime * 2;
04988 if (fr->retrytime < MIN_RETRY_TIME)
04989 fr->retrytime = MIN_RETRY_TIME;
04990 if (fr->retrytime > MAX_RETRY_TIME)
04991 fr->retrytime = MAX_RETRY_TIME;
04992
04993 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04994 fr->retries = -1;
04995 else if (f->frametype == AST_FRAME_VOICE)
04996 pvt->svoiceformat = f->subclass;
04997 else if (f->frametype == AST_FRAME_VIDEO)
04998 pvt->svideoformat = f->subclass & ~0x1;
04999 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05000 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05001 if (iaxdebug) {
05002 if (fr->transfer)
05003 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05004 else
05005 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05006 }
05007 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
05008 fr->encmethods = pvt->encmethods;
05009 fr->ecx = pvt->ecx;
05010 fr->mydcx = pvt->mydcx;
05011 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
05012 } else
05013 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05014 }
05015
05016 if (now) {
05017 res = send_packet(fr);
05018 } else
05019 res = iax2_transmit(fr);
05020 } else {
05021 if (ast_test_flag(pvt, IAX_TRUNK)) {
05022 iax2_trunk_queue(pvt, fr);
05023 res = 0;
05024 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
05025
05026 fr->oseqno = -1;
05027 fr->iseqno = -1;
05028 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
05029 vh->zeros = 0;
05030 vh->callno = htons(0x8000 | fr->callno);
05031 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
05032 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
05033 fr->data = vh;
05034 fr->retries = -1;
05035 res = send_packet(fr);
05036 } else {
05037
05038 fr->oseqno = -1;
05039 fr->iseqno = -1;
05040
05041 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
05042 mh->callno = htons(fr->callno);
05043 mh->ts = htons(fr->ts & 0xFFFF);
05044 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
05045 fr->data = mh;
05046 fr->retries = -1;
05047 if (pvt->transferring == TRANSFER_MEDIAPASS)
05048 fr->transfer = 1;
05049 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05050 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05051 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
05052 } else
05053 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05054 }
05055 res = send_packet(fr);
05056 }
05057 }
05058 return res;
05059 }
05060
05061 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05062 {
05063 regex_t regexbuf;
05064 int havepattern = 0;
05065
05066 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
05067 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
05068
05069 struct iax2_user *user = NULL;
05070 char auth[90];
05071 char *pstr = "";
05072 struct ao2_iterator i;
05073
05074 switch (cmd) {
05075 case CLI_INIT:
05076 e->command = "iax2 show users [like]";
05077 e->usage =
05078 "Usage: iax2 show users [like <pattern>]\n"
05079 " Lists all known IAX2 users.\n"
05080 " Optional regular expression pattern is used to filter the user list.\n";
05081 return NULL;
05082 case CLI_GENERATE:
05083 return NULL;
05084 }
05085
05086 switch (a->argc) {
05087 case 5:
05088 if (!strcasecmp(a->argv[3], "like")) {
05089 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
05090 return CLI_SHOWUSAGE;
05091 havepattern = 1;
05092 } else
05093 return CLI_SHOWUSAGE;
05094 case 3:
05095 break;
05096 default:
05097 return CLI_SHOWUSAGE;
05098 }
05099
05100 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
05101 i = ao2_iterator_init(users, 0);
05102 for (user = ao2_iterator_next(&i); user;
05103 user_unref(user), user = ao2_iterator_next(&i)) {
05104 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
05105 continue;
05106
05107 if (!ast_strlen_zero(user->secret)) {
05108 ast_copy_string(auth,user->secret, sizeof(auth));
05109 } else if (!ast_strlen_zero(user->inkeys)) {
05110 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
05111 } else
05112 ast_copy_string(auth, "-no secret-", sizeof(auth));
05113
05114 if(ast_test_flag(user,IAX_CODEC_NOCAP))
05115 pstr = "REQ Only";
05116 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
05117 pstr = "Disabled";
05118 else
05119 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
05120
05121 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
05122 user->contexts ? user->contexts->context : context,
05123 user->ha ? "Yes" : "No", pstr);
05124 }
05125
05126 if (havepattern)
05127 regfree(®exbuf);
05128
05129 return CLI_SUCCESS;
05130 #undef FORMAT
05131 #undef FORMAT2
05132 }
05133
05134 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
05135 {
05136 regex_t regexbuf;
05137 int havepattern = 0;
05138 int total_peers = 0;
05139 int online_peers = 0;
05140 int offline_peers = 0;
05141 int unmonitored_peers = 0;
05142 struct ao2_iterator i;
05143
05144 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
05145 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
05146
05147 struct iax2_peer *peer = NULL;
05148 char name[256];
05149 int registeredonly=0;
05150 char *term = manager ? "\r\n" : "\n";
05151 char idtext[256] = "";
05152 switch (argc) {
05153 case 6:
05154 if (!strcasecmp(argv[3], "registered"))
05155 registeredonly = 1;
05156 else
05157 return RESULT_SHOWUSAGE;
05158 if (!strcasecmp(argv[4], "like")) {
05159 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
05160 return RESULT_SHOWUSAGE;
05161 havepattern = 1;
05162 } else
05163 return RESULT_SHOWUSAGE;
05164 break;
05165 case 5:
05166 if (!strcasecmp(argv[3], "like")) {
05167 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05168 return RESULT_SHOWUSAGE;
05169 havepattern = 1;
05170 } else
05171 return RESULT_SHOWUSAGE;
05172 break;
05173 case 4:
05174 if (!strcasecmp(argv[3], "registered"))
05175 registeredonly = 1;
05176 else
05177 return RESULT_SHOWUSAGE;
05178 break;
05179 case 3:
05180 break;
05181 default:
05182 return RESULT_SHOWUSAGE;
05183 }
05184
05185
05186 if (!s)
05187 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
05188
05189 i = ao2_iterator_init(peers, 0);
05190 for (peer = ao2_iterator_next(&i); peer;
05191 peer_unref(peer), peer = ao2_iterator_next(&i)) {
05192 char nm[20];
05193 char status[20];
05194 char srch[2000];
05195 int retstatus;
05196
05197 if (registeredonly && !peer->addr.sin_addr.s_addr)
05198 continue;
05199 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
05200 continue;
05201
05202 if (!ast_strlen_zero(peer->username))
05203 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
05204 else
05205 ast_copy_string(name, peer->name, sizeof(name));
05206
05207 retstatus = peer_status(peer, status, sizeof(status));
05208 if (retstatus > 0)
05209 online_peers++;
05210 else if (!retstatus)
05211 offline_peers++;
05212 else
05213 unmonitored_peers++;
05214
05215 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05216
05217 snprintf(srch, sizeof(srch), FORMAT, name,
05218 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05219 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05220 nm,
05221 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
05222 peer->encmethods ? "(E)" : " ", status, term);
05223
05224 if (s)
05225 astman_append(s,
05226 "Event: PeerEntry\r\n%s"
05227 "Channeltype: IAX2\r\n"
05228 "ChanObjectType: peer\r\n"
05229 "ObjectName: %s\r\n"
05230 "IPaddress: %s\r\n"
05231 "IPport: %d\r\n"
05232 "Dynamic: %s\r\n"
05233 "Status: %s\r\n\r\n",
05234 idtext,
05235 name,
05236 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
05237 ntohs(peer->addr.sin_port),
05238 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
05239 status);
05240
05241 else
05242 ast_cli(fd, FORMAT, name,
05243 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05244 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05245 nm,
05246 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
05247 peer->encmethods ? "(E)" : " ", status, term);
05248 total_peers++;
05249 }
05250
05251 if (!s)
05252 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05253
05254 if (havepattern)
05255 regfree(®exbuf);
05256
05257 return RESULT_SUCCESS;
05258 #undef FORMAT
05259 #undef FORMAT2
05260 }
05261
05262 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05263 {
05264 struct iax2_thread *thread = NULL;
05265 time_t t;
05266 int threadcount = 0, dynamiccount = 0;
05267 char type;
05268
05269 switch (cmd) {
05270 case CLI_INIT:
05271 e->command = "iax2 show threads";
05272 e->usage =
05273 "Usage: iax2 show threads\n"
05274 " Lists status of IAX helper threads\n";
05275 return NULL;
05276 case CLI_GENERATE:
05277 return NULL;
05278 }
05279 if (a->argc != 3)
05280 return CLI_SHOWUSAGE;
05281
05282 ast_cli(a->fd, "IAX2 Thread Information\n");
05283 time(&t);
05284 ast_cli(a->fd, "Idle Threads:\n");
05285 AST_LIST_LOCK(&idle_list);
05286 AST_LIST_TRAVERSE(&idle_list, thread, list) {
05287 #ifdef DEBUG_SCHED_MULTITHREAD
05288 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
05289 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05290 #else
05291 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05292 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05293 #endif
05294 threadcount++;
05295 }
05296 AST_LIST_UNLOCK(&idle_list);
05297 ast_cli(a->fd, "Active Threads:\n");
05298 AST_LIST_LOCK(&active_list);
05299 AST_LIST_TRAVERSE(&active_list, thread, list) {
05300 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
05301 type = 'D';
05302 else
05303 type = 'P';
05304 #ifdef DEBUG_SCHED_MULTITHREAD
05305 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
05306 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05307 #else
05308 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
05309 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05310 #endif
05311 threadcount++;
05312 }
05313 AST_LIST_UNLOCK(&active_list);
05314 ast_cli(a->fd, "Dynamic Threads:\n");
05315 AST_LIST_LOCK(&dynamic_list);
05316 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
05317 #ifdef DEBUG_SCHED_MULTITHREAD
05318 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
05319 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05320 #else
05321 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05322 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05323 #endif
05324 dynamiccount++;
05325 }
05326 AST_LIST_UNLOCK(&dynamic_list);
05327 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
05328 return CLI_SUCCESS;
05329 }
05330
05331 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05332 {
05333 struct iax2_peer *p;
05334
05335 switch (cmd) {
05336 case CLI_INIT:
05337 e->command = "iax2 unregister";
05338 e->usage =
05339 "Usage: iax2 unregister <peername>\n"
05340 " Unregister (force expiration) an IAX2 peer from the registry.\n";
05341 return NULL;
05342 case CLI_GENERATE:
05343 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
05344 }
05345
05346 if (a->argc != 3)
05347 return CLI_SHOWUSAGE;
05348
05349 p = find_peer(a->argv[2], 1);
05350 if (p) {
05351 if (p->expire > 0) {
05352 struct iax2_peer tmp_peer = {
05353 .name = a->argv[2],
05354 };
05355 struct iax2_peer *peer;
05356
05357 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
05358 if (peer) {
05359 expire_registry(peer_ref(peer));
05360 peer_unref(peer);
05361 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
05362 } else {
05363 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
05364 }
05365 } else {
05366 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
05367 }
05368 } else {
05369 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
05370 }
05371 return CLI_SUCCESS;
05372 }
05373
05374 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
05375 {
05376 int which = 0;
05377 struct iax2_peer *p = NULL;
05378 char *res = NULL;
05379 int wordlen = strlen(word);
05380
05381
05382 if (pos == 2) {
05383 struct ao2_iterator i = ao2_iterator_init(peers, 0);
05384 while ((p = ao2_iterator_next(&i))) {
05385 if (!strncasecmp(p->name, word, wordlen) &&
05386 ++which > state && p->expire > 0) {
05387 res = ast_strdup(p->name);
05388 peer_unref(p);
05389 break;
05390 }
05391 peer_unref(p);
05392 }
05393 }
05394
05395 return res;
05396 }
05397
05398 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05399 {
05400 switch (cmd) {
05401 case CLI_INIT:
05402 e->command = "iax2 show peers";
05403 e->usage =
05404 "Usage: iax2 show peers [registered] [like <pattern>]\n"
05405 " Lists all known IAX2 peers.\n"
05406 " Optional 'registered' argument lists only peers with known addresses.\n"
05407 " Optional regular expression pattern is used to filter the peer list.\n";
05408 return NULL;
05409 case CLI_GENERATE:
05410 return NULL;
05411 }
05412
05413 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
05414 case RESULT_SHOWUSAGE:
05415 return CLI_SHOWUSAGE;
05416 case RESULT_FAILURE:
05417 return CLI_FAILURE;
05418 default:
05419 return CLI_SUCCESS;
05420 }
05421 }
05422
05423 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
05424 {
05425 ast_cli_netstats(s, -1, 0);
05426 astman_append(s, "\r\n");
05427 return RESULT_SUCCESS;
05428 }
05429
05430 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05431 {
05432 struct iax_firmware *cur = NULL;
05433
05434 switch (cmd) {
05435 case CLI_INIT:
05436 e->command = "iax2 show firmware";
05437 e->usage =
05438 "Usage: iax2 show firmware\n"
05439 " Lists all known IAX firmware images.\n";
05440 return NULL;
05441 case CLI_GENERATE:
05442 return NULL;
05443 }
05444
05445 if (a->argc != 3 && a->argc != 4)
05446 return CLI_SHOWUSAGE;
05447
05448 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
05449 AST_LIST_LOCK(&firmwares);
05450 AST_LIST_TRAVERSE(&firmwares, cur, list) {
05451 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
05452 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
05453 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
05454 }
05455 }
05456 AST_LIST_UNLOCK(&firmwares);
05457
05458 return CLI_SUCCESS;
05459 }
05460
05461
05462 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
05463 {
05464 char *a[] = { "iax2", "show", "users" };
05465 const char *id = astman_get_header(m,"ActionID");
05466 char idtext[256] = "";
05467
05468 if (!ast_strlen_zero(id))
05469 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
05470 astman_send_ack(s, m, "Peer status list will follow");
05471 return __iax2_show_peers(1, -1, s, 3, a );
05472 }
05473
05474
05475 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
05476 {
05477 struct iax2_peer *peer = NULL;
05478 int peer_count = 0;
05479 char nm[20];
05480 char status[20];
05481 const char *id = astman_get_header(m,"ActionID");
05482 char idtext[256] = "";
05483 struct ao2_iterator i;
05484
05485 if (!ast_strlen_zero(id))
05486 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
05487
05488 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
05489
05490
05491 i = ao2_iterator_init(peers, 0);
05492 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
05493
05494 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
05495 if (!ast_strlen_zero(peer->username)) {
05496 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
05497 } else {
05498 astman_append(s, "ObjectName: %s\r\n", peer->name);
05499 }
05500 astman_append(s, "ChanObjectType: peer\r\n");
05501 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
05502 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05503 astman_append(s, "Mask: %s\r\n", nm);
05504 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
05505 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
05506 peer_status(peer, status, sizeof(status));
05507 astman_append(s, "Status: %s\r\n\r\n", status);
05508 peer_count++;
05509 }
05510
05511 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
05512 return RESULT_SUCCESS;
05513 }
05514
05515
05516 static char *regstate2str(int regstate)
05517 {
05518 switch(regstate) {
05519 case REG_STATE_UNREGISTERED:
05520 return "Unregistered";
05521 case REG_STATE_REGSENT:
05522 return "Request Sent";
05523 case REG_STATE_AUTHSENT:
05524 return "Auth. Sent";
05525 case REG_STATE_REGISTERED:
05526 return "Registered";
05527 case REG_STATE_REJECTED:
05528 return "Rejected";
05529 case REG_STATE_TIMEOUT:
05530 return "Timeout";
05531 case REG_STATE_NOAUTH:
05532 return "No Authentication";
05533 default:
05534 return "Unknown";
05535 }
05536 }
05537
05538 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05539 {
05540 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
05541 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
05542 struct iax2_registry *reg = NULL;
05543 char host[80];
05544 char perceived[80];
05545 int counter = 0;
05546
05547 switch (cmd) {
05548 case CLI_INIT:
05549 e->command = "iax2 show registry";
05550 e->usage =
05551 "Usage: iax2 show registry\n"
05552 " Lists all registration requests and status.\n";
05553 return NULL;
05554 case CLI_GENERATE:
05555 return NULL;
05556 }
05557 if (a->argc != 3)
05558 return CLI_SHOWUSAGE;
05559 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
05560 AST_LIST_LOCK(®istrations);
05561 AST_LIST_TRAVERSE(®istrations, reg, entry) {
05562 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
05563 if (reg->us.sin_addr.s_addr)
05564 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05565 else
05566 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
05567 ast_cli(a->fd, FORMAT, host,
05568 (reg->dnsmgr) ? "Y" : "N",
05569 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
05570 counter++;
05571 }
05572 AST_LIST_UNLOCK(®istrations);
05573 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
05574 return CLI_SUCCESS;
05575 #undef FORMAT
05576 #undef FORMAT2
05577 }
05578
05579 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05580 {
05581 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
05582 #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"
05583 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
05584 int x;
05585 int numchans = 0;
05586 char first_message[10] = { 0, };
05587 char last_message[10] = { 0, };
05588
05589 switch (cmd) {
05590 case CLI_INIT:
05591 e->command = "iax2 show channels";
05592 e->usage =
05593 "Usage: iax2 show channels\n"
05594 " Lists all currently active IAX channels.\n";
05595 return NULL;
05596 case CLI_GENERATE:
05597 return NULL;
05598 }
05599
05600 if (a->argc != 3)
05601 return CLI_SHOWUSAGE;
05602 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
05603 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05604 ast_mutex_lock(&iaxsl[x]);
05605 if (iaxs[x]) {
05606 int lag, jitter, localdelay;
05607 jb_info jbinfo;
05608 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05609 jb_getinfo(iaxs[x]->jb, &jbinfo);
05610 jitter = jbinfo.jitter;
05611 localdelay = jbinfo.current - jbinfo.min;
05612 } else {
05613 jitter = -1;
05614 localdelay = 0;
05615 }
05616
05617 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
05618 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
05619 lag = iaxs[x]->remote_rr.delay;
05620 ast_cli(a->fd, FORMAT,
05621 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05622 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
05623 S_OR(iaxs[x]->username, "(None)"),
05624 iaxs[x]->callno, iaxs[x]->peercallno,
05625 iaxs[x]->oseqno, iaxs[x]->iseqno,
05626 lag,
05627 jitter,
05628 localdelay,
05629 ast_getformatname(iaxs[x]->voiceformat),
05630 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05631 first_message,
05632 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05633 last_message);
05634 numchans++;
05635 }
05636 ast_mutex_unlock(&iaxsl[x]);
05637 }
05638 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05639 return CLI_SUCCESS;
05640 #undef FORMAT
05641 #undef FORMAT2
05642 #undef FORMATB
05643 }
05644
05645 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
05646 {
05647 int x;
05648 int numchans = 0;
05649 char first_message[10] = { 0, };
05650 char last_message[10] = { 0, };
05651 #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"
05652 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
05653 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05654 ast_mutex_lock(&iaxsl[x]);
05655 if (iaxs[x]) {
05656 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
05657 jb_info jbinfo;
05658 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
05659 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
05660
05661 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05662 jb_getinfo(iaxs[x]->jb, &jbinfo);
05663 localjitter = jbinfo.jitter;
05664 localdelay = jbinfo.current - jbinfo.min;
05665 locallost = jbinfo.frames_lost;
05666 locallosspct = jbinfo.losspct/1000;
05667 localdropped = jbinfo.frames_dropped;
05668 localooo = jbinfo.frames_ooo;
05669 } else {
05670 localjitter = -1;
05671 localdelay = 0;
05672 locallost = -1;
05673 locallosspct = -1;
05674 localdropped = 0;
05675 localooo = -1;
05676 }
05677 if (s)
05678 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
05679 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05680 iaxs[x]->pingtime,
05681 localjitter,
05682 localdelay,
05683 locallost,
05684 locallosspct,
05685 localdropped,
05686 localooo,
05687 iaxs[x]->frames_received/1000,
05688 iaxs[x]->remote_rr.jitter,
05689 iaxs[x]->remote_rr.delay,
05690 iaxs[x]->remote_rr.losscnt,
05691 iaxs[x]->remote_rr.losspct,
05692 iaxs[x]->remote_rr.dropped,
05693 iaxs[x]->remote_rr.ooo,
05694 iaxs[x]->remote_rr.packets/1000,
05695 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05696 first_message,
05697 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05698 last_message);
05699 else
05700 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
05701 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05702 iaxs[x]->pingtime,
05703 localjitter,
05704 localdelay,
05705 locallost,
05706 locallosspct,
05707 localdropped,
05708 localooo,
05709 iaxs[x]->frames_received/1000,
05710 iaxs[x]->remote_rr.jitter,
05711 iaxs[x]->remote_rr.delay,
05712 iaxs[x]->remote_rr.losscnt,
05713 iaxs[x]->remote_rr.losspct,
05714 iaxs[x]->remote_rr.dropped,
05715 iaxs[x]->remote_rr.ooo,
05716 iaxs[x]->remote_rr.packets/1000,
05717 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05718 first_message,
05719 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
05720 last_message);
05721 numchans++;
05722 }
05723 ast_mutex_unlock(&iaxsl[x]);
05724 }
05725
05726 return numchans;
05727 }
05728
05729 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05730 {
05731 int numchans = 0;
05732
05733 switch (cmd) {
05734 case CLI_INIT:
05735 e->command = "iax2 show netstats";
05736 e->usage =
05737 "Usage: iax2 show netstats\n"
05738 " Lists network status for all currently active IAX channels.\n";
05739 return NULL;
05740 case CLI_GENERATE:
05741 return NULL;
05742 }
05743 if (a->argc != 3)
05744 return CLI_SHOWUSAGE;
05745 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
05746 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
05747 numchans = ast_cli_netstats(NULL, a->fd, 1);
05748 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05749 return CLI_SUCCESS;
05750 }
05751
05752 static char *handle_cli_iax2_set_debug_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05753 {
05754 switch (cmd) {
05755 case CLI_INIT:
05756 e->command = "iax2 set debug [off]";
05757 e->usage =
05758 "Usage: iax2 set debug [off]\n"
05759 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
05760 return NULL;
05761 case CLI_GENERATE:
05762 return NULL;
05763 }
05764 if (a->argc < 3 || a->argc > 4)
05765 return CLI_SHOWUSAGE;
05766 if (a->argc == 3) {
05767 iaxdebug = 1;
05768 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
05769 } else {
05770 iaxdebug = 0;
05771 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
05772 }
05773 return CLI_SUCCESS;
05774 }
05775
05776 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05777 {
05778 switch (cmd) {
05779 case CLI_INIT:
05780 e->command = "iax2 set debug {on|off}";
05781 e->usage =
05782 "Usage: iax2 set debug {on|off}\n"
05783 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
05784 return NULL;
05785 case CLI_GENERATE:
05786 return NULL;
05787 }
05788
05789 if (a->argc != e->args)
05790 return CLI_SHOWUSAGE;
05791
05792 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
05793 iaxdebug = 1;
05794 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
05795 } else {
05796 iaxdebug = 0;
05797 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
05798 }
05799 return CLI_SUCCESS;
05800 }
05801
05802
05803 static char *handle_cli_iax2_set_debug_trunk_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05804 {
05805 switch (cmd) {
05806 case CLI_INIT:
05807 e->command = "iax2 set debug trunk [off]";
05808 e->usage =
05809 "Usage: iax2 set debug trunk [off]\n"
05810 " Enables/Disables debugging of IAX trunking\n";
05811 return NULL;
05812 case CLI_GENERATE:
05813 return NULL;
05814 }
05815
05816 if (a->argc < 4 || a->argc > 5)
05817 return CLI_SHOWUSAGE;
05818
05819 if (a->argc == 4) {
05820 iaxtrunkdebug = 1;
05821 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
05822 } else {
05823 iaxtrunkdebug = 0;
05824 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
05825 }
05826 return CLI_SUCCESS;
05827 }
05828
05829 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05830 {
05831 switch (cmd) {
05832 case CLI_INIT:
05833 e->command = "iax2 set debug trunk {on|off}";
05834 e->usage =
05835 "Usage: iax2 set debug trunk {on|off}\n"
05836 " Enables/Disables debugging of IAX trunking\n";
05837 return NULL;
05838 case CLI_GENERATE:
05839 return NULL;
05840 }
05841
05842 if (a->argc != e->args)
05843 return CLI_SHOWUSAGE;
05844
05845 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
05846 iaxtrunkdebug = 1;
05847 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
05848 } else {
05849 iaxtrunkdebug = 0;
05850 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
05851 }
05852 return CLI_SUCCESS;
05853 }
05854
05855 static char *handle_cli_iax2_set_debug_jb_deprecated(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05856 {
05857 switch (cmd) {
05858 case CLI_INIT:
05859 e->command = "iax2 set debug jb [off]";
05860 e->usage =
05861 "Usage: iax2 set debug jb [off]\n"
05862 " Enables/Disables jitterbuffer debugging information\n";
05863 return NULL;
05864 case CLI_GENERATE:
05865 return NULL;
05866 }
05867
05868 if (a->argc < 4 || a->argc > 5)
05869 return CLI_SHOWUSAGE;
05870
05871 if (a->argc == 4) {
05872 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05873 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05874 } else {
05875 jb_setoutput(jb_error_output, jb_warning_output, NULL);
05876 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05877 }
05878 return CLI_SUCCESS;
05879 }
05880
05881 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05882 {
05883 switch (cmd) {
05884 case CLI_INIT:
05885 e->command = "iax2 set debug jb {on|off}";
05886 e->usage =
05887 "Usage: iax2 set debug jb {on|off}\n"
05888 " Enables/Disables jitterbuffer debugging information\n";
05889 return NULL;
05890 case CLI_GENERATE:
05891 return NULL;
05892 }
05893
05894 if (a->argc != e->args)
05895 return CLI_SHOWUSAGE;
05896
05897 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
05898 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05899 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05900 } else {
05901 jb_setoutput(jb_error_output, jb_warning_output, NULL);
05902 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05903 }
05904 return CLI_SUCCESS;
05905 }
05906
05907 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05908 {
05909 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05910 int res = -1;
05911 ast_mutex_lock(&iaxsl[callno]);
05912 if (iaxs[callno]) {
05913
05914 if (!iaxs[callno]->error) {
05915 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05916 res = 0;
05917
05918 else if (f->frametype == AST_FRAME_NULL)
05919 res = 0;
05920 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05921 res = 0;
05922 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05923 res = 0;
05924 else
05925
05926 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05927 } else {
05928 ast_debug(1, "Write error: %s\n", strerror(errno));
05929 }
05930 }
05931
05932 ast_mutex_unlock(&iaxsl[callno]);
05933 return res;
05934 }
05935
05936 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
05937 int now, int transfer, int final)
05938 {
05939 struct ast_frame f = { 0, };
05940
05941 f.frametype = type;
05942 f.subclass = command;
05943 f.datalen = datalen;
05944 f.src = __FUNCTION__;
05945 f.data = (void *) data;
05946
05947 return iax2_send(i, &f, ts, seqno, now, transfer, final);
05948 }
05949
05950 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05951 {
05952 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05953 }
05954
05955 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05956 {
05957 int res;
05958 ast_mutex_lock(&iaxsl[callno]);
05959 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05960 ast_mutex_unlock(&iaxsl[callno]);
05961 return res;
05962 }
05963
05964
05965
05966
05967
05968
05969 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)
05970 {
05971 int call_num = i->callno;
05972
05973 iax2_predestroy(i->callno);
05974 if (!iaxs[call_num])
05975 return -1;
05976 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05977 }
05978
05979 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)
05980 {
05981 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05982 }
05983
05984 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05985 {
05986 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05987 }
05988
05989 static int apply_context(struct iax2_context *con, const char *context)
05990 {
05991 while(con) {
05992 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05993 return -1;
05994 con = con->next;
05995 }
05996 return 0;
05997 }
05998
05999
06000 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06001 {
06002
06003 int res = -1;
06004 int version = 2;
06005 struct iax2_user *user = NULL, *best = NULL;
06006 int bestscore = 0;
06007 int gotcapability = 0;
06008 struct ast_variable *v = NULL, *tmpvar = NULL;
06009 struct ao2_iterator i;
06010
06011 if (!iaxs[callno])
06012 return res;
06013 if (ies->called_number)
06014 ast_string_field_set(iaxs[callno], exten, ies->called_number);
06015 if (ies->calling_number) {
06016 ast_shrink_phone_number(ies->calling_number);
06017 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
06018 }
06019 if (ies->calling_name)
06020 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
06021 if (ies->calling_ani)
06022 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
06023 if (ies->dnid)
06024 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
06025 if (ies->rdnis)
06026 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
06027 if (ies->called_context)
06028 ast_string_field_set(iaxs[callno], context, ies->called_context);
06029 if (ies->language)
06030 ast_string_field_set(iaxs[callno], language, ies->language);
06031 if (ies->username)
06032 ast_string_field_set(iaxs[callno], username, ies->username);
06033 if (ies->calling_ton > -1)
06034 iaxs[callno]->calling_ton = ies->calling_ton;
06035 if (ies->calling_tns > -1)
06036 iaxs[callno]->calling_tns = ies->calling_tns;
06037 if (ies->calling_pres > -1)
06038 iaxs[callno]->calling_pres = ies->calling_pres;
06039 if (ies->format)
06040 iaxs[callno]->peerformat = ies->format;
06041 if (ies->adsicpe)
06042 iaxs[callno]->peeradsicpe = ies->adsicpe;
06043 if (ies->capability) {
06044 gotcapability = 1;
06045 iaxs[callno]->peercapability = ies->capability;
06046 }
06047 if (ies->version)
06048 version = ies->version;
06049
06050
06051 if(ies->codec_prefs) {
06052 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
06053 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
06054 }
06055
06056 if (!gotcapability)
06057 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
06058 if (version > IAX_PROTO_VERSION) {
06059 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
06060 ast_inet_ntoa(sin->sin_addr), version);
06061 return res;
06062 }
06063
06064 i = ao2_iterator_init(users, 0);
06065 while ((user = ao2_iterator_next(&i))) {
06066 if ((ast_strlen_zero(iaxs[callno]->username) ||
06067 !strcmp(iaxs[callno]->username, user->name))
06068 && ast_apply_ha(user->ha, sin)
06069 && (ast_strlen_zero(iaxs[callno]->context) ||
06070 apply_context(user->contexts, iaxs[callno]->context))) {
06071 if (!ast_strlen_zero(iaxs[callno]->username)) {
06072
06073 if (best)
06074 user_unref(best);
06075 best = user;
06076 break;
06077 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
06078
06079 if (user->ha) {
06080
06081 if (bestscore < 4) {
06082 bestscore = 4;
06083 if (best)
06084 user_unref(best);
06085 best = user;
06086 continue;
06087 }
06088 } else {
06089
06090 if (bestscore < 3) {
06091 bestscore = 3;
06092 if (best)
06093 user_unref(best);
06094 best = user;
06095 continue;
06096 }
06097 }
06098 } else {
06099 if (user->ha) {
06100
06101 if (bestscore < 2) {
06102 bestscore = 2;
06103 if (best)
06104 user_unref(best);
06105 best = user;
06106 continue;
06107 }
06108 } else {
06109
06110 if (bestscore < 1) {
06111 bestscore = 1;
06112 if (best)
06113 user_unref(best);
06114 best = user;
06115 continue;
06116 }
06117 }
06118 }
06119 }
06120 user_unref(user);
06121 }
06122 user = best;
06123 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
06124 user = realtime_user(iaxs[callno]->username, sin);
06125 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
06126 !apply_context(user->contexts, iaxs[callno]->context)) {
06127 user = user_unref(user);
06128 }
06129 }
06130 if (user) {
06131
06132
06133 for (v = user->vars ; v ; v = v->next) {
06134 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
06135 tmpvar->next = iaxs[callno]->vars;
06136 iaxs[callno]->vars = tmpvar;
06137 }
06138 }
06139
06140 if (user->maxauthreq > 0)
06141 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
06142 iaxs[callno]->prefs = user->prefs;
06143 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
06144 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
06145 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
06146 iaxs[callno]->encmethods = user->encmethods;
06147
06148 if (ast_strlen_zero(iaxs[callno]->username))
06149 ast_string_field_set(iaxs[callno], username, user->name);
06150
06151 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
06152 iaxs[callno]->capability = user->capability;
06153
06154 if (ast_strlen_zero(iaxs[callno]->context)) {
06155 if (user->contexts)
06156 ast_string_field_set(iaxs[callno], context, user->contexts->context);
06157 else
06158 ast_string_field_set(iaxs[callno], context, context);
06159 }
06160
06161 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
06162
06163 iaxs[callno]->authmethods = user->authmethods;
06164 iaxs[callno]->adsi = user->adsi;
06165
06166 if (ast_test_flag(user, IAX_HASCALLERID)) {
06167 iaxs[callno]->calling_tns = 0;
06168 iaxs[callno]->calling_ton = 0;
06169 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
06170 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
06171 ast_string_field_set(iaxs[callno], ani, user->cid_num);
06172 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
06173 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
06174 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
06175 }
06176 if (!ast_strlen_zero(user->accountcode))
06177 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
06178 if (!ast_strlen_zero(user->mohinterpret))
06179 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
06180 if (!ast_strlen_zero(user->mohsuggest))
06181 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
06182 if (user->amaflags)
06183 iaxs[callno]->amaflags = user->amaflags;
06184 if (!ast_strlen_zero(user->language))
06185 ast_string_field_set(iaxs[callno], language, user->language);
06186 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
06187
06188 if (!ast_strlen_zero(user->dbsecret)) {
06189 char *family, *key=NULL;
06190 char buf[80];
06191 family = ast_strdupa(user->dbsecret);
06192 key = strchr(family, '/');
06193 if (key) {
06194 *key = '\0';
06195 key++;
06196 }
06197 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
06198 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
06199 else
06200 ast_string_field_set(iaxs[callno], secret, buf);
06201 } else
06202 ast_string_field_set(iaxs[callno], secret, user->secret);
06203 res = 0;
06204 user = user_unref(user);
06205 } else {
06206
06207
06208
06209
06210 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06211 ast_string_field_set(iaxs[callno], secret, "badsecret");
06212 iaxs[callno]->authrej = 1;
06213 if (!ast_strlen_zero(iaxs[callno]->username)) {
06214
06215 res = 0;
06216 }
06217 }
06218 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
06219 return res;
06220 }
06221
06222 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
06223 {
06224 struct ast_iax2_full_hdr fh;
06225 fh.scallno = htons(src | IAX_FLAG_FULL);
06226 fh.dcallno = htons(dst);
06227 fh.ts = 0;
06228 fh.oseqno = 0;
06229 fh.iseqno = 0;
06230 fh.type = AST_FRAME_IAX;
06231 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
06232 if (iaxdebug)
06233 iax_showframe(NULL, &fh, 0, sin, 0);
06234 #if 0
06235 if (option_debug)
06236 #endif
06237 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
06238 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
06239 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
06240 }
06241
06242 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
06243 {
06244
06245 p->encmethods &= enc;
06246 if (p->encmethods) {
06247 if (p->encmethods & IAX_ENCRYPT_AES128)
06248 p->encmethods = IAX_ENCRYPT_AES128;
06249 else
06250 p->encmethods = 0;
06251 }
06252 }
06253
06254
06255
06256
06257
06258
06259
06260 static int authenticate_request(int call_num)
06261 {
06262 struct iax_ie_data ied;
06263 int res = -1, authreq_restrict = 0;
06264 char challenge[10];
06265 struct chan_iax2_pvt *p = iaxs[call_num];
06266
06267 memset(&ied, 0, sizeof(ied));
06268
06269
06270 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06271 struct iax2_user *user, tmp_user = {
06272 .name = p->username,
06273 };
06274
06275 user = ao2_find(users, &tmp_user, OBJ_POINTER);
06276 if (user) {
06277 if (user->curauthreq == user->maxauthreq)
06278 authreq_restrict = 1;
06279 else
06280 user->curauthreq++;
06281 user = user_unref(user);
06282 }
06283 }
06284
06285
06286 if (authreq_restrict) {
06287 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
06288 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
06289 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
06290 return 0;
06291 }
06292
06293 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06294 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
06295 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06296 ast_string_field_set(p, challenge, challenge);
06297
06298 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
06299 }
06300 if (p->encmethods)
06301 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
06302
06303 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
06304
06305 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
06306
06307 if (p->encmethods)
06308 ast_set_flag(p, IAX_ENCRYPTED);
06309
06310 return res;
06311 }
06312
06313 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
06314 {
06315 char requeststr[256];
06316 char md5secret[256] = "";
06317 char secret[256] = "";
06318 char rsasecret[256] = "";
06319 int res = -1;
06320 int x;
06321 struct iax2_user *user, tmp_user = {
06322 .name = p->username,
06323 };
06324
06325 if (p->authrej) {
06326 return res;
06327 }
06328 user = ao2_find(users, &tmp_user, OBJ_POINTER);
06329 if (user) {
06330 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06331 ast_atomic_fetchadd_int(&user->curauthreq, -1);
06332 ast_clear_flag(p, IAX_MAXAUTHREQ);
06333 }
06334 ast_string_field_set(p, host, user->name);
06335 user = user_unref(user);
06336 }
06337
06338 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
06339 return res;
06340 if (ies->password)
06341 ast_copy_string(secret, ies->password, sizeof(secret));
06342 if (ies->md5_result)
06343 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06344 if (ies->rsa_result)
06345 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06346 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
06347 struct ast_key *key;
06348 char *keyn;
06349 char tmpkey[256];
06350 char *stringp=NULL;
06351 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
06352 stringp=tmpkey;
06353 keyn = strsep(&stringp, ":");
06354 while(keyn) {
06355 key = ast_key_get(keyn, AST_KEY_PUBLIC);
06356 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
06357 res = 0;
06358 break;
06359 } else if (!key)
06360 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
06361 keyn = strsep(&stringp, ":");
06362 }
06363 } else if (p->authmethods & IAX_AUTH_MD5) {
06364 struct MD5Context md5;
06365 unsigned char digest[16];
06366 char *tmppw, *stringp;
06367
06368 tmppw = ast_strdupa(p->secret);
06369 stringp = tmppw;
06370 while((tmppw = strsep(&stringp, ";"))) {
06371 MD5Init(&md5);
06372 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
06373 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06374 MD5Final(digest, &md5);
06375
06376 for (x=0;x<16;x++)
06377 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
06378 if (!strcasecmp(requeststr, md5secret)) {
06379 res = 0;
06380 break;
06381 }
06382 }
06383 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
06384 if (!strcmp(secret, p->secret))
06385 res = 0;
06386 }
06387 return res;
06388 }
06389
06390
06391 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06392 {
06393 char requeststr[256] = "";
06394 char peer[256] = "";
06395 char md5secret[256] = "";
06396 char rsasecret[256] = "";
06397 char secret[256] = "";
06398 struct iax2_peer *p = NULL;
06399 struct ast_key *key;
06400 char *keyn;
06401 int x;
06402 int expire = 0;
06403 int res = -1;
06404
06405 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06406
06407 if (ies->username)
06408 ast_copy_string(peer, ies->username, sizeof(peer));
06409 if (ies->password)
06410 ast_copy_string(secret, ies->password, sizeof(secret));
06411 if (ies->md5_result)
06412 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06413 if (ies->rsa_result)
06414 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06415 if (ies->refresh)
06416 expire = ies->refresh;
06417
06418 if (ast_strlen_zero(peer)) {
06419 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
06420 return -1;
06421 }
06422
06423
06424 ast_mutex_unlock(&iaxsl[callno]);
06425 p = find_peer(peer, 1);
06426 ast_mutex_lock(&iaxsl[callno]);
06427 if (!p || !iaxs[callno]) {
06428 if (iaxs[callno]) {
06429 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
06430
06431 ast_string_field_set(iaxs[callno], secret, "badsecret");
06432
06433
06434
06435
06436
06437
06438
06439
06440
06441 if (ast_strlen_zero(iaxs[callno]->challenge) &&
06442 !(!ast_strlen_zero(secret) && plaintext)) {
06443
06444 res = 0;
06445 }
06446 }
06447 if (authdebug && !p)
06448 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06449 goto return_unref;
06450 }
06451
06452 if (!ast_test_flag(p, IAX_DYNAMIC)) {
06453 if (authdebug)
06454 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06455 goto return_unref;
06456 }
06457
06458 if (!ast_apply_ha(p->ha, sin)) {
06459 if (authdebug)
06460 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06461 goto return_unref;
06462 }
06463 ast_string_field_set(iaxs[callno], secret, p->secret);
06464 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
06465
06466 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06467 if (!ast_strlen_zero(p->inkeys)) {
06468 char tmpkeys[256];
06469 char *stringp=NULL;
06470 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
06471 stringp=tmpkeys;
06472 keyn = strsep(&stringp, ":");
06473 while(keyn) {
06474 key = ast_key_get(keyn, AST_KEY_PUBLIC);
06475 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
06476 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06477 break;
06478 } else if (!key)
06479 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
06480 keyn = strsep(&stringp, ":");
06481 }
06482 if (!keyn) {
06483 if (authdebug)
06484 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
06485 goto return_unref;
06486 }
06487 } else {
06488 if (authdebug)
06489 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
06490 goto return_unref;
06491 }
06492 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06493 struct MD5Context md5;
06494 unsigned char digest[16];
06495 char *tmppw, *stringp;
06496
06497 tmppw = ast_strdupa(p->secret);
06498 stringp = tmppw;
06499 while((tmppw = strsep(&stringp, ";"))) {
06500 MD5Init(&md5);
06501 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06502 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06503 MD5Final(digest, &md5);
06504 for (x=0;x<16;x++)
06505 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
06506 if (!strcasecmp(requeststr, md5secret))
06507 break;
06508 }
06509 if (tmppw) {
06510 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06511 } else {
06512 if (authdebug)
06513 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
06514 goto return_unref;
06515 }
06516 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
06517
06518 if (strcmp(secret, p->secret)) {
06519 if (authdebug)
06520 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06521 goto return_unref;
06522 } else
06523 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06524 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
06525
06526 goto return_unref;
06527 }
06528 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
06529
06530
06531 res = 0;
06532
06533 return_unref:
06534 if (iaxs[callno]) {
06535 ast_string_field_set(iaxs[callno], peer, peer);
06536
06537
06538 if (expire && (expire < iaxs[callno]->expiry)) {
06539 iaxs[callno]->expiry = expire;
06540 }
06541 }
06542
06543 if (p) {
06544 peer_unref(p);
06545 }
06546 return res;
06547 }
06548
06549 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)
06550 {
06551 int res = -1;
06552 int x;
06553 if (!ast_strlen_zero(keyn)) {
06554 if (!(authmethods & IAX_AUTH_RSA)) {
06555 if (ast_strlen_zero(secret))
06556 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));
06557 } else if (ast_strlen_zero(challenge)) {
06558 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
06559 } else {
06560 char sig[256];
06561 struct ast_key *key;
06562 key = ast_key_get(keyn, AST_KEY_PRIVATE);
06563 if (!key) {
06564 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
06565 } else {
06566 if (ast_sign(key, (char*)challenge, sig)) {
06567 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
06568 res = -1;
06569 } else {
06570 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
06571 res = 0;
06572 }
06573 }
06574 }
06575 }
06576
06577 if (res && !ast_strlen_zero(secret)) {
06578 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
06579 struct MD5Context md5;
06580 unsigned char digest[16];
06581 char digres[128];
06582 MD5Init(&md5);
06583 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
06584 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
06585 MD5Final(digest, &md5);
06586
06587 for (x=0;x<16;x++)
06588 sprintf(digres + (x << 1), "%2.2x", digest[x]);
06589 if (pvt) {
06590 build_encryption_keys(digest, pvt);
06591 }
06592 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
06593 res = 0;
06594 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
06595 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
06596 res = 0;
06597 } else
06598 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
06599 }
06600 return res;
06601 }
06602
06603
06604
06605
06606
06607 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
06608 {
06609 struct iax2_peer *peer = NULL;
06610
06611 int res = -1;
06612 int authmethods = 0;
06613 struct iax_ie_data ied;
06614 uint16_t callno = p->callno;
06615
06616 memset(&ied, 0, sizeof(ied));
06617
06618 if (ies->username)
06619 ast_string_field_set(p, username, ies->username);
06620 if (ies->challenge)
06621 ast_string_field_set(p, challenge, ies->challenge);
06622 if (ies->authmethods)
06623 authmethods = ies->authmethods;
06624 if (authmethods & IAX_AUTH_MD5)
06625 merge_encryption(p, ies->encmethods);
06626 else
06627 p->encmethods = 0;
06628
06629
06630 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
06631
06632 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
06633 } else {
06634 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06635 while ((peer = ao2_iterator_next(&i))) {
06636 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
06637
06638 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
06639
06640 && (!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)))
06641
06642 ) {
06643 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
06644 if (!res) {
06645 peer_unref(peer);
06646 break;
06647 }
06648 }
06649 peer_unref(peer);
06650 }
06651 if (!peer) {
06652
06653
06654 const char *peer_name = ast_strdupa(p->peer);
06655 ast_mutex_unlock(&iaxsl[callno]);
06656 if ((peer = realtime_peer(peer_name, NULL))) {
06657 ast_mutex_lock(&iaxsl[callno]);
06658 if (!(p = iaxs[callno])) {
06659 peer_unref(peer);
06660 return -1;
06661 }
06662 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
06663 peer_unref(peer);
06664 }
06665 if (!peer) {
06666 ast_mutex_lock(&iaxsl[callno]);
06667 if (!(p = iaxs[callno]))
06668 return -1;
06669 }
06670 }
06671 }
06672 if (ies->encmethods)
06673 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
06674 if (!res) {
06675 struct ast_datastore *variablestore;
06676 struct ast_variable *var, *prev = NULL;
06677 AST_LIST_HEAD(, ast_var_t) *varlist;
06678 varlist = ast_calloc(1, sizeof(*varlist));
06679 variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
06680 if (variablestore && varlist && p->owner) {
06681 variablestore->data = varlist;
06682 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
06683 AST_LIST_HEAD_INIT(varlist);
06684 for (var = ies->vars; var; var = var->next) {
06685 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
06686 if (prev)
06687 ast_free(prev);
06688 prev = var;
06689 if (!newvar) {
06690
06691 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
06692 } else {
06693 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
06694 }
06695 }
06696 if (prev)
06697 ast_free(prev);
06698 ies->vars = NULL;
06699 ast_channel_datastore_add(p->owner, variablestore);
06700 } else {
06701 if (p->owner)
06702 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
06703 if (variablestore)
06704 ast_channel_datastore_free(variablestore);
06705 if (varlist)
06706 ast_free(varlist);
06707 }
06708 }
06709
06710 if (!res)
06711 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
06712 return res;
06713 }
06714
06715 static int iax2_do_register(struct iax2_registry *reg);
06716
06717 static void __iax2_do_register_s(const void *data)
06718 {
06719 struct iax2_registry *reg = (struct iax2_registry *)data;
06720 reg->expire = -1;
06721 iax2_do_register(reg);
06722 }
06723
06724 static int iax2_do_register_s(const void *data)
06725 {
06726 #ifdef SCHED_MULTITHREADED
06727 if (schedule_action(__iax2_do_register_s, data))
06728 #endif
06729 __iax2_do_register_s(data);
06730 return 0;
06731 }
06732
06733 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06734 {
06735 int newcall = 0;
06736 char newip[256];
06737 struct iax_ie_data ied;
06738 struct sockaddr_in new;
06739
06740
06741 memset(&ied, 0, sizeof(ied));
06742 if (ies->apparent_addr)
06743 memmove(&new, ies->apparent_addr, sizeof(new));
06744 if (ies->callno)
06745 newcall = ies->callno;
06746 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
06747 ast_log(LOG_WARNING, "Invalid transfer request\n");
06748 return -1;
06749 }
06750 pvt->transfercallno = newcall;
06751 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
06752 inet_aton(newip, &pvt->transfer.sin_addr);
06753 pvt->transfer.sin_family = AF_INET;
06754 pvt->transferring = TRANSFER_BEGIN;
06755 pvt->transferid = ies->transferid;
06756 store_by_transfercallno(pvt);
06757 if (ies->transferid)
06758 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
06759 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
06760 return 0;
06761 }
06762
06763 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06764 {
06765 char exten[256] = "";
06766 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
06767 struct iax2_dpcache *dp = NULL;
06768
06769 if (ies->called_number)
06770 ast_copy_string(exten, ies->called_number, sizeof(exten));
06771
06772 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
06773 status = CACHE_FLAG_EXISTS;
06774 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
06775 status = CACHE_FLAG_CANEXIST;
06776 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
06777 status = CACHE_FLAG_NONEXISTENT;
06778
06779 if (ies->refresh)
06780 expiry = ies->refresh;
06781 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
06782 matchmore = CACHE_FLAG_MATCHMORE;
06783
06784 AST_LIST_LOCK(&dpcache);
06785 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
06786 if (strcmp(dp->exten, exten))
06787 continue;
06788 AST_LIST_REMOVE_CURRENT(peer_list);
06789 dp->callno = 0;
06790 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
06791 if (dp->flags & CACHE_FLAG_PENDING) {
06792 dp->flags &= ~CACHE_FLAG_PENDING;
06793 dp->flags |= status;
06794 dp->flags |= matchmore;
06795 }
06796
06797 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
06798 if (dp->waiters[x] > -1) {
06799 if (write(dp->waiters[x], "asdf", 4) < 0) {
06800 }
06801 }
06802 }
06803 }
06804 AST_LIST_TRAVERSE_SAFE_END;
06805 AST_LIST_UNLOCK(&dpcache);
06806
06807 return 0;
06808 }
06809
06810 static int complete_transfer(int callno, struct iax_ies *ies)
06811 {
06812 int peercallno = 0;
06813 struct chan_iax2_pvt *pvt = iaxs[callno];
06814 struct iax_frame *cur;
06815 jb_frame frame;
06816
06817 if (ies->callno)
06818 peercallno = ies->callno;
06819
06820 if (peercallno < 1) {
06821 ast_log(LOG_WARNING, "Invalid transfer request\n");
06822 return -1;
06823 }
06824 remove_by_transfercallno(pvt);
06825 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
06826 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
06827
06828 pvt->oseqno = 0;
06829 pvt->rseqno = 0;
06830 pvt->iseqno = 0;
06831 pvt->aseqno = 0;
06832
06833 if (pvt->peercallno) {
06834 remove_by_peercallno(pvt);
06835 }
06836 pvt->peercallno = peercallno;
06837
06838 store_by_peercallno(pvt);
06839 pvt->transferring = TRANSFER_NONE;
06840 pvt->svoiceformat = -1;
06841 pvt->voiceformat = 0;
06842 pvt->svideoformat = -1;
06843 pvt->videoformat = 0;
06844 pvt->transfercallno = -1;
06845 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
06846 memset(&pvt->offset, 0, sizeof(pvt->offset));
06847
06848 while(jb_getall(pvt->jb,&frame) == JB_OK)
06849 iax2_frame_free(frame.data);
06850 jb_reset(pvt->jb);
06851 pvt->lag = 0;
06852 pvt->last = 0;
06853 pvt->lastsent = 0;
06854 pvt->nextpred = 0;
06855 pvt->pingtime = DEFAULT_RETRY_TIME;
06856 AST_LIST_LOCK(&frame_queue);
06857 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
06858
06859
06860
06861 if (callno == cur->callno)
06862 cur->retries = -1;
06863 }
06864 AST_LIST_UNLOCK(&frame_queue);
06865 return 0;
06866 }
06867
06868
06869 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
06870 {
06871 struct iax2_registry *reg;
06872
06873 char peer[256] = "";
06874 char msgstatus[60];
06875 int refresh = 60;
06876 char ourip[256] = "<Unspecified>";
06877 struct sockaddr_in oldus;
06878 struct sockaddr_in us;
06879 int oldmsgs;
06880
06881 memset(&us, 0, sizeof(us));
06882 if (ies->apparent_addr)
06883 memmove(&us, ies->apparent_addr, sizeof(us));
06884 if (ies->username)
06885 ast_copy_string(peer, ies->username, sizeof(peer));
06886 if (ies->refresh)
06887 refresh = ies->refresh;
06888 if (ies->calling_number) {
06889
06890 }
06891 reg = iaxs[callno]->reg;
06892 if (!reg) {
06893 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
06894 return -1;
06895 }
06896 memcpy(&oldus, ®->us, sizeof(oldus));
06897 oldmsgs = reg->messages;
06898 if (inaddrcmp(®->addr, sin)) {
06899 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06900 return -1;
06901 }
06902 memcpy(®->us, &us, sizeof(reg->us));
06903 if (ies->msgcount >= 0)
06904 reg->messages = ies->msgcount & 0xffff;
06905
06906
06907
06908 reg->refresh = refresh;
06909 reg->expire = iax2_sched_replace(reg->expire, sched,
06910 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
06911 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
06912 if (reg->messages > 255)
06913 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
06914 else if (reg->messages > 1)
06915 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
06916 else if (reg->messages > 0)
06917 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
06918 else
06919 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
06920 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06921 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
06922 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
06923 }
06924 reg->regstate = REG_STATE_REGISTERED;
06925 return 0;
06926 }
06927
06928 static int iax2_append_register(const char *hostname, const char *username,
06929 const char *secret, const char *porta)
06930 {
06931 struct iax2_registry *reg;
06932
06933 if (!(reg = ast_calloc(1, sizeof(*reg))))
06934 return -1;
06935
06936 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) {
06937 ast_free(reg);
06938 return -1;
06939 }
06940
06941 ast_copy_string(reg->username, username, sizeof(reg->username));
06942
06943 if (secret)
06944 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06945
06946 reg->expire = -1;
06947 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06948 reg->addr.sin_family = AF_INET;
06949 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06950
06951 AST_LIST_LOCK(®istrations);
06952 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
06953 AST_LIST_UNLOCK(®istrations);
06954
06955 return 0;
06956 }
06957
06958 static int iax2_register(const char *value, int lineno)
06959 {
06960 char copy[256];
06961 char *username, *hostname, *secret;
06962 char *porta;
06963 char *stringp=NULL;
06964
06965 if (!value)
06966 return -1;
06967
06968 ast_copy_string(copy, value, sizeof(copy));
06969 stringp = copy;
06970 username = strsep(&stringp, "@");
06971 hostname = strsep(&stringp, "@");
06972
06973 if (!hostname) {
06974 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06975 return -1;
06976 }
06977
06978 stringp = username;
06979 username = strsep(&stringp, ":");
06980 secret = strsep(&stringp, ":");
06981 stringp = hostname;
06982 hostname = strsep(&stringp, ":");
06983 porta = strsep(&stringp, ":");
06984
06985 if (porta && !atoi(porta)) {
06986 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06987 return -1;
06988 }
06989
06990 return iax2_append_register(hostname, username, secret, porta);
06991 }
06992
06993
06994 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06995 {
06996 char multi[256];
06997 char *stringp, *ext;
06998 if (!ast_strlen_zero(regcontext)) {
06999 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
07000 stringp = multi;
07001 while((ext = strsep(&stringp, "&"))) {
07002 if (onoff) {
07003 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
07004 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
07005 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
07006 } else
07007 ast_context_remove_extension(regcontext, ext, 1, NULL);
07008 }
07009 }
07010 }
07011 static void prune_peers(void);
07012
07013 static void unlink_peer(struct iax2_peer *peer)
07014 {
07015 if (peer->expire > -1) {
07016 if (!ast_sched_del(sched, peer->expire)) {
07017 peer->expire = -1;
07018 peer_unref(peer);
07019 }
07020 }
07021
07022 if (peer->pokeexpire > -1) {
07023 if (!ast_sched_del(sched, peer->pokeexpire)) {
07024 peer->pokeexpire = -1;
07025 peer_unref(peer);
07026 }
07027 }
07028
07029 ao2_unlink(peers, peer);
07030 }
07031
07032 static void __expire_registry(const void *data)
07033 {
07034 struct iax2_peer *peer = (struct iax2_peer *) data;
07035
07036 if (!peer)
07037 return;
07038
07039 peer->expire = -1;
07040
07041 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
07042 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
07043 realtime_update_peer(peer->name, &peer->addr, 0);
07044 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07045
07046 memset(&peer->addr, 0, sizeof(peer->addr));
07047
07048 peer->expiry = min_reg_expire;
07049 if (!ast_test_flag(peer, IAX_TEMPONLY))
07050 ast_db_del("IAX/Registry", peer->name);
07051 register_peer_exten(peer, 0);
07052 ast_device_state_changed("IAX2/%s", peer->name);
07053 if (iax2_regfunk)
07054 iax2_regfunk(peer->name, 0);
07055
07056 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
07057 unlink_peer(peer);
07058
07059 peer_unref(peer);
07060 }
07061
07062 static int expire_registry(const void *data)
07063 {
07064 #ifdef SCHED_MULTITHREADED
07065 if (schedule_action(__expire_registry, data))
07066 #endif
07067 __expire_registry(data);
07068 return 0;
07069 }
07070
07071 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
07072
07073 static void reg_source_db(struct iax2_peer *p)
07074 {
07075 char data[80];
07076 struct in_addr in;
07077 char *c, *d;
07078 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
07079 c = strchr(data, ':');
07080 if (c) {
07081 *c = '\0';
07082 c++;
07083 if (inet_aton(data, &in)) {
07084 d = strchr(c, ':');
07085 if (d) {
07086 *d = '\0';
07087 d++;
07088 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
07089 ast_inet_ntoa(in), atoi(c), atoi(d));
07090 iax2_poke_peer(p, 0);
07091 p->expiry = atoi(d);
07092 memset(&p->addr, 0, sizeof(p->addr));
07093 p->addr.sin_family = AF_INET;
07094 p->addr.sin_addr = in;
07095 p->addr.sin_port = htons(atoi(c));
07096 if (p->expire > -1) {
07097 if (!ast_sched_del(sched, p->expire)) {
07098 p->expire = -1;
07099 peer_unref(p);
07100 }
07101 }
07102 ast_device_state_changed("IAX2/%s", p->name);
07103 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07104 if (p->expire == -1)
07105 peer_unref(p);
07106 if (iax2_regfunk)
07107 iax2_regfunk(p->name, 1);
07108 register_peer_exten(p, 1);
07109 }
07110
07111 }
07112 }
07113 }
07114 }
07115
07116
07117
07118
07119
07120
07121
07122 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
07123 {
07124
07125 struct iax_ie_data ied;
07126 struct iax2_peer *p;
07127 int msgcount;
07128 char data[80];
07129 int version;
07130 const char *peer_name;
07131 int res = -1;
07132
07133 memset(&ied, 0, sizeof(ied));
07134
07135 peer_name = ast_strdupa(iaxs[callno]->peer);
07136
07137
07138 ast_mutex_unlock(&iaxsl[callno]);
07139 if (!(p = find_peer(peer_name, 1))) {
07140 ast_mutex_lock(&iaxsl[callno]);
07141 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
07142 return -1;
07143 }
07144 ast_mutex_lock(&iaxsl[callno]);
07145 if (!iaxs[callno])
07146 goto return_unref;
07147
07148 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
07149 if (sin->sin_addr.s_addr) {
07150 time_t nowtime;
07151 time(&nowtime);
07152 realtime_update_peer(peer_name, sin, nowtime);
07153 } else {
07154 realtime_update_peer(peer_name, sin, 0);
07155 }
07156 }
07157 if (inaddrcmp(&p->addr, sin)) {
07158 if (iax2_regfunk)
07159 iax2_regfunk(p->name, 1);
07160
07161 memcpy(&p->addr, sin, sizeof(p->addr));
07162 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
07163 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
07164 ast_db_put("IAX/Registry", p->name, data);
07165 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
07166 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
07167 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
07168 register_peer_exten(p, 1);
07169 ast_device_state_changed("IAX2/%s", p->name);
07170 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
07171 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
07172 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
07173 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
07174 register_peer_exten(p, 0);
07175 ast_db_del("IAX/Registry", p->name);
07176 ast_device_state_changed("IAX2/%s", p->name);
07177 }
07178
07179
07180 iax2_poke_peer(p, callno);
07181 }
07182
07183
07184 if (!iaxs[callno]) {
07185 res = -1;
07186 goto return_unref;
07187 }
07188
07189
07190 p->sockfd = fd;
07191
07192 if (p->expire > -1) {
07193 if (!ast_sched_del(sched, p->expire)) {
07194 p->expire = -1;
07195 peer_unref(p);
07196 }
07197 }
07198
07199 if (!refresh)
07200 refresh = min_reg_expire;
07201 if (refresh > max_reg_expire) {
07202 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07203 p->name, max_reg_expire, refresh);
07204 p->expiry = max_reg_expire;
07205 } else if (refresh < min_reg_expire) {
07206 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07207 p->name, min_reg_expire, refresh);
07208 p->expiry = min_reg_expire;
07209 } else {
07210 p->expiry = refresh;
07211 }
07212 if (p->expiry && sin->sin_addr.s_addr) {
07213 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07214 if (p->expire == -1)
07215 peer_unref(p);
07216 }
07217 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
07218 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
07219 if (sin->sin_addr.s_addr) {
07220 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
07221 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
07222 if (!ast_strlen_zero(p->mailbox)) {
07223 struct ast_event *event;
07224 int new, old;
07225 char *mailbox, *context;
07226
07227 context = mailbox = ast_strdupa(p->mailbox);
07228 strsep(&context, "@");
07229 if (ast_strlen_zero(context))
07230 context = "default";
07231
07232 event = ast_event_get_cached(AST_EVENT_MWI,
07233 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
07234 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
07235 AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
07236 AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_EXISTS,
07237 AST_EVENT_IE_END);
07238 if (event) {
07239 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
07240 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
07241 ast_event_destroy(event);
07242 } else
07243 ast_app_inboxcount(p->mailbox, &new, &old);
07244
07245 if (new > 255)
07246 new = 255;
07247 if (old > 255)
07248 old = 255;
07249 msgcount = (old << 8) | new;
07250
07251 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
07252 }
07253 if (ast_test_flag(p, IAX_HASCALLERID)) {
07254 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
07255 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
07256 }
07257 }
07258 version = iax_check_version(devtype);
07259 if (version)
07260 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
07261
07262 res = 0;
07263
07264 return_unref:
07265 peer_unref(p);
07266
07267 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
07268 }
07269
07270 static int registry_authrequest(int callno)
07271 {
07272 struct iax_ie_data ied;
07273 struct iax2_peer *p;
07274 char challenge[10];
07275 const char *peer_name;
07276 int sentauthmethod;
07277
07278 peer_name = ast_strdupa(iaxs[callno]->peer);
07279
07280
07281 ast_mutex_unlock(&iaxsl[callno]);
07282 if ((p = find_peer(peer_name, 1))) {
07283 last_authmethod = p->authmethods;
07284 }
07285
07286 ast_mutex_lock(&iaxsl[callno]);
07287 if (!iaxs[callno])
07288 goto return_unref;
07289
07290 memset(&ied, 0, sizeof(ied));
07291
07292
07293
07294
07295
07296
07297 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07298 if (!p) {
07299 iaxs[callno]->authmethods = sentauthmethod;
07300 }
07301 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
07302 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
07303
07304 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07305 ast_string_field_set(iaxs[callno], challenge, challenge);
07306 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
07307 }
07308 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
07309
07310 return_unref:
07311 if (p) {
07312 peer_unref(p);
07313 }
07314
07315 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
07316 }
07317
07318 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
07319 {
07320 struct iax2_registry *reg;
07321
07322 struct iax_ie_data ied;
07323 char peer[256] = "";
07324 char challenge[256] = "";
07325 int res;
07326 int authmethods = 0;
07327 if (ies->authmethods)
07328 authmethods = ies->authmethods;
07329 if (ies->username)
07330 ast_copy_string(peer, ies->username, sizeof(peer));
07331 if (ies->challenge)
07332 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
07333 memset(&ied, 0, sizeof(ied));
07334 reg = iaxs[callno]->reg;
07335 if (reg) {
07336 if (inaddrcmp(®->addr, sin)) {
07337 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07338 return -1;
07339 }
07340 if (ast_strlen_zero(reg->secret)) {
07341 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
07342 reg->regstate = REG_STATE_NOAUTH;
07343 return -1;
07344 }
07345 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07346 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07347 if (reg->secret[0] == '[') {
07348 char tmpkey[256];
07349 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
07350 tmpkey[strlen(tmpkey) - 1] = '\0';
07351 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
07352 } else
07353 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
07354 if (!res) {
07355 reg->regstate = REG_STATE_AUTHSENT;
07356 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07357 } else
07358 return -1;
07359 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
07360 } else
07361 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
07362 return -1;
07363 }
07364
07365 static void stop_stuff(int callno)
07366 {
07367 iax2_destroy_helper(iaxs[callno]);
07368 }
07369
07370 static void __auth_reject(const void *nothing)
07371 {
07372
07373 int callno = (int)(long)(nothing);
07374 struct iax_ie_data ied;
07375 ast_mutex_lock(&iaxsl[callno]);
07376 if (iaxs[callno]) {
07377 memset(&ied, 0, sizeof(ied));
07378 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
07379 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
07380 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
07381 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
07382 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
07383 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07384 }
07385 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
07386 }
07387 ast_mutex_unlock(&iaxsl[callno]);
07388 }
07389
07390 static int auth_reject(const void *data)
07391 {
07392 int callno = (int)(long)(data);
07393 ast_mutex_lock(&iaxsl[callno]);
07394 if (iaxs[callno])
07395 iaxs[callno]->authid = -1;
07396 ast_mutex_unlock(&iaxsl[callno]);
07397 #ifdef SCHED_MULTITHREADED
07398 if (schedule_action(__auth_reject, data))
07399 #endif
07400 __auth_reject(data);
07401 return 0;
07402 }
07403
07404 static int auth_fail(int callno, int failcode)
07405 {
07406
07407
07408 if (iaxs[callno]) {
07409 iaxs[callno]->authfail = failcode;
07410 if (delayreject) {
07411 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
07412 sched, 1000, auth_reject, (void *)(long)callno);
07413 } else
07414 auth_reject((void *)(long)callno);
07415 }
07416 return 0;
07417 }
07418
07419 static void __auto_hangup(const void *nothing)
07420 {
07421
07422 int callno = (int)(long)(nothing);
07423 struct iax_ie_data ied;
07424 ast_mutex_lock(&iaxsl[callno]);
07425 if (iaxs[callno]) {
07426 memset(&ied, 0, sizeof(ied));
07427 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
07428 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
07429 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
07430 }
07431 ast_mutex_unlock(&iaxsl[callno]);
07432 }
07433
07434 static int auto_hangup(const void *data)
07435 {
07436 int callno = (int)(long)(data);
07437 ast_mutex_lock(&iaxsl[callno]);
07438 if (iaxs[callno]) {
07439 iaxs[callno]->autoid = -1;
07440 }
07441 ast_mutex_unlock(&iaxsl[callno]);
07442 #ifdef SCHED_MULTITHREADED
07443 if (schedule_action(__auto_hangup, data))
07444 #endif
07445 __auto_hangup(data);
07446 return 0;
07447 }
07448
07449 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
07450 {
07451 struct iax_ie_data ied;
07452
07453 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
07454 sched, 30000, auto_hangup, (void *)(long)callno);
07455 memset(&ied, 0, sizeof(ied));
07456 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
07457 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
07458 dp->flags |= CACHE_FLAG_TRANSMITTED;
07459 }
07460
07461 static int iax2_vnak(int callno)
07462 {
07463 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
07464 }
07465
07466 static void vnak_retransmit(int callno, int last)
07467 {
07468 struct iax_frame *f;
07469
07470 AST_LIST_LOCK(&frame_queue);
07471 AST_LIST_TRAVERSE(&frame_queue, f, list) {
07472
07473 if ((f->callno == callno) && iaxs[f->callno] &&
07474 ((unsigned char ) (f->oseqno - last) < 128) &&
07475 (f->retries >= 0)) {
07476 send_packet(f);
07477 }
07478 }
07479 AST_LIST_UNLOCK(&frame_queue);
07480 }
07481
07482 static void __iax2_poke_peer_s(const void *data)
07483 {
07484 struct iax2_peer *peer = (struct iax2_peer *)data;
07485 iax2_poke_peer(peer, 0);
07486 peer_unref(peer);
07487 }
07488
07489 static int iax2_poke_peer_s(const void *data)
07490 {
07491 struct iax2_peer *peer = (struct iax2_peer *)data;
07492 peer->pokeexpire = -1;
07493 #ifdef SCHED_MULTITHREADED
07494 if (schedule_action(__iax2_poke_peer_s, data))
07495 #endif
07496 __iax2_poke_peer_s(data);
07497 return 0;
07498 }
07499
07500 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
07501 {
07502 int res = 0;
07503 struct iax_frame *fr;
07504 struct ast_iax2_meta_hdr *meta;
07505 struct ast_iax2_meta_trunk_hdr *mth;
07506 int calls = 0;
07507
07508
07509 fr = (struct iax_frame *)tpeer->trunkdata;
07510
07511 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
07512 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
07513 if (tpeer->trunkdatalen) {
07514
07515 meta->zeros = 0;
07516 meta->metacmd = IAX_META_TRUNK;
07517 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
07518 meta->cmddata = IAX_META_TRUNK_MINI;
07519 else
07520 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
07521 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
07522
07523 fr->direction = DIRECTION_OUTGRESS;
07524 fr->retrans = -1;
07525 fr->transfer = 0;
07526
07527 fr->data = fr->afdata;
07528 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
07529 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
07530 calls = tpeer->calls;
07531 #if 0
07532 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));
07533 #endif
07534
07535 tpeer->trunkdatalen = 0;
07536 tpeer->calls = 0;
07537 }
07538 if (res < 0)
07539 return res;
07540 return calls;
07541 }
07542
07543 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
07544 {
07545
07546 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
07547 return 1;
07548 return 0;
07549 }
07550
07551 static int timing_read(int *id, int fd, short events, void *cbdata)
07552 {
07553 char buf[1024];
07554 int res, processed = 0, totalcalls = 0;
07555 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
07556 #ifdef DAHDI_TIMERACK
07557 int x = 1;
07558 #endif
07559 struct timeval now = ast_tvnow();
07560 if (iaxtrunkdebug)
07561 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
07562 if (events & AST_IO_PRI) {
07563 #ifdef DAHDI_TIMERACK
07564
07565 if (ioctl(fd, DAHDI_TIMERACK, &x)) {
07566 ast_log(LOG_WARNING, "Unable to acknowledge DAHDI timer. IAX trunking will fail!\n");
07567 usleep(1);
07568 return -1;
07569 }
07570 #endif
07571 } else {
07572
07573 res = read(fd, buf, sizeof(buf));
07574 if (res < 1) {
07575 ast_log(LOG_WARNING, "Unable to read from timing fd\n");
07576 return 1;
07577 }
07578 }
07579
07580 AST_LIST_LOCK(&tpeers);
07581 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
07582 processed++;
07583 res = 0;
07584 ast_mutex_lock(&tpeer->lock);
07585
07586
07587 if (!drop && iax2_trunk_expired(tpeer, &now)) {
07588
07589
07590 AST_LIST_REMOVE_CURRENT(list);
07591 drop = tpeer;
07592 } else {
07593 res = send_trunk(tpeer, &now);
07594 trunk_timed++;
07595 if (iaxtrunkdebug)
07596 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);
07597 }
07598 totalcalls += res;
07599 res = 0;
07600 ast_mutex_unlock(&tpeer->lock);
07601 }
07602 AST_LIST_TRAVERSE_SAFE_END;
07603 AST_LIST_UNLOCK(&tpeers);
07604
07605 if (drop) {
07606 ast_mutex_lock(&drop->lock);
07607
07608
07609 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
07610 if (drop->trunkdata) {
07611 ast_free(drop->trunkdata);
07612 drop->trunkdata = NULL;
07613 }
07614 ast_mutex_unlock(&drop->lock);
07615 ast_mutex_destroy(&drop->lock);
07616 ast_free(drop);
07617
07618 }
07619
07620 if (iaxtrunkdebug)
07621 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
07622 iaxtrunkdebug = 0;
07623
07624 return 1;
07625 }
07626
07627 struct dpreq_data {
07628 int callno;
07629 char context[AST_MAX_EXTENSION];
07630 char callednum[AST_MAX_EXTENSION];
07631 char *callerid;
07632 };
07633
07634 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
07635 {
07636 unsigned short dpstatus = 0;
07637 struct iax_ie_data ied1;
07638 int mm;
07639
07640 memset(&ied1, 0, sizeof(ied1));
07641 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
07642
07643 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
07644 dpstatus = IAX_DPSTATUS_EXISTS;
07645 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
07646 dpstatus = IAX_DPSTATUS_CANEXIST;
07647 } else {
07648 dpstatus = IAX_DPSTATUS_NONEXISTENT;
07649 }
07650 if (ast_ignore_pattern(context, callednum))
07651 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
07652 if (mm)
07653 dpstatus |= IAX_DPSTATUS_MATCHMORE;
07654 if (!skiplock)
07655 ast_mutex_lock(&iaxsl[callno]);
07656 if (iaxs[callno]) {
07657 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
07658 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
07659 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
07660 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
07661 }
07662 if (!skiplock)
07663 ast_mutex_unlock(&iaxsl[callno]);
07664 }
07665
07666 static void *dp_lookup_thread(void *data)
07667 {
07668
07669 struct dpreq_data *dpr = data;
07670 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
07671 if (dpr->callerid)
07672 ast_free(dpr->callerid);
07673 ast_free(dpr);
07674 return NULL;
07675 }
07676
07677 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
07678 {
07679 pthread_t newthread;
07680 struct dpreq_data *dpr;
07681
07682 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
07683 return;
07684
07685 dpr->callno = callno;
07686 ast_copy_string(dpr->context, context, sizeof(dpr->context));
07687 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
07688 if (callerid)
07689 dpr->callerid = ast_strdup(callerid);
07690 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
07691 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
07692 }
07693 }
07694
07695 struct iax_dual {
07696 struct ast_channel *chan1;
07697 struct ast_channel *chan2;
07698 };
07699
07700 static void *iax_park_thread(void *stuff)
07701 {
07702 struct ast_channel *chan1, *chan2;
07703 struct iax_dual *d;
07704 struct ast_frame *f;
07705 int ext;
07706 int res;
07707 d = stuff;
07708 chan1 = d->chan1;
07709 chan2 = d->chan2;
07710 ast_free(d);
07711 f = ast_read(chan1);
07712 if (f)
07713 ast_frfree(f);
07714 res = ast_park_call(chan1, chan2, 0, &ext);
07715 ast_hangup(chan2);
07716 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
07717 return NULL;
07718 }
07719
07720 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
07721 {
07722 struct iax_dual *d;
07723 struct ast_channel *chan1m, *chan2m;
07724 pthread_t th;
07725 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
07726 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
07727 if (chan2m && chan1m) {
07728
07729 chan1m->readformat = chan1->readformat;
07730 chan1m->writeformat = chan1->writeformat;
07731 ast_channel_masquerade(chan1m, chan1);
07732
07733 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
07734 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
07735 chan1m->priority = chan1->priority;
07736
07737
07738
07739
07740 chan2m->readformat = chan2->readformat;
07741 chan2m->writeformat = chan2->writeformat;
07742 ast_channel_masquerade(chan2m, chan2);
07743
07744 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
07745 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
07746 chan2m->priority = chan2->priority;
07747 if (ast_do_masquerade(chan2m)) {
07748 ast_log(LOG_WARNING, "Masquerade failed :(\n");
07749 ast_hangup(chan2m);
07750 return -1;
07751 }
07752 } else {
07753 if (chan1m)
07754 ast_hangup(chan1m);
07755 if (chan2m)
07756 ast_hangup(chan2m);
07757 return -1;
07758 }
07759 if ((d = ast_calloc(1, sizeof(*d)))) {
07760 d->chan1 = chan1m;
07761 d->chan2 = chan2m;
07762 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
07763 return 0;
07764 }
07765 ast_free(d);
07766 }
07767 return -1;
07768 }
07769
07770
07771 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
07772
07773 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
07774 {
07775 unsigned int ourver;
07776 char rsi[80];
07777 snprintf(rsi, sizeof(rsi), "si-%s", si);
07778 if (iax_provision_version(&ourver, rsi, 1))
07779 return 0;
07780 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
07781 if (ourver != ver)
07782 iax2_provision(sin, sockfd, NULL, rsi, 1);
07783 return 0;
07784 }
07785
07786 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
07787 {
07788 jb_info stats;
07789 jb_getinfo(pvt->jb, &stats);
07790
07791 memset(iep, 0, sizeof(*iep));
07792
07793 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
07794 if(stats.frames_in == 0) stats.frames_in = 1;
07795 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
07796 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
07797 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
07798 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
07799 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
07800 }
07801
07802 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
07803 {
07804 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
07805 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
07806 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
07807 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
07808 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
07809 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
07810 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
07811 }
07812
07813 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
07814 {
07815 int i;
07816 unsigned int length, offset = 0;
07817 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
07818
07819 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
07820 length = ies->ospblocklength[i];
07821 if (length != 0) {
07822 if (length > IAX_MAX_OSPBLOCK_SIZE) {
07823
07824 offset = 0;
07825 break;
07826 } else {
07827 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
07828 offset += length;
07829 }
07830 } else {
07831 break;
07832 }
07833 }
07834 *(full_osptoken + offset) = '\0';
07835 if (strlen(full_osptoken) != offset) {
07836
07837 *full_osptoken = '\0';
07838 }
07839
07840 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
07841 }
07842
07843 static void log_jitterstats(unsigned short callno)
07844 {
07845 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
07846 jb_info jbinfo;
07847
07848 ast_mutex_lock(&iaxsl[callno]);
07849 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
07850 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
07851 jb_getinfo(iaxs[callno]->jb, &jbinfo);
07852 localjitter = jbinfo.jitter;
07853 localdelay = jbinfo.current - jbinfo.min;
07854 locallost = jbinfo.frames_lost;
07855 locallosspct = jbinfo.losspct/1000;
07856 localdropped = jbinfo.frames_dropped;
07857 localooo = jbinfo.frames_ooo;
07858 localpackets = jbinfo.frames_in;
07859 }
07860 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",
07861 iaxs[callno]->owner->name,
07862 iaxs[callno]->pingtime,
07863 localjitter,
07864 localdelay,
07865 locallost,
07866 locallosspct,
07867 localdropped,
07868 localooo,
07869 localpackets,
07870 iaxs[callno]->remote_rr.jitter,
07871 iaxs[callno]->remote_rr.delay,
07872 iaxs[callno]->remote_rr.losscnt,
07873 iaxs[callno]->remote_rr.losspct/1000,
07874 iaxs[callno]->remote_rr.dropped,
07875 iaxs[callno]->remote_rr.ooo,
07876 iaxs[callno]->remote_rr.packets);
07877 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",
07878 iaxs[callno]->owner->name,
07879 iaxs[callno]->pingtime,
07880 localjitter,
07881 localdelay,
07882 locallost,
07883 locallosspct,
07884 localdropped,
07885 localooo,
07886 localpackets,
07887 iaxs[callno]->remote_rr.jitter,
07888 iaxs[callno]->remote_rr.delay,
07889 iaxs[callno]->remote_rr.losscnt,
07890 iaxs[callno]->remote_rr.losspct/1000,
07891 iaxs[callno]->remote_rr.dropped,
07892 iaxs[callno]->remote_rr.ooo,
07893 iaxs[callno]->remote_rr.packets);
07894 }
07895 ast_mutex_unlock(&iaxsl[callno]);
07896 }
07897
07898 static int socket_process(struct iax2_thread *thread);
07899
07900
07901
07902
07903 static void handle_deferred_full_frames(struct iax2_thread *thread)
07904 {
07905 struct iax2_pkt_buf *pkt_buf;
07906
07907 ast_mutex_lock(&thread->lock);
07908
07909 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
07910 ast_mutex_unlock(&thread->lock);
07911
07912 thread->buf = pkt_buf->buf;
07913 thread->buf_len = pkt_buf->len;
07914 thread->buf_size = pkt_buf->len + 1;
07915
07916 socket_process(thread);
07917
07918 thread->buf = NULL;
07919 ast_free(pkt_buf);
07920
07921 ast_mutex_lock(&thread->lock);
07922 }
07923
07924 ast_mutex_unlock(&thread->lock);
07925 }
07926
07927
07928
07929
07930
07931
07932
07933 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
07934 {
07935 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
07936 struct ast_iax2_full_hdr *fh, *cur_fh;
07937
07938 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
07939 return;
07940
07941 pkt_buf->len = from_here->buf_len;
07942 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
07943
07944 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
07945 ast_mutex_lock(&to_here->lock);
07946 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
07947 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
07948 if (fh->oseqno < cur_fh->oseqno) {
07949 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
07950 break;
07951 }
07952 }
07953 AST_LIST_TRAVERSE_SAFE_END
07954
07955 if (!cur_pkt_buf)
07956 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
07957
07958 ast_mutex_unlock(&to_here->lock);
07959 }
07960
07961 static int socket_read(int *id, int fd, short events, void *cbdata)
07962 {
07963 struct iax2_thread *thread;
07964 socklen_t len;
07965 time_t t;
07966 static time_t last_errtime = 0;
07967 struct ast_iax2_full_hdr *fh;
07968
07969 if (!(thread = find_idle_thread())) {
07970 time(&t);
07971 if (t != last_errtime)
07972 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
07973 last_errtime = t;
07974 usleep(1);
07975 return 1;
07976 }
07977
07978 len = sizeof(thread->iosin);
07979 thread->iofd = fd;
07980 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
07981 thread->buf_size = sizeof(thread->readbuf);
07982 thread->buf = thread->readbuf;
07983 if (thread->buf_len < 0) {
07984 if (errno != ECONNREFUSED && errno != EAGAIN)
07985 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
07986 handle_error();
07987 thread->iostate = IAX_IOSTATE_IDLE;
07988 signal_condition(&thread->lock, &thread->cond);
07989 return 1;
07990 }
07991 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
07992 thread->iostate = IAX_IOSTATE_IDLE;
07993 signal_condition(&thread->lock, &thread->cond);
07994 return 1;
07995 }
07996
07997
07998
07999
08000 fh = (struct ast_iax2_full_hdr *) thread->buf;
08001 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
08002 struct iax2_thread *cur = NULL;
08003 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
08004
08005 AST_LIST_LOCK(&active_list);
08006 AST_LIST_TRAVERSE(&active_list, cur, list) {
08007 if ((cur->ffinfo.callno == callno) &&
08008 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
08009 break;
08010 }
08011 if (cur) {
08012
08013
08014 defer_full_frame(thread, cur);
08015 AST_LIST_UNLOCK(&active_list);
08016 thread->iostate = IAX_IOSTATE_IDLE;
08017 signal_condition(&thread->lock, &thread->cond);
08018 return 1;
08019 } else {
08020
08021 thread->ffinfo.callno = callno;
08022 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
08023 thread->ffinfo.type = fh->type;
08024 thread->ffinfo.csub = fh->csub;
08025 }
08026 AST_LIST_UNLOCK(&active_list);
08027 }
08028
08029
08030 thread->iostate = IAX_IOSTATE_READY;
08031 #ifdef DEBUG_SCHED_MULTITHREAD
08032 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
08033 #endif
08034 signal_condition(&thread->lock, &thread->cond);
08035
08036 return 1;
08037 }
08038
08039 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
08040 struct iax_frame *fr)
08041 {
08042 unsigned char metatype;
08043 struct ast_iax2_meta_trunk_mini *mtm;
08044 struct ast_iax2_meta_trunk_hdr *mth;
08045 struct ast_iax2_meta_trunk_entry *mte;
08046 struct iax2_trunk_peer *tpeer;
08047 unsigned int ts;
08048 void *ptr;
08049 struct timeval rxtrunktime;
08050 struct ast_frame f = { 0, };
08051
08052 if (packet_len < sizeof(*meta)) {
08053 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
08054 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08055 return 1;
08056 }
08057
08058 if (meta->metacmd != IAX_META_TRUNK)
08059 return 1;
08060
08061 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
08062 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
08063 (int) (sizeof(*meta) + sizeof(*mth)));
08064 return 1;
08065 }
08066 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
08067 ts = ntohl(mth->ts);
08068 metatype = meta->cmddata;
08069 packet_len -= (sizeof(*meta) + sizeof(*mth));
08070 ptr = mth->data;
08071 tpeer = find_tpeer(sin, sockfd);
08072 if (!tpeer) {
08073 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
08074 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08075 return 1;
08076 }
08077 tpeer->trunkact = ast_tvnow();
08078 if (!ts || ast_tvzero(tpeer->rxtrunktime))
08079 tpeer->rxtrunktime = tpeer->trunkact;
08080 rxtrunktime = tpeer->rxtrunktime;
08081 ast_mutex_unlock(&tpeer->lock);
08082 while (packet_len >= sizeof(*mte)) {
08083
08084 unsigned short callno, trunked_ts, len;
08085
08086 if (metatype == IAX_META_TRUNK_MINI) {
08087 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
08088 ptr += sizeof(*mtm);
08089 packet_len -= sizeof(*mtm);
08090 len = ntohs(mtm->len);
08091 callno = ntohs(mtm->mini.callno);
08092 trunked_ts = ntohs(mtm->mini.ts);
08093 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
08094 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
08095 ptr += sizeof(*mte);
08096 packet_len -= sizeof(*mte);
08097 len = ntohs(mte->len);
08098 callno = ntohs(mte->callno);
08099 trunked_ts = 0;
08100 } else {
08101 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08102 break;
08103 }
08104
08105 if (len > packet_len)
08106 break;
08107 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
08108 if (!fr->callno)
08109 continue;
08110
08111
08112
08113
08114 memset(&f, 0, sizeof(f));
08115 f.frametype = AST_FRAME_VOICE;
08116 if (!iaxs[fr->callno]) {
08117
08118 } else if (iaxs[fr->callno]->voiceformat == 0) {
08119 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
08120 iax2_vnak(fr->callno);
08121 } else {
08122 f.subclass = iaxs[fr->callno]->voiceformat;
08123 f.datalen = len;
08124 if (f.datalen >= 0) {
08125 if (f.datalen)
08126 f.data = ptr;
08127 else
08128 f.data = NULL;
08129 if (trunked_ts)
08130 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
08131 else
08132 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
08133
08134 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08135 struct iax_frame *duped_fr;
08136
08137
08138 f.src = "IAX2";
08139 f.mallocd = 0;
08140 f.offset = 0;
08141 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
08142 f.samples = ast_codec_get_samples(&f);
08143 else
08144 f.samples = 0;
08145 fr->outoforder = 0;
08146 iax_frame_wrap(fr, &f);
08147 duped_fr = iaxfrdup2(fr);
08148 if (duped_fr)
08149 schedule_delivery(duped_fr, 1, 1, &fr->ts);
08150 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
08151 iaxs[fr->callno]->last = fr->ts;
08152 }
08153 } else {
08154 ast_log(LOG_WARNING, "Datalen < 0?\n");
08155 }
08156 }
08157 ast_mutex_unlock(&iaxsl[fr->callno]);
08158 ptr += len;
08159 packet_len -= len;
08160 }
08161
08162 return 1;
08163 }
08164
08165 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
08166 {
08167 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
08168 AST_LIST_HEAD(, ast_var_t) *varlist;
08169 struct ast_var_t *var;
08170
08171 if (!variablestore) {
08172 *buf = '\0';
08173 return 0;
08174 }
08175 varlist = variablestore->data;
08176
08177 AST_LIST_LOCK(varlist);
08178 AST_LIST_TRAVERSE(varlist, var, entries) {
08179 if (strcmp(var->name, data) == 0) {
08180 ast_copy_string(buf, var->value, len);
08181 break;
08182 }
08183 }
08184 AST_LIST_UNLOCK(varlist);
08185 return 0;
08186 }
08187
08188 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
08189 {
08190 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
08191 AST_LIST_HEAD(, ast_var_t) *varlist;
08192 struct ast_var_t *var;
08193
08194 if (!variablestore) {
08195 variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
08196 if (!variablestore) {
08197 ast_log(LOG_ERROR, "Memory allocation error\n");
08198 return -1;
08199 }
08200 varlist = ast_calloc(1, sizeof(*varlist));
08201 if (!varlist) {
08202 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
08203 return -1;
08204 }
08205
08206 AST_LIST_HEAD_INIT(varlist);
08207 variablestore->data = varlist;
08208 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08209 ast_channel_datastore_add(chan, variablestore);
08210 } else
08211 varlist = variablestore->data;
08212
08213 AST_LIST_LOCK(varlist);
08214 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
08215 if (strcmp(var->name, data) == 0) {
08216 AST_LIST_REMOVE_CURRENT(entries);
08217 ast_var_delete(var);
08218 break;
08219 }
08220 }
08221 AST_LIST_TRAVERSE_SAFE_END;
08222 var = ast_var_assign(data, value);
08223 if (var)
08224 AST_LIST_INSERT_TAIL(varlist, var, entries);
08225 else
08226 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
08227 AST_LIST_UNLOCK(varlist);
08228 return 0;
08229 }
08230
08231 static struct ast_custom_function iaxvar_function = {
08232 .name = "IAXVAR",
08233 .synopsis = "Sets or retrieves a remote variable",
08234 .syntax = "IAXVAR(<varname>)",
08235 .read = acf_iaxvar_read,
08236 .write = acf_iaxvar_write,
08237 };
08238
08239 static int socket_process(struct iax2_thread *thread)
08240 {
08241 struct sockaddr_in sin;
08242 int res;
08243 int updatehistory=1;
08244 int new = NEW_PREVENT;
08245 int dcallno = 0;
08246 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
08247 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
08248 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
08249 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
08250 struct iax_frame *fr;
08251 struct iax_frame *cur;
08252 struct ast_frame f = { 0, };
08253 struct ast_channel *c = NULL;
08254 struct iax2_dpcache *dp;
08255 struct iax2_peer *peer;
08256 struct iax_ies ies;
08257 struct iax_ie_data ied0, ied1;
08258 int format;
08259 int fd;
08260 int exists;
08261 int minivid = 0;
08262 char empty[32]="";
08263 struct iax_frame *duped_fr;
08264 char host_pref_buf[128];
08265 char caller_pref_buf[128];
08266 struct ast_codec_pref pref;
08267 char *using_prefs = "mine";
08268
08269
08270 fr = alloca(sizeof(*fr) + 4096);
08271 memset(fr, 0, sizeof(*fr));
08272 fr->afdatalen = 4096;
08273
08274
08275 res = thread->buf_len;
08276 fd = thread->iofd;
08277 memcpy(&sin, &thread->iosin, sizeof(sin));
08278
08279 if (res < sizeof(*mh)) {
08280 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
08281 return 1;
08282 }
08283 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
08284 if (res < sizeof(*vh)) {
08285 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));
08286 return 1;
08287 }
08288
08289
08290 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
08291 minivid = 1;
08292 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
08293 return socket_process_meta(res, meta, &sin, fd, fr);
08294
08295 #ifdef DEBUG_SUPPORT
08296 if (iaxdebug && (res >= sizeof(*fh)))
08297 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
08298 #endif
08299 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08300 if (res < sizeof(*fh)) {
08301 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));
08302 return 1;
08303 }
08304
08305
08306 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
08307
08308 f.frametype = fh->type;
08309 if (f.frametype == AST_FRAME_VIDEO) {
08310 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
08311 } else {
08312 f.subclass = uncompress_subclass(fh->csub);
08313 }
08314
08315
08316 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
08317
08318 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1);
08319 return 1;
08320 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
08321
08322 return 1;
08323 }
08324
08325 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
08326 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
08327 (f.subclass == IAX_COMMAND_REGREL)))
08328 new = NEW_ALLOW;
08329 } else {
08330
08331 f.frametype = AST_FRAME_NULL;
08332 f.subclass = 0;
08333 }
08334
08335 if (!fr->callno) {
08336 int check_dcallno = 0;
08337
08338
08339
08340
08341
08342
08343
08344
08345
08346
08347
08348
08349
08350 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08351 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
08352 }
08353
08354 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
08355 }
08356
08357 if (fr->callno > 0)
08358 ast_mutex_lock(&iaxsl[fr->callno]);
08359
08360 if (!fr->callno || !iaxs[fr->callno]) {
08361
08362
08363 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08364
08365 if (((f.subclass != IAX_COMMAND_INVAL) &&
08366 (f.subclass != IAX_COMMAND_TXCNT) &&
08367 (f.subclass != IAX_COMMAND_TXACC) &&
08368 (f.subclass != IAX_COMMAND_FWDOWNL))||
08369 (f.frametype != AST_FRAME_IAX))
08370 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
08371 fd);
08372 }
08373 if (fr->callno > 0)
08374 ast_mutex_unlock(&iaxsl[fr->callno]);
08375 return 1;
08376 }
08377 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
08378 if (decrypt_frame(fr->callno, fh, &f, &res)) {
08379 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
08380 ast_mutex_unlock(&iaxsl[fr->callno]);
08381 return 1;
08382 }
08383 #ifdef DEBUG_SUPPORT
08384 else if (iaxdebug)
08385 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
08386 #endif
08387 }
08388
08389
08390 iaxs[fr->callno]->frames_received++;
08391
08392 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
08393 f.subclass != IAX_COMMAND_TXCNT &&
08394 f.subclass != IAX_COMMAND_TXACC) {
08395 unsigned short new_peercallno;
08396
08397 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
08398 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
08399 if (iaxs[fr->callno]->peercallno) {
08400 remove_by_peercallno(iaxs[fr->callno]);
08401 }
08402 iaxs[fr->callno]->peercallno = new_peercallno;
08403 store_by_peercallno(iaxs[fr->callno]);
08404 }
08405 }
08406 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08407 if (iaxdebug)
08408 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
08409
08410 fr->oseqno = fh->oseqno;
08411 fr->iseqno = fh->iseqno;
08412 fr->ts = ntohl(fh->ts);
08413 #ifdef IAXTESTS
08414 if (test_resync) {
08415 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
08416 fr->ts += test_resync;
08417 }
08418 #endif
08419 #if 0
08420 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
08421 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
08422 (f.subclass == IAX_COMMAND_NEW ||
08423 f.subclass == IAX_COMMAND_AUTHREQ ||
08424 f.subclass == IAX_COMMAND_ACCEPT ||
08425 f.subclass == IAX_COMMAND_REJECT)) ) )
08426 #endif
08427 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
08428 updatehistory = 0;
08429 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
08430 (iaxs[fr->callno]->iseqno ||
08431 ((f.subclass != IAX_COMMAND_TXCNT) &&
08432 (f.subclass != IAX_COMMAND_TXREADY) &&
08433 (f.subclass != IAX_COMMAND_TXREL) &&
08434 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
08435 (f.subclass != IAX_COMMAND_TXACC)) ||
08436 (f.frametype != AST_FRAME_IAX))) {
08437 if (
08438 ((f.subclass != IAX_COMMAND_ACK) &&
08439 (f.subclass != IAX_COMMAND_INVAL) &&
08440 (f.subclass != IAX_COMMAND_TXCNT) &&
08441 (f.subclass != IAX_COMMAND_TXREADY) &&
08442 (f.subclass != IAX_COMMAND_TXREL) &&
08443 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
08444 (f.subclass != IAX_COMMAND_TXACC) &&
08445 (f.subclass != IAX_COMMAND_VNAK)) ||
08446 (f.frametype != AST_FRAME_IAX)) {
08447
08448 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
08449 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
08450
08451
08452 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
08453
08454 if ((f.frametype != AST_FRAME_IAX) ||
08455 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
08456 ast_debug(1, "Acking anyway\n");
08457
08458
08459 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08460 }
08461 } else {
08462
08463 iax2_vnak(fr->callno);
08464 }
08465 ast_mutex_unlock(&iaxsl[fr->callno]);
08466 return 1;
08467 }
08468 } else {
08469
08470 if (((f.subclass != IAX_COMMAND_ACK) &&
08471 (f.subclass != IAX_COMMAND_INVAL) &&
08472 (f.subclass != IAX_COMMAND_TXCNT) &&
08473 (f.subclass != IAX_COMMAND_TXACC) &&
08474 (f.subclass != IAX_COMMAND_VNAK)) ||
08475 (f.frametype != AST_FRAME_IAX))
08476 iaxs[fr->callno]->iseqno++;
08477 }
08478
08479 if (res < sizeof(*fh)) {
08480 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*fh));
08481 ast_mutex_unlock(&iaxsl[fr->callno]);
08482 return 1;
08483 }
08484
08485 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
08486 if (res < thread->buf_size)
08487 thread->buf[res++] = '\0';
08488 else
08489 thread->buf[res - 1] = '\0';
08490 }
08491 f.datalen = res - sizeof(*fh);
08492
08493
08494
08495 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
08496 ((f.subclass != IAX_COMMAND_INVAL) ||
08497 (f.frametype != AST_FRAME_IAX))) {
08498 unsigned char x;
08499 int call_to_destroy;
08500
08501
08502
08503 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
08504 if (fr->iseqno == x)
08505 break;
08506 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
08507
08508
08509 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
08510
08511 if (iaxdebug)
08512 ast_debug(1, "Cancelling transmission of packet %d\n", x);
08513 call_to_destroy = 0;
08514 AST_LIST_LOCK(&frame_queue);
08515 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08516
08517 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
08518 cur->retries = -1;
08519
08520 if (cur->final)
08521 call_to_destroy = fr->callno;
08522 }
08523 }
08524 AST_LIST_UNLOCK(&frame_queue);
08525 if (call_to_destroy) {
08526 if (iaxdebug)
08527 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
08528 ast_mutex_lock(&iaxsl[call_to_destroy]);
08529 iax2_destroy(call_to_destroy);
08530 ast_mutex_unlock(&iaxsl[call_to_destroy]);
08531 }
08532 }
08533
08534 if (iaxs[fr->callno])
08535 iaxs[fr->callno]->rseqno = fr->iseqno;
08536 else {
08537
08538 ast_mutex_unlock(&iaxsl[fr->callno]);
08539 return 1;
08540 }
08541 } else {
08542 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
08543 }
08544 }
08545 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
08546 ((f.frametype != AST_FRAME_IAX) ||
08547 ((f.subclass != IAX_COMMAND_TXACC) &&
08548 (f.subclass != IAX_COMMAND_TXCNT)))) {
08549
08550 ast_mutex_unlock(&iaxsl[fr->callno]);
08551 return 1;
08552 }
08553
08554 if (f.datalen) {
08555 if (f.frametype == AST_FRAME_IAX) {
08556 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
08557 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
08558 ast_mutex_unlock(&iaxsl[fr->callno]);
08559 return 1;
08560 }
08561 f.data = NULL;
08562 f.datalen = 0;
08563 } else {
08564 f.data = thread->buf + sizeof(*fh);
08565 memset(&ies, 0, sizeof(ies));
08566 }
08567 } else {
08568 if (f.frametype == AST_FRAME_IAX)
08569 f.data = NULL;
08570 else
08571 f.data = empty;
08572 memset(&ies, 0, sizeof(ies));
08573 }
08574
08575
08576
08577
08578 if ((f.frametype == AST_FRAME_VOICE) ||
08579 (f.frametype == AST_FRAME_VIDEO) ||
08580 (f.frametype == AST_FRAME_IAX)) {
08581 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
08582 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08583 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
08584 ast_mutex_unlock(&iaxsl[fr->callno]);
08585 return 1;
08586 }
08587 }
08588
08589 if (ies.vars) {
08590 struct ast_datastore *variablestore;
08591 struct ast_variable *var, *prev = NULL;
08592 AST_LIST_HEAD(, ast_var_t) *varlist;
08593 if ((c = iaxs[fr->callno]->owner)) {
08594 varlist = ast_calloc(1, sizeof(*varlist));
08595 variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
08596 if (variablestore && varlist) {
08597 variablestore->data = varlist;
08598 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08599 AST_LIST_HEAD_INIT(varlist);
08600 ast_debug(1, "I can haz IAX vars?\n");
08601 for (var = ies.vars; var; var = var->next) {
08602 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08603 if (prev) {
08604 ast_free(prev);
08605 }
08606 prev = var;
08607 if (!newvar) {
08608
08609 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08610 } else {
08611 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08612 }
08613 }
08614 if (prev) {
08615 ast_free(prev);
08616 }
08617 ies.vars = NULL;
08618 ast_channel_datastore_add(c, variablestore);
08619 } else {
08620 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08621 if (variablestore) {
08622 ast_channel_datastore_free(variablestore);
08623 }
08624 if (varlist) {
08625 ast_free(varlist);
08626 }
08627 }
08628 } else {
08629
08630
08631 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
08632 for (var = ies.vars; var && var->next; var = var->next);
08633 if (var) {
08634 var->next = iaxs[fr->callno]->iaxvars;
08635 iaxs[fr->callno]->iaxvars = ies.vars;
08636 ies.vars = NULL;
08637 }
08638 }
08639 }
08640 }
08641
08642 if (ies.vars) {
08643 ast_debug(1, "I have IAX variables, but they were not processed\n");
08644 }
08645
08646 if (f.frametype == AST_FRAME_VOICE) {
08647 if (f.subclass != iaxs[fr->callno]->voiceformat) {
08648 iaxs[fr->callno]->voiceformat = f.subclass;
08649 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
08650 if (iaxs[fr->callno]->owner) {
08651 int orignative;
08652 retryowner:
08653 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
08654 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08655 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
08656 }
08657 if (iaxs[fr->callno]) {
08658 if (iaxs[fr->callno]->owner) {
08659 orignative = iaxs[fr->callno]->owner->nativeformats;
08660 iaxs[fr->callno]->owner->nativeformats = f.subclass;
08661 if (iaxs[fr->callno]->owner->readformat)
08662 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
08663 iaxs[fr->callno]->owner->nativeformats = orignative;
08664 ast_channel_unlock(iaxs[fr->callno]->owner);
08665 }
08666 } else {
08667 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
08668
08669 if (ies.vars) {
08670 ast_variables_destroy(ies.vars);
08671 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
08672 ies.vars = NULL;
08673 }
08674 ast_mutex_unlock(&iaxsl[fr->callno]);
08675 return 1;
08676 }
08677 }
08678 }
08679 }
08680 if (f.frametype == AST_FRAME_VIDEO) {
08681 if (f.subclass != iaxs[fr->callno]->videoformat) {
08682 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
08683 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
08684 }
08685 }
08686 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
08687 if (f.subclass == AST_CONTROL_BUSY) {
08688 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
08689 } else if (f.subclass == AST_CONTROL_CONGESTION) {
08690 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
08691 }
08692 }
08693 if (f.frametype == AST_FRAME_IAX) {
08694 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
08695
08696 if (iaxdebug)
08697 ast_debug(1, "IAX subclass %d received\n", f.subclass);
08698
08699
08700 if (iaxs[fr->callno]->last < fr->ts &&
08701 f.subclass != IAX_COMMAND_ACK &&
08702 f.subclass != IAX_COMMAND_PONG &&
08703 f.subclass != IAX_COMMAND_LAGRP) {
08704 iaxs[fr->callno]->last = fr->ts;
08705 if (iaxdebug)
08706 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08707 }
08708 iaxs[fr->callno]->last_iax_message = f.subclass;
08709 if (!iaxs[fr->callno]->first_iax_message) {
08710 iaxs[fr->callno]->first_iax_message = f.subclass;
08711 }
08712 switch(f.subclass) {
08713 case IAX_COMMAND_ACK:
08714
08715 break;
08716 case IAX_COMMAND_QUELCH:
08717 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08718
08719 if (iaxs[fr->callno]->owner) {
08720 manager_event(EVENT_FLAG_CALL, "Hold",
08721 "Status: On\r\n"
08722 "Channel: %s\r\n"
08723 "Uniqueid: %s\r\n",
08724 iaxs[fr->callno]->owner->name,
08725 iaxs[fr->callno]->owner->uniqueid);
08726 }
08727
08728 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
08729 if (ies.musiconhold) {
08730 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08731 const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
08732 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
08733 S_OR(mohsuggest, NULL),
08734 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
08735 if (!iaxs[fr->callno]) {
08736 ast_mutex_unlock(&iaxsl[fr->callno]);
08737 return 1;
08738 }
08739 }
08740 }
08741 }
08742 break;
08743 case IAX_COMMAND_UNQUELCH:
08744 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08745
08746 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
08747 manager_event(EVENT_FLAG_CALL, "Hold",
08748 "Status: Off\r\n"
08749 "Channel: %s\r\n"
08750 "Uniqueid: %s\r\n",
08751 iaxs[fr->callno]->owner->name,
08752 iaxs[fr->callno]->owner->uniqueid);
08753 }
08754
08755 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
08756 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08757 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
08758 if (!iaxs[fr->callno]) {
08759 ast_mutex_unlock(&iaxsl[fr->callno]);
08760 return 1;
08761 }
08762 }
08763 }
08764 break;
08765 case IAX_COMMAND_TXACC:
08766 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
08767
08768 AST_LIST_LOCK(&frame_queue);
08769 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08770
08771 if ((fr->callno == cur->callno) && (cur->transfer))
08772 cur->retries = -1;
08773 }
08774 AST_LIST_UNLOCK(&frame_queue);
08775 memset(&ied1, 0, sizeof(ied1));
08776 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
08777 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
08778 iaxs[fr->callno]->transferring = TRANSFER_READY;
08779 }
08780 break;
08781 case IAX_COMMAND_NEW:
08782
08783 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
08784 break;
08785 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08786 ast_mutex_unlock(&iaxsl[fr->callno]);
08787 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08788 ast_mutex_lock(&iaxsl[fr->callno]);
08789 if (!iaxs[fr->callno]) {
08790 ast_mutex_unlock(&iaxsl[fr->callno]);
08791 return 1;
08792 }
08793 }
08794
08795 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
08796 int new_callno;
08797 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
08798 fr->callno = new_callno;
08799 }
08800
08801 if (delayreject)
08802 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08803 if (check_access(fr->callno, &sin, &ies)) {
08804
08805 auth_fail(fr->callno, IAX_COMMAND_REJECT);
08806 if (authdebug)
08807 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);
08808 break;
08809 }
08810 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08811 const char *context, *exten, *cid_num;
08812
08813 context = ast_strdupa(iaxs[fr->callno]->context);
08814 exten = ast_strdupa(iaxs[fr->callno]->exten);
08815 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
08816
08817
08818 ast_mutex_unlock(&iaxsl[fr->callno]);
08819 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
08820 ast_mutex_lock(&iaxsl[fr->callno]);
08821
08822 if (!iaxs[fr->callno]) {
08823 ast_mutex_unlock(&iaxsl[fr->callno]);
08824 return 1;
08825 }
08826 } else
08827 exists = 0;
08828
08829 save_osptoken(fr, &ies);
08830 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
08831 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08832 memset(&ied0, 0, sizeof(ied0));
08833 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08834 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08835 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08836 if (!iaxs[fr->callno]) {
08837 ast_mutex_unlock(&iaxsl[fr->callno]);
08838 return 1;
08839 }
08840 if (authdebug)
08841 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);
08842 } else {
08843
08844
08845 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08846 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08847 using_prefs = "reqonly";
08848 } else {
08849 using_prefs = "disabled";
08850 }
08851 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08852 memset(&pref, 0, sizeof(pref));
08853 strcpy(caller_pref_buf, "disabled");
08854 strcpy(host_pref_buf, "disabled");
08855 } else {
08856 using_prefs = "mine";
08857
08858 if (ies.codec_prefs)
08859 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08860 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08861
08862 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08863 pref = iaxs[fr->callno]->rprefs;
08864 using_prefs = "caller";
08865 } else {
08866 pref = iaxs[fr->callno]->prefs;
08867 }
08868 } else
08869 pref = iaxs[fr->callno]->prefs;
08870
08871 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08872 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08873 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08874 }
08875 if (!format) {
08876 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08877 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08878 if (!format) {
08879 memset(&ied0, 0, sizeof(ied0));
08880 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08881 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08882 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08883 if (!iaxs[fr->callno]) {
08884 ast_mutex_unlock(&iaxsl[fr->callno]);
08885 return 1;
08886 }
08887 if (authdebug) {
08888 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08889 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
08890 else
08891 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
08892 }
08893 } else {
08894
08895 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08896 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08897 format = 0;
08898 } else {
08899 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08900 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08901 memset(&pref, 0, sizeof(pref));
08902 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08903 strcpy(caller_pref_buf,"disabled");
08904 strcpy(host_pref_buf,"disabled");
08905 } else {
08906 using_prefs = "mine";
08907 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08908
08909 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08910 pref = iaxs[fr->callno]->prefs;
08911 } else {
08912 pref = iaxs[fr->callno]->rprefs;
08913 using_prefs = "caller";
08914 }
08915 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08916
08917 } else
08918 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08919 }
08920 }
08921
08922 if (!format) {
08923 memset(&ied0, 0, sizeof(ied0));
08924 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08925 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08926 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08927 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08928 if (!iaxs[fr->callno]) {
08929 ast_mutex_unlock(&iaxsl[fr->callno]);
08930 return 1;
08931 }
08932 if (authdebug)
08933 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
08934 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08935 break;
08936 }
08937 }
08938 }
08939 if (format) {
08940
08941 memset(&ied1, 0, sizeof(ied1));
08942 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08943 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08944 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08945 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08946 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
08947 "%srequested format = %s,\n"
08948 "%srequested prefs = %s,\n"
08949 "%sactual format = %s,\n"
08950 "%shost prefs = %s,\n"
08951 "%spriority = %s\n",
08952 ast_inet_ntoa(sin.sin_addr),
08953 VERBOSE_PREFIX_4,
08954 ast_getformatname(iaxs[fr->callno]->peerformat),
08955 VERBOSE_PREFIX_4,
08956 caller_pref_buf,
08957 VERBOSE_PREFIX_4,
08958 ast_getformatname(format),
08959 VERBOSE_PREFIX_4,
08960 host_pref_buf,
08961 VERBOSE_PREFIX_4,
08962 using_prefs);
08963
08964 iaxs[fr->callno]->chosenformat = format;
08965 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08966 } else {
08967 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08968
08969 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08970 }
08971 }
08972 }
08973 break;
08974 }
08975 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
08976 merge_encryption(iaxs[fr->callno],ies.encmethods);
08977 else
08978 iaxs[fr->callno]->encmethods = 0;
08979 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
08980 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
08981 if (!iaxs[fr->callno]) {
08982 ast_mutex_unlock(&iaxsl[fr->callno]);
08983 return 1;
08984 }
08985 break;
08986 case IAX_COMMAND_DPREQ:
08987
08988 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
08989 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
08990 if (iaxcompat) {
08991
08992 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
08993 } else {
08994
08995 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
08996 }
08997 }
08998 break;
08999 case IAX_COMMAND_HANGUP:
09000 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09001 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
09002
09003 if (ies.causecode && iaxs[fr->callno]->owner)
09004 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09005
09006 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09007 iax2_destroy(fr->callno);
09008 break;
09009 case IAX_COMMAND_REJECT:
09010
09011 if (ies.causecode && iaxs[fr->callno]->owner)
09012 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09013
09014 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09015 if (iaxs[fr->callno]->owner && authdebug)
09016 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
09017 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
09018 ies.cause ? ies.cause : "<Unknown>");
09019 ast_debug(1, "Immediately destroying %d, having received reject\n",
09020 fr->callno);
09021 }
09022
09023 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
09024 fr->ts, NULL, 0, fr->iseqno);
09025 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
09026 iaxs[fr->callno]->error = EPERM;
09027 iax2_destroy(fr->callno);
09028 break;
09029 case IAX_COMMAND_TRANSFER:
09030 {
09031 struct ast_channel *bridged_chan;
09032
09033 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
09034
09035
09036 ast_mutex_unlock(&iaxsl[fr->callno]);
09037 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
09038 ast_mutex_lock(&iaxsl[fr->callno]);
09039 if (!iaxs[fr->callno]) {
09040 ast_mutex_unlock(&iaxsl[fr->callno]);
09041 return 1;
09042 }
09043
09044 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
09045 if (!strcmp(ies.called_number, ast_parking_ext())) {
09046 struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
09047 ast_mutex_unlock(&iaxsl[fr->callno]);
09048 if (iax_park(bridged_chan, saved_channel)) {
09049 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
09050 } else {
09051 ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
09052 }
09053 ast_mutex_lock(&iaxsl[fr->callno]);
09054 } else {
09055 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
09056 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
09057 ies.called_number, iaxs[fr->callno]->context);
09058 else {
09059 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
09060 ies.called_number, iaxs[fr->callno]->context);
09061 }
09062 }
09063 } else {
09064 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
09065 }
09066
09067 break;
09068 }
09069 case IAX_COMMAND_ACCEPT:
09070
09071 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
09072 break;
09073 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09074
09075 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09076 iax2_destroy(fr->callno);
09077 break;
09078 }
09079 if (ies.format) {
09080 iaxs[fr->callno]->peerformat = ies.format;
09081 } else {
09082 if (iaxs[fr->callno]->owner)
09083 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
09084 else
09085 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
09086 }
09087 ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
09088 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
09089 memset(&ied0, 0, sizeof(ied0));
09090 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09091 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09092 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09093 if (!iaxs[fr->callno]) {
09094 ast_mutex_unlock(&iaxsl[fr->callno]);
09095 return 1;
09096 }
09097 if (authdebug)
09098 ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09099 } else {
09100 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09101 if (iaxs[fr->callno]->owner) {
09102
09103 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
09104 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
09105 retryowner2:
09106 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
09107 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09108 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
09109 }
09110
09111 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
09112
09113 if (iaxs[fr->callno]->owner->writeformat)
09114 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
09115 if (iaxs[fr->callno]->owner->readformat)
09116 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09117 ast_channel_unlock(iaxs[fr->callno]->owner);
09118 }
09119 }
09120 }
09121 if (iaxs[fr->callno]) {
09122 AST_LIST_LOCK(&dpcache);
09123 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
09124 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
09125 iax2_dprequest(dp, fr->callno);
09126 AST_LIST_UNLOCK(&dpcache);
09127 }
09128 break;
09129 case IAX_COMMAND_POKE:
09130
09131 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
09132 if (!iaxs[fr->callno]) {
09133 ast_mutex_unlock(&iaxsl[fr->callno]);
09134 return 1;
09135 }
09136 break;
09137 case IAX_COMMAND_PING:
09138 {
09139 struct iax_ie_data pingied;
09140 construct_rr(iaxs[fr->callno], &pingied);
09141
09142 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
09143 }
09144 break;
09145 case IAX_COMMAND_PONG:
09146
09147 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
09148
09149 save_rr(fr, &ies);
09150
09151
09152 log_jitterstats(fr->callno);
09153
09154 if (iaxs[fr->callno]->peerpoke) {
09155 peer = iaxs[fr->callno]->peerpoke;
09156 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
09157 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
09158 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
09159 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);
09160 ast_device_state_changed("IAX2/%s", peer->name);
09161 }
09162 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
09163 if (iaxs[fr->callno]->pingtime > peer->maxms) {
09164 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
09165 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);
09166 ast_device_state_changed("IAX2/%s", peer->name);
09167 }
09168 }
09169 peer->lastms = iaxs[fr->callno]->pingtime;
09170 if (peer->smoothing && (peer->lastms > -1))
09171 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
09172 else if (peer->smoothing && peer->lastms < 0)
09173 peer->historicms = (0 + peer->historicms) / 2;
09174 else
09175 peer->historicms = iaxs[fr->callno]->pingtime;
09176
09177
09178 if (peer->pokeexpire > -1) {
09179 if (!ast_sched_del(sched, peer->pokeexpire)) {
09180 peer_unref(peer);
09181 peer->pokeexpire = -1;
09182 }
09183 }
09184
09185 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
09186 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
09187 else
09188 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
09189 if (peer->pokeexpire == -1)
09190 peer_unref(peer);
09191
09192 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09193
09194 iax2_destroy(fr->callno);
09195 peer->callno = 0;
09196 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
09197 }
09198 break;
09199 case IAX_COMMAND_LAGRQ:
09200 case IAX_COMMAND_LAGRP:
09201 f.src = "LAGRQ";
09202 f.mallocd = 0;
09203 f.offset = 0;
09204 f.samples = 0;
09205 iax_frame_wrap(fr, &f);
09206 if(f.subclass == IAX_COMMAND_LAGRQ) {
09207
09208 fr->af.subclass = IAX_COMMAND_LAGRP;
09209 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
09210 } else {
09211
09212 unsigned int ts;
09213
09214 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
09215 iaxs[fr->callno]->lag = ts - fr->ts;
09216 if (iaxdebug)
09217 ast_debug(1, "Peer %s lag measured as %dms\n",
09218 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
09219 }
09220 break;
09221 case IAX_COMMAND_AUTHREQ:
09222 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09223 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09224 break;
09225 }
09226 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
09227 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
09228 .subclass = AST_CONTROL_HANGUP,
09229 };
09230 ast_log(LOG_WARNING,
09231 "I don't know how to authenticate %s to %s\n",
09232 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
09233 iax2_queue_frame(fr->callno, &hangup_fr);
09234 }
09235 if (!iaxs[fr->callno]) {
09236 ast_mutex_unlock(&iaxsl[fr->callno]);
09237 return 1;
09238 }
09239 break;
09240 case IAX_COMMAND_AUTHREP:
09241
09242 if (delayreject)
09243 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09244
09245 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09246 ast_log(LOG_WARNING, "Call on %s is already up, can't start on it\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09247 break;
09248 }
09249 if (authenticate_verify(iaxs[fr->callno], &ies)) {
09250 if (authdebug)
09251 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);
09252 memset(&ied0, 0, sizeof(ied0));
09253 auth_fail(fr->callno, IAX_COMMAND_REJECT);
09254 break;
09255 }
09256 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09257
09258 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
09259 } else
09260 exists = 0;
09261 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09262 if (authdebug)
09263 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);
09264 memset(&ied0, 0, sizeof(ied0));
09265 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09266 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09267 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09268 if (!iaxs[fr->callno]) {
09269 ast_mutex_unlock(&iaxsl[fr->callno]);
09270 return 1;
09271 }
09272 } else {
09273
09274 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09275 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09276 using_prefs = "reqonly";
09277 } else {
09278 using_prefs = "disabled";
09279 }
09280 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09281 memset(&pref, 0, sizeof(pref));
09282 strcpy(caller_pref_buf, "disabled");
09283 strcpy(host_pref_buf, "disabled");
09284 } else {
09285 using_prefs = "mine";
09286 if (ies.codec_prefs)
09287 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09288 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09289 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09290 pref = iaxs[fr->callno]->rprefs;
09291 using_prefs = "caller";
09292 } else {
09293 pref = iaxs[fr->callno]->prefs;
09294 }
09295 } else
09296 pref = iaxs[fr->callno]->prefs;
09297
09298 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09299 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09300 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09301 }
09302 if (!format) {
09303 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09304 ast_debug(1, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
09305 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09306 }
09307 if (!format) {
09308 if (authdebug) {
09309 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09310 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09311 else
09312 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
09313 }
09314 memset(&ied0, 0, sizeof(ied0));
09315 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09316 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09317 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09318 if (!iaxs[fr->callno]) {
09319 ast_mutex_unlock(&iaxsl[fr->callno]);
09320 return 1;
09321 }
09322 } else {
09323
09324 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09325 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09326 format = 0;
09327 } else {
09328 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09329 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09330 memset(&pref, 0, sizeof(pref));
09331 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
09332 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09333 strcpy(caller_pref_buf,"disabled");
09334 strcpy(host_pref_buf,"disabled");
09335 } else {
09336 using_prefs = "mine";
09337 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09338
09339 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09340 pref = iaxs[fr->callno]->prefs;
09341 } else {
09342 pref = iaxs[fr->callno]->rprefs;
09343 using_prefs = "caller";
09344 }
09345 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
09346 } else
09347 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09348 }
09349 }
09350 if (!format) {
09351 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09352 if (authdebug) {
09353 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09354 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09355 else
09356 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
09357 }
09358 memset(&ied0, 0, sizeof(ied0));
09359 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09360 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09361 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09362 if (!iaxs[fr->callno]) {
09363 ast_mutex_unlock(&iaxsl[fr->callno]);
09364 return 1;
09365 }
09366 }
09367 }
09368 }
09369 if (format) {
09370
09371 memset(&ied1, 0, sizeof(ied1));
09372 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
09373 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
09374 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
09375 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09376 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
09377 "%srequested format = %s,\n"
09378 "%srequested prefs = %s,\n"
09379 "%sactual format = %s,\n"
09380 "%shost prefs = %s,\n"
09381 "%spriority = %s\n",
09382 ast_inet_ntoa(sin.sin_addr),
09383 VERBOSE_PREFIX_4,
09384 ast_getformatname(iaxs[fr->callno]->peerformat),
09385 VERBOSE_PREFIX_4,
09386 caller_pref_buf,
09387 VERBOSE_PREFIX_4,
09388 ast_getformatname(format),
09389 VERBOSE_PREFIX_4,
09390 host_pref_buf,
09391 VERBOSE_PREFIX_4,
09392 using_prefs);
09393
09394 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09395 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
09396 iax2_destroy(fr->callno);
09397 else if (ies.vars) {
09398 struct ast_datastore *variablestore;
09399 struct ast_variable *var, *prev = NULL;
09400 AST_LIST_HEAD(, ast_var_t) *varlist;
09401 varlist = ast_calloc(1, sizeof(*varlist));
09402 variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
09403 if (variablestore && varlist) {
09404 variablestore->data = varlist;
09405 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09406 AST_LIST_HEAD_INIT(varlist);
09407 ast_debug(1, "I can haz IAX vars? w00t\n");
09408 for (var = ies.vars; var; var = var->next) {
09409 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09410 if (prev)
09411 ast_free(prev);
09412 prev = var;
09413 if (!newvar) {
09414
09415 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09416 } else {
09417 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09418 }
09419 }
09420 if (prev)
09421 ast_free(prev);
09422 ies.vars = NULL;
09423 ast_channel_datastore_add(c, variablestore);
09424 } else {
09425 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09426 if (variablestore)
09427 ast_channel_datastore_free(variablestore);
09428 if (varlist)
09429 ast_free(varlist);
09430 }
09431 }
09432 } else {
09433 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09434
09435 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
09436 }
09437 }
09438 }
09439 break;
09440 case IAX_COMMAND_DIAL:
09441 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
09442 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09443 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
09444 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
09445 if (authdebug)
09446 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);
09447 memset(&ied0, 0, sizeof(ied0));
09448 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09449 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09450 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09451 if (!iaxs[fr->callno]) {
09452 ast_mutex_unlock(&iaxsl[fr->callno]);
09453 return 1;
09454 }
09455 } else {
09456 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09457 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
09458 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09459 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
09460 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
09461 iax2_destroy(fr->callno);
09462 else if (ies.vars) {
09463 struct ast_datastore *variablestore;
09464 struct ast_variable *var, *prev = NULL;
09465 AST_LIST_HEAD(, ast_var_t) *varlist;
09466 varlist = ast_calloc(1, sizeof(*varlist));
09467 variablestore = ast_channel_datastore_alloc(&iax2_variable_datastore_info, NULL);
09468 if (variablestore && varlist) {
09469 variablestore->data = varlist;
09470 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09471 AST_LIST_HEAD_INIT(varlist);
09472 for (var = ies.vars; var; var = var->next) {
09473 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09474 if (prev)
09475 ast_free(prev);
09476 prev = var;
09477 if (!newvar) {
09478
09479 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09480 } else {
09481 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09482 }
09483 }
09484 if (prev)
09485 ast_free(prev);
09486 ies.vars = NULL;
09487 ast_channel_datastore_add(c, variablestore);
09488 } else {
09489 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09490 if (variablestore)
09491 ast_channel_datastore_free(variablestore);
09492 if (varlist)
09493 ast_free(varlist);
09494 }
09495 }
09496 }
09497 }
09498 break;
09499 case IAX_COMMAND_INVAL:
09500 iaxs[fr->callno]->error = ENOTCONN;
09501 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
09502 iax2_destroy(fr->callno);
09503 ast_debug(1, "Destroying call %d\n", fr->callno);
09504 break;
09505 case IAX_COMMAND_VNAK:
09506 ast_debug(1, "Received VNAK: resending outstanding frames\n");
09507
09508 vnak_retransmit(fr->callno, fr->iseqno);
09509 break;
09510 case IAX_COMMAND_REGREQ:
09511 case IAX_COMMAND_REGREL:
09512
09513 if (delayreject)
09514 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09515 if (register_verify(fr->callno, &sin, &ies)) {
09516 if (!iaxs[fr->callno]) {
09517 ast_mutex_unlock(&iaxsl[fr->callno]);
09518 return 1;
09519 }
09520
09521 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
09522 break;
09523 }
09524 if (!iaxs[fr->callno]) {
09525 ast_mutex_unlock(&iaxsl[fr->callno]);
09526 return 1;
09527 }
09528 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
09529 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
09530
09531 if (f.subclass == IAX_COMMAND_REGREL)
09532 memset(&sin, 0, sizeof(sin));
09533 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
09534 ast_log(LOG_WARNING, "Registry error\n");
09535 if (!iaxs[fr->callno]) {
09536 ast_mutex_unlock(&iaxsl[fr->callno]);
09537 return 1;
09538 }
09539 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09540 ast_mutex_unlock(&iaxsl[fr->callno]);
09541 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09542 ast_mutex_lock(&iaxsl[fr->callno]);
09543 if (!iaxs[fr->callno]) {
09544 ast_mutex_unlock(&iaxsl[fr->callno]);
09545 return 1;
09546 }
09547 }
09548 break;
09549 }
09550 registry_authrequest(fr->callno);
09551 if (!iaxs[fr->callno]) {
09552 ast_mutex_unlock(&iaxsl[fr->callno]);
09553 return 1;
09554 }
09555 break;
09556 case IAX_COMMAND_REGACK:
09557 if (iax2_ack_registry(&ies, &sin, fr->callno))
09558 ast_log(LOG_WARNING, "Registration failure\n");
09559
09560 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09561 iax2_destroy(fr->callno);
09562 break;
09563 case IAX_COMMAND_REGREJ:
09564 if (iaxs[fr->callno]->reg) {
09565 if (authdebug) {
09566 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));
09567 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>");
09568 }
09569 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
09570 }
09571
09572 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09573 iax2_destroy(fr->callno);
09574 break;
09575 case IAX_COMMAND_REGAUTH:
09576
09577 if (registry_rerequest(&ies, fr->callno, &sin)) {
09578 memset(&ied0, 0, sizeof(ied0));
09579 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
09580 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09581 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09582 if (!iaxs[fr->callno]) {
09583 ast_mutex_unlock(&iaxsl[fr->callno]);
09584 return 1;
09585 }
09586 }
09587 break;
09588 case IAX_COMMAND_TXREJ:
09589 iaxs[fr->callno]->transferring = 0;
09590 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09591 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
09592 if (iaxs[fr->callno]->bridgecallno) {
09593 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
09594 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
09595 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
09596 }
09597 }
09598 break;
09599 case IAX_COMMAND_TXREADY:
09600 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
09601 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
09602 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
09603 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
09604 else
09605 iaxs[fr->callno]->transferring = TRANSFER_READY;
09606 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09607 if (iaxs[fr->callno]->bridgecallno) {
09608 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
09609 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
09610
09611 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
09612 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09613 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09614
09615 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
09616 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
09617
09618 memset(&ied0, 0, sizeof(ied0));
09619 memset(&ied1, 0, sizeof(ied1));
09620 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09621 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09622 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
09623 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
09624 } else {
09625 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09626 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09627
09628 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
09629 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
09630 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
09631 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09632
09633
09634 stop_stuff(fr->callno);
09635 stop_stuff(iaxs[fr->callno]->bridgecallno);
09636
09637 memset(&ied0, 0, sizeof(ied0));
09638 memset(&ied1, 0, sizeof(ied1));
09639 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09640 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09641 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
09642 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
09643 }
09644
09645 }
09646 }
09647 }
09648 break;
09649 case IAX_COMMAND_TXREQ:
09650 try_transfer(iaxs[fr->callno], &ies);
09651 break;
09652 case IAX_COMMAND_TXCNT:
09653 if (iaxs[fr->callno]->transferring)
09654 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
09655 break;
09656 case IAX_COMMAND_TXREL:
09657
09658 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09659 complete_transfer(fr->callno, &ies);
09660 stop_stuff(fr->callno);
09661 break;
09662 case IAX_COMMAND_TXMEDIA:
09663 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
09664 AST_LIST_LOCK(&frame_queue);
09665 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09666
09667 if ((fr->callno == cur->callno) && (cur->transfer))
09668 cur->retries = -1;
09669 }
09670 AST_LIST_UNLOCK(&frame_queue);
09671
09672 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
09673 }
09674 break;
09675 case IAX_COMMAND_DPREP:
09676 complete_dpreply(iaxs[fr->callno], &ies);
09677 break;
09678 case IAX_COMMAND_UNSUPPORT:
09679 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
09680 break;
09681 case IAX_COMMAND_FWDOWNL:
09682
09683 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
09684 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
09685 break;
09686 }
09687 memset(&ied0, 0, sizeof(ied0));
09688 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
09689 if (res < 0)
09690 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09691 else if (res > 0)
09692 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09693 else
09694 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09695 if (!iaxs[fr->callno]) {
09696 ast_mutex_unlock(&iaxsl[fr->callno]);
09697 return 1;
09698 }
09699 break;
09700 default:
09701 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
09702 memset(&ied0, 0, sizeof(ied0));
09703 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
09704 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
09705 }
09706
09707 if (ies.vars) {
09708 ast_variables_destroy(ies.vars);
09709 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
09710 ies.vars = NULL;
09711 }
09712
09713
09714 if ((f.subclass != IAX_COMMAND_ACK) &&
09715 (f.subclass != IAX_COMMAND_TXCNT) &&
09716 (f.subclass != IAX_COMMAND_TXACC) &&
09717 (f.subclass != IAX_COMMAND_INVAL) &&
09718 (f.subclass != IAX_COMMAND_VNAK)) {
09719 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09720 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09721 }
09722 ast_mutex_unlock(&iaxsl[fr->callno]);
09723 return 1;
09724 }
09725
09726 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09727 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09728 } else if (minivid) {
09729 f.frametype = AST_FRAME_VIDEO;
09730 if (iaxs[fr->callno]->videoformat > 0)
09731 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
09732 else {
09733 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
09734 iax2_vnak(fr->callno);
09735 ast_mutex_unlock(&iaxsl[fr->callno]);
09736 return 1;
09737 }
09738 f.datalen = res - sizeof(*vh);
09739 if (f.datalen)
09740 f.data = thread->buf + sizeof(*vh);
09741 else
09742 f.data = NULL;
09743 #ifdef IAXTESTS
09744 if (test_resync) {
09745 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
09746 } else
09747 #endif
09748 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
09749 } else {
09750
09751 f.frametype = AST_FRAME_VOICE;
09752 if (iaxs[fr->callno]->voiceformat > 0)
09753 f.subclass = iaxs[fr->callno]->voiceformat;
09754 else {
09755 ast_debug(1, "Received mini frame before first full voice frame\n");
09756 iax2_vnak(fr->callno);
09757 ast_mutex_unlock(&iaxsl[fr->callno]);
09758 return 1;
09759 }
09760 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
09761 if (f.datalen < 0) {
09762 ast_log(LOG_WARNING, "Datalen < 0?\n");
09763 ast_mutex_unlock(&iaxsl[fr->callno]);
09764 return 1;
09765 }
09766 if (f.datalen)
09767 f.data = thread->buf + sizeof(*mh);
09768 else
09769 f.data = NULL;
09770 #ifdef IAXTESTS
09771 if (test_resync) {
09772 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
09773 } else
09774 #endif
09775 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
09776
09777 }
09778
09779 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09780 ast_mutex_unlock(&iaxsl[fr->callno]);
09781 return 1;
09782 }
09783
09784 f.src = "IAX2";
09785 f.mallocd = 0;
09786 f.offset = 0;
09787 f.len = 0;
09788 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
09789 f.samples = ast_codec_get_samples(&f);
09790
09791 if (f.subclass == AST_FORMAT_SLINEAR)
09792 ast_frame_byteswap_be(&f);
09793 } else
09794 f.samples = 0;
09795 iax_frame_wrap(fr, &f);
09796
09797
09798 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09799
09800 fr->outoforder = 0;
09801 } else {
09802 if (iaxdebug && iaxs[fr->callno])
09803 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
09804 fr->outoforder = -1;
09805 }
09806 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
09807 duped_fr = iaxfrdup2(fr);
09808 if (duped_fr) {
09809 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
09810 }
09811 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09812 iaxs[fr->callno]->last = fr->ts;
09813 #if 1
09814 if (iaxdebug)
09815 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09816 #endif
09817 }
09818
09819
09820 ast_mutex_unlock(&iaxsl[fr->callno]);
09821 return 1;
09822 }
09823
09824
09825 static void iax2_process_thread_cleanup(void *data)
09826 {
09827 struct iax2_thread *thread = data;
09828 ast_mutex_destroy(&thread->lock);
09829 ast_cond_destroy(&thread->cond);
09830 ast_free(thread);
09831 ast_atomic_dec_and_test(&iaxactivethreadcount);
09832 }
09833
09834 static void *iax2_process_thread(void *data)
09835 {
09836 struct iax2_thread *thread = data;
09837 struct timeval tv;
09838 struct timespec ts;
09839 int put_into_idle = 0;
09840
09841 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
09842 pthread_cleanup_push(iax2_process_thread_cleanup, data);
09843 for(;;) {
09844
09845 ast_mutex_lock(&thread->lock);
09846
09847
09848 thread->ready_for_signal = 1;
09849
09850
09851 if (put_into_idle)
09852 insert_idle_thread(thread);
09853
09854 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
09855 struct iax2_thread *t = NULL;
09856
09857 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09858 ts.tv_sec = tv.tv_sec;
09859 ts.tv_nsec = tv.tv_usec * 1000;
09860 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
09861
09862
09863 if (!put_into_idle) {
09864 ast_mutex_unlock(&thread->lock);
09865 break;
09866 }
09867 AST_LIST_LOCK(&dynamic_list);
09868
09869 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
09870 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
09871 AST_LIST_UNLOCK(&dynamic_list);
09872 if (t) {
09873
09874
09875
09876 ast_mutex_unlock(&thread->lock);
09877 break;
09878 }
09879
09880
09881
09882 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09883 ts.tv_sec = tv.tv_sec;
09884 ts.tv_nsec = tv.tv_usec * 1000;
09885 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
09886 {
09887 ast_mutex_unlock(&thread->lock);
09888 break;
09889 }
09890 }
09891 } else {
09892 ast_cond_wait(&thread->cond, &thread->lock);
09893 }
09894
09895
09896 put_into_idle = 1;
09897
09898 ast_mutex_unlock(&thread->lock);
09899
09900 if (thread->iostate == IAX_IOSTATE_IDLE)
09901 continue;
09902
09903
09904 AST_LIST_LOCK(&active_list);
09905 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09906 AST_LIST_UNLOCK(&active_list);
09907
09908
09909 switch(thread->iostate) {
09910 case IAX_IOSTATE_READY:
09911 thread->actions++;
09912 thread->iostate = IAX_IOSTATE_PROCESSING;
09913 socket_process(thread);
09914 handle_deferred_full_frames(thread);
09915 break;
09916 case IAX_IOSTATE_SCHEDREADY:
09917 thread->actions++;
09918 thread->iostate = IAX_IOSTATE_PROCESSING;
09919 #ifdef SCHED_MULTITHREADED
09920 thread->schedfunc(thread->scheddata);
09921 #endif
09922 default:
09923 break;
09924 }
09925 time(&thread->checktime);
09926 thread->iostate = IAX_IOSTATE_IDLE;
09927 #ifdef DEBUG_SCHED_MULTITHREAD
09928 thread->curfunc[0]='\0';
09929 #endif
09930
09931
09932 AST_LIST_LOCK(&active_list);
09933 AST_LIST_REMOVE(&active_list, thread, list);
09934 AST_LIST_UNLOCK(&active_list);
09935
09936
09937 handle_deferred_full_frames(thread);
09938 }
09939
09940
09941
09942
09943
09944 AST_LIST_LOCK(&idle_list);
09945 AST_LIST_REMOVE(&idle_list, thread, list);
09946 AST_LIST_UNLOCK(&idle_list);
09947
09948 AST_LIST_LOCK(&dynamic_list);
09949 AST_LIST_REMOVE(&dynamic_list, thread, list);
09950 AST_LIST_UNLOCK(&dynamic_list);
09951
09952
09953
09954
09955 pthread_cleanup_pop(1);
09956 return NULL;
09957 }
09958
09959 static int iax2_do_register(struct iax2_registry *reg)
09960 {
09961 struct iax_ie_data ied;
09962 if (iaxdebug)
09963 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
09964
09965 if (reg->dnsmgr &&
09966 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
09967
09968 ast_dnsmgr_refresh(reg->dnsmgr);
09969 }
09970
09971
09972
09973
09974
09975 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
09976 int callno = reg->callno;
09977 ast_mutex_lock(&iaxsl[callno]);
09978 iax2_destroy(callno);
09979 ast_mutex_unlock(&iaxsl[callno]);
09980 reg->callno = 0;
09981 }
09982 if (!reg->addr.sin_addr.s_addr) {
09983 if (iaxdebug)
09984 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
09985
09986 reg->expire = iax2_sched_replace(reg->expire, sched,
09987 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
09988 return -1;
09989 }
09990
09991 if (!reg->callno) {
09992 ast_debug(3, "Allocate call number\n");
09993 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
09994 if (reg->callno < 1) {
09995 ast_log(LOG_WARNING, "Unable to create call for registration\n");
09996 return -1;
09997 } else
09998 ast_debug(3, "Registration created on call %d\n", reg->callno);
09999 iaxs[reg->callno]->reg = reg;
10000 ast_mutex_unlock(&iaxsl[reg->callno]);
10001 }
10002
10003 reg->expire = iax2_sched_replace(reg->expire, sched,
10004 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10005
10006 memset(&ied, 0, sizeof(ied));
10007 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
10008 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
10009 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
10010 reg->regstate = REG_STATE_REGSENT;
10011 return 0;
10012 }
10013
10014 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
10015 {
10016
10017
10018 struct iax_ie_data provdata;
10019 struct iax_ie_data ied;
10020 unsigned int sig;
10021 struct sockaddr_in sin;
10022 int callno;
10023 struct create_addr_info cai;
10024
10025 memset(&cai, 0, sizeof(cai));
10026
10027 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
10028
10029 if (iax_provision_build(&provdata, &sig, template, force)) {
10030 ast_debug(1, "No provisioning found for template '%s'\n", template);
10031 return 0;
10032 }
10033
10034 if (end) {
10035 memcpy(&sin, end, sizeof(sin));
10036 cai.sockfd = sockfd;
10037 } else if (create_addr(dest, NULL, &sin, &cai))
10038 return -1;
10039
10040
10041 memset(&ied, 0, sizeof(ied));
10042 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
10043
10044 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10045 if (!callno)
10046 return -1;
10047
10048 if (iaxs[callno]) {
10049
10050 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
10051 sched, 15000, auto_hangup, (void *)(long)callno);
10052 ast_set_flag(iaxs[callno], IAX_PROVISION);
10053
10054 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
10055 }
10056 ast_mutex_unlock(&iaxsl[callno]);
10057
10058 return 1;
10059 }
10060
10061 static char *papp = "IAX2Provision";
10062 static char *psyn = "Provision a calling IAXy with a given template";
10063 static char *pdescrip =
10064 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
10065 "the calling entity is in fact an IAXy) with the given template or\n"
10066 "default if one is not specified. Returns -1 on error or 0 on success.\n";
10067
10068
10069
10070
10071 static int iax2_prov_app(struct ast_channel *chan, void *data)
10072 {
10073 int res;
10074 char *sdata;
10075 char *opts;
10076 int force =0;
10077 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
10078 if (ast_strlen_zero(data))
10079 data = "default";
10080 sdata = ast_strdupa(data);
10081 opts = strchr(sdata, '|');
10082 if (opts)
10083 *opts='\0';
10084
10085 if (chan->tech != &iax2_tech) {
10086 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
10087 return -1;
10088 }
10089 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
10090 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
10091 return -1;
10092 }
10093 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
10094 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
10095 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
10096 sdata, res);
10097 return res;
10098 }
10099
10100 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
10101 {
10102 int force = 0;
10103 int res;
10104
10105 switch (cmd) {
10106 case CLI_INIT:
10107 e->command = "iax2 provision";
10108 e->usage =
10109 "Usage: iax2 provision <host> <template> [forced]\n"
10110 " Provisions the given peer or IP address using a template\n"
10111 " matching either 'template' or '*' if the template is not\n"
10112 " found. If 'forced' is specified, even empty provisioning\n"
10113 " fields will be provisioned as empty fields.\n";
10114 return NULL;
10115 case CLI_GENERATE:
10116 if (a->pos == 3)
10117 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
10118 return NULL;
10119 }
10120
10121 if (a->argc < 4)
10122 return CLI_SHOWUSAGE;
10123 if (a->argc > 4) {
10124 if (!strcasecmp(a->argv[4], "forced"))
10125 force = 1;
10126 else
10127 return CLI_SHOWUSAGE;
10128 }
10129 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
10130 if (res < 0)
10131 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
10132 else if (res < 1)
10133 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
10134 else
10135 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
10136 return CLI_SUCCESS;
10137 }
10138
10139 static void __iax2_poke_noanswer(const void *data)
10140 {
10141 struct iax2_peer *peer = (struct iax2_peer *)data;
10142 int callno;
10143
10144 if (peer->lastms > -1) {
10145 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
10146 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
10147 ast_device_state_changed("IAX2/%s", peer->name);
10148 }
10149 if ((callno = peer->callno) > 0) {
10150 ast_mutex_lock(&iaxsl[callno]);
10151 iax2_destroy(callno);
10152 ast_mutex_unlock(&iaxsl[callno]);
10153 }
10154 peer->callno = 0;
10155 peer->lastms = -1;
10156
10157 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10158 if (peer->pokeexpire == -1)
10159 peer_unref(peer);
10160 }
10161
10162 static int iax2_poke_noanswer(const void *data)
10163 {
10164 struct iax2_peer *peer = (struct iax2_peer *)data;
10165 peer->pokeexpire = -1;
10166 #ifdef SCHED_MULTITHREADED
10167 if (schedule_action(__iax2_poke_noanswer, data))
10168 #endif
10169 __iax2_poke_noanswer(data);
10170 peer_unref(peer);
10171 return 0;
10172 }
10173
10174 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
10175 {
10176 struct iax2_peer *peer = obj;
10177
10178 iax2_poke_peer(peer, 0);
10179
10180 return 0;
10181 }
10182
10183 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
10184 {
10185 int callno;
10186 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
10187
10188
10189 peer->lastms = 0;
10190 peer->historicms = 0;
10191 peer->pokeexpire = -1;
10192 peer->callno = 0;
10193 return 0;
10194 }
10195
10196
10197 if ((callno = peer->callno) > 0) {
10198 ast_log(LOG_NOTICE, "Still have a callno...\n");
10199 ast_mutex_lock(&iaxsl[callno]);
10200 iax2_destroy(callno);
10201 ast_mutex_unlock(&iaxsl[callno]);
10202 }
10203 if (heldcall)
10204 ast_mutex_unlock(&iaxsl[heldcall]);
10205 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
10206 if (heldcall)
10207 ast_mutex_lock(&iaxsl[heldcall]);
10208 if (peer->callno < 1) {
10209 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
10210 return -1;
10211 }
10212
10213
10214 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
10215 iaxs[peer->callno]->peerpoke = peer;
10216
10217 if (peer->pokeexpire > -1) {
10218 if (!ast_sched_del(sched, peer->pokeexpire)) {
10219 peer->pokeexpire = -1;
10220 peer_unref(peer);
10221 }
10222 }
10223
10224
10225
10226 if (peer->lastms < 0)
10227 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
10228 else
10229 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
10230
10231 if (peer->pokeexpire == -1)
10232 peer_unref(peer);
10233
10234
10235 ast_mutex_lock(&iaxsl[callno]);
10236 if (iaxs[callno]) {
10237 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
10238 }
10239 ast_mutex_unlock(&iaxsl[callno]);
10240
10241 return 0;
10242 }
10243
10244 static void free_context(struct iax2_context *con)
10245 {
10246 struct iax2_context *conl;
10247 while(con) {
10248 conl = con;
10249 con = con->next;
10250 ast_free(conl);
10251 }
10252 }
10253
10254 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
10255 {
10256 int callno;
10257 int res;
10258 int fmt, native;
10259 struct sockaddr_in sin;
10260 struct ast_channel *c;
10261 struct parsed_dial_string pds;
10262 struct create_addr_info cai;
10263 char *tmpstr;
10264
10265 memset(&pds, 0, sizeof(pds));
10266 tmpstr = ast_strdupa(data);
10267 parse_dial_string(tmpstr, &pds);
10268
10269 if (ast_strlen_zero(pds.peer)) {
10270 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10271 return NULL;
10272 }
10273
10274 memset(&cai, 0, sizeof(cai));
10275 cai.capability = iax2_capability;
10276
10277 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10278
10279
10280 if (create_addr(pds.peer, NULL, &sin, &cai)) {
10281 *cause = AST_CAUSE_UNREGISTERED;
10282 return NULL;
10283 }
10284
10285 if (pds.port)
10286 sin.sin_port = htons(atoi(pds.port));
10287
10288 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10289 if (callno < 1) {
10290 ast_log(LOG_WARNING, "Unable to create call\n");
10291 *cause = AST_CAUSE_CONGESTION;
10292 return NULL;
10293 }
10294
10295
10296 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10297 if (ast_test_flag(&cai, IAX_TRUNK)) {
10298 int new_callno;
10299 if ((new_callno = make_trunk(callno, 1)) != -1)
10300 callno = new_callno;
10301 }
10302 iaxs[callno]->maxtime = cai.maxtime;
10303 if (cai.found)
10304 ast_string_field_set(iaxs[callno], host, pds.peer);
10305
10306 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
10307
10308 ast_mutex_unlock(&iaxsl[callno]);
10309
10310 if (c) {
10311
10312 if (c->nativeformats & format)
10313 c->nativeformats &= format;
10314 else {
10315 native = c->nativeformats;
10316 fmt = format;
10317 res = ast_translator_best_choice(&fmt, &native);
10318 if (res < 0) {
10319 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
10320 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
10321 ast_hangup(c);
10322 return NULL;
10323 }
10324 c->nativeformats = native;
10325 }
10326 c->readformat = ast_best_codec(c->nativeformats);
10327 c->writeformat = c->readformat;
10328 }
10329
10330 return c;
10331 }
10332
10333 static void *sched_thread(void *ignore)
10334 {
10335 int count;
10336 int res;
10337 struct timeval tv;
10338 struct timespec ts;
10339
10340 for (;;) {
10341 res = ast_sched_wait(sched);
10342 if ((res > 1000) || (res < 0))
10343 res = 1000;
10344 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
10345 ts.tv_sec = tv.tv_sec;
10346 ts.tv_nsec = tv.tv_usec * 1000;
10347
10348 pthread_testcancel();
10349 ast_mutex_lock(&sched_lock);
10350 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
10351 ast_mutex_unlock(&sched_lock);
10352 pthread_testcancel();
10353
10354 count = ast_sched_runq(sched);
10355 if (count >= 20)
10356 ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
10357 }
10358
10359 return NULL;
10360 }
10361
10362 static void *network_thread(void *ignore)
10363 {
10364
10365
10366 int res, count, wakeup;
10367 struct iax_frame *f;
10368
10369 if (timingfd > -1)
10370 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
10371
10372 for(;;) {
10373 pthread_testcancel();
10374
10375
10376
10377 AST_LIST_LOCK(&frame_queue);
10378 count = 0;
10379 wakeup = -1;
10380 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
10381 if (f->sentyet)
10382 continue;
10383
10384
10385 if (ast_mutex_trylock(&iaxsl[f->callno])) {
10386 wakeup = 1;
10387 continue;
10388 }
10389
10390 f->sentyet = 1;
10391
10392 if (iaxs[f->callno]) {
10393 send_packet(f);
10394 count++;
10395 }
10396
10397 ast_mutex_unlock(&iaxsl[f->callno]);
10398
10399 if (f->retries < 0) {
10400
10401 AST_LIST_REMOVE_CURRENT(list);
10402
10403 iax_frame_free(f);
10404 } else {
10405
10406 f->retries++;
10407 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
10408 }
10409 }
10410 AST_LIST_TRAVERSE_SAFE_END;
10411 AST_LIST_UNLOCK(&frame_queue);
10412
10413 pthread_testcancel();
10414 if (count >= 20)
10415 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
10416
10417
10418 res = ast_io_wait(io, wakeup);
10419 if (res >= 0) {
10420 if (res >= 20)
10421 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
10422 }
10423 }
10424 return NULL;
10425 }
10426
10427 static int start_network_thread(void)
10428 {
10429 struct iax2_thread *thread;
10430 int threadcount = 0;
10431 int x;
10432 for (x = 0; x < iaxthreadcount; x++) {
10433 thread = ast_calloc(1, sizeof(*thread));
10434 if (thread) {
10435 thread->type = IAX_THREAD_TYPE_POOL;
10436 thread->threadnum = ++threadcount;
10437 ast_mutex_init(&thread->lock);
10438 ast_cond_init(&thread->cond, NULL);
10439 if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) {
10440 ast_log(LOG_WARNING, "Failed to create new thread!\n");
10441 ast_free(thread);
10442 thread = NULL;
10443 }
10444 AST_LIST_LOCK(&idle_list);
10445 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
10446 AST_LIST_UNLOCK(&idle_list);
10447 }
10448 }
10449 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
10450 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
10451 ast_verb(2, "%d helper threads started\n", threadcount);
10452 return 0;
10453 }
10454
10455 static struct iax2_context *build_context(const char *context)
10456 {
10457 struct iax2_context *con;
10458
10459 if ((con = ast_calloc(1, sizeof(*con))))
10460 ast_copy_string(con->context, context, sizeof(con->context));
10461
10462 return con;
10463 }
10464
10465 static int get_auth_methods(const char *value)
10466 {
10467 int methods = 0;
10468 if (strstr(value, "rsa"))
10469 methods |= IAX_AUTH_RSA;
10470 if (strstr(value, "md5"))
10471 methods |= IAX_AUTH_MD5;
10472 if (strstr(value, "plaintext"))
10473 methods |= IAX_AUTH_PLAINTEXT;
10474 return methods;
10475 }
10476
10477
10478
10479
10480
10481 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
10482 {
10483 int sd;
10484 int res;
10485
10486 sd = socket(AF_INET, SOCK_DGRAM, 0);
10487 if (sd < 0) {
10488 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
10489 return -1;
10490 }
10491
10492 res = bind(sd, sa, salen);
10493 if (res < 0) {
10494 ast_debug(1, "Can't bind: %s\n", strerror(errno));
10495 close(sd);
10496 return 1;
10497 }
10498
10499 close(sd);
10500 return 0;
10501 }
10502
10503
10504
10505
10506 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
10507 {
10508 struct sockaddr_in sin;
10509 int nonlocal = 1;
10510 int port = IAX_DEFAULT_PORTNO;
10511 int sockfd = defaultsockfd;
10512 char *tmp;
10513 char *addr;
10514 char *portstr;
10515
10516 if (!(tmp = ast_strdupa(srcaddr)))
10517 return -1;
10518
10519 addr = strsep(&tmp, ":");
10520 portstr = tmp;
10521
10522 if (portstr) {
10523 port = atoi(portstr);
10524 if (port < 1)
10525 port = IAX_DEFAULT_PORTNO;
10526 }
10527
10528 if (!ast_get_ip(&sin, addr)) {
10529 struct ast_netsock *sock;
10530 int res;
10531
10532 sin.sin_port = 0;
10533 sin.sin_family = AF_INET;
10534 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
10535 if (res == 0) {
10536
10537 sin.sin_port = htons(port);
10538 if (!(sock = ast_netsock_find(netsock, &sin)))
10539 sock = ast_netsock_find(outsock, &sin);
10540 if (sock) {
10541 sockfd = ast_netsock_sockfd(sock);
10542 nonlocal = 0;
10543 } else {
10544 unsigned int orig_saddr = sin.sin_addr.s_addr;
10545
10546 sin.sin_addr.s_addr = INADDR_ANY;
10547 if (ast_netsock_find(netsock, &sin)) {
10548 sin.sin_addr.s_addr = orig_saddr;
10549 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, cos, socket_read, NULL);
10550 if (sock) {
10551 sockfd = ast_netsock_sockfd(sock);
10552 ast_netsock_unref(sock);
10553 nonlocal = 0;
10554 } else {
10555 nonlocal = 2;
10556 }
10557 }
10558 }
10559 }
10560 }
10561
10562 peer->sockfd = sockfd;
10563
10564 if (nonlocal == 1) {
10565 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
10566 srcaddr, peer->name);
10567 return -1;
10568 } else if (nonlocal == 2) {
10569 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
10570 srcaddr, peer->name);
10571 return -1;
10572 } else {
10573 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
10574 return 0;
10575 }
10576 }
10577
10578 static void peer_destructor(void *obj)
10579 {
10580 struct iax2_peer *peer = obj;
10581 int callno = peer->callno;
10582
10583 ast_free_ha(peer->ha);
10584
10585 if (callno > 0) {
10586 ast_mutex_lock(&iaxsl[callno]);
10587 iax2_destroy(callno);
10588 ast_mutex_unlock(&iaxsl[callno]);
10589 }
10590
10591 register_peer_exten(peer, 0);
10592
10593 if (peer->dnsmgr)
10594 ast_dnsmgr_release(peer->dnsmgr);
10595
10596 if (peer->mwi_event_sub)
10597 ast_event_unsubscribe(peer->mwi_event_sub);
10598
10599 ast_string_field_free_memory(peer);
10600 }
10601
10602
10603 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10604 {
10605 struct iax2_peer *peer = NULL;
10606 struct ast_ha *oldha = NULL;
10607 int maskfound = 0;
10608 int found = 0;
10609 int firstpass = 1;
10610 struct iax2_peer tmp_peer = {
10611 .name = name,
10612 };
10613
10614 if (!temponly) {
10615 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
10616 if (peer && !ast_test_flag(peer, IAX_DELME))
10617 firstpass = 0;
10618 }
10619
10620 if (peer) {
10621 found++;
10622 if (firstpass) {
10623 oldha = peer->ha;
10624 peer->ha = NULL;
10625 }
10626 unlink_peer(peer);
10627 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
10628 peer->expire = -1;
10629 peer->pokeexpire = -1;
10630 peer->sockfd = defaultsockfd;
10631 if (ast_string_field_init(peer, 32))
10632 peer = peer_unref(peer);
10633 }
10634
10635 if (peer) {
10636 if (firstpass) {
10637 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10638 peer->encmethods = iax2_encryption;
10639 peer->adsi = adsi;
10640 ast_string_field_set(peer,secret,"");
10641 if (!found) {
10642 ast_string_field_set(peer, name, name);
10643 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10644 peer->expiry = min_reg_expire;
10645 }
10646 peer->prefs = prefs;
10647 peer->capability = iax2_capability;
10648 peer->smoothing = 0;
10649 peer->pokefreqok = DEFAULT_FREQ_OK;
10650 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
10651 ast_string_field_set(peer,context,"");
10652 ast_string_field_set(peer,peercontext,"");
10653 ast_clear_flag(peer, IAX_HASCALLERID);
10654 ast_string_field_set(peer, cid_name, "");
10655 ast_string_field_set(peer, cid_num, "");
10656 ast_string_field_set(peer, mohinterpret, mohinterpret);
10657 ast_string_field_set(peer, mohsuggest, mohsuggest);
10658 }
10659
10660 if (!v) {
10661 v = alt;
10662 alt = NULL;
10663 }
10664 while(v) {
10665 if (!strcasecmp(v->name, "secret")) {
10666 ast_string_field_set(peer, secret, v->value);
10667 } else if (!strcasecmp(v->name, "mailbox")) {
10668 ast_string_field_set(peer, mailbox, v->value);
10669 } else if (!strcasecmp(v->name, "hasvoicemail")) {
10670 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
10671 ast_string_field_set(peer, mailbox, name);
10672 }
10673 } else if (!strcasecmp(v->name, "mohinterpret")) {
10674 ast_string_field_set(peer, mohinterpret, v->value);
10675 } else if (!strcasecmp(v->name, "mohsuggest")) {
10676 ast_string_field_set(peer, mohsuggest, v->value);
10677 } else if (!strcasecmp(v->name, "dbsecret")) {
10678 ast_string_field_set(peer, dbsecret, v->value);
10679 } else if (!strcasecmp(v->name, "trunk")) {
10680 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
10681 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
10682 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without DAHDI timing\n", peer->name);
10683 ast_clear_flag(peer, IAX_TRUNK);
10684 }
10685 } else if (!strcasecmp(v->name, "auth")) {
10686 peer->authmethods = get_auth_methods(v->value);
10687 } else if (!strcasecmp(v->name, "encryption")) {
10688 peer->encmethods = get_encrypt_methods(v->value);
10689 } else if (!strcasecmp(v->name, "transfer")) {
10690 if (!strcasecmp(v->value, "mediaonly")) {
10691 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
10692 } else if (ast_true(v->value)) {
10693 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10694 } else
10695 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10696 } else if (!strcasecmp(v->name, "jitterbuffer")) {
10697 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
10698 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10699 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
10700 } else if (!strcasecmp(v->name, "host")) {
10701 if (!strcasecmp(v->value, "dynamic")) {
10702
10703 ast_set_flag(peer, IAX_DYNAMIC);
10704 if (!found) {
10705
10706
10707 memset(&peer->addr.sin_addr, 0, 4);
10708 if (peer->addr.sin_port) {
10709
10710 peer->defaddr.sin_port = peer->addr.sin_port;
10711 peer->addr.sin_port = 0;
10712 }
10713 }
10714 } else {
10715
10716 AST_SCHED_DEL(sched, peer->expire);
10717 ast_clear_flag(peer, IAX_DYNAMIC);
10718 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
10719 return peer_unref(peer);
10720 if (!peer->addr.sin_port)
10721 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10722 }
10723 if (!maskfound)
10724 inet_aton("255.255.255.255", &peer->mask);
10725 } else if (!strcasecmp(v->name, "defaultip")) {
10726 if (ast_get_ip(&peer->defaddr, v->value))
10727 return peer_unref(peer);
10728 } else if (!strcasecmp(v->name, "sourceaddress")) {
10729 peer_set_srcaddr(peer, v->value);
10730 } else if (!strcasecmp(v->name, "permit") ||
10731 !strcasecmp(v->name, "deny")) {
10732 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
10733 } else if (!strcasecmp(v->name, "mask")) {
10734 maskfound++;
10735 inet_aton(v->value, &peer->mask);
10736 } else if (!strcasecmp(v->name, "context")) {
10737 ast_string_field_set(peer, context, v->value);
10738 } else if (!strcasecmp(v->name, "regexten")) {
10739 ast_string_field_set(peer, regexten, v->value);
10740 } else if (!strcasecmp(v->name, "peercontext")) {
10741 ast_string_field_set(peer, peercontext, v->value);
10742 } else if (!strcasecmp(v->name, "port")) {
10743 if (ast_test_flag(peer, IAX_DYNAMIC))
10744 peer->defaddr.sin_port = htons(atoi(v->value));
10745 else
10746 peer->addr.sin_port = htons(atoi(v->value));
10747 } else if (!strcasecmp(v->name, "username")) {
10748 ast_string_field_set(peer, username, v->value);
10749 } else if (!strcasecmp(v->name, "allow")) {
10750 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
10751 } else if (!strcasecmp(v->name, "disallow")) {
10752 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
10753 } else if (!strcasecmp(v->name, "callerid")) {
10754 if (!ast_strlen_zero(v->value)) {
10755 char name2[80];
10756 char num2[80];
10757 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10758 ast_string_field_set(peer, cid_name, name2);
10759 ast_string_field_set(peer, cid_num, num2);
10760 } else {
10761 ast_string_field_set(peer, cid_name, "");
10762 ast_string_field_set(peer, cid_num, "");
10763 }
10764 ast_set_flag(peer, IAX_HASCALLERID);
10765 } else if (!strcasecmp(v->name, "fullname")) {
10766 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
10767 ast_set_flag(peer, IAX_HASCALLERID);
10768 } else if (!strcasecmp(v->name, "cid_number")) {
10769 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
10770 ast_set_flag(peer, IAX_HASCALLERID);
10771 } else if (!strcasecmp(v->name, "sendani")) {
10772 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
10773 } else if (!strcasecmp(v->name, "inkeys")) {
10774 ast_string_field_set(peer, inkeys, v->value);
10775 } else if (!strcasecmp(v->name, "outkey")) {
10776 ast_string_field_set(peer, outkey, v->value);
10777 } else if (!strcasecmp(v->name, "qualify")) {
10778 if (!strcasecmp(v->value, "no")) {
10779 peer->maxms = 0;
10780 } else if (!strcasecmp(v->value, "yes")) {
10781 peer->maxms = DEFAULT_MAXMS;
10782 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
10783 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);
10784 peer->maxms = 0;
10785 }
10786 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
10787 peer->smoothing = ast_true(v->value);
10788 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
10789 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
10790 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);
10791 }
10792 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
10793 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
10794 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);
10795 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
10796 } else if (!strcasecmp(v->name, "timezone")) {
10797 ast_string_field_set(peer, zonetag, v->value);
10798 } else if (!strcasecmp(v->name, "adsi")) {
10799 peer->adsi = ast_true(v->value);
10800 }
10801
10802 v = v->next;
10803 if (!v) {
10804 v = alt;
10805 alt = NULL;
10806 }
10807 }
10808 if (!peer->authmethods)
10809 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
10810 ast_clear_flag(peer, IAX_DELME);
10811
10812 peer->addr.sin_family = AF_INET;
10813 }
10814
10815 if (oldha)
10816 ast_free_ha(oldha);
10817
10818 if (!ast_strlen_zero(peer->mailbox)) {
10819 char *mailbox, *context;
10820 context = mailbox = ast_strdupa(peer->mailbox);
10821 strsep(&context, "@");
10822 if (ast_strlen_zero(context))
10823 context = "default";
10824 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
10825 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
10826 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
10827 AST_EVENT_IE_END);
10828 }
10829
10830 return peer;
10831 }
10832
10833 static void user_destructor(void *obj)
10834 {
10835 struct iax2_user *user = obj;
10836
10837 ast_free_ha(user->ha);
10838 free_context(user->contexts);
10839 if(user->vars) {
10840 ast_variables_destroy(user->vars);
10841 user->vars = NULL;
10842 }
10843 ast_string_field_free_memory(user);
10844 }
10845
10846
10847 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10848 {
10849 struct iax2_user *user = NULL;
10850 struct iax2_context *con, *conl = NULL;
10851 struct ast_ha *oldha = NULL;
10852 struct iax2_context *oldcon = NULL;
10853 int format;
10854 int firstpass=1;
10855 int oldcurauthreq = 0;
10856 char *varname = NULL, *varval = NULL;
10857 struct ast_variable *tmpvar = NULL;
10858 struct iax2_user tmp_user = {
10859 .name = name,
10860 };
10861
10862 if (!temponly) {
10863 user = ao2_find(users, &tmp_user, OBJ_POINTER);
10864 if (user && !ast_test_flag(user, IAX_DELME))
10865 firstpass = 0;
10866 }
10867
10868 if (user) {
10869 if (firstpass) {
10870 oldcurauthreq = user->curauthreq;
10871 oldha = user->ha;
10872 oldcon = user->contexts;
10873 user->ha = NULL;
10874 user->contexts = NULL;
10875 }
10876
10877 ao2_unlink(users, user);
10878 } else {
10879 user = ao2_alloc(sizeof(*user), user_destructor);
10880 }
10881
10882 if (user) {
10883 if (firstpass) {
10884 ast_string_field_free_memory(user);
10885 memset(user, 0, sizeof(struct iax2_user));
10886 if (ast_string_field_init(user, 32)) {
10887 user = user_unref(user);
10888 goto cleanup;
10889 }
10890 user->maxauthreq = maxauthreq;
10891 user->curauthreq = oldcurauthreq;
10892 user->prefs = prefs;
10893 user->capability = iax2_capability;
10894 user->encmethods = iax2_encryption;
10895 user->adsi = adsi;
10896 ast_string_field_set(user, name, name);
10897 ast_string_field_set(user, language, language);
10898 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
10899 ast_clear_flag(user, IAX_HASCALLERID);
10900 ast_string_field_set(user, cid_name, "");
10901 ast_string_field_set(user, cid_num, "");
10902 ast_string_field_set(user, accountcode, accountcode);
10903 ast_string_field_set(user, mohinterpret, mohinterpret);
10904 ast_string_field_set(user, mohsuggest, mohsuggest);
10905 }
10906 if (!v) {
10907 v = alt;
10908 alt = NULL;
10909 }
10910 while(v) {
10911 if (!strcasecmp(v->name, "context")) {
10912 con = build_context(v->value);
10913 if (con) {
10914 if (conl)
10915 conl->next = con;
10916 else
10917 user->contexts = con;
10918 conl = con;
10919 }
10920 } else if (!strcasecmp(v->name, "permit") ||
10921 !strcasecmp(v->name, "deny")) {
10922 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
10923 } else if (!strcasecmp(v->name, "setvar")) {
10924 varname = ast_strdupa(v->value);
10925 if (varname && (varval = strchr(varname,'='))) {
10926 *varval = '\0';
10927 varval++;
10928 if((tmpvar = ast_variable_new(varname, varval, ""))) {
10929 tmpvar->next = user->vars;
10930 user->vars = tmpvar;
10931 }
10932 }
10933 } else if (!strcasecmp(v->name, "allow")) {
10934 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
10935 } else if (!strcasecmp(v->name, "disallow")) {
10936 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
10937 } else if (!strcasecmp(v->name, "trunk")) {
10938 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
10939 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
10940 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without DAHDI timing\n", user->name);
10941 ast_clear_flag(user, IAX_TRUNK);
10942 }
10943 } else if (!strcasecmp(v->name, "auth")) {
10944 user->authmethods = get_auth_methods(v->value);
10945 } else if (!strcasecmp(v->name, "encryption")) {
10946 user->encmethods = get_encrypt_methods(v->value);
10947 } else if (!strcasecmp(v->name, "transfer")) {
10948 if (!strcasecmp(v->value, "mediaonly")) {
10949 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
10950 } else if (ast_true(v->value)) {
10951 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10952 } else
10953 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10954 } else if (!strcasecmp(v->name, "codecpriority")) {
10955 if(!strcasecmp(v->value, "caller"))
10956 ast_set_flag(user, IAX_CODEC_USER_FIRST);
10957 else if(!strcasecmp(v->value, "disabled"))
10958 ast_set_flag(user, IAX_CODEC_NOPREFS);
10959 else if(!strcasecmp(v->value, "reqonly")) {
10960 ast_set_flag(user, IAX_CODEC_NOCAP);
10961 ast_set_flag(user, IAX_CODEC_NOPREFS);
10962 }
10963 } else if (!strcasecmp(v->name, "jitterbuffer")) {
10964 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
10965 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10966 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
10967 } else if (!strcasecmp(v->name, "dbsecret")) {
10968 ast_string_field_set(user, dbsecret, v->value);
10969 } else if (!strcasecmp(v->name, "secret")) {
10970 if (!ast_strlen_zero(user->secret)) {
10971 char *old = ast_strdupa(user->secret);
10972
10973 ast_string_field_build(user, secret, "%s;%s", old, v->value);
10974 } else
10975 ast_string_field_set(user, secret, v->value);
10976 } else if (!strcasecmp(v->name, "callerid")) {
10977 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
10978 char name2[80];
10979 char num2[80];
10980 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10981 ast_string_field_set(user, cid_name, name2);
10982 ast_string_field_set(user, cid_num, num2);
10983 ast_set_flag(user, IAX_HASCALLERID);
10984 } else {
10985 ast_clear_flag(user, IAX_HASCALLERID);
10986 ast_string_field_set(user, cid_name, "");
10987 ast_string_field_set(user, cid_num, "");
10988 }
10989 } else if (!strcasecmp(v->name, "fullname")) {
10990 if (!ast_strlen_zero(v->value)) {
10991 ast_string_field_set(user, cid_name, v->value);
10992 ast_set_flag(user, IAX_HASCALLERID);
10993 } else {
10994 ast_string_field_set(user, cid_name, "");
10995 if (ast_strlen_zero(user->cid_num))
10996 ast_clear_flag(user, IAX_HASCALLERID);
10997 }
10998 } else if (!strcasecmp(v->name, "cid_number")) {
10999 if (!ast_strlen_zero(v->value)) {
11000 ast_string_field_set(user, cid_num, v->value);
11001 ast_set_flag(user, IAX_HASCALLERID);
11002 } else {
11003 ast_string_field_set(user, cid_num, "");
11004 if (ast_strlen_zero(user->cid_name))
11005 ast_clear_flag(user, IAX_HASCALLERID);
11006 }
11007 } else if (!strcasecmp(v->name, "accountcode")) {
11008 ast_string_field_set(user, accountcode, v->value);
11009 } else if (!strcasecmp(v->name, "mohinterpret")) {
11010 ast_string_field_set(user, mohinterpret, v->value);
11011 } else if (!strcasecmp(v->name, "mohsuggest")) {
11012 ast_string_field_set(user, mohsuggest, v->value);
11013 } else if (!strcasecmp(v->name, "language")) {
11014 ast_string_field_set(user, language, v->value);
11015 } else if (!strcasecmp(v->name, "amaflags")) {
11016 format = ast_cdr_amaflags2int(v->value);
11017 if (format < 0) {
11018 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11019 } else {
11020 user->amaflags = format;
11021 }
11022 } else if (!strcasecmp(v->name, "inkeys")) {
11023 ast_string_field_set(user, inkeys, v->value);
11024 } else if (!strcasecmp(v->name, "maxauthreq")) {
11025 user->maxauthreq = atoi(v->value);
11026 if (user->maxauthreq < 0)
11027 user->maxauthreq = 0;
11028 } else if (!strcasecmp(v->name, "adsi")) {
11029 user->adsi = ast_true(v->value);
11030 }
11031
11032 v = v->next;
11033 if (!v) {
11034 v = alt;
11035 alt = NULL;
11036 }
11037 }
11038 if (!user->authmethods) {
11039 if (!ast_strlen_zero(user->secret)) {
11040 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11041 if (!ast_strlen_zero(user->inkeys))
11042 user->authmethods |= IAX_AUTH_RSA;
11043 } else if (!ast_strlen_zero(user->inkeys)) {
11044 user->authmethods = IAX_AUTH_RSA;
11045 } else {
11046 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11047 }
11048 }
11049 ast_clear_flag(user, IAX_DELME);
11050 }
11051 cleanup:
11052 if (oldha)
11053 ast_free_ha(oldha);
11054 if (oldcon)
11055 free_context(oldcon);
11056 return user;
11057 }
11058
11059 static int peer_delme_cb(void *obj, void *arg, int flags)
11060 {
11061 struct iax2_peer *peer = obj;
11062
11063 ast_set_flag(peer, IAX_DELME);
11064
11065 return 0;
11066 }
11067
11068 static int user_delme_cb(void *obj, void *arg, int flags)
11069 {
11070 struct iax2_user *user = obj;
11071
11072 ast_set_flag(user, IAX_DELME);
11073
11074 return 0;
11075 }
11076
11077 static void delete_users(void)
11078 {
11079 struct iax2_registry *reg;
11080
11081 ao2_callback(users, 0, user_delme_cb, NULL);
11082
11083 AST_LIST_LOCK(®istrations);
11084 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
11085 AST_SCHED_DEL(sched, reg->expire);
11086 if (reg->callno) {
11087 int callno = reg->callno;
11088 ast_mutex_lock(&iaxsl[callno]);
11089 if (iaxs[callno]) {
11090 iaxs[callno]->reg = NULL;
11091 iax2_destroy(callno);
11092 }
11093 ast_mutex_unlock(&iaxsl[callno]);
11094 }
11095 if (reg->dnsmgr)
11096 ast_dnsmgr_release(reg->dnsmgr);
11097 ast_free(reg);
11098 }
11099 AST_LIST_UNLOCK(®istrations);
11100
11101 ao2_callback(peers, 0, peer_delme_cb, NULL);
11102 }
11103
11104 static void prune_users(void)
11105 {
11106 struct iax2_user *user;
11107 struct ao2_iterator i;
11108
11109 i = ao2_iterator_init(users, 0);
11110 while ((user = ao2_iterator_next(&i))) {
11111 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
11112 ao2_unlink(users, user);
11113 }
11114 user_unref(user);
11115 }
11116 }
11117
11118
11119 static void prune_peers(void)
11120 {
11121 struct iax2_peer *peer;
11122 struct ao2_iterator i;
11123
11124 i = ao2_iterator_init(peers, 0);
11125 while ((peer = ao2_iterator_next(&i))) {
11126 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
11127 unlink_peer(peer);
11128 }
11129 peer_unref(peer);
11130 }
11131 }
11132
11133 static void set_timing(void)
11134 {
11135 #ifdef HAVE_DAHDI
11136 int bs = trunkfreq * 8;
11137 if (timingfd > -1) {
11138 if (
11139 #ifdef DAHDI_TIMERACK
11140 ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) &&
11141 #endif
11142 ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs))
11143 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
11144 }
11145 #endif
11146 }
11147
11148 static void set_config_destroy(void)
11149 {
11150 strcpy(accountcode, "");
11151 strcpy(language, "");
11152 strcpy(mohinterpret, "default");
11153 strcpy(mohsuggest, "");
11154 trunkmaxsize = MAX_TRUNKDATA;
11155 amaflags = 0;
11156 delayreject = 0;
11157 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
11158 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
11159 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
11160 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
11161 delete_users();
11162 }
11163
11164
11165 static int set_config(char *config_file, int reload)
11166 {
11167 struct ast_config *cfg, *ucfg;
11168 int capability=iax2_capability;
11169 struct ast_variable *v;
11170 char *cat;
11171 const char *utype;
11172 const char *tosval;
11173 int format;
11174 int portno = IAX_DEFAULT_PORTNO;
11175 int x;
11176 int mtuv;
11177 struct iax2_user *user;
11178 struct iax2_peer *peer;
11179 struct ast_netsock *ns;
11180 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
11181 #if 0
11182 static unsigned short int last_port=0;
11183 #endif
11184
11185 cfg = ast_config_load(config_file, config_flags);
11186
11187 if (!cfg) {
11188 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
11189 return -1;
11190 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
11191 ucfg = ast_config_load("users.conf", config_flags);
11192 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
11193 return 0;
11194
11195 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11196 cfg = ast_config_load(config_file, config_flags);
11197 } else {
11198 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11199 ucfg = ast_config_load("users.conf", config_flags);
11200 }
11201
11202 if (reload) {
11203 set_config_destroy();
11204 }
11205
11206
11207 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
11208
11209
11210 memset(&globalflags, 0, sizeof(globalflags));
11211 ast_set_flag(&globalflags, IAX_RTUPDATE);
11212
11213 #ifdef SO_NO_CHECK
11214 nochecksums = 0;
11215 #endif
11216
11217 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11218 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11219 global_max_trunk_mtu = MAX_TRUNK_MTU;
11220
11221 maxauthreq = 3;
11222
11223 srvlookup = 0;
11224
11225 v = ast_variable_browse(cfg, "general");
11226
11227
11228 tosval = ast_variable_retrieve(cfg, "general", "tos");
11229 if (tosval) {
11230 if (ast_str2tos(tosval, &tos))
11231 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
11232 }
11233
11234 tosval = ast_variable_retrieve(cfg, "general", "cos");
11235 if (tosval) {
11236 if (ast_str2cos(tosval, &cos))
11237 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
11238 }
11239 while(v) {
11240 if (!strcasecmp(v->name, "bindport")){
11241 if (reload)
11242 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
11243 else
11244 portno = atoi(v->value);
11245 } else if (!strcasecmp(v->name, "pingtime"))
11246 ping_time = atoi(v->value);
11247 else if (!strcasecmp(v->name, "iaxthreadcount")) {
11248 if (reload) {
11249 if (atoi(v->value) != iaxthreadcount)
11250 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
11251 } else {
11252 iaxthreadcount = atoi(v->value);
11253 if (iaxthreadcount < 1) {
11254 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
11255 iaxthreadcount = 1;
11256 } else if (iaxthreadcount > 256) {
11257 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
11258 iaxthreadcount = 256;
11259 }
11260 }
11261 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
11262 if (reload) {
11263 AST_LIST_LOCK(&dynamic_list);
11264 iaxmaxthreadcount = atoi(v->value);
11265 AST_LIST_UNLOCK(&dynamic_list);
11266 } else {
11267 iaxmaxthreadcount = atoi(v->value);
11268 if (iaxmaxthreadcount < 0) {
11269 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
11270 iaxmaxthreadcount = 0;
11271 } else if (iaxmaxthreadcount > 256) {
11272 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
11273 iaxmaxthreadcount = 256;
11274 }
11275 }
11276 } else if (!strcasecmp(v->name, "nochecksums")) {
11277 #ifdef SO_NO_CHECK
11278 if (ast_true(v->value))
11279 nochecksums = 1;
11280 else
11281 nochecksums = 0;
11282 #else
11283 if (ast_true(v->value))
11284 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
11285 #endif
11286 }
11287 else if (!strcasecmp(v->name, "maxjitterbuffer"))
11288 maxjitterbuffer = atoi(v->value);
11289 else if (!strcasecmp(v->name, "resyncthreshold"))
11290 resyncthreshold = atoi(v->value);
11291 else if (!strcasecmp(v->name, "maxjitterinterps"))
11292 maxjitterinterps = atoi(v->value);
11293 else if (!strcasecmp(v->name, "jittertargetextra"))
11294 jittertargetextra = atoi(v->value);
11295 else if (!strcasecmp(v->name, "lagrqtime"))
11296 lagrq_time = atoi(v->value);
11297 else if (!strcasecmp(v->name, "maxregexpire"))
11298 max_reg_expire = atoi(v->value);
11299 else if (!strcasecmp(v->name, "minregexpire"))
11300 min_reg_expire = atoi(v->value);
11301 else if (!strcasecmp(v->name, "bindaddr")) {
11302 if (reload) {
11303 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
11304 } else {
11305 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, cos, socket_read, NULL))) {
11306 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
11307 } else {
11308 if (strchr(v->value, ':'))
11309 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
11310 else
11311 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
11312 if (defaultsockfd < 0)
11313 defaultsockfd = ast_netsock_sockfd(ns);
11314 ast_netsock_unref(ns);
11315 }
11316 }
11317 } else if (!strcasecmp(v->name, "authdebug"))
11318 authdebug = ast_true(v->value);
11319 else if (!strcasecmp(v->name, "encryption"))
11320 iax2_encryption = get_encrypt_methods(v->value);
11321 else if (!strcasecmp(v->name, "transfer")) {
11322 if (!strcasecmp(v->value, "mediaonly")) {
11323 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
11324 } else if (ast_true(v->value)) {
11325 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11326 } else
11327 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11328 } else if (!strcasecmp(v->name, "codecpriority")) {
11329 if(!strcasecmp(v->value, "caller"))
11330 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
11331 else if(!strcasecmp(v->value, "disabled"))
11332 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11333 else if(!strcasecmp(v->value, "reqonly")) {
11334 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
11335 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11336 }
11337 } else if (!strcasecmp(v->name, "jitterbuffer"))
11338 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
11339 else if (!strcasecmp(v->name, "forcejitterbuffer"))
11340 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
11341 else if (!strcasecmp(v->name, "delayreject"))
11342 delayreject = ast_true(v->value);
11343 else if (!strcasecmp(v->name, "allowfwdownload"))
11344 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
11345 else if (!strcasecmp(v->name, "rtcachefriends"))
11346 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
11347 else if (!strcasecmp(v->name, "rtignoreregexpire"))
11348 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
11349 else if (!strcasecmp(v->name, "rtupdate"))
11350 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
11351 else if (!strcasecmp(v->name, "trunktimestamps"))
11352 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
11353 else if (!strcasecmp(v->name, "rtautoclear")) {
11354 int i = atoi(v->value);
11355 if(i > 0)
11356 global_rtautoclear = i;
11357 else
11358 i = 0;
11359 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
11360 } else if (!strcasecmp(v->name, "trunkfreq")) {
11361 trunkfreq = atoi(v->value);
11362 if (trunkfreq < 10)
11363 trunkfreq = 10;
11364 } else if (!strcasecmp(v->name, "trunkmtu")) {
11365 mtuv = atoi(v->value);
11366 if (mtuv == 0 )
11367 global_max_trunk_mtu = 0;
11368 else if (mtuv >= 172 && mtuv < 4000)
11369 global_max_trunk_mtu = mtuv;
11370 else
11371 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
11372 mtuv, v->lineno);
11373 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
11374 trunkmaxsize = atoi(v->value);
11375 if (trunkmaxsize == 0)
11376 trunkmaxsize = MAX_TRUNKDATA;
11377 } else if (!strcasecmp(v->name, "autokill")) {
11378 if (sscanf(v->value, "%d", &x) == 1) {
11379 if (x >= 0)
11380 autokill = x;
11381 else
11382 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
11383 } else if (ast_true(v->value)) {
11384 autokill = DEFAULT_MAXMS;
11385 } else {
11386 autokill = 0;
11387 }
11388 } else if (!strcasecmp(v->name, "bandwidth")) {
11389 if (!strcasecmp(v->value, "low")) {
11390 capability = IAX_CAPABILITY_LOWBANDWIDTH;
11391 } else if (!strcasecmp(v->value, "medium")) {
11392 capability = IAX_CAPABILITY_MEDBANDWIDTH;
11393 } else if (!strcasecmp(v->value, "high")) {
11394 capability = IAX_CAPABILITY_FULLBANDWIDTH;
11395 } else
11396 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
11397 } else if (!strcasecmp(v->name, "allow")) {
11398 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
11399 } else if (!strcasecmp(v->name, "disallow")) {
11400 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
11401 } else if (!strcasecmp(v->name, "register")) {
11402 iax2_register(v->value, v->lineno);
11403 } else if (!strcasecmp(v->name, "iaxcompat")) {
11404 iaxcompat = ast_true(v->value);
11405 } else if (!strcasecmp(v->name, "regcontext")) {
11406 ast_copy_string(regcontext, v->value, sizeof(regcontext));
11407
11408 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
11409 } else if (!strcasecmp(v->name, "tos")) {
11410 if (ast_str2tos(v->value, &tos))
11411 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
11412 } else if (!strcasecmp(v->name, "cos")) {
11413 if (ast_str2cos(v->value, &cos))
11414 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
11415 } else if (!strcasecmp(v->name, "accountcode")) {
11416 ast_copy_string(accountcode, v->value, sizeof(accountcode));
11417 } else if (!strcasecmp(v->name, "mohinterpret")) {
11418 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
11419 } else if (!strcasecmp(v->name, "mohsuggest")) {
11420 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
11421 } else if (!strcasecmp(v->name, "amaflags")) {
11422 format = ast_cdr_amaflags2int(v->value);
11423 if (format < 0) {
11424 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11425 } else {
11426 amaflags = format;
11427 }
11428 } else if (!strcasecmp(v->name, "language")) {
11429 ast_copy_string(language, v->value, sizeof(language));
11430 } else if (!strcasecmp(v->name, "maxauthreq")) {
11431 maxauthreq = atoi(v->value);
11432 if (maxauthreq < 0)
11433 maxauthreq = 0;
11434 } else if (!strcasecmp(v->name, "adsi")) {
11435 adsi = ast_true(v->value);
11436 } else if (!strcasecmp(v->name, "srvlookup")) {
11437 srvlookup = ast_true(v->value);
11438 }
11439
11440 v = v->next;
11441 }
11442
11443 if (defaultsockfd < 0) {
11444 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, cos, socket_read, NULL))) {
11445 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
11446 } else {
11447 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
11448 defaultsockfd = ast_netsock_sockfd(ns);
11449 ast_netsock_unref(ns);
11450 }
11451 }
11452 if (reload) {
11453 ast_netsock_release(outsock);
11454 outsock = ast_netsock_list_alloc();
11455 if (!outsock) {
11456 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11457 return -1;
11458 }
11459 ast_netsock_init(outsock);
11460 }
11461
11462 if (min_reg_expire > max_reg_expire) {
11463 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
11464 min_reg_expire, max_reg_expire, max_reg_expire);
11465 min_reg_expire = max_reg_expire;
11466 }
11467 iax2_capability = capability;
11468
11469 if (ucfg) {
11470 struct ast_variable *gen;
11471 int genhasiax;
11472 int genregisteriax;
11473 const char *hasiax, *registeriax;
11474
11475 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
11476 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
11477 gen = ast_variable_browse(ucfg, "general");
11478 cat = ast_category_browse(ucfg, NULL);
11479 while (cat) {
11480 if (strcasecmp(cat, "general")) {
11481 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
11482 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
11483 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
11484
11485 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
11486 if (user) {
11487 ao2_link(users, user);
11488 user = user_unref(user);
11489 }
11490 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
11491 if (peer) {
11492 if (ast_test_flag(peer, IAX_DYNAMIC))
11493 reg_source_db(peer);
11494 ao2_link(peers, peer);
11495 peer = peer_unref(peer);
11496 }
11497 }
11498 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
11499 char tmp[256];
11500 const char *host = ast_variable_retrieve(ucfg, cat, "host");
11501 const char *username = ast_variable_retrieve(ucfg, cat, "username");
11502 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
11503 if (!host)
11504 host = ast_variable_retrieve(ucfg, "general", "host");
11505 if (!username)
11506 username = ast_variable_retrieve(ucfg, "general", "username");
11507 if (!secret)
11508 secret = ast_variable_retrieve(ucfg, "general", "secret");
11509 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
11510 if (!ast_strlen_zero(secret))
11511 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
11512 else
11513 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
11514 iax2_register(tmp, 0);
11515 }
11516 }
11517 }
11518 cat = ast_category_browse(ucfg, cat);
11519 }
11520 ast_config_destroy(ucfg);
11521 }
11522
11523 cat = ast_category_browse(cfg, NULL);
11524 while(cat) {
11525 if (strcasecmp(cat, "general")) {
11526 utype = ast_variable_retrieve(cfg, cat, "type");
11527 if (utype) {
11528 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
11529 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
11530 if (user) {
11531 ao2_link(users, user);
11532 user = user_unref(user);
11533 }
11534 }
11535 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
11536 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
11537 if (peer) {
11538 if (ast_test_flag(peer, IAX_DYNAMIC))
11539 reg_source_db(peer);
11540 ao2_link(peers, peer);
11541 peer = peer_unref(peer);
11542 }
11543 } else if (strcasecmp(utype, "user")) {
11544 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
11545 }
11546 } else
11547 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
11548 }
11549 cat = ast_category_browse(cfg, cat);
11550 }
11551 ast_config_destroy(cfg);
11552 set_timing();
11553 return 1;
11554 }
11555
11556 static void poke_all_peers(void)
11557 {
11558 struct ao2_iterator i;
11559 struct iax2_peer *peer;
11560
11561 i = ao2_iterator_init(peers, 0);
11562 while ((peer = ao2_iterator_next(&i))) {
11563 iax2_poke_peer(peer, 0);
11564 peer_unref(peer);
11565 }
11566 }
11567 static int reload_config(void)
11568 {
11569 char *config = "iax.conf";
11570 struct iax2_registry *reg;
11571
11572 if (set_config(config, 1) > 0) {
11573 prune_peers();
11574 prune_users();
11575 trunk_timed = trunk_untimed = 0;
11576 trunk_nmaxmtu = trunk_maxmtu = 0;
11577
11578 AST_LIST_LOCK(®istrations);
11579 AST_LIST_TRAVERSE(®istrations, reg, entry)
11580 iax2_do_register(reg);
11581 AST_LIST_UNLOCK(®istrations);
11582
11583
11584 poke_all_peers();
11585 }
11586
11587 reload_firmware(0);
11588 iax_provision_reload(1);
11589
11590 return 0;
11591 }
11592
11593 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11594 {
11595 switch (cmd) {
11596 case CLI_INIT:
11597 e->command = "iax2 reload";
11598 e->usage =
11599 "Usage: iax2 reload\n"
11600 " Reloads IAX configuration from iax.conf\n";
11601 return NULL;
11602 case CLI_GENERATE:
11603 return NULL;
11604 }
11605
11606 reload_config();
11607
11608 return CLI_SUCCESS;
11609 }
11610
11611 static int reload(void)
11612 {
11613 return reload_config();
11614 }
11615
11616 static int cache_get_callno_locked(const char *data)
11617 {
11618 struct sockaddr_in sin;
11619 int x;
11620 int callno;
11621 struct iax_ie_data ied;
11622 struct create_addr_info cai;
11623 struct parsed_dial_string pds;
11624 char *tmpstr;
11625
11626 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11627
11628
11629 if (!ast_mutex_trylock(&iaxsl[x])) {
11630 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
11631 return x;
11632 ast_mutex_unlock(&iaxsl[x]);
11633 }
11634 }
11635
11636
11637
11638 memset(&cai, 0, sizeof(cai));
11639 memset(&ied, 0, sizeof(ied));
11640 memset(&pds, 0, sizeof(pds));
11641
11642 tmpstr = ast_strdupa(data);
11643 parse_dial_string(tmpstr, &pds);
11644
11645 if (ast_strlen_zero(pds.peer)) {
11646 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
11647 return -1;
11648 }
11649
11650
11651 if (create_addr(pds.peer, NULL, &sin, &cai))
11652 return -1;
11653
11654 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
11655 pds.peer, pds.username, pds.password, pds.context);
11656
11657 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11658 if (callno < 1) {
11659 ast_log(LOG_WARNING, "Unable to create call\n");
11660 return -1;
11661 }
11662
11663 ast_string_field_set(iaxs[callno], dproot, data);
11664 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
11665
11666 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
11667 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
11668
11669
11670
11671 if (pds.exten)
11672 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
11673 if (pds.username)
11674 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
11675 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
11676 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
11677
11678 if (pds.password)
11679 ast_string_field_set(iaxs[callno], secret, pds.password);
11680 if (pds.key)
11681 ast_string_field_set(iaxs[callno], outkey, pds.key);
11682
11683 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
11684
11685 return callno;
11686 }
11687
11688 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
11689 {
11690 struct iax2_dpcache *dp = NULL;
11691 struct timeval tv = ast_tvnow();
11692 int x, com[2], timeout, old = 0, outfd, abort, callno;
11693 struct ast_channel *c = NULL;
11694 struct ast_frame *f = NULL;
11695
11696 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
11697 if (ast_tvcmp(tv, dp->expiry) > 0) {
11698 AST_LIST_REMOVE_CURRENT(cache_list);
11699 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
11700 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
11701 else
11702 ast_free(dp);
11703 continue;
11704 }
11705 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
11706 break;
11707 }
11708 AST_LIST_TRAVERSE_SAFE_END;
11709
11710 if (!dp) {
11711
11712
11713 if ((callno = cache_get_callno_locked(data)) < 0) {
11714 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
11715 return NULL;
11716 }
11717 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
11718 ast_mutex_unlock(&iaxsl[callno]);
11719 return NULL;
11720 }
11721 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
11722 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
11723 dp->expiry = ast_tvnow();
11724 dp->orig = dp->expiry;
11725
11726 dp->expiry.tv_sec += iaxdefaultdpcache;
11727 dp->flags = CACHE_FLAG_PENDING;
11728 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
11729 dp->waiters[x] = -1;
11730
11731 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
11732 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
11733
11734 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
11735 iax2_dprequest(dp, callno);
11736 ast_mutex_unlock(&iaxsl[callno]);
11737 }
11738
11739
11740 if (dp->flags & CACHE_FLAG_PENDING) {
11741
11742
11743 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11744
11745 if (dp->waiters[x] < 0)
11746 break;
11747 }
11748 if (x >= ARRAY_LEN(dp->waiters)) {
11749 ast_log(LOG_WARNING, "No more waiter positions available\n");
11750 return NULL;
11751 }
11752 if (pipe(com)) {
11753 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
11754 return NULL;
11755 }
11756 dp->waiters[x] = com[1];
11757
11758 timeout = iaxdefaulttimeout * 1000;
11759
11760 AST_LIST_UNLOCK(&dpcache);
11761
11762 if (chan)
11763 old = ast_channel_defer_dtmf(chan);
11764 abort = 0;
11765 while(timeout) {
11766 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
11767 if (outfd > -1)
11768 break;
11769 if (!c)
11770 continue;
11771 if (!(f = ast_read(c))) {
11772 abort = 1;
11773 break;
11774 }
11775 ast_frfree(f);
11776 }
11777 if (!timeout) {
11778 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
11779 }
11780 AST_LIST_LOCK(&dpcache);
11781 dp->waiters[x] = -1;
11782 close(com[1]);
11783 close(com[0]);
11784 if (abort) {
11785
11786
11787 if (!old && chan)
11788 ast_channel_undefer_dtmf(chan);
11789 return NULL;
11790 }
11791 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
11792
11793 if (dp->flags & CACHE_FLAG_PENDING) {
11794
11795
11796 dp->flags &= ~CACHE_FLAG_PENDING;
11797 dp->flags |= CACHE_FLAG_TIMEOUT;
11798
11799
11800 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
11801 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11802 if (dp->waiters[x] > -1) {
11803 if (write(dp->waiters[x], "asdf", 4) < 0) {
11804 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
11805 }
11806 }
11807 }
11808 }
11809 }
11810
11811 if (!old && chan)
11812 ast_channel_undefer_dtmf(chan);
11813 }
11814 return dp;
11815 }
11816
11817
11818 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11819 {
11820 int res = 0;
11821 struct iax2_dpcache *dp = NULL;
11822 #if 0
11823 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11824 #endif
11825 if ((priority != 1) && (priority != 2))
11826 return 0;
11827
11828 AST_LIST_LOCK(&dpcache);
11829 if ((dp = find_cache(chan, data, context, exten, priority))) {
11830 if (dp->flags & CACHE_FLAG_EXISTS)
11831 res = 1;
11832 } else {
11833 ast_log(LOG_WARNING, "Unable to make DP cache\n");
11834 }
11835 AST_LIST_UNLOCK(&dpcache);
11836
11837 return res;
11838 }
11839
11840
11841 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11842 {
11843 int res = 0;
11844 struct iax2_dpcache *dp = NULL;
11845 #if 0
11846 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11847 #endif
11848 if ((priority != 1) && (priority != 2))
11849 return 0;
11850
11851 AST_LIST_LOCK(&dpcache);
11852 if ((dp = find_cache(chan, data, context, exten, priority))) {
11853 if (dp->flags & CACHE_FLAG_CANEXIST)
11854 res = 1;
11855 } else {
11856 ast_log(LOG_WARNING, "Unable to make DP cache\n");
11857 }
11858 AST_LIST_UNLOCK(&dpcache);
11859
11860 return res;
11861 }
11862
11863
11864 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11865 {
11866 int res = 0;
11867 struct iax2_dpcache *dp = NULL;
11868 #if 0
11869 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11870 #endif
11871 if ((priority != 1) && (priority != 2))
11872 return 0;
11873
11874 AST_LIST_LOCK(&dpcache);
11875 if ((dp = find_cache(chan, data, context, exten, priority))) {
11876 if (dp->flags & CACHE_FLAG_MATCHMORE)
11877 res = 1;
11878 } else {
11879 ast_log(LOG_WARNING, "Unable to make DP cache\n");
11880 }
11881 AST_LIST_UNLOCK(&dpcache);
11882
11883 return res;
11884 }
11885
11886
11887 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11888 {
11889 char odata[256];
11890 char req[256];
11891 char *ncontext;
11892 struct iax2_dpcache *dp = NULL;
11893 struct ast_app *dial = NULL;
11894 #if 0
11895 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);
11896 #endif
11897 if (priority == 2) {
11898
11899 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
11900 if (dialstatus) {
11901 dial = pbx_findapp(dialstatus);
11902 if (dial)
11903 pbx_exec(chan, dial, "");
11904 }
11905 return -1;
11906 } else if (priority != 1)
11907 return -1;
11908
11909 AST_LIST_LOCK(&dpcache);
11910 if ((dp = find_cache(chan, data, context, exten, priority))) {
11911 if (dp->flags & CACHE_FLAG_EXISTS) {
11912 ast_copy_string(odata, data, sizeof(odata));
11913 ncontext = strchr(odata, '/');
11914 if (ncontext) {
11915 *ncontext = '\0';
11916 ncontext++;
11917 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
11918 } else {
11919 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
11920 }
11921 ast_verb(3, "Executing Dial('%s')\n", req);
11922 } else {
11923 AST_LIST_UNLOCK(&dpcache);
11924 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
11925 return -1;
11926 }
11927 }
11928 AST_LIST_UNLOCK(&dpcache);
11929
11930 if ((dial = pbx_findapp("Dial")))
11931 return pbx_exec(chan, dial, req);
11932 else
11933 ast_log(LOG_WARNING, "No dial application registered\n");
11934
11935 return -1;
11936 }
11937
11938 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
11939 {
11940 struct iax2_peer *peer;
11941 char *peername, *colname;
11942
11943 peername = ast_strdupa(data);
11944
11945
11946 if (!strcmp(peername,"CURRENTCHANNEL")) {
11947 unsigned short callno;
11948 if (chan->tech != &iax2_tech)
11949 return -1;
11950 callno = PTR_TO_CALLNO(chan->tech_pvt);
11951 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
11952 return 0;
11953 }
11954
11955 if ((colname = strchr(peername, ',')))
11956 *colname++ = '\0';
11957 else
11958 colname = "ip";
11959
11960 if (!(peer = find_peer(peername, 1)))
11961 return -1;
11962
11963 if (!strcasecmp(colname, "ip")) {
11964 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11965 } else if (!strcasecmp(colname, "status")) {
11966 peer_status(peer, buf, len);
11967 } else if (!strcasecmp(colname, "mailbox")) {
11968 ast_copy_string(buf, peer->mailbox, len);
11969 } else if (!strcasecmp(colname, "context")) {
11970 ast_copy_string(buf, peer->context, len);
11971 } else if (!strcasecmp(colname, "expire")) {
11972 snprintf(buf, len, "%d", peer->expire);
11973 } else if (!strcasecmp(colname, "dynamic")) {
11974 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
11975 } else if (!strcasecmp(colname, "callerid_name")) {
11976 ast_copy_string(buf, peer->cid_name, len);
11977 } else if (!strcasecmp(colname, "callerid_num")) {
11978 ast_copy_string(buf, peer->cid_num, len);
11979 } else if (!strcasecmp(colname, "codecs")) {
11980 ast_getformatname_multiple(buf, len -1, peer->capability);
11981 } else if (!strncasecmp(colname, "codec[", 6)) {
11982 char *codecnum, *ptr;
11983 int index = 0, codec = 0;
11984
11985 codecnum = strchr(colname, '[');
11986 *codecnum = '\0';
11987 codecnum++;
11988 if ((ptr = strchr(codecnum, ']'))) {
11989 *ptr = '\0';
11990 }
11991 index = atoi(codecnum);
11992 if((codec = ast_codec_pref_index(&peer->prefs, index))) {
11993 ast_copy_string(buf, ast_getformatname(codec), len);
11994 }
11995 }
11996
11997 peer_unref(peer);
11998
11999 return 0;
12000 }
12001
12002 struct ast_custom_function iaxpeer_function = {
12003 .name = "IAXPEER",
12004 .synopsis = "Gets IAX peer information",
12005 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[,item])",
12006 .read = function_iaxpeer,
12007 .desc = "If peername specified, valid items are:\n"
12008 "- ip (default) The IP address.\n"
12009 "- status The peer's status (if qualify=yes)\n"
12010 "- mailbox The configured mailbox.\n"
12011 "- context The configured context.\n"
12012 "- expire The epoch time of the next expire.\n"
12013 "- dynamic Is it dynamic? (yes/no).\n"
12014 "- callerid_name The configured Caller ID name.\n"
12015 "- callerid_num The configured Caller ID number.\n"
12016 "- codecs The configured codecs.\n"
12017 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
12018 "\n"
12019 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
12020 "\n"
12021 };
12022
12023 static int acf_channel_write(struct ast_channel *chan, const char *function, char *args, const char *value)
12024 {
12025 struct chan_iax2_pvt *pvt;
12026 unsigned int callno;
12027 int res = 0;
12028
12029 if (!chan || chan->tech != &iax2_tech) {
12030 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
12031 return -1;
12032 }
12033
12034 callno = PTR_TO_CALLNO(chan->tech_pvt);
12035 ast_mutex_lock(&iaxsl[callno]);
12036 if (!(pvt = iaxs[callno])) {
12037 ast_mutex_unlock(&iaxsl[callno]);
12038 return -1;
12039 }
12040
12041 if (!strcasecmp(args, "osptoken"))
12042 ast_string_field_set(pvt, osptoken, value);
12043 else
12044 res = -1;
12045
12046 ast_mutex_unlock(&iaxsl[callno]);
12047
12048 return res;
12049 }
12050
12051 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
12052 {
12053 struct chan_iax2_pvt *pvt;
12054 unsigned int callno;
12055 int res = 0;
12056
12057 if (!chan || chan->tech != &iax2_tech) {
12058 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
12059 return -1;
12060 }
12061
12062 callno = PTR_TO_CALLNO(chan->tech_pvt);
12063 ast_mutex_lock(&iaxsl[callno]);
12064 if (!(pvt = iaxs[callno])) {
12065 ast_mutex_unlock(&iaxsl[callno]);
12066 return -1;
12067 }
12068
12069 if (!strcasecmp(args, "osptoken"))
12070 ast_copy_string(buf, pvt->osptoken, buflen);
12071 else
12072 res = -1;
12073
12074 ast_mutex_unlock(&iaxsl[callno]);
12075
12076 return res;
12077 }
12078
12079
12080 static int iax2_devicestate(void *data)
12081 {
12082 struct parsed_dial_string pds;
12083 char *tmp = ast_strdupa(data);
12084 struct iax2_peer *p;
12085 int res = AST_DEVICE_INVALID;
12086
12087 memset(&pds, 0, sizeof(pds));
12088 parse_dial_string(tmp, &pds);
12089
12090 if (ast_strlen_zero(pds.peer)) {
12091 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12092 return res;
12093 }
12094
12095 ast_debug(3, "Checking device state for device %s\n", pds.peer);
12096
12097
12098 if (!(p = find_peer(pds.peer, 1)))
12099 return res;
12100
12101 res = AST_DEVICE_UNAVAILABLE;
12102 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
12103 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
12104
12105 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
12106 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
12107
12108
12109 if (p->historicms == 0 || p->historicms <= p->maxms)
12110
12111 res = AST_DEVICE_UNKNOWN;
12112 }
12113
12114 peer_unref(p);
12115
12116 return res;
12117 }
12118
12119 static struct ast_switch iax2_switch =
12120 {
12121 name: "IAX2",
12122 description: "IAX Remote Dialplan Switch",
12123 exists: iax2_exists,
12124 canmatch: iax2_canmatch,
12125 exec: iax2_exec,
12126 matchmore: iax2_matchmore,
12127 };
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233 static struct ast_cli_entry cli_iax2_set_debug_deprecated = AST_CLI_DEFINE(handle_cli_iax2_set_debug_deprecated, "Enable/Disable IAX debugging");
12234 static struct ast_cli_entry cli_iax2_set_debug_trunk_deprecated = AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk_deprecated, "Enable/Disable IAX debugging");
12235 static struct ast_cli_entry cli_iax2_set_debug_jb_deprecated = AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb_deprecated, "Enable/Disable IAX debugging");
12236
12237 static struct ast_cli_entry cli_iax2[] = {
12238 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
12239 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
12240 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
12241 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
12242 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging", .deprecate_cmd = &cli_iax2_set_debug_deprecated),
12243 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging", .deprecate_cmd = &cli_iax2_set_debug_trunk_deprecated),
12244 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging", .deprecate_cmd = &cli_iax2_set_debug_jb_deprecated),
12245 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
12246 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
12247 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
12248 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
12249 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
12250 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
12251 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
12252 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
12253 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
12254 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
12255 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
12256 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
12257 #ifdef IAXTESTS
12258 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
12259 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
12260 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
12261 #endif
12262 };
12263
12264 static int __unload_module(void)
12265 {
12266 struct iax2_thread *thread = NULL;
12267 struct ast_context *con;
12268 int x;
12269
12270
12271
12272
12273
12274 if (netthreadid != AST_PTHREADT_NULL) {
12275 AST_LIST_LOCK(&frame_queue);
12276 ast_mutex_lock(&sched_lock);
12277 pthread_cancel(netthreadid);
12278 ast_cond_signal(&sched_cond);
12279 ast_mutex_unlock(&sched_lock);
12280 AST_LIST_UNLOCK(&frame_queue);
12281 pthread_join(netthreadid, NULL);
12282 }
12283 if (schedthreadid != AST_PTHREADT_NULL) {
12284 ast_mutex_lock(&sched_lock);
12285 pthread_cancel(schedthreadid);
12286 ast_cond_signal(&sched_cond);
12287 ast_mutex_unlock(&sched_lock);
12288 pthread_join(schedthreadid, NULL);
12289 }
12290
12291
12292 AST_LIST_LOCK(&idle_list);
12293 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list)))
12294 pthread_cancel(thread->threadid);
12295 AST_LIST_UNLOCK(&idle_list);
12296
12297 AST_LIST_LOCK(&active_list);
12298 while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list)))
12299 pthread_cancel(thread->threadid);
12300 AST_LIST_UNLOCK(&active_list);
12301
12302 AST_LIST_LOCK(&dynamic_list);
12303 while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list)))
12304 pthread_cancel(thread->threadid);
12305 AST_LIST_UNLOCK(&dynamic_list);
12306
12307
12308 while(0 < iaxactivethreadcount)
12309 usleep(10000);
12310
12311 ast_netsock_release(netsock);
12312 ast_netsock_release(outsock);
12313 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12314 if (iaxs[x]) {
12315 iax2_destroy(x);
12316 }
12317 }
12318 ast_manager_unregister( "IAXpeers" );
12319 ast_manager_unregister( "IAXpeerlist" );
12320 ast_manager_unregister( "IAXnetstats" );
12321 ast_unregister_application(papp);
12322 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12323 ast_unregister_switch(&iax2_switch);
12324 ast_channel_unregister(&iax2_tech);
12325 delete_users();
12326 iax_provision_unload();
12327 sched_context_destroy(sched);
12328 reload_firmware(1);
12329
12330 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12331 ast_mutex_destroy(&iaxsl[x]);
12332 }
12333
12334 ao2_ref(peers, -1);
12335 ao2_ref(users, -1);
12336 ao2_ref(iax_peercallno_pvts, -1);
12337 ao2_ref(iax_transfercallno_pvts, -1);
12338 con = ast_context_find(regcontext);
12339 if (con)
12340 ast_context_destroy(con, "IAX2");
12341
12342 return 0;
12343 }
12344
12345 static int unload_module(void)
12346 {
12347 ast_custom_function_unregister(&iaxpeer_function);
12348 ast_custom_function_unregister(&iaxvar_function);
12349 return __unload_module();
12350 }
12351
12352 static int peer_set_sock_cb(void *obj, void *arg, int flags)
12353 {
12354 struct iax2_peer *peer = obj;
12355
12356 if (peer->sockfd < 0)
12357 peer->sockfd = defaultsockfd;
12358
12359 return 0;
12360 }
12361
12362 static int pvt_hash_cb(const void *obj, const int flags)
12363 {
12364 const struct chan_iax2_pvt *pvt = obj;
12365
12366 return pvt->peercallno;
12367 }
12368
12369 static int pvt_cmp_cb(void *obj, void *arg, int flags)
12370 {
12371 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12372
12373
12374
12375
12376 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
12377 pvt2->frames_received) ? CMP_MATCH : 0;
12378 }
12379
12380 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
12381 {
12382 const struct chan_iax2_pvt *pvt = obj;
12383
12384 return pvt->transfercallno;
12385 }
12386
12387 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
12388 {
12389 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12390
12391
12392
12393
12394 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
12395 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12396 }
12397
12398 static int load_module(void)
12399 {
12400 char *config = "iax.conf";
12401 int x = 0;
12402 struct iax2_registry *reg = NULL;
12403
12404 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
12405 if (!peers)
12406 return AST_MODULE_LOAD_FAILURE;
12407 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
12408 if (!users) {
12409 ao2_ref(peers, -1);
12410 return AST_MODULE_LOAD_FAILURE;
12411 }
12412 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
12413 if (!iax_peercallno_pvts) {
12414 ao2_ref(peers, -1);
12415 ao2_ref(users, -1);
12416 return AST_MODULE_LOAD_FAILURE;
12417 }
12418 iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb);
12419 if (!iax_transfercallno_pvts) {
12420 ao2_ref(peers, -1);
12421 ao2_ref(users, -1);
12422 ao2_ref(iax_peercallno_pvts, -1);
12423 return AST_MODULE_LOAD_FAILURE;
12424 }
12425 ast_custom_function_register(&iaxpeer_function);
12426 ast_custom_function_register(&iaxvar_function);
12427
12428 iax_set_output(iax_debug_output);
12429 iax_set_error(iax_error_output);
12430 jb_setoutput(jb_error_output, jb_warning_output, NULL);
12431
12432 #ifdef HAVE_DAHDI
12433 #ifdef DAHDI_TIMERACK
12434 timingfd = open("/dev/dahdi/timer", O_RDWR);
12435 if (timingfd < 0)
12436 #endif
12437 timingfd = open("/dev/dahdi/pseudo", O_RDWR);
12438 if (timingfd < 0)
12439 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
12440 #endif
12441
12442 memset(iaxs, 0, sizeof(iaxs));
12443
12444 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12445 ast_mutex_init(&iaxsl[x]);
12446 }
12447
12448 ast_cond_init(&sched_cond, NULL);
12449
12450 if (!(sched = sched_context_create())) {
12451 ast_log(LOG_ERROR, "Failed to create scheduler context\n");
12452 return AST_MODULE_LOAD_FAILURE;
12453 }
12454
12455 if (!(io = io_context_create())) {
12456 ast_log(LOG_ERROR, "Failed to create I/O context\n");
12457 sched_context_destroy(sched);
12458 return AST_MODULE_LOAD_FAILURE;
12459 }
12460
12461 if (!(netsock = ast_netsock_list_alloc())) {
12462 ast_log(LOG_ERROR, "Failed to create netsock list\n");
12463 io_context_destroy(io);
12464 sched_context_destroy(sched);
12465 return AST_MODULE_LOAD_FAILURE;
12466 }
12467 ast_netsock_init(netsock);
12468
12469 outsock = ast_netsock_list_alloc();
12470 if (!outsock) {
12471 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12472 io_context_destroy(io);
12473 sched_context_destroy(sched);
12474 return AST_MODULE_LOAD_FAILURE;
12475 }
12476 ast_netsock_init(outsock);
12477
12478 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12479
12480 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
12481
12482 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
12483 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
12484 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
12485
12486 if(set_config(config, 0) == -1)
12487 return AST_MODULE_LOAD_DECLINE;
12488
12489 if (ast_channel_register(&iax2_tech)) {
12490 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
12491 __unload_module();
12492 return AST_MODULE_LOAD_FAILURE;
12493 }
12494
12495 if (ast_register_switch(&iax2_switch))
12496 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
12497
12498 if (start_network_thread()) {
12499 ast_log(LOG_ERROR, "Unable to start network thread\n");
12500 __unload_module();
12501 return AST_MODULE_LOAD_FAILURE;
12502 } else
12503 ast_verb(2, "IAX Ready and Listening\n");
12504
12505 AST_LIST_LOCK(®istrations);
12506 AST_LIST_TRAVERSE(®istrations, reg, entry)
12507 iax2_do_register(reg);
12508 AST_LIST_UNLOCK(®istrations);
12509
12510 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
12511 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
12512
12513
12514 reload_firmware(0);
12515 iax_provision_reload(0);
12516
12517 return AST_MODULE_LOAD_SUCCESS;
12518 }
12519
12520 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
12521 .load = load_module,
12522 .unload = unload_module,
12523 .reload = reload,
12524 );