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: 170642 $")
00039
00040 #include <stdlib.h>
00041 #include <stdio.h>
00042 #include <sys/types.h>
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <string.h>
00054 #include <strings.h>
00055 #include <errno.h>
00056 #include <unistd.h>
00057 #include <netdb.h>
00058 #include <fcntl.h>
00059 #include <sys/stat.h>
00060 #include <regex.h>
00061
00062 #if defined(HAVE_ZAPTEL) || defined (HAVE_DAHDI)
00063 #include <sys/ioctl.h>
00064 #include "asterisk/dahdi_compat.h"
00065 #endif
00066
00067 #include "asterisk/lock.h"
00068 #include "asterisk/frame.h"
00069 #include "asterisk/channel.h"
00070 #include "asterisk/logger.h"
00071 #include "asterisk/module.h"
00072 #include "asterisk/pbx.h"
00073 #include "asterisk/sched.h"
00074 #include "asterisk/io.h"
00075 #include "asterisk/config.h"
00076 #include "asterisk/options.h"
00077 #include "asterisk/cli.h"
00078 #include "asterisk/translate.h"
00079 #include "asterisk/md5.h"
00080 #include "asterisk/cdr.h"
00081 #include "asterisk/crypto.h"
00082 #include "asterisk/acl.h"
00083 #include "asterisk/manager.h"
00084 #include "asterisk/callerid.h"
00085 #include "asterisk/app.h"
00086 #include "asterisk/astdb.h"
00087 #include "asterisk/musiconhold.h"
00088 #include "asterisk/features.h"
00089 #include "asterisk/utils.h"
00090 #include "asterisk/causes.h"
00091 #include "asterisk/localtime.h"
00092 #include "asterisk/aes.h"
00093 #include "asterisk/dnsmgr.h"
00094 #include "asterisk/devicestate.h"
00095 #include "asterisk/netsock.h"
00096 #include "asterisk/stringfields.h"
00097 #include "asterisk/linkedlists.h"
00098 #include "asterisk/astobj2.h"
00099
00100 #include "iax2.h"
00101 #include "iax2-parser.h"
00102 #include "iax2-provision.h"
00103 #include "jitterbuf.h"
00104
00105
00106
00107 #define SCHED_MULTITHREADED
00108
00109
00110
00111 #define DEBUG_SCHED_MULTITHREAD
00112
00113 #ifndef IPTOS_MINCOST
00114 #define IPTOS_MINCOST 0x02
00115 #endif
00116
00117 #ifdef SO_NO_CHECK
00118 static int nochecksums = 0;
00119 #endif
00120
00121
00122 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00123 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00124
00125 #define DEFAULT_THREAD_COUNT 10
00126 #define DEFAULT_MAX_THREAD_COUNT 100
00127 #define DEFAULT_RETRY_TIME 1000
00128 #define MEMORY_SIZE 100
00129 #define DEFAULT_DROP 3
00130
00131 #define DEBUG_SUPPORT
00132
00133 #define MIN_REUSE_TIME 60
00134
00135
00136 #define GAMMA (0.01)
00137
00138 static struct ast_codec_pref prefs;
00139
00140 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
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 trunkfreq = 20;
00155 static int authdebug = 1;
00156 static int autokill = 0;
00157 static int iaxcompat = 0;
00158 static int last_authmethod = 0;
00159
00160 static int iaxdefaultdpcache=10 * 60;
00161
00162 static int iaxdefaulttimeout = 5;
00163
00164 static unsigned int tos = 0;
00165
00166 static int min_reg_expire;
00167 static int max_reg_expire;
00168
00169 static int timingfd = -1;
00170
00171 static struct ast_netsock_list *netsock;
00172 static struct ast_netsock_list *outsock;
00173 static int defaultsockfd = -1;
00174
00175 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00176
00177
00178 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00179
00180 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00181 ~AST_FORMAT_SLINEAR & \
00182 ~AST_FORMAT_ULAW & \
00183 ~AST_FORMAT_ALAW & \
00184 ~AST_FORMAT_G722)
00185
00186 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00187 ~AST_FORMAT_G726 & \
00188 ~AST_FORMAT_G726_AAL2 & \
00189 ~AST_FORMAT_ADPCM)
00190
00191 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00192 ~AST_FORMAT_G723_1)
00193
00194
00195 #define DEFAULT_MAXMS 2000
00196 #define DEFAULT_FREQ_OK 60 * 1000
00197 #define DEFAULT_FREQ_NOTOK 10 * 1000
00198
00199 static struct io_context *io;
00200 static struct sched_context *sched;
00201
00202 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00203
00204 static int iaxdebug = 0;
00205
00206 static int iaxtrunkdebug = 0;
00207
00208 static int test_losspct = 0;
00209 #ifdef IAXTESTS
00210 static int test_late = 0;
00211 static int test_resync = 0;
00212 static int test_jit = 0;
00213 static int test_jitpct = 0;
00214 #endif
00215
00216 static char accountcode[AST_MAX_ACCOUNT_CODE];
00217 static char mohinterpret[MAX_MUSICCLASS];
00218 static char mohsuggest[MAX_MUSICCLASS];
00219 static int amaflags = 0;
00220 static int adsi = 0;
00221 static int delayreject = 0;
00222 static int iax2_encryption = 0;
00223
00224 static struct ast_flags globalflags = { 0 };
00225
00226 static pthread_t netthreadid = AST_PTHREADT_NULL;
00227 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00228 AST_MUTEX_DEFINE_STATIC(sched_lock);
00229 static ast_cond_t sched_cond;
00230
00231 enum {
00232 IAX_STATE_STARTED = (1 << 0),
00233 IAX_STATE_AUTHENTICATED = (1 << 1),
00234 IAX_STATE_TBD = (1 << 2),
00235 IAX_STATE_UNCHANGED = (1 << 3),
00236 } iax2_state;
00237
00238 struct iax2_context {
00239 char context[AST_MAX_CONTEXT];
00240 struct iax2_context *next;
00241 };
00242
00243 enum {
00244 IAX_HASCALLERID = (1 << 0),
00245 IAX_DELME = (1 << 1),
00246 IAX_TEMPONLY = (1 << 2),
00247 IAX_TRUNK = (1 << 3),
00248 IAX_NOTRANSFER = (1 << 4),
00249 IAX_USEJITTERBUF = (1 << 5),
00250 IAX_DYNAMIC = (1 << 6),
00251 IAX_SENDANI = (1 << 7),
00252
00253 IAX_ALREADYGONE = (1 << 9),
00254 IAX_PROVISION = (1 << 10),
00255 IAX_QUELCH = (1 << 11),
00256 IAX_ENCRYPTED = (1 << 12),
00257 IAX_KEYPOPULATED = (1 << 13),
00258 IAX_CODEC_USER_FIRST = (1 << 14),
00259 IAX_CODEC_NOPREFS = (1 << 15),
00260 IAX_CODEC_NOCAP = (1 << 16),
00261 IAX_RTCACHEFRIENDS = (1 << 17),
00262 IAX_RTUPDATE = (1 << 18),
00263 IAX_RTAUTOCLEAR = (1 << 19),
00264 IAX_FORCEJITTERBUF = (1 << 20),
00265 IAX_RTIGNOREREGEXPIRE = (1 << 21),
00266 IAX_TRUNKTIMESTAMPS = (1 << 22),
00267 IAX_TRANSFERMEDIA = (1 << 23),
00268 IAX_MAXAUTHREQ = (1 << 24),
00269 IAX_DELAYPBXSTART = (1 << 25),
00270
00271
00272 IAX_ALLOWFWDOWNLOAD = (1 << 26),
00273 } iax2_flags;
00274
00275 static int global_rtautoclear = 120;
00276
00277 static int reload_config(void);
00278 static int iax2_reload(int fd, int argc, char *argv[]);
00279
00280
00281 struct iax2_user {
00282 AST_DECLARE_STRING_FIELDS(
00283 AST_STRING_FIELD(name);
00284 AST_STRING_FIELD(secret);
00285 AST_STRING_FIELD(dbsecret);
00286 AST_STRING_FIELD(accountcode);
00287 AST_STRING_FIELD(mohinterpret);
00288 AST_STRING_FIELD(mohsuggest);
00289 AST_STRING_FIELD(inkeys);
00290 AST_STRING_FIELD(language);
00291 AST_STRING_FIELD(cid_num);
00292 AST_STRING_FIELD(cid_name);
00293 );
00294
00295 int authmethods;
00296 int encmethods;
00297 int amaflags;
00298 int adsi;
00299 unsigned int flags;
00300 int capability;
00301 int maxauthreq;
00302 int curauthreq;
00303 struct ast_codec_pref prefs;
00304 struct ast_ha *ha;
00305 struct iax2_context *contexts;
00306 struct ast_variable *vars;
00307 };
00308
00309 struct iax2_peer {
00310 AST_DECLARE_STRING_FIELDS(
00311 AST_STRING_FIELD(name);
00312 AST_STRING_FIELD(username);
00313 AST_STRING_FIELD(secret);
00314 AST_STRING_FIELD(dbsecret);
00315 AST_STRING_FIELD(outkey);
00316
00317 AST_STRING_FIELD(regexten);
00318 AST_STRING_FIELD(context);
00319 AST_STRING_FIELD(peercontext);
00320 AST_STRING_FIELD(mailbox);
00321 AST_STRING_FIELD(mohinterpret);
00322 AST_STRING_FIELD(mohsuggest);
00323 AST_STRING_FIELD(inkeys);
00324
00325 AST_STRING_FIELD(cid_num);
00326 AST_STRING_FIELD(cid_name);
00327 AST_STRING_FIELD(zonetag);
00328 );
00329 struct ast_codec_pref prefs;
00330 struct ast_dnsmgr_entry *dnsmgr;
00331 struct sockaddr_in addr;
00332 int formats;
00333 int sockfd;
00334 struct in_addr mask;
00335 int adsi;
00336 unsigned int flags;
00337
00338
00339 struct sockaddr_in defaddr;
00340 int authmethods;
00341 int encmethods;
00342
00343 int expire;
00344 int expiry;
00345 int capability;
00346
00347
00348 int callno;
00349 int pokeexpire;
00350 int lastms;
00351 int maxms;
00352
00353 int pokefreqok;
00354 int pokefreqnotok;
00355 int historicms;
00356 int smoothing;
00357
00358 struct ast_ha *ha;
00359 };
00360
00361 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00362
00363 static struct iax2_trunk_peer {
00364 ast_mutex_t lock;
00365 int sockfd;
00366 struct sockaddr_in addr;
00367 struct timeval txtrunktime;
00368 struct timeval rxtrunktime;
00369 struct timeval lasttxtime;
00370 struct timeval trunkact;
00371 unsigned int lastsent;
00372
00373 unsigned char *trunkdata;
00374 unsigned int trunkdatalen;
00375 unsigned int trunkdataalloc;
00376 struct iax2_trunk_peer *next;
00377 int trunkerror;
00378 int calls;
00379 } *tpeers = NULL;
00380
00381 AST_MUTEX_DEFINE_STATIC(tpeerlock);
00382
00383 struct iax_firmware {
00384 struct iax_firmware *next;
00385 int fd;
00386 int mmaplen;
00387 int dead;
00388 struct ast_iax2_firmware_header *fwh;
00389 unsigned char *buf;
00390 };
00391
00392 enum iax_reg_state {
00393 REG_STATE_UNREGISTERED = 0,
00394 REG_STATE_REGSENT,
00395 REG_STATE_AUTHSENT,
00396 REG_STATE_REGISTERED,
00397 REG_STATE_REJECTED,
00398 REG_STATE_TIMEOUT,
00399 REG_STATE_NOAUTH
00400 };
00401
00402 enum iax_transfer_state {
00403 TRANSFER_NONE = 0,
00404 TRANSFER_BEGIN,
00405 TRANSFER_READY,
00406 TRANSFER_RELEASED,
00407 TRANSFER_PASSTHROUGH,
00408 TRANSFER_MBEGIN,
00409 TRANSFER_MREADY,
00410 TRANSFER_MRELEASED,
00411 TRANSFER_MPASSTHROUGH,
00412 TRANSFER_MEDIA,
00413 TRANSFER_MEDIAPASS
00414 };
00415
00416 struct iax2_registry {
00417 struct sockaddr_in addr;
00418 char username[80];
00419 char secret[80];
00420 char random[80];
00421 int expire;
00422 int refresh;
00423 enum iax_reg_state regstate;
00424 int messages;
00425 int callno;
00426 struct sockaddr_in us;
00427 struct ast_dnsmgr_entry *dnsmgr;
00428 AST_LIST_ENTRY(iax2_registry) entry;
00429 };
00430
00431 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00432
00433
00434 #define MIN_RETRY_TIME 100
00435 #define MAX_RETRY_TIME 10000
00436
00437 #define MAX_JITTER_BUFFER 50
00438 #define MIN_JITTER_BUFFER 10
00439
00440 #define DEFAULT_TRUNKDATA 640 * 10
00441 #define MAX_TRUNKDATA 640 * 200
00442
00443 #define MAX_TIMESTAMP_SKEW 160
00444
00445
00446 #define TS_GAP_FOR_JB_RESYNC 5000
00447
00448 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00449 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00450 static int iaxdynamicthreadcount = 0;
00451 static int iaxdynamicthreadnum = 0;
00452 static int iaxactivethreadcount = 0;
00453
00454 struct iax_rr {
00455 int jitter;
00456 int losspct;
00457 int losscnt;
00458 int packets;
00459 int delay;
00460 int dropped;
00461 int ooo;
00462 };
00463
00464 struct chan_iax2_pvt {
00465
00466 int sockfd;
00467
00468 int voiceformat;
00469
00470 int videoformat;
00471
00472 int svoiceformat;
00473
00474 int svideoformat;
00475
00476 int capability;
00477
00478 unsigned int last;
00479
00480 unsigned int lastsent;
00481
00482 unsigned int lastvsent;
00483
00484 unsigned int nextpred;
00485
00486 int notsilenttx;
00487
00488 unsigned int pingtime;
00489
00490 int maxtime;
00491
00492 struct sockaddr_in addr;
00493
00494 struct ast_codec_pref prefs;
00495
00496 struct ast_codec_pref rprefs;
00497
00498 unsigned short callno;
00499
00500 unsigned short peercallno;
00501
00502
00503
00504 int chosenformat;
00505
00506 int peerformat;
00507
00508 int peercapability;
00509
00510 struct timeval offset;
00511
00512 struct timeval rxcore;
00513
00514 jitterbuf *jb;
00515
00516 int jbid;
00517
00518 int lag;
00519
00520 int error;
00521
00522 struct ast_channel *owner;
00523
00524 struct ast_flags state;
00525
00526 int expiry;
00527
00528 unsigned char oseqno;
00529
00530 unsigned char rseqno;
00531
00532 unsigned char iseqno;
00533
00534 unsigned char aseqno;
00535
00536 AST_DECLARE_STRING_FIELDS(
00537
00538 AST_STRING_FIELD(peer);
00539
00540 AST_STRING_FIELD(context);
00541
00542 AST_STRING_FIELD(cid_num);
00543 AST_STRING_FIELD(cid_name);
00544
00545 AST_STRING_FIELD(ani);
00546
00547 AST_STRING_FIELD(dnid);
00548
00549 AST_STRING_FIELD(rdnis);
00550
00551 AST_STRING_FIELD(exten);
00552
00553 AST_STRING_FIELD(username);
00554
00555 AST_STRING_FIELD(secret);
00556
00557 AST_STRING_FIELD(challenge);
00558
00559 AST_STRING_FIELD(inkeys);
00560
00561 AST_STRING_FIELD(outkey);
00562
00563 AST_STRING_FIELD(language);
00564
00565 AST_STRING_FIELD(host);
00566
00567 AST_STRING_FIELD(dproot);
00568 AST_STRING_FIELD(accountcode);
00569 AST_STRING_FIELD(mohinterpret);
00570 AST_STRING_FIELD(mohsuggest);
00571 );
00572
00573
00574 int authmethods;
00575
00576 int encmethods;
00577
00578 aes_encrypt_ctx ecx;
00579
00580 aes_decrypt_ctx dcx;
00581
00582 unsigned char semirand[32];
00583
00584 struct iax2_registry *reg;
00585
00586 struct iax2_peer *peerpoke;
00587
00588 unsigned int flags;
00589 int adsi;
00590
00591
00592 enum iax_transfer_state transferring;
00593
00594 int transferid;
00595
00596 struct sockaddr_in transfer;
00597
00598 unsigned short transfercallno;
00599
00600 aes_encrypt_ctx tdcx;
00601
00602
00603 int peeradsicpe;
00604
00605
00606 unsigned short bridgecallno;
00607
00608 int pingid;
00609 int lagid;
00610 int autoid;
00611 int authid;
00612 int authfail;
00613 int initid;
00614 int calling_ton;
00615 int calling_tns;
00616 int calling_pres;
00617 int amaflags;
00618 struct iax2_dpcache *dpentries;
00619 struct ast_variable *vars;
00620
00621 struct iax_rr remote_rr;
00622
00623 int min;
00624
00625 int frames_dropped;
00626
00627 int frames_received;
00628 };
00629
00630 static struct ast_iax2_queue {
00631 AST_LIST_HEAD(, iax_frame) queue;
00632 int count;
00633 } iaxq;
00634
00635
00636
00637
00638
00639
00640
00641
00642 #ifdef LOW_MEMORY
00643 #define MAX_PEER_BUCKETS 1
00644
00645 #else
00646 #define MAX_PEER_BUCKETS 1
00647
00648 #endif
00649 static struct ao2_container *peers;
00650
00651 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00652 static struct ao2_container *users;
00653
00654 static struct ast_firmware_list {
00655 struct iax_firmware *wares;
00656 ast_mutex_t lock;
00657 } waresl;
00658
00659
00660 #define CACHE_FLAG_EXISTS (1 << 0)
00661
00662 #define CACHE_FLAG_NONEXISTENT (1 << 1)
00663
00664 #define CACHE_FLAG_CANEXIST (1 << 2)
00665
00666 #define CACHE_FLAG_PENDING (1 << 3)
00667
00668 #define CACHE_FLAG_TIMEOUT (1 << 4)
00669
00670 #define CACHE_FLAG_TRANSMITTED (1 << 5)
00671
00672 #define CACHE_FLAG_UNKNOWN (1 << 6)
00673
00674 #define CACHE_FLAG_MATCHMORE (1 << 7)
00675
00676 static struct iax2_dpcache {
00677 char peercontext[AST_MAX_CONTEXT];
00678 char exten[AST_MAX_EXTENSION];
00679 struct timeval orig;
00680 struct timeval expiry;
00681 int flags;
00682 unsigned short callno;
00683 int waiters[256];
00684 struct iax2_dpcache *next;
00685 struct iax2_dpcache *peer;
00686 } *dpcache;
00687
00688 AST_MUTEX_DEFINE_STATIC(dpcache_lock);
00689
00690 static void reg_source_db(struct iax2_peer *p);
00691 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00692
00693 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00694
00695 #define IAX_IOSTATE_IDLE 0
00696 #define IAX_IOSTATE_READY 1
00697 #define IAX_IOSTATE_PROCESSING 2
00698 #define IAX_IOSTATE_SCHEDREADY 3
00699
00700 #define IAX_TYPE_POOL 1
00701 #define IAX_TYPE_DYNAMIC 2
00702
00703 struct iax2_pkt_buf {
00704 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00705 size_t len;
00706 unsigned char buf[1];
00707 };
00708
00709 struct iax2_thread {
00710 AST_LIST_ENTRY(iax2_thread) list;
00711 int type;
00712 int iostate;
00713 #ifdef SCHED_MULTITHREADED
00714 void (*schedfunc)(const void *);
00715 const void *scheddata;
00716 #endif
00717 #ifdef DEBUG_SCHED_MULTITHREAD
00718 char curfunc[80];
00719 #endif
00720 int actions;
00721 pthread_t threadid;
00722 int threadnum;
00723 struct sockaddr_in iosin;
00724 unsigned char readbuf[4096];
00725 unsigned char *buf;
00726 ssize_t buf_len;
00727 size_t buf_size;
00728 int iofd;
00729 time_t checktime;
00730 ast_mutex_t lock;
00731 ast_cond_t cond;
00732 unsigned int ready_for_signal:1;
00733
00734
00735
00736
00737 struct {
00738 unsigned short callno;
00739 struct sockaddr_in sin;
00740 unsigned char type;
00741 unsigned char csub;
00742 } ffinfo;
00743
00744
00745
00746 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00747 };
00748
00749
00750 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00751 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00752 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00753
00754 static void *iax2_process_thread(void *data);
00755
00756 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00757 {
00758 ast_mutex_lock(lock);
00759 ast_cond_signal(cond);
00760 ast_mutex_unlock(lock);
00761 }
00762
00763 static void iax_debug_output(const char *data)
00764 {
00765 if (iaxdebug)
00766 ast_verbose("%s", data);
00767 }
00768
00769 static void iax_error_output(const char *data)
00770 {
00771 ast_log(LOG_WARNING, "%s", data);
00772 }
00773
00774 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00775 {
00776 va_list args;
00777 char buf[1024];
00778
00779 va_start(args, fmt);
00780 vsnprintf(buf, 1024, fmt, args);
00781 va_end(args);
00782
00783 ast_log(LOG_ERROR, "%s", buf);
00784 }
00785
00786 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
00787 {
00788 va_list args;
00789 char buf[1024];
00790
00791 va_start(args, fmt);
00792 vsnprintf(buf, 1024, fmt, args);
00793 va_end(args);
00794
00795 ast_log(LOG_WARNING, "%s", buf);
00796 }
00797
00798 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
00799 {
00800 va_list args;
00801 char buf[1024];
00802
00803 va_start(args, fmt);
00804 vsnprintf(buf, 1024, fmt, args);
00805 va_end(args);
00806
00807 ast_verbose("%s", buf);
00808 }
00809
00810
00811 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00812 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00813 static struct timeval lastused[ARRAY_LEN(iaxs)];
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824 static struct ao2_container *iax_peercallno_pvts;
00825
00826
00827
00828 #define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2
00829
00830 static int maxtrunkcall = TRUNK_CALL_START;
00831 static int maxnontrunkcall = 1;
00832
00833 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);
00834 static int expire_registry(const void *data);
00835 static int iax2_answer(struct ast_channel *c);
00836 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00837 static int iax2_devicestate(void *data);
00838 static int iax2_digit_begin(struct ast_channel *c, char digit);
00839 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00840 static int iax2_do_register(struct iax2_registry *reg);
00841 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00842 static int iax2_hangup(struct ast_channel *c);
00843 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00844 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00845 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00846 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00847 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00848 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00849 static int iax2_sendtext(struct ast_channel *c, const char *text);
00850 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00851 static int iax2_transfer(struct ast_channel *c, const char *dest);
00852 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00853 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00854 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00855 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00856 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00857 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00858 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00859 static struct ast_frame *iax2_read(struct ast_channel *c);
00860 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00861 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00862 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00863 static void prune_peers(void);
00864
00865 static const struct ast_channel_tech iax2_tech = {
00866 .type = "IAX2",
00867 .description = tdesc,
00868 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00869 .properties = AST_CHAN_TP_WANTSJITTER,
00870 .requester = iax2_request,
00871 .devicestate = iax2_devicestate,
00872 .send_digit_begin = iax2_digit_begin,
00873 .send_digit_end = iax2_digit_end,
00874 .send_text = iax2_sendtext,
00875 .send_image = iax2_sendimage,
00876 .send_html = iax2_sendhtml,
00877 .call = iax2_call,
00878 .hangup = iax2_hangup,
00879 .answer = iax2_answer,
00880 .read = iax2_read,
00881 .write = iax2_write,
00882 .write_video = iax2_write,
00883 .indicate = iax2_indicate,
00884 .setoption = iax2_setoption,
00885 .bridge = iax2_bridge,
00886 .transfer = iax2_transfer,
00887 .fixup = iax2_fixup,
00888 };
00889
00890
00891
00892
00893 static void insert_idle_thread(struct iax2_thread *thread)
00894 {
00895 if (thread->type == IAX_TYPE_DYNAMIC) {
00896 AST_LIST_LOCK(&dynamic_list);
00897 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
00898 AST_LIST_UNLOCK(&dynamic_list);
00899 } else {
00900 AST_LIST_LOCK(&idle_list);
00901 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
00902 AST_LIST_UNLOCK(&idle_list);
00903 }
00904
00905 return;
00906 }
00907
00908 static struct iax2_thread *find_idle_thread(void)
00909 {
00910 pthread_attr_t attr;
00911 struct iax2_thread *thread = NULL;
00912
00913
00914 AST_LIST_LOCK(&idle_list);
00915 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
00916 AST_LIST_UNLOCK(&idle_list);
00917
00918
00919 if (thread == NULL) {
00920 AST_LIST_LOCK(&dynamic_list);
00921 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
00922
00923 if (thread == NULL && iaxmaxthreadcount > iaxdynamicthreadcount) {
00924
00925 if ((thread = ast_calloc(1, sizeof(*thread)))) {
00926 thread->threadnum = iaxdynamicthreadnum++;
00927 thread->type = IAX_TYPE_DYNAMIC;
00928 ast_mutex_init(&thread->lock);
00929 ast_cond_init(&thread->cond, NULL);
00930 pthread_attr_init(&attr);
00931 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00932 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
00933 free(thread);
00934 thread = NULL;
00935 } else {
00936
00937 iaxdynamicthreadcount++;
00938
00939
00940 while (!thread->ready_for_signal)
00941 usleep(1);
00942 }
00943 }
00944 }
00945 AST_LIST_UNLOCK(&dynamic_list);
00946 }
00947
00948
00949
00950 if (thread)
00951 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
00952
00953 return thread;
00954 }
00955
00956 #ifdef SCHED_MULTITHREADED
00957 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
00958 {
00959 struct iax2_thread *thread = NULL;
00960 static time_t lasterror;
00961 static time_t t;
00962
00963 thread = find_idle_thread();
00964
00965 if (thread != NULL) {
00966 thread->schedfunc = func;
00967 thread->scheddata = data;
00968 thread->iostate = IAX_IOSTATE_SCHEDREADY;
00969 #ifdef DEBUG_SCHED_MULTITHREAD
00970 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
00971 #endif
00972 signal_condition(&thread->lock, &thread->cond);
00973 return 0;
00974 }
00975 time(&t);
00976 if (t != lasterror && option_debug)
00977 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for scheduling!\n");
00978 lasterror = t;
00979
00980 return -1;
00981 }
00982 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
00983 #endif
00984
00985 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
00986 {
00987 int res;
00988
00989 res = ast_sched_add(con, when, callback, data);
00990 signal_condition(&sched_lock, &sched_cond);
00991
00992 return res;
00993 }
00994
00995 static int send_ping(const void *data);
00996
00997 static void __send_ping(const void *data)
00998 {
00999 int callno = (long) data;
01000
01001 ast_mutex_lock(&iaxsl[callno]);
01002
01003 if (iaxs[callno]) {
01004 if (iaxs[callno]->peercallno) {
01005 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01006 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01007 } else {
01008
01009 iaxs[callno]->pingid = -1;
01010 }
01011 } else if (option_debug > 0) {
01012 ast_log(LOG_DEBUG, "I was supposed to send a PING with callno %d, but no such call exists (and I cannot remove pingid, either).\n", callno);
01013 }
01014
01015 ast_mutex_unlock(&iaxsl[callno]);
01016 }
01017
01018 static int send_ping(const void *data)
01019 {
01020 #ifdef SCHED_MULTITHREADED
01021 if (schedule_action(__send_ping, data))
01022 #endif
01023 __send_ping(data);
01024
01025 return 0;
01026 }
01027
01028 static int get_encrypt_methods(const char *s)
01029 {
01030 int e;
01031 if (!strcasecmp(s, "aes128"))
01032 e = IAX_ENCRYPT_AES128;
01033 else if (ast_true(s))
01034 e = IAX_ENCRYPT_AES128;
01035 else
01036 e = 0;
01037 return e;
01038 }
01039
01040 static int send_lagrq(const void *data);
01041
01042 static void __send_lagrq(const void *data)
01043 {
01044 int callno = (long) data;
01045
01046 ast_mutex_lock(&iaxsl[callno]);
01047
01048 if (iaxs[callno]) {
01049 if (iaxs[callno]->peercallno) {
01050 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01051 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01052 } else {
01053
01054 iaxs[callno]->lagid = -1;
01055 }
01056 } else {
01057 ast_log(LOG_WARNING, "I was supposed to send a LAGRQ with callno %d, but no such call exists (and I cannot remove lagid, either).\n", callno);
01058 }
01059
01060 ast_mutex_unlock(&iaxsl[callno]);
01061 }
01062
01063 static int send_lagrq(const void *data)
01064 {
01065 #ifdef SCHED_MULTITHREADED
01066 if (schedule_action(__send_lagrq, data))
01067 #endif
01068 __send_lagrq(data);
01069
01070 return 0;
01071 }
01072
01073 static unsigned char compress_subclass(int subclass)
01074 {
01075 int x;
01076 int power=-1;
01077
01078 if (subclass < IAX_FLAG_SC_LOG)
01079 return subclass;
01080
01081 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01082 if (subclass & (1 << x)) {
01083 if (power > -1) {
01084 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01085 return 0;
01086 } else
01087 power = x;
01088 }
01089 }
01090 return power | IAX_FLAG_SC_LOG;
01091 }
01092
01093 static int uncompress_subclass(unsigned char csub)
01094 {
01095
01096 if (csub & IAX_FLAG_SC_LOG) {
01097
01098 if (csub == 0xff)
01099 return -1;
01100 else
01101 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01102 }
01103 else
01104 return csub;
01105 }
01106
01107
01108
01109
01110 static int peer_hash_cb(const void *obj, const int flags)
01111 {
01112 const struct iax2_peer *peer = obj;
01113
01114 return ast_str_hash(peer->name);
01115 }
01116
01117
01118
01119
01120 static int peer_cmp_cb(void *obj, void *arg, int flags)
01121 {
01122 struct iax2_peer *peer = obj, *peer2 = arg;
01123
01124 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01125 }
01126
01127
01128
01129
01130 static int user_hash_cb(const void *obj, const int flags)
01131 {
01132 const struct iax2_user *user = obj;
01133
01134 return ast_str_hash(user->name);
01135 }
01136
01137
01138
01139
01140 static int user_cmp_cb(void *obj, void *arg, int flags)
01141 {
01142 struct iax2_user *user = obj, *user2 = arg;
01143
01144 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01145 }
01146
01147
01148
01149
01150
01151 static struct iax2_peer *find_peer(const char *name, int realtime)
01152 {
01153 struct iax2_peer *peer = NULL;
01154 struct iax2_peer tmp_peer = {
01155 .name = name,
01156 };
01157
01158 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01159
01160
01161 if(!peer && realtime)
01162 peer = realtime_peer(name, NULL);
01163
01164 return peer;
01165 }
01166
01167 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01168 {
01169 ao2_ref(peer, +1);
01170 return peer;
01171 }
01172
01173 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01174 {
01175 ao2_ref(peer, -1);
01176 return NULL;
01177 }
01178
01179 static inline struct iax2_user *user_ref(struct iax2_user *user)
01180 {
01181 ao2_ref(user, +1);
01182 return user;
01183 }
01184
01185 static inline struct iax2_user *user_unref(struct iax2_user *user)
01186 {
01187 ao2_ref(user, -1);
01188 return NULL;
01189 }
01190
01191 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01192 {
01193 struct iax2_peer *peer = NULL;
01194 int res = 0;
01195 struct ao2_iterator i;
01196
01197 i = ao2_iterator_init(peers, 0);
01198 while ((peer = ao2_iterator_next(&i))) {
01199 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01200 (peer->addr.sin_port == sin.sin_port)) {
01201 ast_copy_string(host, peer->name, len);
01202 peer_unref(peer);
01203 res = 1;
01204 break;
01205 }
01206 peer_unref(peer);
01207 }
01208
01209 if (!peer) {
01210 peer = realtime_peer(NULL, &sin);
01211 if (peer) {
01212 ast_copy_string(host, peer->name, len);
01213 peer_unref(peer);
01214 res = 1;
01215 }
01216 }
01217
01218 return res;
01219 }
01220
01221 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01222 {
01223
01224 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01225 struct iax2_user *user;
01226 struct iax2_user tmp_user = {
01227 .name = pvt->username,
01228 };
01229
01230 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01231 if (user) {
01232 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01233 user = user_unref(user);
01234 }
01235
01236 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01237 }
01238
01239
01240 AST_SCHED_DEL(sched, pvt->pingid);
01241 AST_SCHED_DEL(sched, pvt->lagid);
01242 AST_SCHED_DEL(sched, pvt->autoid);
01243 AST_SCHED_DEL(sched, pvt->authid);
01244 AST_SCHED_DEL(sched, pvt->initid);
01245 AST_SCHED_DEL(sched, pvt->jbid);
01246 }
01247
01248 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01249 {
01250 if (!pvt->peercallno) {
01251 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01252 return;
01253 }
01254
01255 ao2_link(iax_peercallno_pvts, pvt);
01256 }
01257
01258 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01259 {
01260 if (!pvt->peercallno) {
01261 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01262 return;
01263 }
01264
01265 ao2_unlink(iax_peercallno_pvts, pvt);
01266 }
01267
01268 static void update_max_trunk(void)
01269 {
01270 int max = TRUNK_CALL_START;
01271 int x;
01272
01273
01274 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01275 if (iaxs[x]) {
01276 max = x + 1;
01277 }
01278 }
01279
01280 maxtrunkcall = max;
01281 if (option_debug && iaxdebug)
01282 ast_log(LOG_DEBUG, "New max trunk callno is %d\n", max);
01283 }
01284
01285 static void iax2_frame_free(struct iax_frame *fr)
01286 {
01287 AST_SCHED_DEL(sched, fr->retrans);
01288 iax_frame_free(fr);
01289 }
01290
01291 static void iax2_destroy(int callno)
01292 {
01293 struct chan_iax2_pvt *pvt;
01294 struct ast_channel *owner;
01295
01296 retry:
01297 pvt = iaxs[callno];
01298 gettimeofday(&lastused[callno], NULL);
01299
01300 owner = pvt ? pvt->owner : NULL;
01301
01302 if (owner) {
01303 if (ast_mutex_trylock(&owner->lock)) {
01304 if (option_debug > 2)
01305 ast_log(LOG_DEBUG, "Avoiding IAX destroy deadlock\n");
01306 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01307 goto retry;
01308 }
01309 }
01310 if (!owner && iaxs[callno]) {
01311 AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->lagid, &iaxsl[callno]);
01312 AST_SCHED_DEL_SPINLOCK(sched, iaxs[callno]->pingid, &iaxsl[callno]);
01313 iaxs[callno] = NULL;
01314 }
01315
01316 if (pvt) {
01317 if (!owner) {
01318 pvt->owner = NULL;
01319 } else {
01320
01321
01322
01323 ast_queue_hangup(owner);
01324 }
01325
01326 if (pvt->peercallno) {
01327 remove_by_peercallno(pvt);
01328 }
01329
01330 if (!owner) {
01331 ao2_ref(pvt, -1);
01332 pvt = NULL;
01333 }
01334 }
01335
01336 if (owner) {
01337 ast_mutex_unlock(&owner->lock);
01338 }
01339
01340 if (callno & 0x4000) {
01341 update_max_trunk();
01342 }
01343 }
01344
01345 static int scheduled_destroy(const void *vid)
01346 {
01347 short callno = PTR_TO_CALLNO(vid);
01348 ast_mutex_lock(&iaxsl[callno]);
01349 if (iaxs[callno]) {
01350 if (option_debug) {
01351 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01352 }
01353 iax2_destroy(callno);
01354 }
01355 ast_mutex_unlock(&iaxsl[callno]);
01356 return 0;
01357 }
01358
01359 static void pvt_destructor(void *obj)
01360 {
01361 struct chan_iax2_pvt *pvt = obj;
01362 struct iax_frame *cur = NULL;
01363
01364 iax2_destroy_helper(pvt);
01365
01366
01367 ast_set_flag(pvt, IAX_ALREADYGONE);
01368
01369 AST_LIST_LOCK(&iaxq.queue);
01370 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
01371
01372 if (cur->callno == pvt->callno) {
01373 cur->retries = -1;
01374 }
01375 }
01376 AST_LIST_UNLOCK(&iaxq.queue);
01377
01378 if (pvt->reg) {
01379 pvt->reg->callno = 0;
01380 }
01381
01382 if (!pvt->owner) {
01383 jb_frame frame;
01384 if (pvt->vars) {
01385 ast_variables_destroy(pvt->vars);
01386 pvt->vars = NULL;
01387 }
01388
01389 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01390 iax2_frame_free(frame.data);
01391 }
01392
01393 jb_destroy(pvt->jb);
01394 ast_string_field_free_memory(pvt);
01395 }
01396 }
01397
01398 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01399 {
01400 struct chan_iax2_pvt *tmp;
01401 jb_conf jbconf;
01402
01403 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01404 return NULL;
01405 }
01406
01407 if (ast_string_field_init(tmp, 32)) {
01408 ao2_ref(tmp, -1);
01409 tmp = NULL;
01410 return NULL;
01411 }
01412
01413 tmp->prefs = prefs;
01414 tmp->callno = 0;
01415 tmp->peercallno = 0;
01416 tmp->transfercallno = 0;
01417 tmp->bridgecallno = 0;
01418 tmp->pingid = -1;
01419 tmp->lagid = -1;
01420 tmp->autoid = -1;
01421 tmp->authid = -1;
01422 tmp->initid = -1;
01423
01424 ast_string_field_set(tmp,exten, "s");
01425 ast_string_field_set(tmp,host, host);
01426
01427 tmp->jb = jb_new();
01428 tmp->jbid = -1;
01429 jbconf.max_jitterbuf = maxjitterbuffer;
01430 jbconf.resync_threshold = resyncthreshold;
01431 jbconf.max_contig_interp = maxjitterinterps;
01432 jb_setconf(tmp->jb,&jbconf);
01433
01434 return tmp;
01435 }
01436
01437 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01438 {
01439 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01440 if (new) {
01441 size_t afdatalen = new->afdatalen;
01442 memcpy(new, fr, sizeof(*new));
01443 iax_frame_wrap(new, &fr->af);
01444 new->afdatalen = afdatalen;
01445 new->data = NULL;
01446 new->datalen = 0;
01447 new->direction = DIRECTION_INGRESS;
01448 new->retrans = -1;
01449 }
01450 return new;
01451 }
01452
01453 #define NEW_PREVENT 0
01454 #define NEW_ALLOW 1
01455 #define NEW_FORCE 2
01456
01457 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, struct chan_iax2_pvt *cur, int check_dcallno)
01458 {
01459 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01460 (cur->addr.sin_port == sin->sin_port)) {
01461
01462 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01463 (check_dcallno ? dcallno == cur->callno : 1) ) {
01464
01465 return 1;
01466 }
01467 }
01468 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01469 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01470
01471 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01472 return 1;
01473 }
01474 return 0;
01475 }
01476
01477 static void update_max_nontrunk(void)
01478 {
01479 int max = 1;
01480 int x;
01481
01482 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01483 if (iaxs[x])
01484 max = x + 1;
01485 }
01486 maxnontrunkcall = max;
01487 if (option_debug && iaxdebug)
01488 ast_log(LOG_DEBUG, "New max nontrunk callno is %d\n", max);
01489 }
01490
01491 static int make_trunk(unsigned short callno, int locked)
01492 {
01493 int x;
01494 int res= 0;
01495 struct timeval now;
01496 if (iaxs[callno]->oseqno) {
01497 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01498 return -1;
01499 }
01500 if (callno & TRUNK_CALL_START) {
01501 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01502 return -1;
01503 }
01504 gettimeofday(&now, NULL);
01505 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01506 ast_mutex_lock(&iaxsl[x]);
01507 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01508
01509
01510
01511
01512
01513 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01514 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01515 iaxs[x] = iaxs[callno];
01516 iaxs[x]->callno = x;
01517 iaxs[callno] = NULL;
01518 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01519 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01520 if (locked)
01521 ast_mutex_unlock(&iaxsl[callno]);
01522 res = x;
01523 if (!locked)
01524 ast_mutex_unlock(&iaxsl[x]);
01525 break;
01526 }
01527 ast_mutex_unlock(&iaxsl[x]);
01528 }
01529 if (x >= ARRAY_LEN(iaxs) - 1) {
01530 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01531 return -1;
01532 }
01533 if (option_debug)
01534 ast_log(LOG_DEBUG, "Made call %d into trunk call %d\n", callno, x);
01535
01536 update_max_trunk();
01537 update_max_nontrunk();
01538 return res;
01539 }
01540
01541
01542
01543
01544 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01545 {
01546 int res = 0;
01547 int x;
01548 struct timeval now;
01549 char host[80];
01550
01551 if (new <= NEW_ALLOW) {
01552 if (callno) {
01553 struct chan_iax2_pvt *pvt;
01554 struct chan_iax2_pvt tmp_pvt = {
01555 .callno = dcallno,
01556 .peercallno = callno,
01557
01558 .frames_received = check_dcallno,
01559 };
01560
01561 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01562
01563 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01564 if (return_locked) {
01565 ast_mutex_lock(&iaxsl[pvt->callno]);
01566 }
01567 res = pvt->callno;
01568 ao2_ref(pvt, -1);
01569 pvt = NULL;
01570 return res;
01571 }
01572 }
01573
01574
01575
01576 if (dcallno) {
01577 ast_mutex_lock(&iaxsl[dcallno]);
01578 }
01579 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
01580 iaxs[dcallno]->peercallno = callno;
01581 res = dcallno;
01582 store_by_peercallno(iaxs[dcallno]);
01583 if (!res || !return_locked) {
01584 ast_mutex_unlock(&iaxsl[dcallno]);
01585 }
01586 return res;
01587 }
01588 if (dcallno) {
01589 ast_mutex_unlock(&iaxsl[dcallno]);
01590 }
01591
01592 #ifdef IAX_OLD_FIND
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604 for (x = 1; !res && x < maxnontrunkcall; x++) {
01605 ast_mutex_lock(&iaxsl[x]);
01606 if (iaxs[x]) {
01607
01608 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01609 res = x;
01610 }
01611 }
01612 if (!res || !return_locked)
01613 ast_mutex_unlock(&iaxsl[x]);
01614 }
01615
01616 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01617 ast_mutex_lock(&iaxsl[x]);
01618 if (iaxs[x]) {
01619
01620 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01621 res = x;
01622 }
01623 }
01624 if (!res || !return_locked)
01625 ast_mutex_unlock(&iaxsl[x]);
01626 }
01627
01628 if (res) {
01629 ast_log(LOG_WARNING, "Old call search code found call number %d that was not in hash table!\n", res);
01630 }
01631 #endif
01632 }
01633 if (!res && (new >= NEW_ALLOW)) {
01634 int start, found = 0;
01635
01636
01637
01638
01639
01640
01641
01642 if (!iax2_getpeername(*sin, host, sizeof(host)))
01643 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01644
01645 now = ast_tvnow();
01646 start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01647 for (x = start; 1; x++) {
01648 if (x == TRUNK_CALL_START) {
01649 x = 1;
01650 continue;
01651 }
01652
01653
01654 ast_mutex_lock(&iaxsl[x]);
01655 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01656 found = 1;
01657 break;
01658 }
01659 ast_mutex_unlock(&iaxsl[x]);
01660
01661 if (x == start - 1) {
01662 break;
01663 }
01664 }
01665
01666 if (x == start - 1 && !found) {
01667 ast_log(LOG_WARNING, "No more space\n");
01668 return 0;
01669 }
01670 iaxs[x] = new_iax(sin, host);
01671 update_max_nontrunk();
01672 if (iaxs[x]) {
01673 if (option_debug && iaxdebug)
01674 ast_log(LOG_DEBUG, "Creating new call structure %d\n", x);
01675 iaxs[x]->sockfd = sockfd;
01676 iaxs[x]->addr.sin_port = sin->sin_port;
01677 iaxs[x]->addr.sin_family = sin->sin_family;
01678 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01679 iaxs[x]->peercallno = callno;
01680 iaxs[x]->callno = x;
01681 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01682 iaxs[x]->expiry = min_reg_expire;
01683 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01684 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01685 iaxs[x]->amaflags = amaflags;
01686 ast_copy_flags(iaxs[x], (&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01687
01688 ast_string_field_set(iaxs[x], accountcode, accountcode);
01689 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01690 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01691
01692 if (iaxs[x]->peercallno) {
01693 store_by_peercallno(iaxs[x]);
01694 }
01695 } else {
01696 ast_log(LOG_WARNING, "Out of resources\n");
01697 ast_mutex_unlock(&iaxsl[x]);
01698 return 0;
01699 }
01700 if (!return_locked)
01701 ast_mutex_unlock(&iaxsl[x]);
01702 res = x;
01703 }
01704 return res;
01705 }
01706
01707 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01708
01709 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01710 }
01711
01712 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01713
01714 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01715 }
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727 static int iax2_queue_frame(int callno, struct ast_frame *f)
01728 {
01729 for (;;) {
01730 if (iaxs[callno] && iaxs[callno]->owner) {
01731 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01732
01733 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01734 } else {
01735 ast_queue_frame(iaxs[callno]->owner, f);
01736 ast_mutex_unlock(&iaxs[callno]->owner->lock);
01737 break;
01738 }
01739 } else
01740 break;
01741 }
01742 return 0;
01743 }
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756
01757
01758 static int iax2_queue_hangup(int callno)
01759 {
01760 for (;;) {
01761 if (iaxs[callno] && iaxs[callno]->owner) {
01762 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01763
01764 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01765 } else {
01766 ast_queue_hangup(iaxs[callno]->owner);
01767 ast_mutex_unlock(&iaxs[callno]->owner->lock);
01768 break;
01769 }
01770 } else
01771 break;
01772 }
01773 return 0;
01774 }
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789 static int iax2_queue_control_data(int callno,
01790 enum ast_control_frame_type control, const void *data, size_t datalen)
01791 {
01792 for (;;) {
01793 if (iaxs[callno] && iaxs[callno]->owner) {
01794 if (ast_mutex_trylock(&iaxs[callno]->owner->lock)) {
01795
01796 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01797 } else {
01798 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01799 ast_mutex_unlock(&iaxs[callno]->owner->lock);
01800 break;
01801 }
01802 } else
01803 break;
01804 }
01805 return 0;
01806 }
01807 static void destroy_firmware(struct iax_firmware *cur)
01808 {
01809
01810 if (cur->fwh) {
01811 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
01812 }
01813 close(cur->fd);
01814 free(cur);
01815 }
01816
01817 static int try_firmware(char *s)
01818 {
01819 struct stat stbuf;
01820 struct iax_firmware *cur;
01821 int ifd;
01822 int fd;
01823 int res;
01824
01825 struct ast_iax2_firmware_header *fwh, fwh2;
01826 struct MD5Context md5;
01827 unsigned char sum[16];
01828 unsigned char buf[1024];
01829 int len, chunk;
01830 char *s2;
01831 char *last;
01832 s2 = alloca(strlen(s) + 100);
01833 if (!s2) {
01834 ast_log(LOG_WARNING, "Alloca failed!\n");
01835 return -1;
01836 }
01837 last = strrchr(s, '/');
01838 if (last)
01839 last++;
01840 else
01841 last = s;
01842 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
01843 res = stat(s, &stbuf);
01844 if (res < 0) {
01845 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
01846 return -1;
01847 }
01848
01849 if (S_ISDIR(stbuf.st_mode))
01850 return -1;
01851 ifd = open(s, O_RDONLY);
01852 if (ifd < 0) {
01853 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
01854 return -1;
01855 }
01856 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, 0600);
01857 if (fd < 0) {
01858 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
01859 close(ifd);
01860 return -1;
01861 }
01862
01863 unlink(s2);
01864
01865
01866 len = stbuf.st_size;
01867 while(len) {
01868 chunk = len;
01869 if (chunk > sizeof(buf))
01870 chunk = sizeof(buf);
01871 res = read(ifd, buf, chunk);
01872 if (res != chunk) {
01873 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01874 close(ifd);
01875 close(fd);
01876 return -1;
01877 }
01878 res = write(fd, buf, chunk);
01879 if (res != chunk) {
01880 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
01881 close(ifd);
01882 close(fd);
01883 return -1;
01884 }
01885 len -= chunk;
01886 }
01887 close(ifd);
01888
01889 lseek(fd, 0, SEEK_SET);
01890 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
01891 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
01892 close(fd);
01893 return -1;
01894 }
01895 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
01896 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
01897 close(fd);
01898 return -1;
01899 }
01900 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
01901 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
01902 close(fd);
01903 return -1;
01904 }
01905 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
01906 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
01907 close(fd);
01908 return -1;
01909 }
01910 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
01911 if (fwh == (void *) -1) {
01912 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
01913 close(fd);
01914 return -1;
01915 }
01916 MD5Init(&md5);
01917 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
01918 MD5Final(sum, &md5);
01919 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
01920 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
01921 munmap((void*)fwh, stbuf.st_size);
01922 close(fd);
01923 return -1;
01924 }
01925 cur = waresl.wares;
01926 while(cur) {
01927 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
01928
01929 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
01930
01931 break;
01932
01933
01934 munmap((void*)fwh, stbuf.st_size);
01935 close(fd);
01936 return 0;
01937 }
01938 cur = cur->next;
01939 }
01940 if (!cur) {
01941
01942 if ((cur = ast_calloc(1, sizeof(*cur)))) {
01943 cur->fd = -1;
01944 cur->next = waresl.wares;
01945 waresl.wares = cur;
01946 }
01947 }
01948 if (cur) {
01949 if (cur->fwh) {
01950 munmap((void*)cur->fwh, cur->mmaplen);
01951 }
01952 if (cur->fd > -1)
01953 close(cur->fd);
01954 cur->fwh = fwh;
01955 cur->fd = fd;
01956 cur->mmaplen = stbuf.st_size;
01957 cur->dead = 0;
01958 }
01959 return 0;
01960 }
01961
01962 static int iax_check_version(char *dev)
01963 {
01964 int res = 0;
01965 struct iax_firmware *cur;
01966 if (!ast_strlen_zero(dev)) {
01967 ast_mutex_lock(&waresl.lock);
01968 cur = waresl.wares;
01969 while(cur) {
01970 if (!strcmp(dev, (char *)cur->fwh->devname)) {
01971 res = ntohs(cur->fwh->version);
01972 break;
01973 }
01974 cur = cur->next;
01975 }
01976 ast_mutex_unlock(&waresl.lock);
01977 }
01978 return res;
01979 }
01980
01981 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
01982 {
01983 int res = -1;
01984 unsigned int bs = desc & 0xff;
01985 unsigned int start = (desc >> 8) & 0xffffff;
01986 unsigned int bytes;
01987 struct iax_firmware *cur;
01988 if (!ast_strlen_zero((char *)dev) && bs) {
01989 start *= bs;
01990 ast_mutex_lock(&waresl.lock);
01991 cur = waresl.wares;
01992 while(cur) {
01993 if (!strcmp((char *)dev, (char *)cur->fwh->devname)) {
01994 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
01995 if (start < ntohl(cur->fwh->datalen)) {
01996 bytes = ntohl(cur->fwh->datalen) - start;
01997 if (bytes > bs)
01998 bytes = bs;
01999 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02000 } else {
02001 bytes = 0;
02002 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02003 }
02004 if (bytes == bs)
02005 res = 0;
02006 else
02007 res = 1;
02008 break;
02009 }
02010 cur = cur->next;
02011 }
02012 ast_mutex_unlock(&waresl.lock);
02013 }
02014 return res;
02015 }
02016
02017
02018 static void reload_firmware(int unload)
02019 {
02020 struct iax_firmware *cur, *curl, *curp;
02021 DIR *fwd;
02022 struct dirent *de;
02023 char dir[256];
02024 char fn[256];
02025
02026 ast_mutex_lock(&waresl.lock);
02027 cur = waresl.wares;
02028 while(cur) {
02029 cur->dead = 1;
02030 cur = cur->next;
02031 }
02032
02033
02034 if (!unload) {
02035 snprintf(dir, sizeof(dir), "%s/firmware/iax", (char *)ast_config_AST_DATA_DIR);
02036 fwd = opendir(dir);
02037 if (fwd) {
02038 while((de = readdir(fwd))) {
02039 if (de->d_name[0] != '.') {
02040 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02041 if (!try_firmware(fn)) {
02042 if (option_verbose > 1)
02043 ast_verbose(VERBOSE_PREFIX_2 "Loaded firmware '%s'\n", de->d_name);
02044 }
02045 }
02046 }
02047 closedir(fwd);
02048 } else
02049 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02050 }
02051
02052
02053 cur = waresl.wares;
02054 curp = NULL;
02055 while(cur) {
02056 curl = cur;
02057 cur = cur->next;
02058 if (curl->dead) {
02059 if (curp) {
02060 curp->next = cur;
02061 } else {
02062 waresl.wares = cur;
02063 }
02064 destroy_firmware(curl);
02065 } else {
02066 curp = cur;
02067 }
02068 }
02069 ast_mutex_unlock(&waresl.lock);
02070 }
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080 static int __do_deliver(void *data)
02081 {
02082
02083
02084 struct iax_frame *fr = data;
02085 fr->retrans = -1;
02086 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02087 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02088 iax2_queue_frame(fr->callno, &fr->af);
02089
02090 iax2_frame_free(fr);
02091
02092 return 0;
02093 }
02094
02095 static int handle_error(void)
02096 {
02097
02098
02099
02100 #if 0
02101 struct sockaddr_in *sin;
02102 int res;
02103 struct msghdr m;
02104 struct sock_extended_err e;
02105 m.msg_name = NULL;
02106 m.msg_namelen = 0;
02107 m.msg_iov = NULL;
02108 m.msg_control = &e;
02109 m.msg_controllen = sizeof(e);
02110 m.msg_flags = 0;
02111 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02112 if (res < 0)
02113 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02114 else {
02115 if (m.msg_controllen) {
02116 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02117 if (sin)
02118 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02119 else
02120 ast_log(LOG_WARNING, "No address detected??\n");
02121 } else {
02122 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02123 }
02124 }
02125 #endif
02126 return 0;
02127 }
02128
02129 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02130 {
02131 int res;
02132 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02133 sizeof(*sin));
02134 if (res < 0) {
02135 if (option_debug)
02136 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02137 handle_error();
02138 } else
02139 res = 0;
02140 return res;
02141 }
02142
02143 static int send_packet(struct iax_frame *f)
02144 {
02145 int res;
02146 int callno = f->callno;
02147
02148
02149 if (!callno || !iaxs[callno] || iaxs[callno]->error)
02150 return -1;
02151
02152
02153 if (option_debug > 2 && iaxdebug)
02154 ast_log(LOG_DEBUG, "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));
02155 if (f->transfer) {
02156 if (iaxdebug)
02157 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02158 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer,
02159 sizeof(iaxs[callno]->transfer));
02160 } else {
02161 if (iaxdebug)
02162 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02163 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr,
02164 sizeof(iaxs[callno]->addr));
02165 }
02166 if (res < 0) {
02167 if (option_debug && iaxdebug)
02168 ast_log(LOG_DEBUG, "Received error: %s\n", strerror(errno));
02169 handle_error();
02170 } else
02171 res = 0;
02172 return res;
02173 }
02174
02175
02176
02177
02178
02179 static int iax2_predestroy(int callno)
02180 {
02181 struct ast_channel *c;
02182 struct chan_iax2_pvt *pvt = iaxs[callno];
02183
02184 if (!pvt)
02185 return -1;
02186 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02187 iax2_destroy_helper(pvt);
02188 ast_set_flag(pvt, IAX_ALREADYGONE);
02189 }
02190 c = pvt->owner;
02191 if (c) {
02192 c->tech_pvt = NULL;
02193 iax2_queue_hangup(callno);
02194 pvt->owner = NULL;
02195 ast_module_unref(ast_module_info->self);
02196 }
02197 return 0;
02198 }
02199
02200 static int update_packet(struct iax_frame *f)
02201 {
02202
02203 struct ast_iax2_full_hdr *fh = f->data;
02204
02205 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02206
02207 f->iseqno = iaxs[f->callno]->iseqno;
02208 fh->iseqno = f->iseqno;
02209 return 0;
02210 }
02211
02212 static int attempt_transmit(const void *data);
02213 static void __attempt_transmit(const void *data)
02214 {
02215
02216
02217 struct iax_frame *f = (struct iax_frame *)data;
02218 int freeme=0;
02219 int callno = f->callno;
02220
02221 if (callno)
02222 ast_mutex_lock(&iaxsl[callno]);
02223 if (callno && iaxs[callno]) {
02224 if ((f->retries < 0) ||
02225 (f->retries >= max_retries) ) {
02226
02227 if (f->retries >= max_retries) {
02228 if (f->transfer) {
02229
02230 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02231 } else if (f->final) {
02232 if (f->final)
02233 iax2_destroy(callno);
02234 } else {
02235 if (iaxs[callno]->owner)
02236 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);
02237 iaxs[callno]->error = ETIMEDOUT;
02238 if (iaxs[callno]->owner) {
02239 struct ast_frame fr = { 0, };
02240
02241 fr.frametype = AST_FRAME_CONTROL;
02242 fr.subclass = AST_CONTROL_HANGUP;
02243 iax2_queue_frame(callno, &fr);
02244
02245 if (iaxs[callno] && iaxs[callno]->owner)
02246 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02247 } else {
02248 if (iaxs[callno]->reg) {
02249 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02250 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02251 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02252 }
02253 iax2_destroy(callno);
02254 }
02255 }
02256
02257 }
02258 freeme++;
02259 } else {
02260
02261 update_packet(f);
02262
02263 send_packet(f);
02264 f->retries++;
02265
02266 f->retrytime *= 10;
02267 if (f->retrytime > MAX_RETRY_TIME)
02268 f->retrytime = MAX_RETRY_TIME;
02269
02270 if (f->transfer && (f->retrytime > 1000))
02271 f->retrytime = 1000;
02272 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02273 }
02274 } else {
02275
02276 f->retries = -1;
02277 freeme++;
02278 }
02279 if (callno)
02280 ast_mutex_unlock(&iaxsl[callno]);
02281
02282 if (freeme) {
02283
02284 AST_LIST_LOCK(&iaxq.queue);
02285 AST_LIST_REMOVE(&iaxq.queue, f, list);
02286 iaxq.count--;
02287 AST_LIST_UNLOCK(&iaxq.queue);
02288 f->retrans = -1;
02289
02290 iax2_frame_free(f);
02291 }
02292 }
02293
02294 static int attempt_transmit(const void *data)
02295 {
02296 #ifdef SCHED_MULTITHREADED
02297 if (schedule_action(__attempt_transmit, data))
02298 #endif
02299 __attempt_transmit(data);
02300 return 0;
02301 }
02302
02303 static int iax2_prune_realtime(int fd, int argc, char *argv[])
02304 {
02305 struct iax2_peer *peer;
02306
02307 if (argc != 4)
02308 return RESULT_SHOWUSAGE;
02309 if (!strcmp(argv[3],"all")) {
02310 reload_config();
02311 ast_cli(fd, "OK cache is flushed.\n");
02312 } else if ((peer = find_peer(argv[3], 0))) {
02313 if(ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02314 ast_set_flag(peer, IAX_RTAUTOCLEAR);
02315 expire_registry(peer_ref(peer));
02316 ast_cli(fd, "OK peer %s was removed from the cache.\n", argv[3]);
02317 } else {
02318 ast_cli(fd, "SORRY peer %s is not eligible for this operation.\n", argv[3]);
02319 }
02320 peer_unref(peer);
02321 } else {
02322 ast_cli(fd, "SORRY peer %s was not found in the cache.\n", argv[3]);
02323 }
02324
02325 return RESULT_SUCCESS;
02326 }
02327
02328 static int iax2_test_losspct(int fd, int argc, char *argv[])
02329 {
02330 if (argc != 4)
02331 return RESULT_SHOWUSAGE;
02332
02333 test_losspct = atoi(argv[3]);
02334
02335 return RESULT_SUCCESS;
02336 }
02337
02338 #ifdef IAXTESTS
02339 static int iax2_test_late(int fd, int argc, char *argv[])
02340 {
02341 if (argc != 4)
02342 return RESULT_SHOWUSAGE;
02343
02344 test_late = atoi(argv[3]);
02345
02346 return RESULT_SUCCESS;
02347 }
02348
02349 static int iax2_test_resync(int fd, int argc, char *argv[])
02350 {
02351 if (argc != 4)
02352 return RESULT_SHOWUSAGE;
02353
02354 test_resync = atoi(argv[3]);
02355
02356 return RESULT_SUCCESS;
02357 }
02358
02359 static int iax2_test_jitter(int fd, int argc, char *argv[])
02360 {
02361 if (argc < 4 || argc > 5)
02362 return RESULT_SHOWUSAGE;
02363
02364 test_jit = atoi(argv[3]);
02365 if (argc == 5)
02366 test_jitpct = atoi(argv[4]);
02367
02368 return RESULT_SUCCESS;
02369 }
02370 #endif
02371
02372
02373
02374 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02375 {
02376 int res = 0;
02377 if (peer->maxms) {
02378 if (peer->lastms < 0) {
02379 ast_copy_string(status, "UNREACHABLE", statuslen);
02380 } else if (peer->lastms > peer->maxms) {
02381 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02382 res = 1;
02383 } else if (peer->lastms) {
02384 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02385 res = 1;
02386 } else {
02387 ast_copy_string(status, "UNKNOWN", statuslen);
02388 }
02389 } else {
02390 ast_copy_string(status, "Unmonitored", statuslen);
02391 res = -1;
02392 }
02393 return res;
02394 }
02395
02396
02397 static int iax2_show_peer(int fd, int argc, char *argv[])
02398 {
02399 char status[30];
02400 char cbuf[256];
02401 struct iax2_peer *peer;
02402 char codec_buf[512];
02403 int x = 0, codec = 0, load_realtime = 0;
02404
02405 if (argc < 4)
02406 return RESULT_SHOWUSAGE;
02407
02408 load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? 1 : 0;
02409
02410 peer = find_peer(argv[3], load_realtime);
02411 if (peer) {
02412 ast_cli(fd,"\n\n");
02413 ast_cli(fd, " * Name : %s\n", peer->name);
02414 ast_cli(fd, " Secret : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
02415 ast_cli(fd, " Context : %s\n", peer->context);
02416 ast_cli(fd, " Mailbox : %s\n", peer->mailbox);
02417 ast_cli(fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes":"No");
02418 ast_cli(fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02419 ast_cli(fd, " Expire : %d\n", peer->expire);
02420 ast_cli(fd, " ACL : %s\n", (peer->ha?"Yes":"No"));
02421 ast_cli(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));
02422 ast_cli(fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02423 ast_cli(fd, " Username : %s\n", peer->username);
02424 ast_cli(fd, " Codecs : ");
02425 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02426 ast_cli(fd, "%s\n", codec_buf);
02427
02428 ast_cli(fd, " Codec Order : (");
02429 for(x = 0; x < 32 ; x++) {
02430 codec = ast_codec_pref_index(&peer->prefs,x);
02431 if(!codec)
02432 break;
02433 ast_cli(fd, "%s", ast_getformatname(codec));
02434 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02435 ast_cli(fd, "|");
02436 }
02437
02438 if (!x)
02439 ast_cli(fd, "none");
02440 ast_cli(fd, ")\n");
02441
02442 ast_cli(fd, " Status : ");
02443 peer_status(peer, status, sizeof(status));
02444 ast_cli(fd, "%s\n",status);
02445 ast_cli(fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02446 ast_cli(fd,"\n");
02447 peer_unref(peer);
02448 } else {
02449 ast_cli(fd,"Peer %s not found.\n", argv[3]);
02450 ast_cli(fd,"\n");
02451 }
02452
02453 return RESULT_SUCCESS;
02454 }
02455
02456 static char *complete_iax2_show_peer(const char *line, const char *word, int pos, int state)
02457 {
02458 int which = 0;
02459 struct iax2_peer *peer;
02460 char *res = NULL;
02461 int wordlen = strlen(word);
02462 struct ao2_iterator i;
02463
02464
02465 if (pos != 3)
02466 return NULL;
02467
02468 i = ao2_iterator_init(peers, 0);
02469 while ((peer = ao2_iterator_next(&i))) {
02470 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02471 res = ast_strdup(peer->name);
02472 peer_unref(peer);
02473 break;
02474 }
02475 peer_unref(peer);
02476 }
02477
02478 return res;
02479 }
02480
02481 static int iax2_show_stats(int fd, int argc, char *argv[])
02482 {
02483 struct iax_frame *cur;
02484 int cnt = 0, dead=0, final=0;
02485
02486 if (argc != 3)
02487 return RESULT_SHOWUSAGE;
02488
02489 AST_LIST_LOCK(&iaxq.queue);
02490 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
02491 if (cur->retries < 0)
02492 dead++;
02493 if (cur->final)
02494 final++;
02495 cnt++;
02496 }
02497 AST_LIST_UNLOCK(&iaxq.queue);
02498
02499 ast_cli(fd, " IAX Statistics\n");
02500 ast_cli(fd, "---------------------\n");
02501 ast_cli(fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02502 ast_cli(fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02503
02504 return RESULT_SUCCESS;
02505 }
02506
02507 static int iax2_show_cache(int fd, int argc, char *argv[])
02508 {
02509 struct iax2_dpcache *dp;
02510 char tmp[1024], *pc;
02511 int s;
02512 int x,y;
02513 struct timeval tv;
02514 gettimeofday(&tv, NULL);
02515 ast_mutex_lock(&dpcache_lock);
02516 dp = dpcache;
02517 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02518 while(dp) {
02519 s = dp->expiry.tv_sec - tv.tv_sec;
02520 tmp[0] = '\0';
02521 if (dp->flags & CACHE_FLAG_EXISTS)
02522 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02523 if (dp->flags & CACHE_FLAG_NONEXISTENT)
02524 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02525 if (dp->flags & CACHE_FLAG_CANEXIST)
02526 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02527 if (dp->flags & CACHE_FLAG_PENDING)
02528 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02529 if (dp->flags & CACHE_FLAG_TIMEOUT)
02530 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02531 if (dp->flags & CACHE_FLAG_TRANSMITTED)
02532 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02533 if (dp->flags & CACHE_FLAG_MATCHMORE)
02534 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02535 if (dp->flags & CACHE_FLAG_UNKNOWN)
02536 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02537
02538 if (!ast_strlen_zero(tmp))
02539 tmp[strlen(tmp) - 1] = '\0';
02540 else
02541 ast_copy_string(tmp, "(none)", sizeof(tmp));
02542 y=0;
02543 pc = strchr(dp->peercontext, '@');
02544 if (!pc)
02545 pc = dp->peercontext;
02546 else
02547 pc++;
02548 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
02549 if (dp->waiters[x] > -1)
02550 y++;
02551 if (s > 0)
02552 ast_cli(fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02553 else
02554 ast_cli(fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02555 dp = dp->next;
02556 }
02557 ast_mutex_unlock(&dpcache_lock);
02558 return RESULT_SUCCESS;
02559 }
02560
02561 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02562
02563 static void unwrap_timestamp(struct iax_frame *fr)
02564 {
02565
02566
02567 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
02568 const int lower_mask = (1 << ts_shift) - 1;
02569 const int upper_mask = ~lower_mask;
02570 const int last_upper = iaxs[fr->callno]->last & upper_mask;
02571
02572 if ( (fr->ts & upper_mask) == last_upper ) {
02573 const int x = fr->ts - iaxs[fr->callno]->last;
02574 const int threshold = (ts_shift == 15) ? 25000 : 50000;
02575
02576 if (x < -threshold) {
02577
02578
02579
02580
02581 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
02582 if (option_debug && iaxdebug)
02583 ast_log(LOG_DEBUG, "schedule_delivery: pushed forward timestamp\n");
02584 } else if (x > threshold) {
02585
02586
02587
02588
02589 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
02590 if (option_debug && iaxdebug)
02591 ast_log(LOG_DEBUG, "schedule_delivery: pushed back timestamp\n");
02592 }
02593 }
02594 }
02595
02596 static int get_from_jb(const void *p);
02597
02598 static void update_jbsched(struct chan_iax2_pvt *pvt)
02599 {
02600 int when;
02601
02602 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
02603
02604 when = jb_next(pvt->jb) - when;
02605
02606 AST_SCHED_DEL(sched, pvt->jbid);
02607
02608 if(when <= 0) {
02609
02610 when = 1;
02611 }
02612
02613 pvt->jbid = iax2_sched_add(sched, when, get_from_jb, CALLNO_TO_PTR(pvt->callno));
02614 }
02615
02616 static void __get_from_jb(const void *p)
02617 {
02618 int callno = PTR_TO_CALLNO(p);
02619 struct chan_iax2_pvt *pvt = NULL;
02620 struct iax_frame *fr;
02621 jb_frame frame;
02622 int ret;
02623 long now;
02624 long next;
02625 struct timeval tv;
02626
02627
02628 ast_mutex_lock(&iaxsl[callno]);
02629 pvt = iaxs[callno];
02630 if (!pvt) {
02631
02632 ast_mutex_unlock(&iaxsl[callno]);
02633 return;
02634 }
02635
02636 pvt->jbid = -1;
02637
02638 gettimeofday(&tv,NULL);
02639
02640
02641
02642 tv.tv_usec += 1000;
02643
02644 now = ast_tvdiff_ms(tv, pvt->rxcore);
02645
02646 if(now >= (next = jb_next(pvt->jb))) {
02647 ret = jb_get(pvt->jb,&frame,now,ast_codec_interp_len(pvt->voiceformat));
02648 switch(ret) {
02649 case JB_OK:
02650 fr = frame.data;
02651 __do_deliver(fr);
02652
02653 pvt = iaxs[callno];
02654 break;
02655 case JB_INTERP:
02656 {
02657 struct ast_frame af = { 0, };
02658
02659
02660 af.frametype = AST_FRAME_VOICE;
02661 af.subclass = pvt->voiceformat;
02662 af.samples = frame.ms * 8;
02663 af.src = "IAX2 JB interpolation";
02664 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
02665 af.offset = AST_FRIENDLY_OFFSET;
02666
02667
02668
02669 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
02670 iax2_queue_frame(callno, &af);
02671
02672 pvt = iaxs[callno];
02673 }
02674 }
02675 break;
02676 case JB_DROP:
02677 iax2_frame_free(frame.data);
02678 break;
02679 case JB_NOFRAME:
02680 case JB_EMPTY:
02681
02682 break;
02683 default:
02684
02685 break;
02686 }
02687 }
02688 if (pvt)
02689 update_jbsched(pvt);
02690 ast_mutex_unlock(&iaxsl[callno]);
02691 }
02692
02693 static int get_from_jb(const void *data)
02694 {
02695 #ifdef SCHED_MULTITHREADED
02696 if (schedule_action(__get_from_jb, data))
02697 #endif
02698 __get_from_jb(data);
02699 return 0;
02700 }
02701
02702
02703
02704
02705
02706
02707
02708 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
02709 {
02710 int type, len;
02711 int ret;
02712 int needfree = 0;
02713 struct ast_channel *owner = NULL;
02714 struct ast_channel *bridge = NULL;
02715
02716
02717 unwrap_timestamp(fr);
02718
02719
02720 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
02721 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
02722 else {
02723 #if 0
02724 if (option_debug)
02725 ast_log(LOG_DEBUG, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
02726 #endif
02727 fr->af.delivery = ast_tv(0,0);
02728 }
02729
02730 type = JB_TYPE_CONTROL;
02731 len = 0;
02732
02733 if(fr->af.frametype == AST_FRAME_VOICE) {
02734 type = JB_TYPE_VOICE;
02735 len = ast_codec_get_samples(&fr->af) / 8;
02736 } else if(fr->af.frametype == AST_FRAME_CNG) {
02737 type = JB_TYPE_SILENCE;
02738 }
02739
02740 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
02741 if (tsout)
02742 *tsout = fr->ts;
02743 __do_deliver(fr);
02744 return -1;
02745 }
02746
02747 if ((owner = iaxs[fr->callno]->owner))
02748 bridge = ast_bridged_channel(owner);
02749
02750
02751
02752 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
02753 jb_frame frame;
02754
02755
02756 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
02757 __do_deliver(frame.data);
02758
02759 if (!iaxs[fr->callno])
02760 return -1;
02761 }
02762
02763 jb_reset(iaxs[fr->callno]->jb);
02764
02765 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
02766
02767
02768 if (tsout)
02769 *tsout = fr->ts;
02770 __do_deliver(fr);
02771 return -1;
02772 }
02773
02774
02775
02776 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
02777 calc_rxstamp(iaxs[fr->callno],fr->ts));
02778 if (ret == JB_DROP) {
02779 needfree++;
02780 } else if (ret == JB_SCHED) {
02781 update_jbsched(iaxs[fr->callno]);
02782 }
02783 if (tsout)
02784 *tsout = fr->ts;
02785 if (needfree) {
02786
02787 iax2_frame_free(fr);
02788 return -1;
02789 }
02790 return 0;
02791 }
02792
02793 static int iax2_transmit(struct iax_frame *fr)
02794 {
02795
02796
02797
02798 fr->sentyet = 0;
02799 AST_LIST_LOCK(&iaxq.queue);
02800 AST_LIST_INSERT_TAIL(&iaxq.queue, fr, list);
02801 iaxq.count++;
02802 AST_LIST_UNLOCK(&iaxq.queue);
02803
02804 if (netthreadid != AST_PTHREADT_NULL)
02805 pthread_kill(netthreadid, SIGURG);
02806 signal_condition(&sched_lock, &sched_cond);
02807 return 0;
02808 }
02809
02810
02811
02812 static int iax2_digit_begin(struct ast_channel *c, char digit)
02813 {
02814 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02815 }
02816
02817 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02818 {
02819 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02820 }
02821
02822 static int iax2_sendtext(struct ast_channel *c, const char *text)
02823 {
02824
02825 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02826 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02827 }
02828
02829 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02830 {
02831 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02832 }
02833
02834 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02835 {
02836 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02837 }
02838
02839 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02840 {
02841 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02842 ast_mutex_lock(&iaxsl[callno]);
02843 if (iaxs[callno])
02844 iaxs[callno]->owner = newchan;
02845 else
02846 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02847 ast_mutex_unlock(&iaxsl[callno]);
02848 return 0;
02849 }
02850
02851
02852
02853
02854
02855 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02856 {
02857 struct ast_variable *var = NULL;
02858 struct ast_variable *tmp;
02859 struct iax2_peer *peer=NULL;
02860 time_t regseconds = 0, nowtime;
02861 int dynamic=0;
02862
02863 if (peername) {
02864 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", NULL);
02865 if (!var && sin)
02866 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02867 } else if (sin) {
02868 char porta[25];
02869 sprintf(porta, "%d", ntohs(sin->sin_port));
02870 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02871 if (var) {
02872
02873 for (tmp = var; tmp; tmp = tmp->next) {
02874 if (!strcasecmp(tmp->name, "name"))
02875 peername = tmp->value;
02876 }
02877 }
02878 }
02879 if (!var && peername) {
02880 var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02881
02882
02883
02884
02885
02886
02887 if (var && sin) {
02888 for (tmp = var; tmp; tmp = tmp->next) {
02889 if (!strcasecmp(tmp->name, "host")) {
02890 struct ast_hostent ahp;
02891 struct hostent *hp;
02892 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
02893
02894 ast_variables_destroy(var);
02895 var = NULL;
02896 }
02897 break;
02898 }
02899 }
02900 }
02901 }
02902 if (!var)
02903 return NULL;
02904
02905 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02906
02907 if (!peer) {
02908 ast_variables_destroy(var);
02909 return NULL;
02910 }
02911
02912 for (tmp = var; tmp; tmp = tmp->next) {
02913
02914 if (!strcasecmp(tmp->name, "type")) {
02915 if (strcasecmp(tmp->value, "friend") &&
02916 strcasecmp(tmp->value, "peer")) {
02917
02918 peer = peer_unref(peer);
02919 break;
02920 }
02921 } else if (!strcasecmp(tmp->name, "regseconds")) {
02922 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
02923 } else if (!strcasecmp(tmp->name, "ipaddr")) {
02924 inet_aton(tmp->value, &(peer->addr.sin_addr));
02925 } else if (!strcasecmp(tmp->name, "port")) {
02926 peer->addr.sin_port = htons(atoi(tmp->value));
02927 } else if (!strcasecmp(tmp->name, "host")) {
02928 if (!strcasecmp(tmp->value, "dynamic"))
02929 dynamic = 1;
02930 }
02931 }
02932
02933 ast_variables_destroy(var);
02934
02935 if (!peer)
02936 return NULL;
02937
02938 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02939 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02940 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02941 if (peer->expire > -1) {
02942 if (!ast_sched_del(sched, peer->expire)) {
02943 peer->expire = -1;
02944 peer_unref(peer);
02945 }
02946 }
02947 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
02948 if (peer->expire == -1)
02949 peer_unref(peer);
02950 }
02951 ao2_link(peers, peer);
02952 if (ast_test_flag(peer, IAX_DYNAMIC))
02953 reg_source_db(peer);
02954 } else {
02955 ast_set_flag(peer, IAX_TEMPONLY);
02956 }
02957
02958 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02959 time(&nowtime);
02960 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02961 memset(&peer->addr, 0, sizeof(peer->addr));
02962 realtime_update_peer(peer->name, &peer->addr, 0);
02963 if (option_debug)
02964 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02965 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02966 }
02967 else {
02968 if (option_debug)
02969 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02970 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02971 }
02972 }
02973
02974 return peer;
02975 }
02976
02977 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
02978 {
02979 struct ast_variable *var;
02980 struct ast_variable *tmp;
02981 struct iax2_user *user=NULL;
02982
02983 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", NULL);
02984 if (!var)
02985 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), NULL);
02986 if (!var && sin) {
02987 char porta[6];
02988 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
02989 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02990 if (!var)
02991 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02992 }
02993 if (!var) {
02994 var = ast_load_realtime("iaxusers", "name", username, NULL);
02995
02996
02997
02998
02999
03000
03001 if (var) {
03002 for (tmp = var; tmp; tmp = tmp->next) {
03003 if (!strcasecmp(tmp->name, "host")) {
03004 struct ast_hostent ahp;
03005 struct hostent *hp;
03006 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03007
03008 ast_variables_destroy(var);
03009 var = NULL;
03010 }
03011 break;
03012 }
03013 }
03014 }
03015 }
03016 if (!var)
03017 return NULL;
03018
03019 tmp = var;
03020 while(tmp) {
03021
03022 if (!strcasecmp(tmp->name, "type")) {
03023 if (strcasecmp(tmp->value, "friend") &&
03024 strcasecmp(tmp->value, "user")) {
03025 return NULL;
03026 }
03027 }
03028 tmp = tmp->next;
03029 }
03030
03031 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03032
03033 ast_variables_destroy(var);
03034
03035 if (!user)
03036 return NULL;
03037
03038 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03039 ast_set_flag(user, IAX_RTCACHEFRIENDS);
03040 ao2_link(users, user);
03041 } else {
03042 ast_set_flag(user, IAX_TEMPONLY);
03043 }
03044
03045 return user;
03046 }
03047
03048 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
03049 {
03050 char port[10];
03051 char regseconds[20];
03052
03053 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03054 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03055 ast_update_realtime("iaxpeers", "name", peername,
03056 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
03057 "regseconds", regseconds, NULL);
03058 }
03059
03060 struct create_addr_info {
03061 int capability;
03062 unsigned int flags;
03063 int maxtime;
03064 int encmethods;
03065 int found;
03066 int sockfd;
03067 int adsi;
03068 char username[80];
03069 char secret[80];
03070 char outkey[80];
03071 char timezone[80];
03072 char prefs[32];
03073 char context[AST_MAX_CONTEXT];
03074 char peercontext[AST_MAX_CONTEXT];
03075 char mohinterpret[MAX_MUSICCLASS];
03076 char mohsuggest[MAX_MUSICCLASS];
03077 };
03078
03079 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03080 {
03081 struct ast_hostent ahp;
03082 struct hostent *hp;
03083 struct iax2_peer *peer;
03084 int res = -1;
03085 struct ast_codec_pref ourprefs;
03086
03087 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03088 cai->sockfd = defaultsockfd;
03089 cai->maxtime = 0;
03090 sin->sin_family = AF_INET;
03091
03092 if (!(peer = find_peer(peername, 1))) {
03093 cai->found = 0;
03094
03095 hp = ast_gethostbyname(peername, &ahp);
03096 if (hp) {
03097 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
03098 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03099
03100
03101 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03102 if (c)
03103 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03104 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03105 return 0;
03106 } else {
03107 ast_log(LOG_WARNING, "No such host: %s\n", peername);
03108 return -1;
03109 }
03110 }
03111
03112 cai->found = 1;
03113
03114
03115 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03116 goto return_unref;
03117
03118
03119 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03120 goto return_unref;
03121
03122 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03123 cai->maxtime = peer->maxms;
03124 cai->capability = peer->capability;
03125 cai->encmethods = peer->encmethods;
03126 cai->sockfd = peer->sockfd;
03127 cai->adsi = peer->adsi;
03128 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03129
03130 if (c) {
03131 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03132 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03133 }
03134 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03135 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03136 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03137 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03138 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03139 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03140 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03141 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03142 if (ast_strlen_zero(peer->dbsecret)) {
03143 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03144 } else {
03145 char *family;
03146 char *key = NULL;
03147
03148 family = ast_strdupa(peer->dbsecret);
03149 key = strchr(family, '/');
03150 if (key)
03151 *key++ = '\0';
03152 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03153 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03154 goto return_unref;
03155 }
03156 }
03157
03158 if (peer->addr.sin_addr.s_addr) {
03159 sin->sin_addr = peer->addr.sin_addr;
03160 sin->sin_port = peer->addr.sin_port;
03161 } else {
03162 sin->sin_addr = peer->defaddr.sin_addr;
03163 sin->sin_port = peer->defaddr.sin_port;
03164 }
03165
03166 res = 0;
03167
03168 return_unref:
03169 peer_unref(peer);
03170
03171 return res;
03172 }
03173
03174 static void __auto_congest(const void *nothing)
03175 {
03176 int callno = PTR_TO_CALLNO(nothing);
03177 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03178 ast_mutex_lock(&iaxsl[callno]);
03179 if (iaxs[callno]) {
03180 iaxs[callno]->initid = -1;
03181 iax2_queue_frame(callno, &f);
03182 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03183 }
03184 ast_mutex_unlock(&iaxsl[callno]);
03185 }
03186
03187 static int auto_congest(const void *data)
03188 {
03189 #ifdef SCHED_MULTITHREADED
03190 if (schedule_action(__auto_congest, data))
03191 #endif
03192 __auto_congest(data);
03193 return 0;
03194 }
03195
03196 static unsigned int iax2_datetime(const char *tz)
03197 {
03198 time_t t;
03199 struct tm tm;
03200 unsigned int tmp;
03201 time(&t);
03202 if (!ast_strlen_zero(tz))
03203 ast_localtime(&t, &tm, tz);
03204 else
03205 ast_localtime(&t, &tm, NULL);
03206 tmp = (tm.tm_sec >> 1) & 0x1f;
03207 tmp |= (tm.tm_min & 0x3f) << 5;
03208 tmp |= (tm.tm_hour & 0x1f) << 11;
03209 tmp |= (tm.tm_mday & 0x1f) << 16;
03210 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
03211 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
03212 return tmp;
03213 }
03214
03215 struct parsed_dial_string {
03216 char *username;
03217 char *password;
03218 char *key;
03219 char *peer;
03220 char *port;
03221 char *exten;
03222 char *context;
03223 char *options;
03224 };
03225
03226 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03227 {
03228 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03229 .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX,
03230 .csub = compress_subclass(command) };
03231
03232 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03233 }
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03254 {
03255 if (ast_strlen_zero(data))
03256 return;
03257
03258 pds->peer = strsep(&data, "/");
03259 pds->exten = strsep(&data, "/");
03260 pds->options = data;
03261
03262 if (pds->exten) {
03263 data = pds->exten;
03264 pds->exten = strsep(&data, "@");
03265 pds->context = data;
03266 }
03267
03268 if (strchr(pds->peer, '@')) {
03269 data = pds->peer;
03270 pds->username = strsep(&data, "@");
03271 pds->peer = data;
03272 }
03273
03274 if (pds->username) {
03275 data = pds->username;
03276 pds->username = strsep(&data, ":");
03277 pds->password = data;
03278 }
03279
03280 data = pds->peer;
03281 pds->peer = strsep(&data, ":");
03282 pds->port = data;
03283
03284
03285
03286
03287 if (pds->password && (pds->password[0] == '[')) {
03288 pds->key = ast_strip_quoted(pds->password, "[", "]");
03289 pds->password = NULL;
03290 }
03291 }
03292
03293 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03294 {
03295 struct sockaddr_in sin;
03296 char *l=NULL, *n=NULL, *tmpstr;
03297 struct iax_ie_data ied;
03298 char *defaultrdest = "s";
03299 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03300 struct parsed_dial_string pds;
03301 struct create_addr_info cai;
03302
03303 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03304 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03305 return -1;
03306 }
03307
03308 memset(&cai, 0, sizeof(cai));
03309 cai.encmethods = iax2_encryption;
03310
03311 memset(&pds, 0, sizeof(pds));
03312 tmpstr = ast_strdupa(dest);
03313 parse_dial_string(tmpstr, &pds);
03314
03315 if (ast_strlen_zero(pds.peer)) {
03316 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03317 return -1;
03318 }
03319
03320 if (!pds.exten) {
03321 pds.exten = defaultrdest;
03322 }
03323
03324 if (create_addr(pds.peer, c, &sin, &cai)) {
03325 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03326 return -1;
03327 }
03328
03329 if (!pds.username && !ast_strlen_zero(cai.username))
03330 pds.username = cai.username;
03331 if (!pds.password && !ast_strlen_zero(cai.secret))
03332 pds.password = cai.secret;
03333 if (!pds.key && !ast_strlen_zero(cai.outkey))
03334 pds.key = cai.outkey;
03335 if (!pds.context && !ast_strlen_zero(cai.peercontext))
03336 pds.context = cai.peercontext;
03337
03338
03339 ast_copy_string(c->context, cai.context, sizeof(c->context));
03340
03341 if (pds.port)
03342 sin.sin_port = htons(atoi(pds.port));
03343
03344 l = c->cid.cid_num;
03345 n = c->cid.cid_name;
03346
03347
03348 memset(&ied, 0, sizeof(ied));
03349
03350
03351 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03352 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03353 if (pds.options && strchr(pds.options, 'a')) {
03354
03355 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03356 }
03357
03358 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03359
03360 if (l) {
03361 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03362 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03363 } else {
03364 if (n)
03365 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03366 else
03367 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03368 }
03369
03370 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03371 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03372
03373 if (n)
03374 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03375 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03376 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03377
03378 if (!ast_strlen_zero(c->language))
03379 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03380 if (!ast_strlen_zero(c->cid.cid_dnid))
03381 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03382 if (!ast_strlen_zero(c->cid.cid_rdnis))
03383 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03384
03385 if (pds.context)
03386 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03387
03388 if (pds.username)
03389 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03390
03391 if (cai.encmethods)
03392 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03393
03394 ast_mutex_lock(&iaxsl[callno]);
03395
03396 if (!ast_strlen_zero(c->context))
03397 ast_string_field_set(iaxs[callno], context, c->context);
03398
03399 if (pds.username)
03400 ast_string_field_set(iaxs[callno], username, pds.username);
03401
03402 iaxs[callno]->encmethods = cai.encmethods;
03403
03404 iaxs[callno]->adsi = cai.adsi;
03405
03406 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03407 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03408
03409 if (pds.key)
03410 ast_string_field_set(iaxs[callno], outkey, pds.key);
03411 if (pds.password)
03412 ast_string_field_set(iaxs[callno], secret, pds.password);
03413
03414 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03415 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03416 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03417 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03418
03419 if (iaxs[callno]->maxtime) {
03420
03421 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03422 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03423 } else if (autokill) {
03424 iaxs[callno]->pingtime = autokill / 2;
03425 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03426 }
03427
03428
03429 iaxs[callno]->sockfd = cai.sockfd;
03430
03431
03432 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03433
03434 ast_mutex_unlock(&iaxsl[callno]);
03435 ast_setstate(c, AST_STATE_RINGING);
03436
03437 return 0;
03438 }
03439
03440 static int iax2_hangup(struct ast_channel *c)
03441 {
03442 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03443 struct iax_ie_data ied;
03444 int alreadygone;
03445 memset(&ied, 0, sizeof(ied));
03446 ast_mutex_lock(&iaxsl[callno]);
03447 if (callno && iaxs[callno]) {
03448 if (option_debug)
03449 ast_log(LOG_DEBUG, "We're hanging up %s now...\n", c->name);
03450 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03451
03452 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03453 if (!iaxs[callno]->error && !alreadygone) {
03454 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
03455 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
03456 }
03457 if (!iaxs[callno]) {
03458 ast_mutex_unlock(&iaxsl[callno]);
03459 return 0;
03460 }
03461 }
03462
03463 iax2_predestroy(callno);
03464
03465 if (iaxs[callno] && alreadygone) {
03466 if (option_debug)
03467 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
03468 iax2_destroy(callno);
03469 } else if (iaxs[callno]) {
03470 ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno));
03471 }
03472 } else if (c->tech_pvt) {
03473
03474
03475
03476
03477 c->tech_pvt = NULL;
03478 }
03479 ast_mutex_unlock(&iaxsl[callno]);
03480 if (option_verbose > 2)
03481 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
03482 return 0;
03483 }
03484
03485
03486
03487
03488 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
03489 {
03490 unsigned short callno = pvt->callno;
03491
03492 if (!pvt->peercallno) {
03493
03494 int count = 10;
03495 while (count-- && pvt && !pvt->peercallno) {
03496 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03497 pvt = iaxs[callno];
03498 }
03499 if (!pvt->peercallno) {
03500 return -1;
03501 }
03502 }
03503
03504 return 0;
03505 }
03506
03507 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03508 {
03509 struct ast_option_header *h;
03510 int res;
03511
03512 switch (option) {
03513 case AST_OPTION_TXGAIN:
03514 case AST_OPTION_RXGAIN:
03515
03516 errno = ENOSYS;
03517 return -1;
03518 default:
03519 {
03520 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03521 struct chan_iax2_pvt *pvt;
03522
03523 ast_mutex_lock(&iaxsl[callno]);
03524 pvt = iaxs[callno];
03525
03526 if (wait_for_peercallno(pvt)) {
03527 ast_mutex_unlock(&iaxsl[callno]);
03528 return -1;
03529 }
03530
03531 ast_mutex_unlock(&iaxsl[callno]);
03532
03533 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
03534 return -1;
03535 }
03536
03537 h->flag = AST_OPTION_FLAG_REQUEST;
03538 h->option = htons(option);
03539 memcpy(h->data, data, datalen);
03540 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03541 AST_CONTROL_OPTION, 0, (unsigned char *) h,
03542 datalen + sizeof(*h), -1);
03543 free(h);
03544 return res;
03545 }
03546 }
03547 }
03548
03549 static struct ast_frame *iax2_read(struct ast_channel *c)
03550 {
03551 ast_log(LOG_NOTICE, "I should never be called! Hanging up.\n");
03552 return NULL;
03553 }
03554
03555 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03556 {
03557 int res;
03558 struct iax_ie_data ied0;
03559 struct iax_ie_data ied1;
03560 unsigned int transferid = (unsigned int)ast_random();
03561 memset(&ied0, 0, sizeof(ied0));
03562 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03563 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03564 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03565
03566 memset(&ied1, 0, sizeof(ied1));
03567 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03568 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03569 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03570
03571 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03572 if (res)
03573 return -1;
03574 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03575 if (res)
03576 return -1;
03577 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03578 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03579 return 0;
03580 }
03581
03582 static void lock_both(unsigned short callno0, unsigned short callno1)
03583 {
03584 ast_mutex_lock(&iaxsl[callno0]);
03585 while (ast_mutex_trylock(&iaxsl[callno1])) {
03586 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03587 }
03588 }
03589
03590 static void unlock_both(unsigned short callno0, unsigned short callno1)
03591 {
03592 ast_mutex_unlock(&iaxsl[callno1]);
03593 ast_mutex_unlock(&iaxsl[callno0]);
03594 }
03595
03596 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)
03597 {
03598 struct ast_channel *cs[3];
03599 struct ast_channel *who, *other;
03600 int to = -1;
03601 int res = -1;
03602 int transferstarted=0;
03603 struct ast_frame *f;
03604 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03605 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03606 struct timeval waittimer = {0, 0}, tv;
03607
03608 lock_both(callno0, callno1);
03609 if (!iaxs[callno0] || !iaxs[callno1]) {
03610 unlock_both(callno0, callno1);
03611 return AST_BRIDGE_FAILED;
03612 }
03613
03614 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03615 iaxs[callno0]->bridgecallno = callno1;
03616 iaxs[callno1]->bridgecallno = callno0;
03617 }
03618
03619 if (iaxs[callno0]->transferring && iaxs[callno1]->transferring) {
03620 transferstarted = 1;
03621 }
03622 unlock_both(callno0, callno1);
03623
03624
03625 cs[0] = c0;
03626 cs[1] = c1;
03627 for (;;) {
03628
03629 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03630 if (option_verbose > 2)
03631 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03632
03633 if (c0->tech == &iax2_tech) {
03634 ast_mutex_lock(&iaxsl[callno0]);
03635 iaxs[callno0]->bridgecallno = 0;
03636 ast_mutex_unlock(&iaxsl[callno0]);
03637 }
03638 if (c1->tech == &iax2_tech) {
03639 ast_mutex_lock(&iaxsl[callno1]);
03640 iaxs[callno1]->bridgecallno = 0;
03641 ast_mutex_unlock(&iaxsl[callno1]);
03642 }
03643 return AST_BRIDGE_FAILED_NOWARN;
03644 }
03645 if (c0->nativeformats != c1->nativeformats) {
03646 if (option_verbose > 2) {
03647 char buf0[255];
03648 char buf1[255];
03649 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03650 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03651 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03652 }
03653
03654 lock_both(callno0, callno1);
03655 if (iaxs[callno0])
03656 iaxs[callno0]->bridgecallno = 0;
03657 if (iaxs[callno1])
03658 iaxs[callno1]->bridgecallno = 0;
03659 unlock_both(callno0, callno1);
03660 return AST_BRIDGE_FAILED_NOWARN;
03661 }
03662
03663 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03664
03665 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03666 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03667 ast_log(LOG_WARNING, "Unable to start the transfer\n");
03668 transferstarted = 1;
03669 }
03670 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03671
03672 gettimeofday(&tv, NULL);
03673 if (ast_tvzero(waittimer)) {
03674 waittimer = tv;
03675 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03676 c0->_softhangup |= AST_SOFTHANGUP_DEV;
03677 c1->_softhangup |= AST_SOFTHANGUP_DEV;
03678 *fo = NULL;
03679 *rc = c0;
03680 res = AST_BRIDGE_COMPLETE;
03681 break;
03682 }
03683 }
03684 to = 1000;
03685 who = ast_waitfor_n(cs, 2, &to);
03686 if (timeoutms > -1) {
03687 timeoutms -= (1000 - to);
03688 if (timeoutms < 0)
03689 timeoutms = 0;
03690 }
03691 if (!who) {
03692 if (!timeoutms) {
03693 res = AST_BRIDGE_RETRY;
03694 break;
03695 }
03696 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03697 res = AST_BRIDGE_FAILED;
03698 break;
03699 }
03700 continue;
03701 }
03702 f = ast_read(who);
03703 if (!f) {
03704 *fo = NULL;
03705 *rc = who;
03706 res = AST_BRIDGE_COMPLETE;
03707 break;
03708 }
03709 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03710 *fo = f;
03711 *rc = who;
03712 res = AST_BRIDGE_COMPLETE;
03713 break;
03714 }
03715 other = (who == c0) ? c1 : c0;
03716 if ((f->frametype == AST_FRAME_VOICE) ||
03717 (f->frametype == AST_FRAME_TEXT) ||
03718 (f->frametype == AST_FRAME_VIDEO) ||
03719 (f->frametype == AST_FRAME_IMAGE) ||
03720 (f->frametype == AST_FRAME_DTMF)) {
03721
03722
03723
03724 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03725 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03726 *rc = who;
03727 *fo = f;
03728 res = AST_BRIDGE_COMPLETE;
03729
03730 break;
03731 }
03732
03733 ast_write(other, f);
03734 }
03735 ast_frfree(f);
03736
03737 cs[2] = cs[0];
03738 cs[0] = cs[1];
03739 cs[1] = cs[2];
03740 }
03741 lock_both(callno0, callno1);
03742 if(iaxs[callno0])
03743 iaxs[callno0]->bridgecallno = 0;
03744 if(iaxs[callno1])
03745 iaxs[callno1]->bridgecallno = 0;
03746 unlock_both(callno0, callno1);
03747 return res;
03748 }
03749
03750 static int iax2_answer(struct ast_channel *c)
03751 {
03752 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03753 if (option_debug)
03754 ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03755 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03756 }
03757
03758 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03759 {
03760 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03761 struct chan_iax2_pvt *pvt;
03762 int res = 0;
03763
03764 if (option_debug && iaxdebug)
03765 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03766
03767 ast_mutex_lock(&iaxsl[callno]);
03768 pvt = iaxs[callno];
03769
03770 if (wait_for_peercallno(pvt)) {
03771 res = -1;
03772 goto done;
03773 }
03774
03775 switch (condition) {
03776 case AST_CONTROL_HOLD:
03777 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03778 ast_moh_start(c, data, pvt->mohinterpret);
03779 goto done;
03780 }
03781 break;
03782 case AST_CONTROL_UNHOLD:
03783 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03784 ast_moh_stop(c);
03785 goto done;
03786 }
03787 }
03788
03789 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03790
03791 done:
03792 ast_mutex_unlock(&iaxsl[callno]);
03793
03794 return res;
03795 }
03796
03797 static int iax2_transfer(struct ast_channel *c, const char *dest)
03798 {
03799 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03800 struct iax_ie_data ied;
03801 char tmp[256], *context;
03802 ast_copy_string(tmp, dest, sizeof(tmp));
03803 context = strchr(tmp, '@');
03804 if (context) {
03805 *context = '\0';
03806 context++;
03807 }
03808 memset(&ied, 0, sizeof(ied));
03809 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03810 if (context)
03811 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03812 if (option_debug)
03813 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03814 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03815 }
03816
03817 static int iax2_getpeertrunk(struct sockaddr_in sin)
03818 {
03819 struct iax2_peer *peer;
03820 int res = 0;
03821 struct ao2_iterator i;
03822
03823 i = ao2_iterator_init(peers, 0);
03824 while ((peer = ao2_iterator_next(&i))) {
03825 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03826 (peer->addr.sin_port == sin.sin_port)) {
03827 res = ast_test_flag(peer, IAX_TRUNK);
03828 peer_unref(peer);
03829 break;
03830 }
03831 peer_unref(peer);
03832 }
03833
03834 return res;
03835 }
03836
03837
03838 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03839 {
03840 struct ast_channel *tmp;
03841 struct chan_iax2_pvt *i;
03842 struct ast_variable *v = NULL;
03843
03844 if (!(i = iaxs[callno])) {
03845 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03846 return NULL;
03847 }
03848
03849
03850 ast_mutex_unlock(&iaxsl[callno]);
03851 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);
03852 ast_mutex_lock(&iaxsl[callno]);
03853 if (i != iaxs[callno]) {
03854 if (tmp) {
03855
03856 ast_mutex_unlock(&iaxsl[callno]);
03857 ast_channel_free(tmp);
03858 ast_mutex_lock(&iaxsl[callno]);
03859 }
03860 return NULL;
03861 }
03862
03863 if (!tmp)
03864 return NULL;
03865 tmp->tech = &iax2_tech;
03866
03867 tmp->nativeformats = capability;
03868 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
03869 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
03870 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03871
03872
03873
03874 if (!ast_strlen_zero(i->ani))
03875 tmp->cid.cid_ani = ast_strdup(i->ani);
03876 else
03877 tmp->cid.cid_ani = ast_strdup(i->cid_num);
03878 tmp->cid.cid_dnid = ast_strdup(i->dnid);
03879 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03880 tmp->cid.cid_pres = i->calling_pres;
03881 tmp->cid.cid_ton = i->calling_ton;
03882 tmp->cid.cid_tns = i->calling_tns;
03883 if (!ast_strlen_zero(i->language))
03884 ast_string_field_set(tmp, language, i->language);
03885 if (!ast_strlen_zero(i->accountcode))
03886 ast_string_field_set(tmp, accountcode, i->accountcode);
03887 if (i->amaflags)
03888 tmp->amaflags = i->amaflags;
03889 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03890 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03891 if (i->adsi)
03892 tmp->adsicpe = i->peeradsicpe;
03893 else
03894 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03895 i->owner = tmp;
03896 i->capability = capability;
03897
03898 for (v = i->vars ; v ; v = v->next)
03899 pbx_builtin_setvar_helper(tmp, v->name, v->value);
03900
03901 if (state != AST_STATE_DOWN) {
03902 if (ast_pbx_start(tmp)) {
03903 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03904 ast_hangup(tmp);
03905 i->owner = NULL;
03906 return NULL;
03907 }
03908 }
03909
03910 ast_module_ref(ast_module_info->self);
03911
03912 return tmp;
03913 }
03914
03915 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03916 {
03917 unsigned long int mssincetx;
03918 long int ms, pred;
03919
03920 tpeer->trunkact = *tv;
03921 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03922 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03923
03924 tpeer->txtrunktime = *tv;
03925 tpeer->lastsent = 999999;
03926 }
03927
03928 tpeer->lasttxtime = *tv;
03929
03930
03931 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03932
03933 pred = tpeer->lastsent + sampms;
03934 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03935 ms = pred;
03936
03937
03938 if (ms == tpeer->lastsent)
03939 ms = tpeer->lastsent + 1;
03940 tpeer->lastsent = ms;
03941 return ms;
03942 }
03943
03944 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03945 {
03946 long ms;
03947 if (ast_tvzero(iaxs[callno]->rxcore)) {
03948
03949 gettimeofday(&iaxs[callno]->rxcore, NULL);
03950
03951 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03952 }
03953
03954 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03955
03956 return ms + ts;
03957 }
03958
03959 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03960 {
03961 int ms;
03962 int voice = 0;
03963 int genuine = 0;
03964 int adjust;
03965 struct timeval *delivery = NULL;
03966
03967
03968
03969
03970
03971
03972
03973
03974 if (f) {
03975 if (f->frametype == AST_FRAME_VOICE) {
03976 voice = 1;
03977 delivery = &f->delivery;
03978 } else if (f->frametype == AST_FRAME_IAX) {
03979 genuine = 1;
03980 } else if (f->frametype == AST_FRAME_CNG) {
03981 p->notsilenttx = 0;
03982 }
03983 }
03984 if (ast_tvzero(p->offset)) {
03985 gettimeofday(&p->offset, NULL);
03986
03987 p->offset.tv_usec -= p->offset.tv_usec % 20000;
03988 }
03989
03990 if (ts)
03991 return ts;
03992
03993 if (delivery && !ast_tvzero(*delivery)) {
03994 ms = ast_tvdiff_ms(*delivery, p->offset);
03995 if (option_debug > 2 && iaxdebug)
03996 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03997 } else {
03998 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03999 if (ms < 0)
04000 ms = 0;
04001 if (voice) {
04002
04003 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
04004
04005
04006
04007
04008
04009
04010
04011
04012
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022 adjust = (ms - p->nextpred);
04023 if (adjust < 0)
04024 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
04025 else if (adjust > 0)
04026 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
04027
04028 if (!p->nextpred) {
04029 p->nextpred = ms;
04030 if (p->nextpred <= p->lastsent)
04031 p->nextpred = p->lastsent + 3;
04032 }
04033 ms = p->nextpred;
04034 } else {
04035
04036
04037
04038
04039
04040
04041
04042
04043
04044 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
04045 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
04046 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
04047
04048 if (f->samples >= 8)
04049 {
04050 int diff = ms % (f->samples / 8);
04051 if (diff)
04052 ms += f->samples/8 - diff;
04053 }
04054
04055 p->nextpred = ms;
04056 p->notsilenttx = 1;
04057 }
04058 } else if ( f->frametype == AST_FRAME_VIDEO ) {
04059
04060
04061
04062
04063
04064
04065
04066
04067 if ( (unsigned int)ms < p->lastsent )
04068 ms = p->lastsent;
04069 } else {
04070
04071
04072 if (genuine) {
04073
04074 if (ms <= p->lastsent)
04075 ms = p->lastsent + 3;
04076 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
04077
04078 ms = p->lastsent + 3;
04079 }
04080 }
04081 }
04082 p->lastsent = ms;
04083 if (voice)
04084 p->nextpred = p->nextpred + f->samples / 8;
04085 return ms;
04086 }
04087
04088 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
04089 {
04090
04091
04092 int ms;
04093 #ifdef IAXTESTS
04094 int jit;
04095 #endif
04096
04097 if (ast_tvzero(p->rxcore)) {
04098 p->rxcore = ast_tvnow();
04099 if (option_debug && iaxdebug)
04100 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04101 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04102 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04103 #if 1
04104 if (option_debug && iaxdebug)
04105 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04106 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04107 #endif
04108 }
04109
04110 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04111 #ifdef IAXTESTS
04112 if (test_jit) {
04113 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04114 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04115 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04116 jit = -jit;
04117 ms += jit;
04118 }
04119 }
04120 if (test_late) {
04121 ms += test_late;
04122 test_late = 0;
04123 }
04124 #endif
04125 return ms;
04126 }
04127
04128 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04129 {
04130 struct iax2_trunk_peer *tpeer;
04131
04132
04133 ast_mutex_lock(&tpeerlock);
04134 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04135
04136 if (!inaddrcmp(&tpeer->addr, sin)) {
04137 ast_mutex_lock(&tpeer->lock);
04138 break;
04139 }
04140 }
04141 if (!tpeer) {
04142 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04143 ast_mutex_init(&tpeer->lock);
04144 tpeer->lastsent = 9999;
04145 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04146 tpeer->trunkact = ast_tvnow();
04147 ast_mutex_lock(&tpeer->lock);
04148 tpeer->next = tpeers;
04149 tpeer->sockfd = fd;
04150 tpeers = tpeer;
04151 #ifdef SO_NO_CHECK
04152 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04153 #endif
04154 if (option_debug)
04155 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04156 }
04157 }
04158 ast_mutex_unlock(&tpeerlock);
04159 return tpeer;
04160 }
04161
04162 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04163 {
04164 struct ast_frame *f;
04165 struct iax2_trunk_peer *tpeer;
04166 void *tmp, *ptr;
04167 struct ast_iax2_meta_trunk_entry *met;
04168 struct ast_iax2_meta_trunk_mini *mtm;
04169
04170 f = &fr->af;
04171 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04172 if (tpeer) {
04173 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04174
04175 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04176 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04177 ast_mutex_unlock(&tpeer->lock);
04178 return -1;
04179 }
04180
04181 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04182 tpeer->trunkdata = tmp;
04183 if (option_debug)
04184 ast_log(LOG_DEBUG, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
04185 } else {
04186 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));
04187 ast_mutex_unlock(&tpeer->lock);
04188 return -1;
04189 }
04190 }
04191
04192
04193 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04194 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04195 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04196 mtm->len = htons(f->datalen);
04197 mtm->mini.callno = htons(pvt->callno);
04198 mtm->mini.ts = htons(0xffff & fr->ts);
04199 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04200 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04201 } else {
04202 met = (struct ast_iax2_meta_trunk_entry *)ptr;
04203
04204 met->callno = htons(pvt->callno);
04205 met->len = htons(f->datalen);
04206
04207 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04208 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04209 }
04210
04211 memcpy(ptr, f->data, f->datalen);
04212 tpeer->trunkdatalen += f->datalen;
04213
04214 tpeer->calls++;
04215 ast_mutex_unlock(&tpeer->lock);
04216 }
04217 return 0;
04218 }
04219
04220 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
04221 {
04222 aes_encrypt_key128(digest, ecx);
04223 aes_decrypt_key128(digest, dcx);
04224 }
04225
04226 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04227 {
04228 #if 0
04229
04230 int x;
04231 if (len % 16)
04232 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04233 for (x=0;x<len;x++)
04234 dst[x] = src[x] ^ 0xff;
04235 #else
04236 unsigned char lastblock[16] = { 0 };
04237 int x;
04238 while(len > 0) {
04239 aes_decrypt(src, dst, dcx);
04240 for (x=0;x<16;x++)
04241 dst[x] ^= lastblock[x];
04242 memcpy(lastblock, src, sizeof(lastblock));
04243 dst += 16;
04244 src += 16;
04245 len -= 16;
04246 }
04247 #endif
04248 }
04249
04250 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04251 {
04252 #if 0
04253
04254 int x;
04255 if (len % 16)
04256 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04257 for (x=0;x<len;x++)
04258 dst[x] = src[x] ^ 0xff;
04259 #else
04260 unsigned char curblock[16] = { 0 };
04261 int x;
04262 while(len > 0) {
04263 for (x=0;x<16;x++)
04264 curblock[x] ^= src[x];
04265 aes_encrypt(curblock, dst, ecx);
04266 memcpy(curblock, dst, sizeof(curblock));
04267 dst += 16;
04268 src += 16;
04269 len -= 16;
04270 }
04271 #endif
04272 }
04273
04274 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04275 {
04276 int padding;
04277 unsigned char *workspace;
04278
04279 workspace = alloca(*datalen);
04280 memset(f, 0, sizeof(*f));
04281 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04282 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04283 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04284 return -1;
04285
04286 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04287
04288 padding = 16 + (workspace[15] & 0xf);
04289 if (option_debug && iaxdebug)
04290 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04291 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04292 return -1;
04293
04294 *datalen -= padding;
04295 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04296 f->frametype = fh->type;
04297 if (f->frametype == AST_FRAME_VIDEO) {
04298 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04299 } else {
04300 f->subclass = uncompress_subclass(fh->csub);
04301 }
04302 } else {
04303 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04304 if (option_debug && iaxdebug)
04305 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04306 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04307 return -1;
04308
04309 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04310 padding = 16 + (workspace[15] & 0x0f);
04311 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04312 return -1;
04313 *datalen -= padding;
04314 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04315 }
04316 return 0;
04317 }
04318
04319 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04320 {
04321 int padding;
04322 unsigned char *workspace;
04323 workspace = alloca(*datalen + 32);
04324 if (!workspace)
04325 return -1;
04326 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04327 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04328 if (option_debug && iaxdebug)
04329 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04330 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04331 padding = 16 + (padding & 0xf);
04332 memcpy(workspace, poo, padding);
04333 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04334 workspace[15] &= 0xf0;
04335 workspace[15] |= (padding & 0xf);
04336 if (option_debug && iaxdebug)
04337 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
04338 *datalen += padding;
04339 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04340 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04341 memcpy(poo, workspace + *datalen - 32, 32);
04342 } else {
04343 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04344 if (option_debug && iaxdebug)
04345 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04346 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04347 padding = 16 + (padding & 0xf);
04348 memcpy(workspace, poo, padding);
04349 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04350 workspace[15] &= 0xf0;
04351 workspace[15] |= (padding & 0x0f);
04352 *datalen += padding;
04353 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04354 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04355 memcpy(poo, workspace + *datalen - 32, 32);
04356 }
04357 return 0;
04358 }
04359
04360 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04361 {
04362 int res=-1;
04363 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04364
04365 struct MD5Context md5;
04366 unsigned char digest[16];
04367 char *tmppw, *stringp;
04368
04369 tmppw = ast_strdupa(iaxs[callno]->secret);
04370 stringp = tmppw;
04371 while ((tmppw = strsep(&stringp, ";"))) {
04372 MD5Init(&md5);
04373 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04374 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04375 MD5Final(digest, &md5);
04376 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04377 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04378 if (!res) {
04379 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04380 break;
04381 }
04382 }
04383 } else
04384 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04385 return res;
04386 }
04387
04388 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04389 {
04390
04391
04392
04393 struct ast_iax2_full_hdr *fh;
04394 struct ast_iax2_mini_hdr *mh;
04395 struct ast_iax2_video_hdr *vh;
04396 struct {
04397 struct iax_frame fr2;
04398 unsigned char buffer[4096];
04399 } frb;
04400 struct iax_frame *fr;
04401 int res;
04402 int sendmini=0;
04403 unsigned int lastsent;
04404 unsigned int fts;
04405
04406 frb.fr2.afdatalen = sizeof(frb.buffer);
04407
04408 if (!pvt) {
04409 ast_log(LOG_WARNING, "No private structure for packet?\n");
04410 return -1;
04411 }
04412
04413 lastsent = pvt->lastsent;
04414
04415
04416 fts = calc_timestamp(pvt, ts, f);
04417
04418
04419
04420
04421 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04422 return 0;
04423
04424
04425 if ((ast_test_flag(pvt, IAX_TRUNK) ||
04426 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04427 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04428 &&
04429 (f->frametype == AST_FRAME_VOICE)
04430 &&
04431 (f->subclass == pvt->svoiceformat)
04432 ) {
04433
04434 now = 1;
04435
04436 sendmini = 1;
04437 }
04438 if ( f->frametype == AST_FRAME_VIDEO ) {
04439
04440
04441
04442
04443
04444 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04445 ((f->subclass & ~0x1) == pvt->svideoformat)
04446 ) {
04447 now = 1;
04448 sendmini = 1;
04449 } else {
04450 now = 0;
04451 sendmini = 0;
04452 }
04453 pvt->lastvsent = fts;
04454 }
04455
04456 if (now) {
04457 fr = &frb.fr2;
04458 } else
04459 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));
04460 if (!fr) {
04461 ast_log(LOG_WARNING, "Out of memory\n");
04462 return -1;
04463 }
04464
04465 iax_frame_wrap(fr, f);
04466
04467 fr->ts = fts;
04468 fr->callno = pvt->callno;
04469 fr->transfer = transfer;
04470 fr->final = final;
04471 if (!sendmini) {
04472
04473 if (seqno > -1)
04474 fr->oseqno = seqno;
04475 else
04476 fr->oseqno = pvt->oseqno++;
04477 fr->iseqno = pvt->iseqno;
04478 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04479 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04480 fh->ts = htonl(fr->ts);
04481 fh->oseqno = fr->oseqno;
04482 if (transfer) {
04483 fh->iseqno = 0;
04484 } else
04485 fh->iseqno = fr->iseqno;
04486
04487 if (!transfer)
04488 pvt->aseqno = fr->iseqno;
04489 fh->type = fr->af.frametype & 0xFF;
04490 if (fr->af.frametype == AST_FRAME_VIDEO)
04491 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04492 else
04493 fh->csub = compress_subclass(fr->af.subclass);
04494 if (transfer) {
04495 fr->dcallno = pvt->transfercallno;
04496 } else
04497 fr->dcallno = pvt->peercallno;
04498 fh->dcallno = htons(fr->dcallno);
04499 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04500 fr->data = fh;
04501 fr->retries = 0;
04502
04503 fr->retrytime = pvt->pingtime * 2;
04504 if (fr->retrytime < MIN_RETRY_TIME)
04505 fr->retrytime = MIN_RETRY_TIME;
04506 if (fr->retrytime > MAX_RETRY_TIME)
04507 fr->retrytime = MAX_RETRY_TIME;
04508
04509 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04510 fr->retries = -1;
04511 else if (f->frametype == AST_FRAME_VOICE)
04512 pvt->svoiceformat = f->subclass;
04513 else if (f->frametype == AST_FRAME_VIDEO)
04514 pvt->svideoformat = f->subclass & ~0x1;
04515 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04516 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04517 if (iaxdebug) {
04518 if (fr->transfer)
04519 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04520 else
04521 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04522 }
04523 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04524 } else
04525 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04526 }
04527
04528 if (now) {
04529 res = send_packet(fr);
04530 } else
04531 res = iax2_transmit(fr);
04532 } else {
04533 if (ast_test_flag(pvt, IAX_TRUNK)) {
04534 iax2_trunk_queue(pvt, fr);
04535 res = 0;
04536 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04537
04538 fr->oseqno = -1;
04539 fr->iseqno = -1;
04540 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04541 vh->zeros = 0;
04542 vh->callno = htons(0x8000 | fr->callno);
04543 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04544 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04545 fr->data = vh;
04546 fr->retries = -1;
04547 res = send_packet(fr);
04548 } else {
04549
04550 fr->oseqno = -1;
04551 fr->iseqno = -1;
04552
04553 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04554 mh->callno = htons(fr->callno);
04555 mh->ts = htons(fr->ts & 0xFFFF);
04556 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04557 fr->data = mh;
04558 fr->retries = -1;
04559 if (pvt->transferring == TRANSFER_MEDIAPASS)
04560 fr->transfer = 1;
04561 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04562 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04563 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04564 } else
04565 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04566 }
04567 res = send_packet(fr);
04568 }
04569 }
04570 return res;
04571 }
04572
04573 static int iax2_show_users(int fd, int argc, char *argv[])
04574 {
04575 regex_t regexbuf;
04576 int havepattern = 0;
04577
04578 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
04579 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
04580
04581 struct iax2_user *user = NULL;
04582 char auth[90];
04583 char *pstr = "";
04584 struct ao2_iterator i;
04585
04586 switch (argc) {
04587 case 5:
04588 if (!strcasecmp(argv[3], "like")) {
04589 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04590 return RESULT_SHOWUSAGE;
04591 havepattern = 1;
04592 } else
04593 return RESULT_SHOWUSAGE;
04594 case 3:
04595 break;
04596 default:
04597 return RESULT_SHOWUSAGE;
04598 }
04599
04600 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04601 i = ao2_iterator_init(users, 0);
04602 for (user = ao2_iterator_next(&i); user;
04603 user_unref(user), user = ao2_iterator_next(&i)) {
04604 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
04605 continue;
04606
04607 if (!ast_strlen_zero(user->secret)) {
04608 ast_copy_string(auth,user->secret,sizeof(auth));
04609 } else if (!ast_strlen_zero(user->inkeys)) {
04610 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04611 } else
04612 ast_copy_string(auth, "-no secret-", sizeof(auth));
04613
04614 if(ast_test_flag(user,IAX_CODEC_NOCAP))
04615 pstr = "REQ Only";
04616 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04617 pstr = "Disabled";
04618 else
04619 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04620
04621 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods,
04622 user->contexts ? user->contexts->context : context,
04623 user->ha ? "Yes" : "No", pstr);
04624 }
04625
04626 if (havepattern)
04627 regfree(®exbuf);
04628
04629 return RESULT_SUCCESS;
04630 #undef FORMAT
04631 #undef FORMAT2
04632 }
04633
04634 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04635 {
04636 regex_t regexbuf;
04637 int havepattern = 0;
04638 int total_peers = 0;
04639 int online_peers = 0;
04640 int offline_peers = 0;
04641 int unmonitored_peers = 0;
04642 struct ao2_iterator i;
04643
04644 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
04645 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
04646
04647 struct iax2_peer *peer = NULL;
04648 char name[256];
04649 int registeredonly=0;
04650 char *term = manager ? "\r\n" : "\n";
04651
04652 switch (argc) {
04653 case 6:
04654 if (!strcasecmp(argv[3], "registered"))
04655 registeredonly = 1;
04656 else
04657 return RESULT_SHOWUSAGE;
04658 if (!strcasecmp(argv[4], "like")) {
04659 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04660 return RESULT_SHOWUSAGE;
04661 havepattern = 1;
04662 } else
04663 return RESULT_SHOWUSAGE;
04664 break;
04665 case 5:
04666 if (!strcasecmp(argv[3], "like")) {
04667 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04668 return RESULT_SHOWUSAGE;
04669 havepattern = 1;
04670 } else
04671 return RESULT_SHOWUSAGE;
04672 break;
04673 case 4:
04674 if (!strcasecmp(argv[3], "registered"))
04675 registeredonly = 1;
04676 else
04677 return RESULT_SHOWUSAGE;
04678 break;
04679 case 3:
04680 break;
04681 default:
04682 return RESULT_SHOWUSAGE;
04683 }
04684
04685
04686 if (s)
04687 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
04688 else
04689 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
04690
04691 i = ao2_iterator_init(peers, 0);
04692 for (peer = ao2_iterator_next(&i); peer;
04693 peer_unref(peer), peer = ao2_iterator_next(&i)) {
04694 char nm[20];
04695 char status[20];
04696 char srch[2000];
04697 int retstatus;
04698
04699 if (registeredonly && !peer->addr.sin_addr.s_addr)
04700 continue;
04701 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
04702 continue;
04703
04704 if (!ast_strlen_zero(peer->username))
04705 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04706 else
04707 ast_copy_string(name, peer->name, sizeof(name));
04708
04709 retstatus = peer_status(peer, status, sizeof(status));
04710 if (retstatus > 0)
04711 online_peers++;
04712 else if (!retstatus)
04713 offline_peers++;
04714 else
04715 unmonitored_peers++;
04716
04717 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04718
04719 snprintf(srch, sizeof(srch), FORMAT, name,
04720 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04721 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04722 nm,
04723 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04724 peer->encmethods ? "(E)" : " ", status, term);
04725
04726 if (s)
04727 astman_append(s, FORMAT, name,
04728 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04729 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04730 nm,
04731 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04732 peer->encmethods ? "(E)" : " ", status, term);
04733 else
04734 ast_cli(fd, FORMAT, name,
04735 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04736 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04737 nm,
04738 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04739 peer->encmethods ? "(E)" : " ", status, term);
04740 total_peers++;
04741 }
04742
04743 if (s)
04744 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04745 else
04746 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04747
04748 if (havepattern)
04749 regfree(®exbuf);
04750
04751 return RESULT_SUCCESS;
04752 #undef FORMAT
04753 #undef FORMAT2
04754 }
04755
04756 static int iax2_show_threads(int fd, int argc, char *argv[])
04757 {
04758 struct iax2_thread *thread = NULL;
04759 time_t t;
04760 int threadcount = 0, dynamiccount = 0;
04761 char type;
04762
04763 if (argc != 3)
04764 return RESULT_SHOWUSAGE;
04765
04766 ast_cli(fd, "IAX2 Thread Information\n");
04767 time(&t);
04768 ast_cli(fd, "Idle Threads:\n");
04769 AST_LIST_LOCK(&idle_list);
04770 AST_LIST_TRAVERSE(&idle_list, thread, list) {
04771 #ifdef DEBUG_SCHED_MULTITHREAD
04772 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04773 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04774 #else
04775 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04776 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04777 #endif
04778 threadcount++;
04779 }
04780 AST_LIST_UNLOCK(&idle_list);
04781 ast_cli(fd, "Active Threads:\n");
04782 AST_LIST_LOCK(&active_list);
04783 AST_LIST_TRAVERSE(&active_list, thread, list) {
04784 if (thread->type == IAX_TYPE_DYNAMIC)
04785 type = 'D';
04786 else
04787 type = 'P';
04788 #ifdef DEBUG_SCHED_MULTITHREAD
04789 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
04790 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04791 #else
04792 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
04793 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04794 #endif
04795 threadcount++;
04796 }
04797 AST_LIST_UNLOCK(&active_list);
04798 ast_cli(fd, "Dynamic Threads:\n");
04799 AST_LIST_LOCK(&dynamic_list);
04800 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04801 #ifdef DEBUG_SCHED_MULTITHREAD
04802 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04803 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04804 #else
04805 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04806 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04807 #endif
04808 dynamiccount++;
04809 }
04810 AST_LIST_UNLOCK(&dynamic_list);
04811 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04812 return RESULT_SUCCESS;
04813 }
04814
04815 static int iax2_show_peers(int fd, int argc, char *argv[])
04816 {
04817 return __iax2_show_peers(0, fd, NULL, argc, argv);
04818 }
04819 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04820 {
04821 ast_cli_netstats(s, -1, 0);
04822 astman_append(s, "\r\n");
04823 return RESULT_SUCCESS;
04824 }
04825
04826 static int iax2_show_firmware(int fd, int argc, char *argv[])
04827 {
04828 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
04829 #if !defined(__FreeBSD__)
04830 #define FORMAT "%-15.15s %-15d %-15d\n"
04831 #else
04832 #define FORMAT "%-15.15s %-15d %-15d\n"
04833 #endif
04834 struct iax_firmware *cur;
04835 if ((argc != 3) && (argc != 4))
04836 return RESULT_SHOWUSAGE;
04837 ast_mutex_lock(&waresl.lock);
04838
04839 ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04840 for (cur = waresl.wares;cur;cur = cur->next) {
04841 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))
04842 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04843 (int)ntohl(cur->fwh->datalen));
04844 }
04845 ast_mutex_unlock(&waresl.lock);
04846 return RESULT_SUCCESS;
04847 #undef FORMAT
04848 #undef FORMAT2
04849 }
04850
04851
04852 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04853 {
04854 char *a[] = { "iax2", "show", "users" };
04855 int ret;
04856 const char *id = astman_get_header(m,"ActionID");
04857
04858 if (!ast_strlen_zero(id))
04859 astman_append(s, "ActionID: %s\r\n",id);
04860 ret = __iax2_show_peers(1, -1, s, 3, a );
04861 astman_append(s, "\r\n\r\n" );
04862 return ret;
04863 }
04864
04865 static char *regstate2str(int regstate)
04866 {
04867 switch(regstate) {
04868 case REG_STATE_UNREGISTERED:
04869 return "Unregistered";
04870 case REG_STATE_REGSENT:
04871 return "Request Sent";
04872 case REG_STATE_AUTHSENT:
04873 return "Auth. Sent";
04874 case REG_STATE_REGISTERED:
04875 return "Registered";
04876 case REG_STATE_REJECTED:
04877 return "Rejected";
04878 case REG_STATE_TIMEOUT:
04879 return "Timeout";
04880 case REG_STATE_NOAUTH:
04881 return "No Authentication";
04882 default:
04883 return "Unknown";
04884 }
04885 }
04886
04887 static int iax2_show_registry(int fd, int argc, char *argv[])
04888 {
04889 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
04890 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
04891 struct iax2_registry *reg = NULL;
04892
04893 char host[80];
04894 char perceived[80];
04895 if (argc != 3)
04896 return RESULT_SHOWUSAGE;
04897 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04898 AST_LIST_LOCK(®istrations);
04899 AST_LIST_TRAVERSE(®istrations, reg, entry) {
04900 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04901 if (reg->us.sin_addr.s_addr)
04902 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04903 else
04904 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04905 ast_cli(fd, FORMAT, host,
04906 (reg->dnsmgr) ? "Y" : "N",
04907 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04908 }
04909 AST_LIST_UNLOCK(®istrations);
04910 return RESULT_SUCCESS;
04911 #undef FORMAT
04912 #undef FORMAT2
04913 }
04914
04915 static int iax2_show_channels(int fd, int argc, char *argv[])
04916 {
04917 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
04918 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s\n"
04919 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
04920 int x;
04921 int numchans = 0;
04922
04923 if (argc != 3)
04924 return RESULT_SHOWUSAGE;
04925 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04926 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04927 ast_mutex_lock(&iaxsl[x]);
04928 if (iaxs[x]) {
04929 int lag, jitter, localdelay;
04930 jb_info jbinfo;
04931
04932 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04933 jb_getinfo(iaxs[x]->jb, &jbinfo);
04934 jitter = jbinfo.jitter;
04935 localdelay = jbinfo.current - jbinfo.min;
04936 } else {
04937 jitter = -1;
04938 localdelay = 0;
04939 }
04940 lag = iaxs[x]->remote_rr.delay;
04941 ast_cli(fd, FORMAT,
04942 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04943 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
04944 S_OR(iaxs[x]->username, "(None)"),
04945 iaxs[x]->callno, iaxs[x]->peercallno,
04946 iaxs[x]->oseqno, iaxs[x]->iseqno,
04947 lag,
04948 jitter,
04949 localdelay,
04950 ast_getformatname(iaxs[x]->voiceformat) );
04951 numchans++;
04952 }
04953 ast_mutex_unlock(&iaxsl[x]);
04954 }
04955 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04956 return RESULT_SUCCESS;
04957 #undef FORMAT
04958 #undef FORMAT2
04959 #undef FORMATB
04960 }
04961
04962 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04963 {
04964 int x;
04965 int numchans = 0;
04966 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04967 ast_mutex_lock(&iaxsl[x]);
04968 if (iaxs[x]) {
04969 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04970 char *fmt;
04971 jb_info jbinfo;
04972
04973 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04974 jb_getinfo(iaxs[x]->jb, &jbinfo);
04975 localjitter = jbinfo.jitter;
04976 localdelay = jbinfo.current - jbinfo.min;
04977 locallost = jbinfo.frames_lost;
04978 locallosspct = jbinfo.losspct/1000;
04979 localdropped = jbinfo.frames_dropped;
04980 localooo = jbinfo.frames_ooo;
04981 } else {
04982 localjitter = -1;
04983 localdelay = 0;
04984 locallost = -1;
04985 locallosspct = -1;
04986 localdropped = 0;
04987 localooo = -1;
04988 }
04989 if (limit_fmt)
04990 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04991 else
04992 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04993 if (s)
04994
04995 astman_append(s, fmt,
04996 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04997 iaxs[x]->pingtime,
04998 localjitter,
04999 localdelay,
05000 locallost,
05001 locallosspct,
05002 localdropped,
05003 localooo,
05004 iaxs[x]->frames_received/1000,
05005 iaxs[x]->remote_rr.jitter,
05006 iaxs[x]->remote_rr.delay,
05007 iaxs[x]->remote_rr.losscnt,
05008 iaxs[x]->remote_rr.losspct,
05009 iaxs[x]->remote_rr.dropped,
05010 iaxs[x]->remote_rr.ooo,
05011 iaxs[x]->remote_rr.packets/1000);
05012 else
05013 ast_cli(fd, fmt,
05014 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05015 iaxs[x]->pingtime,
05016 localjitter,
05017 localdelay,
05018 locallost,
05019 locallosspct,
05020 localdropped,
05021 localooo,
05022 iaxs[x]->frames_received/1000,
05023 iaxs[x]->remote_rr.jitter,
05024 iaxs[x]->remote_rr.delay,
05025 iaxs[x]->remote_rr.losscnt,
05026 iaxs[x]->remote_rr.losspct,
05027 iaxs[x]->remote_rr.dropped,
05028 iaxs[x]->remote_rr.ooo,
05029 iaxs[x]->remote_rr.packets/1000
05030 );
05031 numchans++;
05032 }
05033 ast_mutex_unlock(&iaxsl[x]);
05034 }
05035 return numchans;
05036 }
05037
05038 static int iax2_show_netstats(int fd, int argc, char *argv[])
05039 {
05040 int numchans = 0;
05041 if (argc != 3)
05042 return RESULT_SHOWUSAGE;
05043 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
05044 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
05045 numchans = ast_cli_netstats(NULL, fd, 1);
05046 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05047 return RESULT_SUCCESS;
05048 }
05049
05050 static int iax2_do_debug(int fd, int argc, char *argv[])
05051 {
05052 if (argc < 2 || argc > 3)
05053 return RESULT_SHOWUSAGE;
05054 iaxdebug = 1;
05055 ast_cli(fd, "IAX2 Debugging Enabled\n");
05056 return RESULT_SUCCESS;
05057 }
05058
05059 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
05060 {
05061 if (argc < 3 || argc > 4)
05062 return RESULT_SHOWUSAGE;
05063 iaxtrunkdebug = 1;
05064 ast_cli(fd, "IAX2 Trunk Debug Requested\n");
05065 return RESULT_SUCCESS;
05066 }
05067
05068 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
05069 {
05070 if (argc < 3 || argc > 4)
05071 return RESULT_SHOWUSAGE;
05072 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05073 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05074 return RESULT_SUCCESS;
05075 }
05076
05077 static int iax2_no_debug(int fd, int argc, char *argv[])
05078 {
05079 if (argc < 3 || argc > 4)
05080 return RESULT_SHOWUSAGE;
05081 iaxdebug = 0;
05082 ast_cli(fd, "IAX2 Debugging Disabled\n");
05083 return RESULT_SUCCESS;
05084 }
05085
05086 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
05087 {
05088 if (argc < 4 || argc > 5)
05089 return RESULT_SHOWUSAGE;
05090 iaxtrunkdebug = 0;
05091 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
05092 return RESULT_SUCCESS;
05093 }
05094
05095 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
05096 {
05097 if (argc < 4 || argc > 5)
05098 return RESULT_SHOWUSAGE;
05099 jb_setoutput(jb_error_output, jb_warning_output, NULL);
05100 jb_debug_output("\n");
05101 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05102 return RESULT_SUCCESS;
05103 }
05104
05105 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05106 {
05107 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05108 int res = -1;
05109 ast_mutex_lock(&iaxsl[callno]);
05110 if (iaxs[callno]) {
05111
05112 if (!iaxs[callno]->error) {
05113 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05114 res = 0;
05115
05116 else if (f->frametype == AST_FRAME_NULL)
05117 res = 0;
05118 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05119 res = 0;
05120 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05121 res = 0;
05122 else
05123
05124 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05125 } else {
05126 if (option_debug)
05127 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05128 }
05129 }
05130
05131 ast_mutex_unlock(&iaxsl[callno]);
05132 return res;
05133 }
05134
05135 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
05136 int now, int transfer, int final)
05137 {
05138 struct ast_frame f = { 0, };
05139
05140 f.frametype = type;
05141 f.subclass = command;
05142 f.datalen = datalen;
05143 f.src = __FUNCTION__;
05144 f.data = (void *) data;
05145
05146 return iax2_send(i, &f, ts, seqno, now, transfer, final);
05147 }
05148
05149 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05150 {
05151 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05152 }
05153
05154 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05155 {
05156 int res;
05157 ast_mutex_lock(&iaxsl[callno]);
05158 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05159 ast_mutex_unlock(&iaxsl[callno]);
05160 return res;
05161 }
05162
05163
05164
05165
05166
05167
05168 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)
05169 {
05170 int call_num = i->callno;
05171
05172 iax2_predestroy(i->callno);
05173 if (!iaxs[call_num])
05174 return -1;
05175 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05176 }
05177
05178 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)
05179 {
05180 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05181 }
05182
05183 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05184 {
05185 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05186 }
05187
05188 static int apply_context(struct iax2_context *con, const char *context)
05189 {
05190 while(con) {
05191 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05192 return -1;
05193 con = con->next;
05194 }
05195 return 0;
05196 }
05197
05198
05199 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05200 {
05201
05202 int res = -1;
05203 int version = 2;
05204 struct iax2_user *user = NULL, *best = NULL;
05205 int bestscore = 0;
05206 int gotcapability = 0;
05207 struct ast_variable *v = NULL, *tmpvar = NULL;
05208 struct ao2_iterator i;
05209
05210 if (!iaxs[callno])
05211 return res;
05212 if (ies->called_number)
05213 ast_string_field_set(iaxs[callno], exten, ies->called_number);
05214 if (ies->calling_number) {
05215 ast_shrink_phone_number(ies->calling_number);
05216 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05217 }
05218 if (ies->calling_name)
05219 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05220 if (ies->calling_ani)
05221 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05222 if (ies->dnid)
05223 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05224 if (ies->rdnis)
05225 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05226 if (ies->called_context)
05227 ast_string_field_set(iaxs[callno], context, ies->called_context);
05228 if (ies->language)
05229 ast_string_field_set(iaxs[callno], language, ies->language);
05230 if (ies->username)
05231 ast_string_field_set(iaxs[callno], username, ies->username);
05232 if (ies->calling_ton > -1)
05233 iaxs[callno]->calling_ton = ies->calling_ton;
05234 if (ies->calling_tns > -1)
05235 iaxs[callno]->calling_tns = ies->calling_tns;
05236 if (ies->calling_pres > -1)
05237 iaxs[callno]->calling_pres = ies->calling_pres;
05238 if (ies->format)
05239 iaxs[callno]->peerformat = ies->format;
05240 if (ies->adsicpe)
05241 iaxs[callno]->peeradsicpe = ies->adsicpe;
05242 if (ies->capability) {
05243 gotcapability = 1;
05244 iaxs[callno]->peercapability = ies->capability;
05245 }
05246 if (ies->version)
05247 version = ies->version;
05248
05249
05250 if(ies->codec_prefs) {
05251 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05252 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05253 }
05254
05255 if (!gotcapability)
05256 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05257 if (version > IAX_PROTO_VERSION) {
05258 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
05259 ast_inet_ntoa(sin->sin_addr), version);
05260 return res;
05261 }
05262
05263 i = ao2_iterator_init(users, 0);
05264 while ((user = ao2_iterator_next(&i))) {
05265 if ((ast_strlen_zero(iaxs[callno]->username) ||
05266 !strcmp(iaxs[callno]->username, user->name))
05267 && ast_apply_ha(user->ha, sin)
05268 && (ast_strlen_zero(iaxs[callno]->context) ||
05269 apply_context(user->contexts, iaxs[callno]->context))) {
05270 if (!ast_strlen_zero(iaxs[callno]->username)) {
05271
05272 if (best)
05273 user_unref(best);
05274 best = user;
05275 break;
05276 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05277
05278 if (user->ha) {
05279
05280 if (bestscore < 4) {
05281 bestscore = 4;
05282 if (best)
05283 user_unref(best);
05284 best = user;
05285 continue;
05286 }
05287 } else {
05288
05289 if (bestscore < 3) {
05290 bestscore = 3;
05291 if (best)
05292 user_unref(best);
05293 best = user;
05294 continue;
05295 }
05296 }
05297 } else {
05298 if (user->ha) {
05299
05300 if (bestscore < 2) {
05301 bestscore = 2;
05302 if (best)
05303 user_unref(best);
05304 best = user;
05305 continue;
05306 }
05307 } else {
05308
05309 if (bestscore < 1) {
05310 bestscore = 1;
05311 if (best)
05312 user_unref(best);
05313 best = user;
05314 continue;
05315 }
05316 }
05317 }
05318 }
05319 user_unref(user);
05320 }
05321 user = best;
05322 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05323 user = realtime_user(iaxs[callno]->username, sin);
05324 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
05325 !apply_context(user->contexts, iaxs[callno]->context)) {
05326 user = user_unref(user);
05327 }
05328 }
05329 if (user) {
05330
05331
05332 for (v = user->vars ; v ; v = v->next) {
05333 if((tmpvar = ast_variable_new(v->name, v->value))) {
05334 tmpvar->next = iaxs[callno]->vars;
05335 iaxs[callno]->vars = tmpvar;
05336 }
05337 }
05338
05339 if (user->maxauthreq > 0)
05340 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05341 iaxs[callno]->prefs = user->prefs;
05342 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05343 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05344 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05345 iaxs[callno]->encmethods = user->encmethods;
05346
05347 if (ast_strlen_zero(iaxs[callno]->username))
05348 ast_string_field_set(iaxs[callno], username, user->name);
05349
05350 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05351 iaxs[callno]->capability = user->capability;
05352
05353 if (ast_strlen_zero(iaxs[callno]->context)) {
05354 if (user->contexts)
05355 ast_string_field_set(iaxs[callno], context, user->contexts->context);
05356 else
05357 ast_string_field_set(iaxs[callno], context, context);
05358 }
05359
05360 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05361
05362 iaxs[callno]->authmethods = user->authmethods;
05363 iaxs[callno]->adsi = user->adsi;
05364
05365 if (ast_test_flag(user, IAX_HASCALLERID)) {
05366 iaxs[callno]->calling_tns = 0;
05367 iaxs[callno]->calling_ton = 0;
05368 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05369 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05370 ast_string_field_set(iaxs[callno], ani, user->cid_num);
05371 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05372 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
05373 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05374 }
05375 if (!ast_strlen_zero(user->accountcode))
05376 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05377 if (!ast_strlen_zero(user->mohinterpret))
05378 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05379 if (!ast_strlen_zero(user->mohsuggest))
05380 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05381 if (user->amaflags)
05382 iaxs[callno]->amaflags = user->amaflags;
05383 if (!ast_strlen_zero(user->language))
05384 ast_string_field_set(iaxs[callno], language, user->language);
05385 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
05386
05387 if (!ast_strlen_zero(user->dbsecret)) {
05388 char *family, *key=NULL;
05389 char buf[80];
05390 family = ast_strdupa(user->dbsecret);
05391 key = strchr(family, '/');
05392 if (key) {
05393 *key = '\0';
05394 key++;
05395 }
05396 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05397 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05398 else
05399 ast_string_field_set(iaxs[callno], secret, buf);
05400 } else
05401 ast_string_field_set(iaxs[callno], secret, user->secret);
05402 res = 0;
05403 user = user_unref(user);
05404 }
05405 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
05406 return res;
05407 }
05408
05409 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05410 {
05411 struct ast_iax2_full_hdr fh;
05412 fh.scallno = htons(src | IAX_FLAG_FULL);
05413 fh.dcallno = htons(dst);
05414 fh.ts = 0;
05415 fh.oseqno = 0;
05416 fh.iseqno = 0;
05417 fh.type = AST_FRAME_IAX;
05418 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05419 if (iaxdebug)
05420 iax_showframe(NULL, &fh, 0, sin, 0);
05421 if (option_debug)
05422 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05423 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05424 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05425 }
05426
05427 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05428 {
05429
05430 p->encmethods &= enc;
05431 if (p->encmethods) {
05432 if (p->encmethods & IAX_ENCRYPT_AES128)
05433 p->encmethods = IAX_ENCRYPT_AES128;
05434 else
05435 p->encmethods = 0;
05436 }
05437 }
05438
05439
05440
05441
05442
05443
05444
05445 static int authenticate_request(int call_num)
05446 {
05447 struct iax_ie_data ied;
05448 int res = -1, authreq_restrict = 0;
05449 char challenge[10];
05450 struct chan_iax2_pvt *p = iaxs[call_num];
05451
05452 memset(&ied, 0, sizeof(ied));
05453
05454
05455 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05456 struct iax2_user *user, tmp_user = {
05457 .name = p->username,
05458 };
05459
05460 user = ao2_find(users, &tmp_user, OBJ_POINTER);
05461 if (user) {
05462 if (user->curauthreq == user->maxauthreq)
05463 authreq_restrict = 1;
05464 else
05465 user->curauthreq++;
05466 user = user_unref(user);
05467 }
05468 }
05469
05470
05471 if (authreq_restrict) {
05472 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05473 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05474 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05475 return 0;
05476 }
05477
05478 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05479 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05480 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05481 ast_string_field_set(p, challenge, challenge);
05482
05483 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05484 }
05485 if (p->encmethods)
05486 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05487
05488 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05489
05490 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05491
05492 if (p->encmethods)
05493 ast_set_flag(p, IAX_ENCRYPTED);
05494
05495 return res;
05496 }
05497
05498 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05499 {
05500 char requeststr[256];
05501 char md5secret[256] = "";
05502 char secret[256] = "";
05503 char rsasecret[256] = "";
05504 int res = -1;
05505 int x;
05506 struct iax2_user *user, tmp_user = {
05507 .name = p->username,
05508 };
05509
05510 user = ao2_find(users, &tmp_user, OBJ_POINTER);
05511 if (user) {
05512 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05513 ast_atomic_fetchadd_int(&user->curauthreq, -1);
05514 ast_clear_flag(p, IAX_MAXAUTHREQ);
05515 }
05516 ast_string_field_set(p, host, user->name);
05517 user = user_unref(user);
05518 }
05519
05520 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05521 return res;
05522 if (ies->password)
05523 ast_copy_string(secret, ies->password, sizeof(secret));
05524 if (ies->md5_result)
05525 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05526 if (ies->rsa_result)
05527 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05528 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05529 struct ast_key *key;
05530 char *keyn;
05531 char tmpkey[256];
05532 char *stringp=NULL;
05533 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05534 stringp=tmpkey;
05535 keyn = strsep(&stringp, ":");
05536 while(keyn) {
05537 key = ast_key_get(keyn, AST_KEY_PUBLIC);
05538 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05539 res = 0;
05540 break;
05541 } else if (!key)
05542 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05543 keyn = strsep(&stringp, ":");
05544 }
05545 } else if (p->authmethods & IAX_AUTH_MD5) {
05546 struct MD5Context md5;
05547 unsigned char digest[16];
05548 char *tmppw, *stringp;
05549
05550 tmppw = ast_strdupa(p->secret);
05551 stringp = tmppw;
05552 while((tmppw = strsep(&stringp, ";"))) {
05553 MD5Init(&md5);
05554 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05555 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05556 MD5Final(digest, &md5);
05557
05558 for (x=0;x<16;x++)
05559 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
05560 if (!strcasecmp(requeststr, md5secret)) {
05561 res = 0;
05562 break;
05563 }
05564 }
05565 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05566 if (!strcmp(secret, p->secret))
05567 res = 0;
05568 }
05569 return res;
05570 }
05571
05572
05573 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05574 {
05575 char requeststr[256] = "";
05576 char peer[256] = "";
05577 char md5secret[256] = "";
05578 char rsasecret[256] = "";
05579 char secret[256] = "";
05580 struct iax2_peer *p = NULL;
05581 struct ast_key *key;
05582 char *keyn;
05583 int x;
05584 int expire = 0;
05585 int res = -1;
05586
05587 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
05588
05589 if (ies->username)
05590 ast_copy_string(peer, ies->username, sizeof(peer));
05591 if (ies->password)
05592 ast_copy_string(secret, ies->password, sizeof(secret));
05593 if (ies->md5_result)
05594 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05595 if (ies->rsa_result)
05596 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05597 if (ies->refresh)
05598 expire = ies->refresh;
05599
05600 if (ast_strlen_zero(peer)) {
05601 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05602 return -1;
05603 }
05604
05605
05606 ast_mutex_unlock(&iaxsl[callno]);
05607 p = find_peer(peer, 1);
05608 ast_mutex_lock(&iaxsl[callno]);
05609 if (!p || !iaxs[callno]) {
05610 if (iaxs[callno]) {
05611 ast_string_field_set(iaxs[callno], secret, "badsecret");
05612 }
05613 if (authdebug && !p)
05614 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05615 goto return_unref;
05616 }
05617
05618 if (!ast_test_flag(p, IAX_DYNAMIC)) {
05619 if (authdebug)
05620 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05621 goto return_unref;
05622 }
05623
05624 if (!ast_apply_ha(p->ha, sin)) {
05625 if (authdebug)
05626 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05627 goto return_unref;
05628 }
05629 if (!inaddrcmp(&p->addr, sin))
05630 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05631 ast_string_field_set(iaxs[callno], secret, p->secret);
05632 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05633
05634 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05635 if (!ast_strlen_zero(p->inkeys)) {
05636 char tmpkeys[256];
05637 char *stringp=NULL;
05638 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05639 stringp=tmpkeys;
05640 keyn = strsep(&stringp, ":");
05641 while(keyn) {
05642 key = ast_key_get(keyn, AST_KEY_PUBLIC);
05643 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05644 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05645 break;
05646 } else if (!key)
05647 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05648 keyn = strsep(&stringp, ":");
05649 }
05650 if (!keyn) {
05651 if (authdebug)
05652 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05653 goto return_unref;
05654 }
05655 } else {
05656 if (authdebug)
05657 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05658 goto return_unref;
05659 }
05660 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05661 struct MD5Context md5;
05662 unsigned char digest[16];
05663 char *tmppw, *stringp;
05664
05665 tmppw = ast_strdupa(p->secret);
05666 stringp = tmppw;
05667 while((tmppw = strsep(&stringp, ";"))) {
05668 MD5Init(&md5);
05669 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05670 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05671 MD5Final(digest, &md5);
05672 for (x=0;x<16;x++)
05673 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
05674 if (!strcasecmp(requeststr, md5secret))
05675 break;
05676 }
05677 if (tmppw) {
05678 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05679 } else {
05680 if (authdebug)
05681 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05682 goto return_unref;
05683 }
05684 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05685
05686 if (strcmp(secret, p->secret)) {
05687 if (authdebug)
05688 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05689 goto return_unref;
05690 } else
05691 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05692 } else if (!ast_strlen_zero(iaxs[callno]->secret) || !ast_strlen_zero(iaxs[callno]->inkeys)) {
05693 if (authdebug &&
05694 ((!ast_strlen_zero(iaxs[callno]->secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) ||
05695 (!ast_strlen_zero(iaxs[callno]->inkeys) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)))) {
05696 ast_log(LOG_NOTICE, "Inappropriate authentication received for '%s'\n", p->name);
05697 }
05698 goto return_unref;
05699 }
05700 ast_device_state_changed("IAX2/%s", p->name);
05701
05702 return_unref:
05703 ast_string_field_set(iaxs[callno], peer, peer);
05704
05705 if (expire && (expire < iaxs[callno]->expiry))
05706 iaxs[callno]->expiry = expire;
05707
05708 res = 0;
05709
05710 if (p)
05711 peer_unref(p);
05712
05713 return res;
05714 }
05715
05716 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
05717 {
05718 int res = -1;
05719 int x;
05720 if (!ast_strlen_zero(keyn)) {
05721 if (!(authmethods & IAX_AUTH_RSA)) {
05722 if (ast_strlen_zero(secret))
05723 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));
05724 } else if (ast_strlen_zero(challenge)) {
05725 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05726 } else {
05727 char sig[256];
05728 struct ast_key *key;
05729 key = ast_key_get(keyn, AST_KEY_PRIVATE);
05730 if (!key) {
05731 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05732 } else {
05733 if (ast_sign(key, (char*)challenge, sig)) {
05734 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05735 res = -1;
05736 } else {
05737 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05738 res = 0;
05739 }
05740 }
05741 }
05742 }
05743
05744 if (res && !ast_strlen_zero(secret)) {
05745 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05746 struct MD5Context md5;
05747 unsigned char digest[16];
05748 char digres[128];
05749 MD5Init(&md5);
05750 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05751 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05752 MD5Final(digest, &md5);
05753
05754 for (x=0;x<16;x++)
05755 sprintf(digres + (x << 1), "%2.2x", digest[x]);
05756 if (ecx && dcx)
05757 build_enc_keys(digest, ecx, dcx);
05758 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05759 res = 0;
05760 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05761 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05762 res = 0;
05763 } else
05764 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05765 }
05766 return res;
05767 }
05768
05769
05770
05771
05772
05773 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05774 {
05775 struct iax2_peer *peer = NULL;
05776
05777 int res = -1;
05778 int authmethods = 0;
05779 struct iax_ie_data ied;
05780 uint16_t callno = p->callno;
05781
05782 memset(&ied, 0, sizeof(ied));
05783
05784 if (ies->username)
05785 ast_string_field_set(p, username, ies->username);
05786 if (ies->challenge)
05787 ast_string_field_set(p, challenge, ies->challenge);
05788 if (ies->authmethods)
05789 authmethods = ies->authmethods;
05790 if (authmethods & IAX_AUTH_MD5)
05791 merge_encryption(p, ies->encmethods);
05792 else
05793 p->encmethods = 0;
05794
05795
05796 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05797
05798 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05799 } else {
05800 struct ao2_iterator i = ao2_iterator_init(peers, 0);
05801 while ((peer = ao2_iterator_next(&i))) {
05802 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
05803
05804 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05805
05806 && (!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)))
05807
05808 ) {
05809 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05810 if (!res) {
05811 peer_unref(peer);
05812 break;
05813 }
05814 }
05815 peer_unref(peer);
05816 }
05817 if (!peer) {
05818
05819
05820 const char *peer_name = ast_strdupa(p->peer);
05821 ast_mutex_unlock(&iaxsl[callno]);
05822 if ((peer = realtime_peer(peer_name, NULL))) {
05823 ast_mutex_lock(&iaxsl[callno]);
05824 if (!(p = iaxs[callno])) {
05825 peer_unref(peer);
05826 return -1;
05827 }
05828 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05829 peer_unref(peer);
05830 }
05831 if (!peer) {
05832 ast_mutex_lock(&iaxsl[callno]);
05833 if (!(p = iaxs[callno]))
05834 return -1;
05835 }
05836 }
05837 }
05838 if (ies->encmethods)
05839 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05840 if (!res)
05841 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05842 return res;
05843 }
05844
05845 static int iax2_do_register(struct iax2_registry *reg);
05846
05847 static void __iax2_do_register_s(const void *data)
05848 {
05849 struct iax2_registry *reg = (struct iax2_registry *)data;
05850 reg->expire = -1;
05851 iax2_do_register(reg);
05852 }
05853
05854 static int iax2_do_register_s(const void *data)
05855 {
05856 #ifdef SCHED_MULTITHREADED
05857 if (schedule_action(__iax2_do_register_s, data))
05858 #endif
05859 __iax2_do_register_s(data);
05860 return 0;
05861 }
05862
05863 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05864 {
05865 int newcall = 0;
05866 char newip[256];
05867 struct iax_ie_data ied;
05868 struct sockaddr_in new;
05869
05870
05871 memset(&ied, 0, sizeof(ied));
05872 if (ies->apparent_addr)
05873 bcopy(ies->apparent_addr, &new, sizeof(new));
05874 if (ies->callno)
05875 newcall = ies->callno;
05876 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05877 ast_log(LOG_WARNING, "Invalid transfer request\n");
05878 return -1;
05879 }
05880 pvt->transfercallno = newcall;
05881 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05882 inet_aton(newip, &pvt->transfer.sin_addr);
05883 pvt->transfer.sin_family = AF_INET;
05884 pvt->transferring = TRANSFER_BEGIN;
05885 pvt->transferid = ies->transferid;
05886 if (ies->transferid)
05887 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05888 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05889 return 0;
05890 }
05891
05892 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05893 {
05894 char exten[256] = "";
05895 int status = CACHE_FLAG_UNKNOWN;
05896 int expiry = iaxdefaultdpcache;
05897 int x;
05898 int matchmore = 0;
05899 struct iax2_dpcache *dp, *prev;
05900
05901 if (ies->called_number)
05902 ast_copy_string(exten, ies->called_number, sizeof(exten));
05903
05904 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05905 status = CACHE_FLAG_EXISTS;
05906 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05907 status = CACHE_FLAG_CANEXIST;
05908 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05909 status = CACHE_FLAG_NONEXISTENT;
05910
05911 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05912
05913 }
05914 if (ies->refresh)
05915 expiry = ies->refresh;
05916 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05917 matchmore = CACHE_FLAG_MATCHMORE;
05918 ast_mutex_lock(&dpcache_lock);
05919 prev = NULL;
05920 dp = pvt->dpentries;
05921 while(dp) {
05922 if (!strcmp(dp->exten, exten)) {
05923
05924 if (prev)
05925 prev->peer = dp->peer;
05926 else
05927 pvt->dpentries = dp->peer;
05928 dp->peer = NULL;
05929 dp->callno = 0;
05930 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05931 if (dp->flags & CACHE_FLAG_PENDING) {
05932 dp->flags &= ~CACHE_FLAG_PENDING;
05933 dp->flags |= status;
05934 dp->flags |= matchmore;
05935 }
05936
05937 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
05938 if (dp->waiters[x] > -1) {
05939 if (write(dp->waiters[x], "asdf", 4) < 0) {
05940 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
05941 }
05942 }
05943 }
05944 }
05945 prev = dp;
05946 dp = dp->peer;
05947 }
05948 ast_mutex_unlock(&dpcache_lock);
05949 return 0;
05950 }
05951
05952 static int complete_transfer(int callno, struct iax_ies *ies)
05953 {
05954 int peercallno = 0;
05955 struct chan_iax2_pvt *pvt = iaxs[callno];
05956 struct iax_frame *cur;
05957 jb_frame frame;
05958
05959 if (ies->callno)
05960 peercallno = ies->callno;
05961
05962 if (peercallno < 1) {
05963 ast_log(LOG_WARNING, "Invalid transfer request\n");
05964 return -1;
05965 }
05966 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05967 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05968
05969 pvt->oseqno = 0;
05970 pvt->rseqno = 0;
05971 pvt->iseqno = 0;
05972 pvt->aseqno = 0;
05973
05974 if (pvt->peercallno) {
05975 remove_by_peercallno(pvt);
05976 }
05977 pvt->peercallno = peercallno;
05978 store_by_peercallno(pvt);
05979
05980 pvt->transferring = TRANSFER_NONE;
05981 pvt->svoiceformat = -1;
05982 pvt->voiceformat = 0;
05983 pvt->svideoformat = -1;
05984 pvt->videoformat = 0;
05985 pvt->transfercallno = -1;
05986 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05987 memset(&pvt->offset, 0, sizeof(pvt->offset));
05988
05989 while(jb_getall(pvt->jb,&frame) == JB_OK)
05990 iax2_frame_free(frame.data);
05991 jb_reset(pvt->jb);
05992 pvt->lag = 0;
05993 pvt->last = 0;
05994 pvt->lastsent = 0;
05995 pvt->nextpred = 0;
05996 pvt->pingtime = DEFAULT_RETRY_TIME;
05997 AST_LIST_LOCK(&iaxq.queue);
05998 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05999
06000
06001
06002 if (callno == cur->callno)
06003 cur->retries = -1;
06004 }
06005 AST_LIST_UNLOCK(&iaxq.queue);
06006 return 0;
06007 }
06008
06009
06010 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
06011 {
06012 struct iax2_registry *reg;
06013
06014 char peer[256] = "";
06015 char msgstatus[60];
06016 int refresh = 60;
06017 char ourip[256] = "<Unspecified>";
06018 struct sockaddr_in oldus;
06019 struct sockaddr_in us;
06020 int oldmsgs;
06021
06022 memset(&us, 0, sizeof(us));
06023 if (ies->apparent_addr)
06024 bcopy(ies->apparent_addr, &us, sizeof(us));
06025 if (ies->username)
06026 ast_copy_string(peer, ies->username, sizeof(peer));
06027 if (ies->refresh)
06028 refresh = ies->refresh;
06029 if (ies->calling_number) {
06030
06031 }
06032 reg = iaxs[callno]->reg;
06033 if (!reg) {
06034 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
06035 return -1;
06036 }
06037 memcpy(&oldus, ®->us, sizeof(oldus));
06038 oldmsgs = reg->messages;
06039 if (inaddrcmp(®->addr, sin)) {
06040 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06041 return -1;
06042 }
06043 memcpy(®->us, &us, sizeof(reg->us));
06044 if (ies->msgcount >= 0)
06045 reg->messages = ies->msgcount & 0xffff;
06046
06047
06048
06049 reg->refresh = refresh;
06050 AST_SCHED_DEL(sched, reg->expire);
06051 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
06052 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
06053 if (option_verbose > 2) {
06054 if (reg->messages > 255)
06055 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
06056 else if (reg->messages > 1)
06057 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
06058 else if (reg->messages > 0)
06059 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
06060 else
06061 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
06062 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06063 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
06064 }
06065 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
06066 }
06067 reg->regstate = REG_STATE_REGISTERED;
06068 return 0;
06069 }
06070
06071 static int iax2_register(char *value, int lineno)
06072 {
06073 struct iax2_registry *reg;
06074 char copy[256];
06075 char *username, *hostname, *secret;
06076 char *porta;
06077 char *stringp=NULL;
06078
06079 if (!value)
06080 return -1;
06081 ast_copy_string(copy, value, sizeof(copy));
06082 stringp=copy;
06083 username = strsep(&stringp, "@");
06084 hostname = strsep(&stringp, "@");
06085 if (!hostname) {
06086 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06087 return -1;
06088 }
06089 stringp=username;
06090 username = strsep(&stringp, ":");
06091 secret = strsep(&stringp, ":");
06092 stringp=hostname;
06093 hostname = strsep(&stringp, ":");
06094 porta = strsep(&stringp, ":");
06095
06096 if (porta && !atoi(porta)) {
06097 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06098 return -1;
06099 }
06100 if (!(reg = ast_calloc(1, sizeof(*reg))))
06101 return -1;
06102 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) {
06103 free(reg);
06104 return -1;
06105 }
06106 ast_copy_string(reg->username, username, sizeof(reg->username));
06107 if (secret)
06108 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06109 reg->expire = -1;
06110 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06111 reg->addr.sin_family = AF_INET;
06112 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06113 AST_LIST_LOCK(®istrations);
06114 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
06115 AST_LIST_UNLOCK(®istrations);
06116
06117 return 0;
06118 }
06119
06120 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06121 {
06122 char multi[256];
06123 char *stringp, *ext;
06124 if (!ast_strlen_zero(regcontext)) {
06125 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06126 stringp = multi;
06127 while((ext = strsep(&stringp, "&"))) {
06128 if (onoff) {
06129 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06130 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06131 "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06132 } else
06133 ast_context_remove_extension(regcontext, ext, 1, NULL);
06134 }
06135 }
06136 }
06137 static void prune_peers(void);
06138
06139 static void unlink_peer(struct iax2_peer *peer)
06140 {
06141 if (peer->expire > -1) {
06142 if (!ast_sched_del(sched, peer->expire)) {
06143 peer->expire = -1;
06144 peer_unref(peer);
06145 }
06146 }
06147
06148 if (peer->pokeexpire > -1) {
06149 if (!ast_sched_del(sched, peer->pokeexpire)) {
06150 peer->pokeexpire = -1;
06151 peer_unref(peer);
06152 }
06153 }
06154
06155 ao2_unlink(peers, peer);
06156 }
06157
06158 static void __expire_registry(const void *data)
06159 {
06160 struct iax2_peer *peer = (struct iax2_peer *) data;
06161
06162 if (!peer)
06163 return;
06164
06165 peer->expire = -1;
06166
06167 if (option_debug)
06168 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06169 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06170 realtime_update_peer(peer->name, &peer->addr, 0);
06171 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06172
06173 memset(&peer->addr, 0, sizeof(peer->addr));
06174
06175 peer->expiry = min_reg_expire;
06176 if (!ast_test_flag(peer, IAX_TEMPONLY))
06177 ast_db_del("IAX/Registry", peer->name);
06178 register_peer_exten(peer, 0);
06179 ast_device_state_changed("IAX2/%s", peer->name);
06180 if (iax2_regfunk)
06181 iax2_regfunk(peer->name, 0);
06182
06183 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06184 unlink_peer(peer);
06185
06186 peer_unref(peer);
06187 }
06188
06189 static int expire_registry(const void *data)
06190 {
06191 #ifdef SCHED_MULTITHREADED
06192 if (schedule_action(__expire_registry, data))
06193 #endif
06194 __expire_registry(data);
06195 return 0;
06196 }
06197
06198 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06199
06200 static void reg_source_db(struct iax2_peer *p)
06201 {
06202 char data[80];
06203 struct in_addr in;
06204 char *c, *d;
06205 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06206 c = strchr(data, ':');
06207 if (c) {
06208 *c = '\0';
06209 c++;
06210 if (inet_aton(data, &in)) {
06211 d = strchr(c, ':');
06212 if (d) {
06213 *d = '\0';
06214 d++;
06215 if (option_verbose > 2)
06216 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name,
06217 ast_inet_ntoa(in), atoi(c), atoi(d));
06218 iax2_poke_peer(p, 0);
06219 p->expiry = atoi(d);
06220 memset(&p->addr, 0, sizeof(p->addr));
06221 p->addr.sin_family = AF_INET;
06222 p->addr.sin_addr = in;
06223 p->addr.sin_port = htons(atoi(c));
06224 if (p->expire > -1) {
06225 if (!ast_sched_del(sched, p->expire)) {
06226 p->expire = -1;
06227 peer_unref(p);
06228 }
06229 }
06230 ast_device_state_changed("IAX2/%s", p->name);
06231 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06232 if (p->expire == -1)
06233 peer_unref(p);
06234 if (iax2_regfunk)
06235 iax2_regfunk(p->name, 1);
06236 register_peer_exten(p, 1);
06237 }
06238
06239 }
06240 }
06241 }
06242 }
06243
06244
06245
06246
06247
06248
06249
06250 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06251 {
06252
06253 struct iax_ie_data ied;
06254 struct iax2_peer *p;
06255 int msgcount;
06256 char data[80];
06257 int version;
06258 const char *peer_name;
06259 int res = -1;
06260
06261 memset(&ied, 0, sizeof(ied));
06262
06263 peer_name = ast_strdupa(iaxs[callno]->peer);
06264
06265
06266 ast_mutex_unlock(&iaxsl[callno]);
06267 if (!(p = find_peer(peer_name, 1))) {
06268 ast_mutex_lock(&iaxsl[callno]);
06269 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06270 return -1;
06271 }
06272 ast_mutex_lock(&iaxsl[callno]);
06273 if (!iaxs[callno])
06274 goto return_unref;
06275
06276 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06277 if (sin->sin_addr.s_addr) {
06278 time_t nowtime;
06279 time(&nowtime);
06280 realtime_update_peer(peer_name, sin, nowtime);
06281 } else {
06282 realtime_update_peer(peer_name, sin, 0);
06283 }
06284 }
06285 if (inaddrcmp(&p->addr, sin)) {
06286 if (iax2_regfunk)
06287 iax2_regfunk(p->name, 1);
06288
06289 memcpy(&p->addr, sin, sizeof(p->addr));
06290 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06291 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06292 ast_db_put("IAX/Registry", p->name, data);
06293 if (option_verbose > 2)
06294 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
06295 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06296 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06297 register_peer_exten(p, 1);
06298 ast_device_state_changed("IAX2/%s", p->name);
06299 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06300 if (option_verbose > 2)
06301 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name,
06302 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06303 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06304 register_peer_exten(p, 0);
06305 ast_db_del("IAX/Registry", p->name);
06306 ast_device_state_changed("IAX2/%s", p->name);
06307 }
06308
06309
06310 iax2_poke_peer(p, callno);
06311 }
06312
06313
06314 if (!iaxs[callno]) {
06315 res = -1;
06316 goto return_unref;
06317 }
06318
06319
06320 p->sockfd = fd;
06321
06322 if (p->expire > -1) {
06323 if (!ast_sched_del(sched, p->expire)) {
06324 p->expire = -1;
06325 peer_unref(p);
06326 }
06327 }
06328
06329 if (!refresh)
06330 refresh = min_reg_expire;
06331 if (refresh > max_reg_expire) {
06332 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06333 p->name, max_reg_expire, refresh);
06334 p->expiry = max_reg_expire;
06335 } else if (refresh < min_reg_expire) {
06336 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06337 p->name, min_reg_expire, refresh);
06338 p->expiry = min_reg_expire;
06339 } else {
06340 p->expiry = refresh;
06341 }
06342 if (p->expiry && sin->sin_addr.s_addr) {
06343 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06344 if (p->expire == -1)
06345 peer_unref(p);
06346 }
06347 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06348 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06349 if (sin->sin_addr.s_addr) {
06350 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06351 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06352 if (!ast_strlen_zero(p->mailbox)) {
06353 int new, old;
06354 ast_app_inboxcount(p->mailbox, &new, &old);
06355 if (new > 255)
06356 new = 255;
06357 if (old > 255)
06358 old = 255;
06359 msgcount = (old << 8) | new;
06360 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06361 }
06362 if (ast_test_flag(p, IAX_HASCALLERID)) {
06363 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06364 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06365 }
06366 }
06367 version = iax_check_version(devtype);
06368 if (version)
06369 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06370
06371 res = 0;
06372
06373 return_unref:
06374 peer_unref(p);
06375
06376 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06377 }
06378
06379 static int registry_authrequest(int callno)
06380 {
06381 struct iax_ie_data ied;
06382 struct iax2_peer *p;
06383 char challenge[10];
06384 const char *peer_name;
06385 int sentauthmethod;
06386
06387 peer_name = ast_strdupa(iaxs[callno]->peer);
06388
06389
06390 ast_mutex_unlock(&iaxsl[callno]);
06391 if ((p = find_peer(peer_name, 1))) {
06392 last_authmethod = p->authmethods;
06393 }
06394
06395 ast_mutex_lock(&iaxsl[callno]);
06396 if (!iaxs[callno])
06397 goto return_unref;
06398
06399 memset(&ied, 0, sizeof(ied));
06400
06401
06402
06403
06404
06405
06406 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06407 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
06408 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06409
06410 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06411 ast_string_field_set(iaxs[callno], challenge, challenge);
06412 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06413 }
06414 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06415
06416 return_unref:
06417 if (p) {
06418 peer_unref(p);
06419 }
06420
06421 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
06422 }
06423
06424 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06425 {
06426 struct iax2_registry *reg;
06427
06428 struct iax_ie_data ied;
06429 char peer[256] = "";
06430 char challenge[256] = "";
06431 int res;
06432 int authmethods = 0;
06433 if (ies->authmethods)
06434 authmethods = ies->authmethods;
06435 if (ies->username)
06436 ast_copy_string(peer, ies->username, sizeof(peer));
06437 if (ies->challenge)
06438 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06439 memset(&ied, 0, sizeof(ied));
06440 reg = iaxs[callno]->reg;
06441 if (reg) {
06442 if (inaddrcmp(®->addr, sin)) {
06443 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06444 return -1;
06445 }
06446 if (ast_strlen_zero(reg->secret)) {
06447 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06448 reg->regstate = REG_STATE_NOAUTH;
06449 return -1;
06450 }
06451 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06452 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06453 if (reg->secret[0] == '[') {
06454 char tmpkey[256];
06455 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06456 tmpkey[strlen(tmpkey) - 1] = '\0';
06457 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06458 } else
06459 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06460 if (!res) {
06461 reg->regstate = REG_STATE_AUTHSENT;
06462 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06463 } else
06464 return -1;
06465 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06466 } else
06467 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06468 return -1;
06469 }
06470
06471 static void stop_stuff(int callno)
06472 {
06473 iax2_destroy_helper(iaxs[callno]);
06474 }
06475
06476 static void __auth_reject(const void *nothing)
06477 {
06478
06479 int callno = (int)(long)(nothing);
06480 struct iax_ie_data ied;
06481 ast_mutex_lock(&iaxsl[callno]);
06482 if (iaxs[callno]) {
06483 memset(&ied, 0, sizeof(ied));
06484 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06485 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06486 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06487 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06488 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06489 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06490 }
06491 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06492 }
06493 ast_mutex_unlock(&iaxsl[callno]);
06494 }
06495
06496 static int auth_reject(const void *data)
06497 {
06498 int callno = (int)(long)(data);
06499 ast_mutex_lock(&iaxsl[callno]);
06500 if (iaxs[callno])
06501 iaxs[callno]->authid = -1;
06502 ast_mutex_unlock(&iaxsl[callno]);
06503 #ifdef SCHED_MULTITHREADED
06504 if (schedule_action(__auth_reject, data))
06505 #endif
06506 __auth_reject(data);
06507 return 0;
06508 }
06509
06510 static int auth_fail(int callno, int failcode)
06511 {
06512
06513
06514 if (iaxs[callno]) {
06515 iaxs[callno]->authfail = failcode;
06516 if (delayreject) {
06517 AST_SCHED_DEL(sched, iaxs[callno]->authid);
06518 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06519 } else
06520 auth_reject((void *)(long)callno);
06521 }
06522 return 0;
06523 }
06524
06525 static void __auto_hangup(const void *nothing)
06526 {
06527
06528 int callno = (int)(long)(nothing);
06529 struct iax_ie_data ied;
06530 ast_mutex_lock(&iaxsl[callno]);
06531 if (iaxs[callno]) {
06532 memset(&ied, 0, sizeof(ied));
06533 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06534 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06535 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06536 }
06537 ast_mutex_unlock(&iaxsl[callno]);
06538 }
06539
06540 static int auto_hangup(const void *data)
06541 {
06542 int callno = (int)(long)(data);
06543 ast_mutex_lock(&iaxsl[callno]);
06544 if (iaxs[callno]) {
06545 iaxs[callno]->autoid = -1;
06546 }
06547 ast_mutex_unlock(&iaxsl[callno]);
06548 #ifdef SCHED_MULTITHREADED
06549 if (schedule_action(__auto_hangup, data))
06550 #endif
06551 __auto_hangup(data);
06552 return 0;
06553 }
06554
06555 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06556 {
06557 struct iax_ie_data ied;
06558
06559 AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06560 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06561 memset(&ied, 0, sizeof(ied));
06562 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06563 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06564 dp->flags |= CACHE_FLAG_TRANSMITTED;
06565 }
06566
06567 static int iax2_vnak(int callno)
06568 {
06569 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06570 }
06571
06572 static void vnak_retransmit(int callno, int last)
06573 {
06574 struct iax_frame *f;
06575
06576 AST_LIST_LOCK(&iaxq.queue);
06577 AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06578
06579 if ((f->callno == callno) && iaxs[f->callno] &&
06580 ((unsigned char ) (f->oseqno - last) < 128) &&
06581 (f->retries >= 0)) {
06582 send_packet(f);
06583 }
06584 }
06585 AST_LIST_UNLOCK(&iaxq.queue);
06586 }
06587
06588 static void __iax2_poke_peer_s(const void *data)
06589 {
06590 struct iax2_peer *peer = (struct iax2_peer *)data;
06591 iax2_poke_peer(peer, 0);
06592 peer_unref(peer);
06593 }
06594
06595 static int iax2_poke_peer_s(const void *data)
06596 {
06597 struct iax2_peer *peer = (struct iax2_peer *)data;
06598 peer->pokeexpire = -1;
06599 #ifdef SCHED_MULTITHREADED
06600 if (schedule_action(__iax2_poke_peer_s, data))
06601 #endif
06602 __iax2_poke_peer_s(data);
06603 return 0;
06604 }
06605
06606 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06607 {
06608 int res = 0;
06609 struct iax_frame *fr;
06610 struct ast_iax2_meta_hdr *meta;
06611 struct ast_iax2_meta_trunk_hdr *mth;
06612 int calls = 0;
06613
06614
06615 fr = (struct iax_frame *)tpeer->trunkdata;
06616
06617 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06618 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06619 if (tpeer->trunkdatalen) {
06620
06621 meta->zeros = 0;
06622 meta->metacmd = IAX_META_TRUNK;
06623 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06624 meta->cmddata = IAX_META_TRUNK_MINI;
06625 else
06626 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06627 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06628
06629 fr->direction = DIRECTION_OUTGRESS;
06630 fr->retrans = -1;
06631 fr->transfer = 0;
06632
06633 fr->data = fr->afdata;
06634 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06635 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06636 calls = tpeer->calls;
06637 #if 0
06638 if (option_debug)
06639 ast_log(LOG_DEBUG, "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));
06640 #endif
06641
06642 tpeer->trunkdatalen = 0;
06643 tpeer->calls = 0;
06644 }
06645 if (res < 0)
06646 return res;
06647 return calls;
06648 }
06649
06650 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06651 {
06652
06653 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
06654 return 1;
06655 return 0;
06656 }
06657
06658 static int timing_read(int *id, int fd, short events, void *cbdata)
06659 {
06660 char buf[1024];
06661 int res;
06662 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06663 int processed = 0;
06664 int totalcalls = 0;
06665 #ifdef DAHDI_TIMERACK
06666 int x = 1;
06667 #endif
06668 struct timeval now;
06669 if (iaxtrunkdebug)
06670 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06671 gettimeofday(&now, NULL);
06672 if (events & AST_IO_PRI) {
06673 #ifdef DAHDI_TIMERACK
06674
06675 if (ioctl(fd, DAHDI_TIMERACK, &x)) {
06676 ast_log(LOG_WARNING, "Unable to acknowledge timer. IAX trunking will fail!\n");
06677 usleep(1);
06678 return -1;
06679 }
06680 #endif
06681 } else {
06682
06683 res = read(fd, buf, sizeof(buf));
06684 if (res < 1) {
06685 ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06686 return 1;
06687 }
06688 }
06689
06690 ast_mutex_lock(&tpeerlock);
06691 tpeer = tpeers;
06692 while(tpeer) {
06693 processed++;
06694 res = 0;
06695 ast_mutex_lock(&tpeer->lock);
06696
06697
06698 if (!drop && iax2_trunk_expired(tpeer, &now)) {
06699
06700
06701 if (prev)
06702 prev->next = tpeer->next;
06703 else
06704 tpeers = tpeer->next;
06705 drop = tpeer;
06706 } else {
06707 res = send_trunk(tpeer, &now);
06708 if (iaxtrunkdebug)
06709 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);
06710 }
06711 totalcalls += res;
06712 res = 0;
06713 ast_mutex_unlock(&tpeer->lock);
06714 prev = tpeer;
06715 tpeer = tpeer->next;
06716 }
06717 ast_mutex_unlock(&tpeerlock);
06718 if (drop) {
06719 ast_mutex_lock(&drop->lock);
06720
06721
06722 if (option_debug)
06723 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06724 if (drop->trunkdata) {
06725 free(drop->trunkdata);
06726 drop->trunkdata = NULL;
06727 }
06728 ast_mutex_unlock(&drop->lock);
06729 ast_mutex_destroy(&drop->lock);
06730 free(drop);
06731
06732 }
06733 if (iaxtrunkdebug)
06734 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06735 iaxtrunkdebug =0;
06736 return 1;
06737 }
06738
06739 struct dpreq_data {
06740 int callno;
06741 char context[AST_MAX_EXTENSION];
06742 char callednum[AST_MAX_EXTENSION];
06743 char *callerid;
06744 };
06745
06746 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06747 {
06748 unsigned short dpstatus = 0;
06749 struct iax_ie_data ied1;
06750 int mm;
06751
06752 memset(&ied1, 0, sizeof(ied1));
06753 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06754
06755 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06756 dpstatus = IAX_DPSTATUS_EXISTS;
06757 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06758 dpstatus = IAX_DPSTATUS_CANEXIST;
06759 } else {
06760 dpstatus = IAX_DPSTATUS_NONEXISTENT;
06761 }
06762 if (ast_ignore_pattern(context, callednum))
06763 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06764 if (mm)
06765 dpstatus |= IAX_DPSTATUS_MATCHMORE;
06766 if (!skiplock)
06767 ast_mutex_lock(&iaxsl[callno]);
06768 if (iaxs[callno]) {
06769 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06770 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06771 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06772 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06773 }
06774 if (!skiplock)
06775 ast_mutex_unlock(&iaxsl[callno]);
06776 }
06777
06778 static void *dp_lookup_thread(void *data)
06779 {
06780
06781 struct dpreq_data *dpr = data;
06782 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06783 if (dpr->callerid)
06784 free(dpr->callerid);
06785 free(dpr);
06786 return NULL;
06787 }
06788
06789 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06790 {
06791 pthread_t newthread;
06792 struct dpreq_data *dpr;
06793 pthread_attr_t attr;
06794
06795 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06796 return;
06797
06798 pthread_attr_init(&attr);
06799 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06800
06801 dpr->callno = callno;
06802 ast_copy_string(dpr->context, context, sizeof(dpr->context));
06803 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06804 if (callerid)
06805 dpr->callerid = ast_strdup(callerid);
06806 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06807 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06808 }
06809
06810 pthread_attr_destroy(&attr);
06811 }
06812
06813 struct iax_dual {
06814 struct ast_channel *chan1;
06815 struct ast_channel *chan2;
06816 };
06817
06818 static void *iax_park_thread(void *stuff)
06819 {
06820 struct ast_channel *chan1, *chan2;
06821 struct iax_dual *d;
06822 struct ast_frame *f;
06823 int ext;
06824 int res;
06825 d = stuff;
06826 chan1 = d->chan1;
06827 chan2 = d->chan2;
06828 free(d);
06829 f = ast_read(chan1);
06830 if (f)
06831 ast_frfree(f);
06832 res = ast_park_call(chan1, chan2, 0, &ext);
06833 ast_hangup(chan2);
06834 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06835 return NULL;
06836 }
06837
06838 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06839 {
06840 struct iax_dual *d;
06841 struct ast_channel *chan1m, *chan2m;
06842 pthread_t th;
06843 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06844 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06845 if (chan2m && chan1m) {
06846
06847 chan1m->readformat = chan1->readformat;
06848 chan1m->writeformat = chan1->writeformat;
06849 ast_channel_masquerade(chan1m, chan1);
06850
06851 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06852 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06853 chan1m->priority = chan1->priority;
06854
06855
06856
06857
06858 chan2m->readformat = chan2->readformat;
06859 chan2m->writeformat = chan2->writeformat;
06860 ast_channel_masquerade(chan2m, chan2);
06861
06862 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06863 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06864 chan2m->priority = chan2->priority;
06865 if (ast_do_masquerade(chan2m)) {
06866 ast_log(LOG_WARNING, "Masquerade failed :(\n");
06867 ast_hangup(chan2m);
06868 return -1;
06869 }
06870 } else {
06871 if (chan1m)
06872 ast_hangup(chan1m);
06873 if (chan2m)
06874 ast_hangup(chan2m);
06875 return -1;
06876 }
06877 if ((d = ast_calloc(1, sizeof(*d)))) {
06878 pthread_attr_t attr;
06879
06880 pthread_attr_init(&attr);
06881 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06882
06883 d->chan1 = chan1m;
06884 d->chan2 = chan2m;
06885 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06886 pthread_attr_destroy(&attr);
06887 return 0;
06888 }
06889 pthread_attr_destroy(&attr);
06890 free(d);
06891 }
06892 return -1;
06893 }
06894
06895
06896 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06897
06898 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06899 {
06900 unsigned int ourver;
06901 char rsi[80];
06902 snprintf(rsi, sizeof(rsi), "si-%s", si);
06903 if (iax_provision_version(&ourver, rsi, 1))
06904 return 0;
06905 if (option_debug)
06906 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06907 if (ourver != ver)
06908 iax2_provision(sin, sockfd, NULL, rsi, 1);
06909 return 0;
06910 }
06911
06912 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
06913 {
06914 jb_info stats;
06915 jb_getinfo(pvt->jb, &stats);
06916
06917 memset(iep, 0, sizeof(*iep));
06918
06919 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06920 if(stats.frames_in == 0) stats.frames_in = 1;
06921 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06922 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06923 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06924 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06925 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06926 }
06927
06928 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
06929 {
06930 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06931 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06932 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06933 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06934 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06935 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06936 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06937 }
06938
06939 static int socket_process(struct iax2_thread *thread);
06940
06941
06942
06943
06944 static void handle_deferred_full_frames(struct iax2_thread *thread)
06945 {
06946 struct iax2_pkt_buf *pkt_buf;
06947
06948 ast_mutex_lock(&thread->lock);
06949
06950 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06951 ast_mutex_unlock(&thread->lock);
06952
06953 thread->buf = pkt_buf->buf;
06954 thread->buf_len = pkt_buf->len;
06955 thread->buf_size = pkt_buf->len + 1;
06956
06957 socket_process(thread);
06958
06959 thread->buf = NULL;
06960 ast_free(pkt_buf);
06961
06962 ast_mutex_lock(&thread->lock);
06963 }
06964
06965 ast_mutex_unlock(&thread->lock);
06966 }
06967
06968
06969
06970
06971
06972
06973
06974 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06975 {
06976 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06977 struct ast_iax2_full_hdr *fh, *cur_fh;
06978
06979 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06980 return;
06981
06982 pkt_buf->len = from_here->buf_len;
06983 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06984
06985 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06986 ast_mutex_lock(&to_here->lock);
06987 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06988 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06989 if (fh->oseqno < cur_fh->oseqno) {
06990 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06991 break;
06992 }
06993 }
06994 AST_LIST_TRAVERSE_SAFE_END
06995
06996 if (!cur_pkt_buf)
06997 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06998
06999 ast_mutex_unlock(&to_here->lock);
07000 }
07001
07002 static int socket_read(int *id, int fd, short events, void *cbdata)
07003 {
07004 struct iax2_thread *thread;
07005 socklen_t len;
07006 time_t t;
07007 static time_t last_errtime = 0;
07008 struct ast_iax2_full_hdr *fh;
07009
07010 if (!(thread = find_idle_thread())) {
07011 time(&t);
07012 if (t != last_errtime && option_debug)
07013 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
07014 last_errtime = t;
07015 usleep(1);
07016 return 1;
07017 }
07018
07019 len = sizeof(thread->iosin);
07020 thread->iofd = fd;
07021 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
07022 thread->buf_size = sizeof(thread->readbuf);
07023 thread->buf = thread->readbuf;
07024 if (thread->buf_len < 0) {
07025 if (errno != ECONNREFUSED && errno != EAGAIN)
07026 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
07027 handle_error();
07028 thread->iostate = IAX_IOSTATE_IDLE;
07029 signal_condition(&thread->lock, &thread->cond);
07030 return 1;
07031 }
07032 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
07033 thread->iostate = IAX_IOSTATE_IDLE;
07034 signal_condition(&thread->lock, &thread->cond);
07035 return 1;
07036 }
07037
07038
07039
07040
07041 fh = (struct ast_iax2_full_hdr *) thread->buf;
07042 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
07043 struct iax2_thread *cur = NULL;
07044 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
07045
07046 AST_LIST_LOCK(&active_list);
07047 AST_LIST_TRAVERSE(&active_list, cur, list) {
07048 if ((cur->ffinfo.callno == callno) &&
07049 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
07050 break;
07051 }
07052 if (cur) {
07053
07054
07055 defer_full_frame(thread, cur);
07056 AST_LIST_UNLOCK(&active_list);
07057 thread->iostate = IAX_IOSTATE_IDLE;
07058 signal_condition(&thread->lock, &thread->cond);
07059 return 1;
07060 } else {
07061
07062 thread->ffinfo.callno = callno;
07063 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
07064 thread->ffinfo.type = fh->type;
07065 thread->ffinfo.csub = fh->csub;
07066 }
07067 AST_LIST_UNLOCK(&active_list);
07068 }
07069
07070
07071 thread->iostate = IAX_IOSTATE_READY;
07072 #ifdef DEBUG_SCHED_MULTITHREAD
07073 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
07074 #endif
07075 signal_condition(&thread->lock, &thread->cond);
07076
07077 return 1;
07078 }
07079
07080 static int socket_process(struct iax2_thread *thread)
07081 {
07082 struct sockaddr_in sin;
07083 int res;
07084 int updatehistory=1;
07085 int new = NEW_PREVENT;
07086 void *ptr;
07087 int dcallno = 0;
07088 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
07089 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
07090 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
07091 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
07092 struct ast_iax2_meta_trunk_hdr *mth;
07093 struct ast_iax2_meta_trunk_entry *mte;
07094 struct ast_iax2_meta_trunk_mini *mtm;
07095 struct iax_frame *fr;
07096 struct iax_frame *cur;
07097 struct ast_frame f = { 0, };
07098 struct ast_channel *c;
07099 struct iax2_dpcache *dp;
07100 struct iax2_peer *peer;
07101 struct iax2_trunk_peer *tpeer;
07102 struct timeval rxtrunktime;
07103 struct iax_ies ies;
07104 struct iax_ie_data ied0, ied1;
07105 int format;
07106 int fd;
07107 int exists;
07108 int minivid = 0;
07109 unsigned int ts;
07110 char empty[32]="";
07111 struct iax_frame *duped_fr;
07112 char host_pref_buf[128];
07113 char caller_pref_buf[128];
07114 struct ast_codec_pref pref;
07115 char *using_prefs = "mine";
07116
07117
07118 fr = alloca(sizeof(*fr) + 4096);
07119 memset(fr, 0, sizeof(*fr));
07120 fr->afdatalen = 4096;
07121
07122
07123 res = thread->buf_len;
07124 fd = thread->iofd;
07125 memcpy(&sin, &thread->iosin, sizeof(sin));
07126
07127 if (res < sizeof(*mh)) {
07128 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
07129 return 1;
07130 }
07131 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07132 if (res < sizeof(*vh)) {
07133 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));
07134 return 1;
07135 }
07136
07137
07138 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07139 minivid = 1;
07140 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07141 unsigned char metatype;
07142
07143 if (res < sizeof(*meta)) {
07144 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07145 return 1;
07146 }
07147
07148
07149 switch(meta->metacmd) {
07150 case IAX_META_TRUNK:
07151 if (res < (sizeof(*meta) + sizeof(*mth))) {
07152 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07153 sizeof(*meta) + sizeof(*mth));
07154 return 1;
07155 }
07156 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07157 ts = ntohl(mth->ts);
07158 metatype = meta->cmddata;
07159 res -= (sizeof(*meta) + sizeof(*mth));
07160 ptr = mth->data;
07161 tpeer = find_tpeer(&sin, fd);
07162 if (!tpeer) {
07163 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07164 return 1;
07165 }
07166 tpeer->trunkact = ast_tvnow();
07167 if (!ts || ast_tvzero(tpeer->rxtrunktime))
07168 tpeer->rxtrunktime = tpeer->trunkact;
07169 rxtrunktime = tpeer->rxtrunktime;
07170 ast_mutex_unlock(&tpeer->lock);
07171 while(res >= sizeof(*mte)) {
07172
07173 unsigned short callno, trunked_ts, len;
07174
07175 if (metatype == IAX_META_TRUNK_MINI) {
07176 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07177 ptr += sizeof(*mtm);
07178 res -= sizeof(*mtm);
07179 len = ntohs(mtm->len);
07180 callno = ntohs(mtm->mini.callno);
07181 trunked_ts = ntohs(mtm->mini.ts);
07182 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07183 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07184 ptr += sizeof(*mte);
07185 res -= sizeof(*mte);
07186 len = ntohs(mte->len);
07187 callno = ntohs(mte->callno);
07188 trunked_ts = 0;
07189 } else {
07190 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07191 break;
07192 }
07193
07194 if (len > res)
07195 break;
07196 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07197 if (fr->callno) {
07198
07199
07200
07201 memset(&f, 0, sizeof(f));
07202 f.frametype = AST_FRAME_VOICE;
07203 if (iaxs[fr->callno]) {
07204 if (iaxs[fr->callno]->voiceformat > 0) {
07205 f.subclass = iaxs[fr->callno]->voiceformat;
07206 f.datalen = len;
07207 if (f.datalen >= 0) {
07208 if (f.datalen)
07209 f.data = ptr;
07210 if(trunked_ts) {
07211 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07212 } else
07213 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07214
07215 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07216
07217 f.src = "IAX2";
07218 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
07219 f.samples = ast_codec_get_samples(&f);
07220 iax_frame_wrap(fr, &f);
07221 duped_fr = iaxfrdup2(fr);
07222 if (duped_fr) {
07223 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07224 }
07225
07226 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07227 iaxs[fr->callno]->last = fr->ts;
07228 #if 1
07229 if (option_debug && iaxdebug)
07230 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07231 #endif
07232 }
07233 }
07234 } else {
07235 ast_log(LOG_WARNING, "Datalen < 0?\n");
07236 }
07237 } else {
07238 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
07239 iax2_vnak(fr->callno);
07240 }
07241 }
07242 ast_mutex_unlock(&iaxsl[fr->callno]);
07243 }
07244 ptr += len;
07245 res -= len;
07246 }
07247
07248 }
07249 return 1;
07250 }
07251
07252 #ifdef DEBUG_SUPPORT
07253 if (iaxdebug && (res >= sizeof(*fh)))
07254 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07255 #endif
07256 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07257 if (res < sizeof(*fh)) {
07258 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));
07259 return 1;
07260 }
07261
07262
07263 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07264
07265 f.frametype = fh->type;
07266 if (f.frametype == AST_FRAME_VIDEO) {
07267 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07268 } else {
07269 f.subclass = uncompress_subclass(fh->csub);
07270 }
07271
07272
07273 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07274
07275 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->iseqno + 1);
07276 return 1;
07277 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07278
07279 return 1;
07280 }
07281
07282 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07283 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07284 (f.subclass == IAX_COMMAND_REGREL)))
07285 new = NEW_ALLOW;
07286 } else {
07287
07288 f.frametype = AST_FRAME_NULL;
07289 f.subclass = 0;
07290 }
07291
07292 if (!fr->callno) {
07293 int check_dcallno = 0;
07294
07295
07296
07297
07298
07299
07300
07301
07302
07303
07304
07305
07306
07307 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07308 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07309 }
07310
07311 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07312 }
07313
07314 if (fr->callno > 0)
07315 ast_mutex_lock(&iaxsl[fr->callno]);
07316
07317 if (!fr->callno || !iaxs[fr->callno]) {
07318
07319
07320 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07321
07322 if (((f.subclass != IAX_COMMAND_INVAL) &&
07323 (f.subclass != IAX_COMMAND_TXCNT) &&
07324 (f.subclass != IAX_COMMAND_TXACC) &&
07325 (f.subclass != IAX_COMMAND_FWDOWNL))||
07326 (f.frametype != AST_FRAME_IAX))
07327 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07328 fd);
07329 }
07330 if (fr->callno > 0)
07331 ast_mutex_unlock(&iaxsl[fr->callno]);
07332 return 1;
07333 }
07334 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07335 if (decrypt_frame(fr->callno, fh, &f, &res)) {
07336 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07337 ast_mutex_unlock(&iaxsl[fr->callno]);
07338 return 1;
07339 }
07340 #ifdef DEBUG_SUPPORT
07341 else if (iaxdebug)
07342 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07343 #endif
07344 }
07345
07346
07347 iaxs[fr->callno]->frames_received++;
07348
07349 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07350 f.subclass != IAX_COMMAND_TXCNT &&
07351 f.subclass != IAX_COMMAND_TXACC) {
07352 unsigned short new_peercallno;
07353
07354 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07355 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07356 if (iaxs[fr->callno]->peercallno) {
07357 remove_by_peercallno(iaxs[fr->callno]);
07358 }
07359 iaxs[fr->callno]->peercallno = new_peercallno;
07360 store_by_peercallno(iaxs[fr->callno]);
07361 }
07362 }
07363 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07364 if (option_debug && iaxdebug)
07365 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07366
07367 fr->oseqno = fh->oseqno;
07368 fr->iseqno = fh->iseqno;
07369 fr->ts = ntohl(fh->ts);
07370 #ifdef IAXTESTS
07371 if (test_resync) {
07372 if (option_debug)
07373 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07374 fr->ts += test_resync;
07375 }
07376 #endif
07377 #if 0
07378 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07379 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07380 (f.subclass == IAX_COMMAND_NEW ||
07381 f.subclass == IAX_COMMAND_AUTHREQ ||
07382 f.subclass == IAX_COMMAND_ACCEPT ||
07383 f.subclass == IAX_COMMAND_REJECT)) ) )
07384 #endif
07385 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07386 updatehistory = 0;
07387 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07388 (iaxs[fr->callno]->iseqno ||
07389 ((f.subclass != IAX_COMMAND_TXCNT) &&
07390 (f.subclass != IAX_COMMAND_TXREADY) &&
07391 (f.subclass != IAX_COMMAND_TXREL) &&
07392 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
07393 (f.subclass != IAX_COMMAND_TXACC)) ||
07394 (f.frametype != AST_FRAME_IAX))) {
07395 if (
07396 ((f.subclass != IAX_COMMAND_ACK) &&
07397 (f.subclass != IAX_COMMAND_INVAL) &&
07398 (f.subclass != IAX_COMMAND_TXCNT) &&
07399 (f.subclass != IAX_COMMAND_TXREADY) &&
07400 (f.subclass != IAX_COMMAND_TXREL) &&
07401 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
07402 (f.subclass != IAX_COMMAND_TXACC) &&
07403 (f.subclass != IAX_COMMAND_VNAK)) ||
07404 (f.frametype != AST_FRAME_IAX)) {
07405
07406 if (option_debug)
07407 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
07408 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07409
07410
07411 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07412
07413 if ((f.frametype != AST_FRAME_IAX) ||
07414 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07415 if (option_debug)
07416 ast_log(LOG_DEBUG, "Acking anyway\n");
07417
07418
07419 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07420 }
07421 } else {
07422
07423 iax2_vnak(fr->callno);
07424 }
07425 ast_mutex_unlock(&iaxsl[fr->callno]);
07426 return 1;
07427 }
07428 } else {
07429
07430 if (((f.subclass != IAX_COMMAND_ACK) &&
07431 (f.subclass != IAX_COMMAND_INVAL) &&
07432 (f.subclass != IAX_COMMAND_TXCNT) &&
07433 (f.subclass != IAX_COMMAND_TXACC) &&
07434 (f.subclass != IAX_COMMAND_VNAK)) ||
07435 (f.frametype != AST_FRAME_IAX))
07436 iaxs[fr->callno]->iseqno++;
07437 }
07438
07439 if (res < sizeof(*fh)) {
07440 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07441 ast_mutex_unlock(&iaxsl[fr->callno]);
07442 return 1;
07443 }
07444
07445 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07446 if (res < thread->buf_size)
07447 thread->buf[res++] = '\0';
07448 else
07449 thread->buf[res - 1] = '\0';
07450 }
07451 f.datalen = res - sizeof(*fh);
07452
07453
07454
07455 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
07456 ((f.subclass != IAX_COMMAND_INVAL) ||
07457 (f.frametype != AST_FRAME_IAX))) {
07458 unsigned char x;
07459 int call_to_destroy;
07460
07461
07462
07463 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07464 if (fr->iseqno == x)
07465 break;
07466 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07467
07468
07469 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07470
07471 if (option_debug && iaxdebug)
07472 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07473 call_to_destroy = 0;
07474 AST_LIST_LOCK(&iaxq.queue);
07475 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07476
07477 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07478 cur->retries = -1;
07479
07480 if (cur->final)
07481 call_to_destroy = fr->callno;
07482 }
07483 }
07484 AST_LIST_UNLOCK(&iaxq.queue);
07485 if (call_to_destroy) {
07486 if (iaxdebug && option_debug)
07487 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07488 ast_mutex_lock(&iaxsl[call_to_destroy]);
07489 iax2_destroy(call_to_destroy);
07490 ast_mutex_unlock(&iaxsl[call_to_destroy]);
07491 }
07492 }
07493
07494 if (iaxs[fr->callno])
07495 iaxs[fr->callno]->rseqno = fr->iseqno;
07496 else {
07497
07498 ast_mutex_unlock(&iaxsl[fr->callno]);
07499 return 1;
07500 }
07501 } else if (option_debug)
07502 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07503 }
07504 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
07505 ((f.frametype != AST_FRAME_IAX) ||
07506 ((f.subclass != IAX_COMMAND_TXACC) &&
07507 (f.subclass != IAX_COMMAND_TXCNT)))) {
07508
07509 ast_mutex_unlock(&iaxsl[fr->callno]);
07510 return 1;
07511 }
07512
07513 if (f.datalen) {
07514 if (f.frametype == AST_FRAME_IAX) {
07515 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07516 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07517 ast_mutex_unlock(&iaxsl[fr->callno]);
07518 return 1;
07519 }
07520 f.data = NULL;
07521 f.datalen = 0;
07522 } else
07523 f.data = thread->buf + sizeof(*fh);
07524 } else {
07525 if (f.frametype == AST_FRAME_IAX)
07526 f.data = NULL;
07527 else
07528 f.data = empty;
07529 memset(&ies, 0, sizeof(ies));
07530 }
07531
07532
07533
07534
07535 if ((f.frametype == AST_FRAME_VOICE) ||
07536 (f.frametype == AST_FRAME_VIDEO) ||
07537 (f.frametype == AST_FRAME_IAX)) {
07538 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07539 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07540 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07541 ast_mutex_unlock(&iaxsl[fr->callno]);
07542 return 1;
07543 }
07544 }
07545 }
07546
07547 if (f.frametype == AST_FRAME_VOICE) {
07548 if (f.subclass != iaxs[fr->callno]->voiceformat) {
07549 iaxs[fr->callno]->voiceformat = f.subclass;
07550 if (option_debug)
07551 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07552 if (iaxs[fr->callno]->owner) {
07553 int orignative;
07554 retryowner:
07555 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07556 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07557 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07558 }
07559 if (iaxs[fr->callno]) {
07560 if (iaxs[fr->callno]->owner) {
07561 orignative = iaxs[fr->callno]->owner->nativeformats;
07562 iaxs[fr->callno]->owner->nativeformats = f.subclass;
07563 if (iaxs[fr->callno]->owner->readformat)
07564 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07565 iaxs[fr->callno]->owner->nativeformats = orignative;
07566 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07567 }
07568 } else {
07569 if (option_debug)
07570 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07571 ast_mutex_unlock(&iaxsl[fr->callno]);
07572 return 1;
07573 }
07574 }
07575 }
07576 }
07577 if (f.frametype == AST_FRAME_VIDEO) {
07578 if (f.subclass != iaxs[fr->callno]->videoformat) {
07579 if (option_debug)
07580 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07581 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07582 }
07583 }
07584 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
07585 if (f.subclass == AST_CONTROL_BUSY) {
07586 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
07587 } else if (f.subclass == AST_CONTROL_CONGESTION) {
07588 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
07589 }
07590 }
07591 if (f.frametype == AST_FRAME_IAX) {
07592 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07593
07594 if (option_debug && iaxdebug)
07595 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07596
07597
07598 if (iaxs[fr->callno]->last < fr->ts &&
07599 f.subclass != IAX_COMMAND_ACK &&
07600 f.subclass != IAX_COMMAND_PONG &&
07601 f.subclass != IAX_COMMAND_LAGRP) {
07602 iaxs[fr->callno]->last = fr->ts;
07603 if (option_debug && iaxdebug)
07604 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07605 }
07606
07607 switch(f.subclass) {
07608 case IAX_COMMAND_ACK:
07609
07610 break;
07611 case IAX_COMMAND_QUELCH:
07612 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07613
07614 if (iaxs[fr->callno]->owner) {
07615 manager_event(EVENT_FLAG_CALL, "Hold",
07616 "Channel: %s\r\n"
07617 "Uniqueid: %s\r\n",
07618 iaxs[fr->callno]->owner->name,
07619 iaxs[fr->callno]->owner->uniqueid);
07620 }
07621
07622 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07623 if (ies.musiconhold) {
07624 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07625 const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07626 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
07627 S_OR(mohsuggest, NULL),
07628 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07629 if (!iaxs[fr->callno]) {
07630 ast_mutex_unlock(&iaxsl[fr->callno]);
07631 return 1;
07632 }
07633 }
07634 }
07635 }
07636 break;
07637 case IAX_COMMAND_UNQUELCH:
07638 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07639
07640 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07641 manager_event(EVENT_FLAG_CALL, "Unhold",
07642 "Channel: %s\r\n"
07643 "Uniqueid: %s\r\n",
07644 iaxs[fr->callno]->owner->name,
07645 iaxs[fr->callno]->owner->uniqueid);
07646 }
07647
07648 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07649 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07650 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07651 if (!iaxs[fr->callno]) {
07652 ast_mutex_unlock(&iaxsl[fr->callno]);
07653 return 1;
07654 }
07655 }
07656 }
07657 break;
07658 case IAX_COMMAND_TXACC:
07659 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07660
07661 AST_LIST_LOCK(&iaxq.queue);
07662 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07663
07664 if ((fr->callno == cur->callno) && (cur->transfer))
07665 cur->retries = -1;
07666 }
07667 AST_LIST_UNLOCK(&iaxq.queue);
07668 memset(&ied1, 0, sizeof(ied1));
07669 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07670 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07671 iaxs[fr->callno]->transferring = TRANSFER_READY;
07672 }
07673 break;
07674 case IAX_COMMAND_NEW:
07675
07676 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07677 break;
07678 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07679 ast_mutex_unlock(&iaxsl[fr->callno]);
07680 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07681 ast_mutex_lock(&iaxsl[fr->callno]);
07682 if (!iaxs[fr->callno]) {
07683 ast_mutex_unlock(&iaxsl[fr->callno]);
07684 return 1;
07685 }
07686 }
07687
07688 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07689 int new_callno;
07690 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07691 fr->callno = new_callno;
07692 }
07693
07694 if (delayreject)
07695 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07696 if (check_access(fr->callno, &sin, &ies)) {
07697
07698 auth_fail(fr->callno, IAX_COMMAND_REJECT);
07699 if (authdebug)
07700 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);
07701 break;
07702 }
07703 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07704 const char *context, *exten, *cid_num;
07705
07706 context = ast_strdupa(iaxs[fr->callno]->context);
07707 exten = ast_strdupa(iaxs[fr->callno]->exten);
07708 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07709
07710
07711 ast_mutex_unlock(&iaxsl[fr->callno]);
07712 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07713 ast_mutex_lock(&iaxsl[fr->callno]);
07714
07715 if (!iaxs[fr->callno]) {
07716 ast_mutex_unlock(&iaxsl[fr->callno]);
07717 return 1;
07718 }
07719 } else
07720 exists = 0;
07721 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07722 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07723 memset(&ied0, 0, sizeof(ied0));
07724 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07725 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07726 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07727 if (!iaxs[fr->callno]) {
07728 ast_mutex_unlock(&iaxsl[fr->callno]);
07729 return 1;
07730 }
07731 if (authdebug)
07732 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);
07733 } else {
07734
07735
07736 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07737 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07738 using_prefs = "reqonly";
07739 } else {
07740 using_prefs = "disabled";
07741 }
07742 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07743 memset(&pref, 0, sizeof(pref));
07744 strcpy(caller_pref_buf, "disabled");
07745 strcpy(host_pref_buf, "disabled");
07746 } else {
07747 using_prefs = "mine";
07748
07749 if (ies.codec_prefs)
07750 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07751 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07752
07753 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07754 pref = iaxs[fr->callno]->rprefs;
07755 using_prefs = "caller";
07756 } else {
07757 pref = iaxs[fr->callno]->prefs;
07758 }
07759 } else
07760 pref = iaxs[fr->callno]->prefs;
07761
07762 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07763 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07764 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07765 }
07766 if (!format) {
07767 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07768 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07769 if (!format) {
07770 memset(&ied0, 0, sizeof(ied0));
07771 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07772 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07773 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07774 if (!iaxs[fr->callno]) {
07775 ast_mutex_unlock(&iaxsl[fr->callno]);
07776 return 1;
07777 }
07778 if (authdebug) {
07779 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07780 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);
07781 else
07782 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);
07783 }
07784 } else {
07785
07786 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07787 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07788 format = 0;
07789 } else {
07790 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07791 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07792 memset(&pref, 0, sizeof(pref));
07793 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07794 strcpy(caller_pref_buf,"disabled");
07795 strcpy(host_pref_buf,"disabled");
07796 } else {
07797 using_prefs = "mine";
07798 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07799
07800 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07801 pref = iaxs[fr->callno]->prefs;
07802 } else {
07803 pref = iaxs[fr->callno]->rprefs;
07804 using_prefs = "caller";
07805 }
07806 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07807
07808 } else
07809 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07810 }
07811 }
07812
07813 if (!format) {
07814 memset(&ied0, 0, sizeof(ied0));
07815 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07816 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07817 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07818 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07819 if (!iaxs[fr->callno]) {
07820 ast_mutex_unlock(&iaxsl[fr->callno]);
07821 return 1;
07822 }
07823 if (authdebug)
07824 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);
07825 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07826 break;
07827 }
07828 }
07829 }
07830 if (format) {
07831
07832 memset(&ied1, 0, sizeof(ied1));
07833 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07834 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07835 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07836 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07837 if (option_verbose > 2)
07838 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07839 "%srequested format = %s,\n"
07840 "%srequested prefs = %s,\n"
07841 "%sactual format = %s,\n"
07842 "%shost prefs = %s,\n"
07843 "%spriority = %s\n",
07844 ast_inet_ntoa(sin.sin_addr),
07845 VERBOSE_PREFIX_4,
07846 ast_getformatname(iaxs[fr->callno]->peerformat),
07847 VERBOSE_PREFIX_4,
07848 caller_pref_buf,
07849 VERBOSE_PREFIX_4,
07850 ast_getformatname(format),
07851 VERBOSE_PREFIX_4,
07852 host_pref_buf,
07853 VERBOSE_PREFIX_4,
07854 using_prefs);
07855
07856 iaxs[fr->callno]->chosenformat = format;
07857 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07858 } else {
07859 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07860
07861 if (option_verbose > 2)
07862 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07863 }
07864 }
07865 }
07866 break;
07867 }
07868 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07869 merge_encryption(iaxs[fr->callno],ies.encmethods);
07870 else
07871 iaxs[fr->callno]->encmethods = 0;
07872 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07873 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07874 if (!iaxs[fr->callno]) {
07875 ast_mutex_unlock(&iaxsl[fr->callno]);
07876 return 1;
07877 }
07878 break;
07879 case IAX_COMMAND_DPREQ:
07880
07881 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07882 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07883 if (iaxcompat) {
07884
07885 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07886 } else {
07887
07888 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07889 }
07890 }
07891 break;
07892 case IAX_COMMAND_HANGUP:
07893 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07894 if (option_debug)
07895 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07896
07897 if (ies.causecode && iaxs[fr->callno]->owner)
07898 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07899
07900 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07901 iax2_destroy(fr->callno);
07902 break;
07903 case IAX_COMMAND_REJECT:
07904
07905 if (ies.causecode && iaxs[fr->callno]->owner)
07906 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07907
07908 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07909 if (iaxs[fr->callno]->owner && authdebug)
07910 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07911 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07912 ies.cause ? ies.cause : "<Unknown>");
07913 if (option_debug)
07914 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07915 fr->callno);
07916 }
07917
07918 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07919 fr->ts, NULL, 0, fr->iseqno);
07920 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07921 iaxs[fr->callno]->error = EPERM;
07922 iax2_destroy(fr->callno);
07923 break;
07924 case IAX_COMMAND_TRANSFER:
07925 {
07926 struct ast_channel *bridged_chan;
07927
07928 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07929
07930
07931 ast_mutex_unlock(&iaxsl[fr->callno]);
07932 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07933 ast_mutex_lock(&iaxsl[fr->callno]);
07934 if (!iaxs[fr->callno]) {
07935 ast_mutex_unlock(&iaxsl[fr->callno]);
07936 return 1;
07937 }
07938
07939 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07940 if (!strcmp(ies.called_number, ast_parking_ext())) {
07941 struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
07942 ast_mutex_unlock(&iaxsl[fr->callno]);
07943 if (iax_park(bridged_chan, saved_channel)) {
07944 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07945 } else {
07946 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07947 }
07948 ast_mutex_lock(&iaxsl[fr->callno]);
07949 } else {
07950 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07951 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
07952 ies.called_number, iaxs[fr->callno]->context);
07953 else
07954 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
07955 ies.called_number, iaxs[fr->callno]->context);
07956 }
07957 } else
07958 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07959
07960 break;
07961 }
07962 case IAX_COMMAND_ACCEPT:
07963
07964 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07965 break;
07966 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07967
07968 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07969 iax2_destroy(fr->callno);
07970 break;
07971 }
07972 if (ies.format) {
07973 iaxs[fr->callno]->peerformat = ies.format;
07974 } else {
07975 if (iaxs[fr->callno]->owner)
07976 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07977 else
07978 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07979 }
07980 if (option_verbose > 2)
07981 ast_verbose(VERBOSE_PREFIX_3 "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
07982 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07983 memset(&ied0, 0, sizeof(ied0));
07984 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07985 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07986 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07987 if (!iaxs[fr->callno]) {
07988 ast_mutex_unlock(&iaxsl[fr->callno]);
07989 return 1;
07990 }
07991 if (authdebug)
07992 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);
07993 } else {
07994 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07995 if (iaxs[fr->callno]->owner) {
07996
07997 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07998 if (option_verbose > 2)
07999 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
08000 retryowner2:
08001 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
08002 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08003 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
08004 }
08005
08006 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
08007
08008 if (iaxs[fr->callno]->owner->writeformat)
08009 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
08010 if (iaxs[fr->callno]->owner->readformat)
08011 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
08012 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
08013 }
08014 }
08015 }
08016 if (iaxs[fr->callno]) {
08017 ast_mutex_lock(&dpcache_lock);
08018 dp = iaxs[fr->callno]->dpentries;
08019 while(dp) {
08020 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
08021 iax2_dprequest(dp, fr->callno);
08022 }
08023 dp = dp->peer;
08024 }
08025 ast_mutex_unlock(&dpcache_lock);
08026 }
08027 break;
08028 case IAX_COMMAND_POKE:
08029
08030 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
08031 if (!iaxs[fr->callno]) {
08032 ast_mutex_unlock(&iaxsl[fr->callno]);
08033 return 1;
08034 }
08035 break;
08036 case IAX_COMMAND_PING:
08037 {
08038 struct iax_ie_data pingied;
08039 construct_rr(iaxs[fr->callno], &pingied);
08040
08041 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
08042 }
08043 break;
08044 case IAX_COMMAND_PONG:
08045
08046 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
08047
08048 save_rr(fr, &ies);
08049
08050 if (iaxs[fr->callno]->peerpoke) {
08051 peer = iaxs[fr->callno]->peerpoke;
08052 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
08053 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
08054 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
08055 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
08056 ast_device_state_changed("IAX2/%s", peer->name);
08057 }
08058 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
08059 if (iaxs[fr->callno]->pingtime > peer->maxms) {
08060 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
08061 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
08062 ast_device_state_changed("IAX2/%s", peer->name);
08063 }
08064 }
08065 peer->lastms = iaxs[fr->callno]->pingtime;
08066 if (peer->smoothing && (peer->lastms > -1))
08067 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
08068 else if (peer->smoothing && peer->lastms < 0)
08069 peer->historicms = (0 + peer->historicms) / 2;
08070 else
08071 peer->historicms = iaxs[fr->callno]->pingtime;
08072
08073
08074 if (peer->pokeexpire > -1) {
08075 if (!ast_sched_del(sched, peer->pokeexpire)) {
08076 peer_unref(peer);
08077 peer->pokeexpire = -1;
08078 }
08079 }
08080
08081 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
08082 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08083 else
08084 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
08085 if (peer->pokeexpire == -1)
08086 peer_unref(peer);
08087
08088 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08089
08090 iax2_destroy(fr->callno);
08091 peer->callno = 0;
08092 if (option_debug)
08093 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
08094 }
08095 break;
08096 case IAX_COMMAND_LAGRQ:
08097 case IAX_COMMAND_LAGRP:
08098 f.src = "LAGRQ";
08099 f.mallocd = 0;
08100 f.offset = 0;
08101 f.samples = 0;
08102 iax_frame_wrap(fr, &f);
08103 if(f.subclass == IAX_COMMAND_LAGRQ) {
08104
08105 fr->af.subclass = IAX_COMMAND_LAGRP;
08106 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
08107 } else {
08108
08109 unsigned int ts;
08110
08111 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
08112 iaxs[fr->callno]->lag = ts - fr->ts;
08113 if (option_debug && iaxdebug)
08114 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
08115 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
08116 }
08117 break;
08118 case IAX_COMMAND_AUTHREQ:
08119 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08120 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>");
08121 break;
08122 }
08123 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
08124 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
08125 .subclass = AST_CONTROL_HANGUP,
08126 };
08127 ast_log(LOG_WARNING,
08128 "I don't know how to authenticate %s to %s\n",
08129 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
08130 iax2_queue_frame(fr->callno, &hangup_fr);
08131 }
08132 if (!iaxs[fr->callno]) {
08133 ast_mutex_unlock(&iaxsl[fr->callno]);
08134 return 1;
08135 }
08136 break;
08137 case IAX_COMMAND_AUTHREP:
08138
08139 if (delayreject)
08140 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08141
08142 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08143 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>");
08144 break;
08145 }
08146 if (authenticate_verify(iaxs[fr->callno], &ies)) {
08147 if (authdebug)
08148 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);
08149 memset(&ied0, 0, sizeof(ied0));
08150 auth_fail(fr->callno, IAX_COMMAND_REJECT);
08151 break;
08152 }
08153 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08154
08155 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08156 } else
08157 exists = 0;
08158 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08159 if (authdebug)
08160 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);
08161 memset(&ied0, 0, sizeof(ied0));
08162 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08163 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08164 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08165 if (!iaxs[fr->callno]) {
08166 ast_mutex_unlock(&iaxsl[fr->callno]);
08167 return 1;
08168 }
08169 } else {
08170
08171 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08172 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08173 using_prefs = "reqonly";
08174 } else {
08175 using_prefs = "disabled";
08176 }
08177 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08178 memset(&pref, 0, sizeof(pref));
08179 strcpy(caller_pref_buf, "disabled");
08180 strcpy(host_pref_buf, "disabled");
08181 } else {
08182 using_prefs = "mine";
08183 if (ies.codec_prefs)
08184 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08185 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08186 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08187 pref = iaxs[fr->callno]->rprefs;
08188 using_prefs = "caller";
08189 } else {
08190 pref = iaxs[fr->callno]->prefs;
08191 }
08192 } else
08193 pref = iaxs[fr->callno]->prefs;
08194
08195 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08196 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08197 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08198 }
08199 if (!format) {
08200 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08201 if (option_debug)
08202 ast_log(LOG_DEBUG, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
08203 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08204 }
08205 if (!format) {
08206 if (authdebug) {
08207 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08208 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);
08209 else
08210 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);
08211 }
08212 memset(&ied0, 0, sizeof(ied0));
08213 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08214 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08215 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08216 if (!iaxs[fr->callno]) {
08217 ast_mutex_unlock(&iaxsl[fr->callno]);
08218 return 1;
08219 }
08220 } else {
08221
08222 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08223 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08224 format = 0;
08225 } else {
08226 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08227 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08228 memset(&pref, 0, sizeof(pref));
08229 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08230 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08231 strcpy(caller_pref_buf,"disabled");
08232 strcpy(host_pref_buf,"disabled");
08233 } else {
08234 using_prefs = "mine";
08235 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08236
08237 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08238 pref = iaxs[fr->callno]->prefs;
08239 } else {
08240 pref = iaxs[fr->callno]->rprefs;
08241 using_prefs = "caller";
08242 }
08243 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08244 } else
08245 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08246 }
08247 }
08248 if (!format) {
08249 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08250 if (authdebug) {
08251 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08252 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);
08253 else
08254 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);
08255 }
08256 memset(&ied0, 0, sizeof(ied0));
08257 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08258 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08259 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08260 if (!iaxs[fr->callno]) {
08261 ast_mutex_unlock(&iaxsl[fr->callno]);
08262 return 1;
08263 }
08264 }
08265 }
08266 }
08267 if (format) {
08268
08269 memset(&ied1, 0, sizeof(ied1));
08270 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08271 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08272 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08273 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08274 if (option_verbose > 2)
08275 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08276 "%srequested format = %s,\n"
08277 "%srequested prefs = %s,\n"
08278 "%sactual format = %s,\n"
08279 "%shost prefs = %s,\n"
08280 "%spriority = %s\n",
08281 ast_inet_ntoa(sin.sin_addr),
08282 VERBOSE_PREFIX_4,
08283 ast_getformatname(iaxs[fr->callno]->peerformat),
08284 VERBOSE_PREFIX_4,
08285 caller_pref_buf,
08286 VERBOSE_PREFIX_4,
08287 ast_getformatname(format),
08288 VERBOSE_PREFIX_4,
08289 host_pref_buf,
08290 VERBOSE_PREFIX_4,
08291 using_prefs);
08292
08293 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08294 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08295 iax2_destroy(fr->callno);
08296 } else {
08297 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08298
08299 if (option_verbose > 2)
08300 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08301 }
08302 }
08303 }
08304 break;
08305 case IAX_COMMAND_DIAL:
08306 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08307 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08308 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08309 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08310 if (authdebug)
08311 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);
08312 memset(&ied0, 0, sizeof(ied0));
08313 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08314 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08315 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08316 if (!iaxs[fr->callno]) {
08317 ast_mutex_unlock(&iaxsl[fr->callno]);
08318 return 1;
08319 }
08320 } else {
08321 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08322 if (option_verbose > 2)
08323 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08324 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08325 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08326 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08327 iax2_destroy(fr->callno);
08328 }
08329 }
08330 break;
08331 case IAX_COMMAND_INVAL:
08332 iaxs[fr->callno]->error = ENOTCONN;
08333 if (option_debug)
08334 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08335 iax2_destroy(fr->callno);
08336 if (option_debug)
08337 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08338 break;
08339 case IAX_COMMAND_VNAK:
08340 if (option_debug)
08341 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08342
08343 vnak_retransmit(fr->callno, fr->iseqno);
08344 break;
08345 case IAX_COMMAND_REGREQ:
08346 case IAX_COMMAND_REGREL:
08347
08348 if (delayreject)
08349 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08350 if (register_verify(fr->callno, &sin, &ies)) {
08351 if (!iaxs[fr->callno]) {
08352 ast_mutex_unlock(&iaxsl[fr->callno]);
08353 return 1;
08354 }
08355
08356 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08357 break;
08358 }
08359 if (!iaxs[fr->callno]) {
08360 ast_mutex_unlock(&iaxsl[fr->callno]);
08361 return 1;
08362 }
08363 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
08364 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
08365 if (f.subclass == IAX_COMMAND_REGREL)
08366 memset(&sin, 0, sizeof(sin));
08367 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08368 ast_log(LOG_WARNING, "Registry error\n");
08369 if (!iaxs[fr->callno]) {
08370 ast_mutex_unlock(&iaxsl[fr->callno]);
08371 return 1;
08372 }
08373 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08374 ast_mutex_unlock(&iaxsl[fr->callno]);
08375 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08376 ast_mutex_lock(&iaxsl[fr->callno]);
08377 if (!iaxs[fr->callno]) {
08378 ast_mutex_unlock(&iaxsl[fr->callno]);
08379 return 1;
08380 }
08381 }
08382 break;
08383 }
08384 registry_authrequest(fr->callno);
08385 if (!iaxs[fr->callno]) {
08386 ast_mutex_unlock(&iaxsl[fr->callno]);
08387 return 1;
08388 }
08389 break;
08390 case IAX_COMMAND_REGACK:
08391 if (iax2_ack_registry(&ies, &sin, fr->callno))
08392 ast_log(LOG_WARNING, "Registration failure\n");
08393
08394 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08395 iax2_destroy(fr->callno);
08396 break;
08397 case IAX_COMMAND_REGREJ:
08398 if (iaxs[fr->callno]->reg) {
08399 if (authdebug) {
08400 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));
08401 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
08402 }
08403 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08404 }
08405
08406 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08407 iax2_destroy(fr->callno);
08408 break;
08409 case IAX_COMMAND_REGAUTH:
08410
08411 if (registry_rerequest(&ies, fr->callno, &sin)) {
08412 memset(&ied0, 0, sizeof(ied0));
08413 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08414 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08415 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08416 if (!iaxs[fr->callno]) {
08417 ast_mutex_unlock(&iaxsl[fr->callno]);
08418 return 1;
08419 }
08420 }
08421 break;
08422 case IAX_COMMAND_TXREJ:
08423 iaxs[fr->callno]->transferring = 0;
08424 if (option_verbose > 2)
08425 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08426 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08427 if (iaxs[fr->callno]->bridgecallno) {
08428 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08429 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08430 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08431 }
08432 }
08433 break;
08434 case IAX_COMMAND_TXREADY:
08435 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08436 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08437 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08438 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08439 else
08440 iaxs[fr->callno]->transferring = TRANSFER_READY;
08441 if (option_verbose > 2)
08442 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08443 if (iaxs[fr->callno]->bridgecallno) {
08444 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08445 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08446
08447 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08448 if (option_verbose > 2)
08449 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08450 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08451
08452 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08453 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08454
08455 memset(&ied0, 0, sizeof(ied0));
08456 memset(&ied1, 0, sizeof(ied1));
08457 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08458 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08459 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08460 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08461 } else {
08462 if (option_verbose > 2)
08463 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08464 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08465
08466 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08467 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08468 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08469 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08470
08471
08472 stop_stuff(fr->callno);
08473 stop_stuff(iaxs[fr->callno]->bridgecallno);
08474
08475 memset(&ied0, 0, sizeof(ied0));
08476 memset(&ied1, 0, sizeof(ied1));
08477 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08478 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08479 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08480 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08481 }
08482
08483 }
08484 }
08485 }
08486 break;
08487 case IAX_COMMAND_TXREQ:
08488 try_transfer(iaxs[fr->callno], &ies);
08489 break;
08490 case IAX_COMMAND_TXCNT:
08491 if (iaxs[fr->callno]->transferring)
08492 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08493 break;
08494 case IAX_COMMAND_TXREL:
08495
08496 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08497 complete_transfer(fr->callno, &ies);
08498 stop_stuff(fr->callno);
08499 break;
08500 case IAX_COMMAND_TXMEDIA:
08501 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08502 AST_LIST_LOCK(&iaxq.queue);
08503 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08504
08505 if ((fr->callno == cur->callno) && (cur->transfer)) {
08506 cur->retries = -1;
08507 }
08508 }
08509 AST_LIST_UNLOCK(&iaxq.queue);
08510
08511 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08512 }
08513 break;
08514 case IAX_COMMAND_DPREP:
08515 complete_dpreply(iaxs[fr->callno], &ies);
08516 break;
08517 case IAX_COMMAND_UNSUPPORT:
08518 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08519 break;
08520 case IAX_COMMAND_FWDOWNL:
08521
08522 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08523 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08524 break;
08525 }
08526 memset(&ied0, 0, sizeof(ied0));
08527 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08528 if (res < 0)
08529 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08530 else if (res > 0)
08531 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08532 else
08533 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08534 if (!iaxs[fr->callno]) {
08535 ast_mutex_unlock(&iaxsl[fr->callno]);
08536 return 1;
08537 }
08538 break;
08539 default:
08540 if (option_debug)
08541 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08542 memset(&ied0, 0, sizeof(ied0));
08543 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08544 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08545 }
08546
08547 if ((f.subclass != IAX_COMMAND_ACK) &&
08548 (f.subclass != IAX_COMMAND_TXCNT) &&
08549 (f.subclass != IAX_COMMAND_TXACC) &&
08550 (f.subclass != IAX_COMMAND_INVAL) &&
08551 (f.subclass != IAX_COMMAND_VNAK)) {
08552 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08553 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08554 }
08555 ast_mutex_unlock(&iaxsl[fr->callno]);
08556 return 1;
08557 }
08558
08559 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08560 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08561 } else if (minivid) {
08562 f.frametype = AST_FRAME_VIDEO;
08563 if (iaxs[fr->callno]->videoformat > 0)
08564 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08565 else {
08566 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
08567 iax2_vnak(fr->callno);
08568 ast_mutex_unlock(&iaxsl[fr->callno]);
08569 return 1;
08570 }
08571 f.datalen = res - sizeof(*vh);
08572 if (f.datalen)
08573 f.data = thread->buf + sizeof(*vh);
08574 else
08575 f.data = NULL;
08576 #ifdef IAXTESTS
08577 if (test_resync) {
08578 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08579 } else
08580 #endif
08581 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08582 } else {
08583
08584 f.frametype = AST_FRAME_VOICE;
08585 if (iaxs[fr->callno]->voiceformat > 0)
08586 f.subclass = iaxs[fr->callno]->voiceformat;
08587 else {
08588 if (option_debug)
08589 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08590 iax2_vnak(fr->callno);
08591 ast_mutex_unlock(&iaxsl[fr->callno]);
08592 return 1;
08593 }
08594 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08595 if (f.datalen < 0) {
08596 ast_log(LOG_WARNING, "Datalen < 0?\n");
08597 ast_mutex_unlock(&iaxsl[fr->callno]);
08598 return 1;
08599 }
08600 if (f.datalen)
08601 f.data = thread->buf + sizeof(*mh);
08602 else
08603 f.data = NULL;
08604 #ifdef IAXTESTS
08605 if (test_resync) {
08606 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08607 } else
08608 #endif
08609 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08610
08611 }
08612
08613 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08614 ast_mutex_unlock(&iaxsl[fr->callno]);
08615 return 1;
08616 }
08617
08618 f.src = "IAX2";
08619 f.mallocd = 0;
08620 f.offset = 0;
08621 f.len = 0;
08622 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08623 f.samples = ast_codec_get_samples(&f);
08624
08625 if (f.subclass == AST_FORMAT_SLINEAR)
08626 ast_frame_byteswap_be(&f);
08627 } else
08628 f.samples = 0;
08629 iax_frame_wrap(fr, &f);
08630
08631
08632 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08633
08634 fr->outoforder = 0;
08635 } else {
08636 if (option_debug && iaxdebug && iaxs[fr->callno])
08637 ast_log(LOG_DEBUG, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
08638 fr->outoforder = -1;
08639 }
08640 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08641 duped_fr = iaxfrdup2(fr);
08642 if (duped_fr) {
08643 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08644 }
08645 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08646 iaxs[fr->callno]->last = fr->ts;
08647 #if 1
08648 if (option_debug && iaxdebug)
08649 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08650 #endif
08651 }
08652
08653
08654 ast_mutex_unlock(&iaxsl[fr->callno]);
08655 return 1;
08656 }
08657
08658
08659 static void iax2_process_thread_cleanup(void *data)
08660 {
08661 struct iax2_thread *thread = data;
08662 ast_mutex_destroy(&thread->lock);
08663 ast_cond_destroy(&thread->cond);
08664 free(thread);
08665 ast_atomic_dec_and_test(&iaxactivethreadcount);
08666 }
08667
08668 static void *iax2_process_thread(void *data)
08669 {
08670 struct iax2_thread *thread = data;
08671 struct timeval tv;
08672 struct timespec ts;
08673 int put_into_idle = 0;
08674
08675 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08676 pthread_cleanup_push(iax2_process_thread_cleanup, data);
08677 for(;;) {
08678
08679 ast_mutex_lock(&thread->lock);
08680
08681
08682 thread->ready_for_signal = 1;
08683
08684
08685 if (put_into_idle)
08686 insert_idle_thread(thread);
08687
08688 if (thread->type == IAX_TYPE_DYNAMIC) {
08689 struct iax2_thread *t = NULL;
08690
08691 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08692 ts.tv_sec = tv.tv_sec;
08693 ts.tv_nsec = tv.tv_usec * 1000;
08694 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08695
08696
08697 if (!put_into_idle) {
08698 ast_mutex_unlock(&thread->lock);
08699 break;
08700 }
08701 AST_LIST_LOCK(&dynamic_list);
08702
08703 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08704 iaxdynamicthreadcount--;
08705 AST_LIST_UNLOCK(&dynamic_list);
08706 if (t) {
08707
08708
08709
08710 ast_mutex_unlock(&thread->lock);
08711 break;
08712 }
08713
08714
08715
08716 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08717 ts.tv_sec = tv.tv_sec;
08718 ts.tv_nsec = tv.tv_usec * 1000;
08719 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08720 {
08721 ast_mutex_unlock(&thread->lock);
08722 break;
08723 }
08724 }
08725 } else {
08726 ast_cond_wait(&thread->cond, &thread->lock);
08727 }
08728
08729
08730 put_into_idle = 1;
08731
08732 ast_mutex_unlock(&thread->lock);
08733
08734 if (thread->iostate == IAX_IOSTATE_IDLE)
08735 continue;
08736
08737
08738 AST_LIST_LOCK(&active_list);
08739 AST_LIST_INSERT_HEAD(&active_list, thread, list);
08740 AST_LIST_UNLOCK(&active_list);
08741
08742
08743 switch(thread->iostate) {
08744 case IAX_IOSTATE_READY:
08745 thread->actions++;
08746 thread->iostate = IAX_IOSTATE_PROCESSING;
08747 socket_process(thread);
08748 handle_deferred_full_frames(thread);
08749 break;
08750 case IAX_IOSTATE_SCHEDREADY:
08751 thread->actions++;
08752 thread->iostate = IAX_IOSTATE_PROCESSING;
08753 #ifdef SCHED_MULTITHREADED
08754 thread->schedfunc(thread->scheddata);
08755 #endif
08756 break;
08757 }
08758 time(&thread->checktime);
08759 thread->iostate = IAX_IOSTATE_IDLE;
08760 #ifdef DEBUG_SCHED_MULTITHREAD
08761 thread->curfunc[0]='\0';
08762 #endif
08763
08764
08765 AST_LIST_LOCK(&active_list);
08766 AST_LIST_REMOVE(&active_list, thread, list);
08767 AST_LIST_UNLOCK(&active_list);
08768
08769
08770 handle_deferred_full_frames(thread);
08771 }
08772
08773
08774
08775
08776
08777 AST_LIST_LOCK(&idle_list);
08778 AST_LIST_REMOVE(&idle_list, thread, list);
08779 AST_LIST_UNLOCK(&idle_list);
08780
08781 AST_LIST_LOCK(&dynamic_list);
08782 AST_LIST_REMOVE(&dynamic_list, thread, list);
08783 AST_LIST_UNLOCK(&dynamic_list);
08784
08785
08786
08787
08788 pthread_cleanup_pop(1);
08789
08790 return NULL;
08791 }
08792
08793 static int iax2_do_register(struct iax2_registry *reg)
08794 {
08795 struct iax_ie_data ied;
08796 if (option_debug && iaxdebug)
08797 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08798
08799 if (reg->dnsmgr &&
08800 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08801
08802 ast_dnsmgr_refresh(reg->dnsmgr);
08803 }
08804
08805
08806
08807
08808
08809 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08810 int callno = reg->callno;
08811 ast_mutex_lock(&iaxsl[callno]);
08812 iax2_destroy(callno);
08813 ast_mutex_unlock(&iaxsl[callno]);
08814 reg->callno = 0;
08815 }
08816 if (!reg->addr.sin_addr.s_addr) {
08817 if (option_debug && iaxdebug)
08818 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08819
08820 AST_SCHED_DEL(sched, reg->expire);
08821 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08822 return -1;
08823 }
08824
08825 if (!reg->callno) {
08826 if (option_debug)
08827 ast_log(LOG_DEBUG, "Allocate call number\n");
08828 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
08829 if (reg->callno < 1) {
08830 ast_log(LOG_WARNING, "Unable to create call for registration\n");
08831 return -1;
08832 } else if (option_debug)
08833 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08834 iaxs[reg->callno]->reg = reg;
08835 ast_mutex_unlock(&iaxsl[reg->callno]);
08836 }
08837
08838 AST_SCHED_DEL(sched, reg->expire);
08839
08840 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08841
08842 memset(&ied, 0, sizeof(ied));
08843 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08844 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08845 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08846 reg->regstate = REG_STATE_REGSENT;
08847 return 0;
08848 }
08849
08850 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08851 {
08852 if (pos != 3)
08853 return NULL;
08854 return iax_prov_complete_template(line, word, pos, state);
08855 }
08856
08857 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08858 {
08859
08860
08861 struct iax_ie_data provdata;
08862 struct iax_ie_data ied;
08863 unsigned int sig;
08864 struct sockaddr_in sin;
08865 int callno;
08866 struct create_addr_info cai;
08867
08868 memset(&cai, 0, sizeof(cai));
08869
08870 if (option_debug)
08871 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08872
08873 if (iax_provision_build(&provdata, &sig, template, force)) {
08874 if (option_debug)
08875 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08876 return 0;
08877 }
08878
08879 if (end) {
08880 memcpy(&sin, end, sizeof(sin));
08881 cai.sockfd = sockfd;
08882 } else if (create_addr(dest, NULL, &sin, &cai))
08883 return -1;
08884
08885
08886 memset(&ied, 0, sizeof(ied));
08887 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08888
08889 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08890 if (!callno)
08891 return -1;
08892
08893 if (iaxs[callno]) {
08894
08895 AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08896 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08897 ast_set_flag(iaxs[callno], IAX_PROVISION);
08898
08899 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08900 }
08901 ast_mutex_unlock(&iaxsl[callno]);
08902
08903 return 1;
08904 }
08905
08906 static char *papp = "IAX2Provision";
08907 static char *psyn = "Provision a calling IAXy with a given template";
08908 static char *pdescrip =
08909 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08910 "the calling entity is in fact an IAXy) with the given template or\n"
08911 "default if one is not specified. Returns -1 on error or 0 on success.\n";
08912
08913
08914
08915
08916 static int iax2_prov_app(struct ast_channel *chan, void *data)
08917 {
08918 int res;
08919 char *sdata;
08920 char *opts;
08921 int force =0;
08922 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08923 if (ast_strlen_zero(data))
08924 data = "default";
08925 sdata = ast_strdupa(data);
08926 opts = strchr(sdata, '|');
08927 if (opts)
08928 *opts='\0';
08929
08930 if (chan->tech != &iax2_tech) {
08931 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08932 return -1;
08933 }
08934 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08935 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08936 return -1;
08937 }
08938 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08939 if (option_verbose > 2)
08940 ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n",
08941 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08942 sdata, res);
08943 return res;
08944 }
08945
08946
08947 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08948 {
08949 int force = 0;
08950 int res;
08951 if (argc < 4)
08952 return RESULT_SHOWUSAGE;
08953 if ((argc > 4)) {
08954 if (!strcasecmp(argv[4], "forced"))
08955 force = 1;
08956 else
08957 return RESULT_SHOWUSAGE;
08958 }
08959 res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08960 if (res < 0)
08961 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08962 else if (res < 1)
08963 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08964 else
08965 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08966 return RESULT_SUCCESS;
08967 }
08968
08969 static void __iax2_poke_noanswer(const void *data)
08970 {
08971 struct iax2_peer *peer = (struct iax2_peer *)data;
08972 int callno;
08973
08974 if (peer->lastms > -1) {
08975 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08976 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08977 ast_device_state_changed("IAX2/%s", peer->name);
08978 }
08979 if ((callno = peer->callno) > 0) {
08980 ast_mutex_lock(&iaxsl[callno]);
08981 iax2_destroy(callno);
08982 ast_mutex_unlock(&iaxsl[callno]);
08983 }
08984 peer->callno = 0;
08985 peer->lastms = -1;
08986
08987 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08988 if (peer->pokeexpire == -1)
08989 peer_unref(peer);
08990 }
08991
08992 static int iax2_poke_noanswer(const void *data)
08993 {
08994 struct iax2_peer *peer = (struct iax2_peer *)data;
08995 peer->pokeexpire = -1;
08996 #ifdef SCHED_MULTITHREADED
08997 if (schedule_action(__iax2_poke_noanswer, data))
08998 #endif
08999 __iax2_poke_noanswer(data);
09000 peer_unref(peer);
09001 return 0;
09002 }
09003
09004 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
09005 {
09006 struct iax2_peer *peer = obj;
09007
09008 iax2_poke_peer(peer, 0);
09009
09010 return 0;
09011 }
09012
09013 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
09014 {
09015 int callno;
09016 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
09017
09018
09019 peer->lastms = 0;
09020 peer->historicms = 0;
09021 peer->pokeexpire = -1;
09022 peer->callno = 0;
09023 return 0;
09024 }
09025
09026
09027 if ((callno = peer->callno) > 0) {
09028 ast_log(LOG_NOTICE, "Still have a callno...\n");
09029 ast_mutex_lock(&iaxsl[callno]);
09030 iax2_destroy(callno);
09031 ast_mutex_unlock(&iaxsl[callno]);
09032 }
09033 if (heldcall)
09034 ast_mutex_unlock(&iaxsl[heldcall]);
09035 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
09036 if (heldcall)
09037 ast_mutex_lock(&iaxsl[heldcall]);
09038 if (peer->callno < 1) {
09039 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
09040 return -1;
09041 }
09042
09043
09044 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
09045 iaxs[peer->callno]->peerpoke = peer;
09046
09047
09048 if (peer->pokeexpire > -1) {
09049 if (!ast_sched_del(sched, peer->pokeexpire)) {
09050 peer->pokeexpire = -1;
09051 peer_unref(peer);
09052 }
09053 }
09054
09055
09056
09057 if (peer->lastms < 0) {
09058 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
09059 } else
09060 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
09061
09062 if (peer->pokeexpire == -1)
09063 peer_unref(peer);
09064
09065
09066 ast_mutex_lock(&iaxsl[callno]);
09067 if (iaxs[callno]) {
09068 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
09069 }
09070 ast_mutex_unlock(&iaxsl[callno]);
09071
09072 return 0;
09073 }
09074
09075 static void free_context(struct iax2_context *con)
09076 {
09077 struct iax2_context *conl;
09078 while(con) {
09079 conl = con;
09080 con = con->next;
09081 free(conl);
09082 }
09083 }
09084
09085 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
09086 {
09087 int callno;
09088 int res;
09089 int fmt, native;
09090 struct sockaddr_in sin;
09091 struct ast_channel *c;
09092 struct parsed_dial_string pds;
09093 struct create_addr_info cai;
09094 char *tmpstr;
09095
09096 memset(&pds, 0, sizeof(pds));
09097 tmpstr = ast_strdupa(data);
09098 parse_dial_string(tmpstr, &pds);
09099
09100 if (ast_strlen_zero(pds.peer)) {
09101 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
09102 return NULL;
09103 }
09104
09105 memset(&cai, 0, sizeof(cai));
09106 cai.capability = iax2_capability;
09107
09108 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09109
09110
09111 if (create_addr(pds.peer, NULL, &sin, &cai)) {
09112 *cause = AST_CAUSE_UNREGISTERED;
09113 return NULL;
09114 }
09115
09116 if (pds.port)
09117 sin.sin_port = htons(atoi(pds.port));
09118
09119 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
09120 if (callno < 1) {
09121 ast_log(LOG_WARNING, "Unable to create call\n");
09122 *cause = AST_CAUSE_CONGESTION;
09123 return NULL;
09124 }
09125
09126
09127 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09128 if (ast_test_flag(&cai, IAX_TRUNK)) {
09129 int new_callno;
09130 if ((new_callno = make_trunk(callno, 1)) != -1)
09131 callno = new_callno;
09132 }
09133 iaxs[callno]->maxtime = cai.maxtime;
09134 if (cai.found)
09135 ast_string_field_set(iaxs[callno], host, pds.peer);
09136
09137 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
09138
09139 ast_mutex_unlock(&iaxsl[callno]);
09140
09141 if (c) {
09142
09143 if (c->nativeformats & format)
09144 c->nativeformats &= format;
09145 else {
09146 native = c->nativeformats;
09147 fmt = format;
09148 res = ast_translator_best_choice(&fmt, &native);
09149 if (res < 0) {
09150 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09151 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09152 ast_hangup(c);
09153 return NULL;
09154 }
09155 c->nativeformats = native;
09156 }
09157 c->readformat = ast_best_codec(c->nativeformats);
09158 c->writeformat = c->readformat;
09159 }
09160
09161 return c;
09162 }
09163
09164 static void *sched_thread(void *ignore)
09165 {
09166 int count;
09167 int res;
09168 struct timeval tv;
09169 struct timespec ts;
09170
09171 for (;;) {
09172 pthread_testcancel();
09173 ast_mutex_lock(&sched_lock);
09174 res = ast_sched_wait(sched);
09175 if ((res > 1000) || (res < 0))
09176 res = 1000;
09177 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
09178 ts.tv_sec = tv.tv_sec;
09179 ts.tv_nsec = tv.tv_usec * 1000;
09180 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09181 ast_mutex_unlock(&sched_lock);
09182 pthread_testcancel();
09183
09184 count = ast_sched_runq(sched);
09185 if (option_debug && count >= 20)
09186 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09187 }
09188 return NULL;
09189 }
09190
09191 static void *network_thread(void *ignore)
09192 {
09193
09194
09195 int res, count, wakeup;
09196 struct iax_frame *f;
09197
09198 if (timingfd > -1)
09199 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09200
09201 for(;;) {
09202 pthread_testcancel();
09203
09204
09205
09206 AST_LIST_LOCK(&iaxq.queue);
09207 count = 0;
09208 wakeup = -1;
09209 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09210 if (f->sentyet)
09211 continue;
09212
09213
09214 if (ast_mutex_trylock(&iaxsl[f->callno])) {
09215 wakeup = 1;
09216 continue;
09217 }
09218
09219 f->sentyet++;
09220
09221 if (iaxs[f->callno]) {
09222 send_packet(f);
09223 count++;
09224 }
09225
09226 ast_mutex_unlock(&iaxsl[f->callno]);
09227
09228 if (f->retries < 0) {
09229
09230 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09231 iaxq.count--;
09232
09233 iax_frame_free(f);
09234 } else {
09235
09236 f->retries++;
09237 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09238 }
09239 }
09240 AST_LIST_TRAVERSE_SAFE_END
09241 AST_LIST_UNLOCK(&iaxq.queue);
09242
09243 pthread_testcancel();
09244
09245 if (option_debug && count >= 20)
09246 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09247
09248
09249 res = ast_io_wait(io, wakeup);
09250 if (res >= 0) {
09251 if (option_debug && res >= 20)
09252 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09253 }
09254 }
09255 return NULL;
09256 }
09257
09258 static int start_network_thread(void)
09259 {
09260 pthread_attr_t attr;
09261 int threadcount = 0;
09262 int x;
09263 for (x = 0; x < iaxthreadcount; x++) {
09264 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09265 if (thread) {
09266 thread->type = IAX_TYPE_POOL;
09267 thread->threadnum = ++threadcount;
09268 ast_mutex_init(&thread->lock);
09269 ast_cond_init(&thread->cond, NULL);
09270 pthread_attr_init(&attr);
09271 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
09272 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09273 ast_log(LOG_WARNING, "Failed to create new thread!\n");
09274 free(thread);
09275 thread = NULL;
09276 }
09277 AST_LIST_LOCK(&idle_list);
09278 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09279 AST_LIST_UNLOCK(&idle_list);
09280 }
09281 }
09282 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09283 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09284 if (option_verbose > 1)
09285 ast_verbose(VERBOSE_PREFIX_2 "%d helper threads started\n", threadcount);
09286 return 0;
09287 }
09288
09289 static struct iax2_context *build_context(char *context)
09290 {
09291 struct iax2_context *con;
09292
09293 if ((con = ast_calloc(1, sizeof(*con))))
09294 ast_copy_string(con->context, context, sizeof(con->context));
09295
09296 return con;
09297 }
09298
09299 static int get_auth_methods(char *value)
09300 {
09301 int methods = 0;
09302 if (strstr(value, "rsa"))
09303 methods |= IAX_AUTH_RSA;
09304 if (strstr(value, "md5"))
09305 methods |= IAX_AUTH_MD5;
09306 if (strstr(value, "plaintext"))
09307 methods |= IAX_AUTH_PLAINTEXT;
09308 return methods;
09309 }
09310
09311
09312
09313
09314
09315 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09316 {
09317 int sd;
09318 int res;
09319
09320 sd = socket(AF_INET, SOCK_DGRAM, 0);
09321 if (sd < 0) {
09322 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09323 return -1;
09324 }
09325
09326 res = bind(sd, sa, salen);
09327 if (res < 0) {
09328 if (option_debug)
09329 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09330 close(sd);
09331 return 1;
09332 }
09333
09334 close(sd);
09335 return 0;
09336 }
09337
09338
09339
09340
09341 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09342 {
09343 struct sockaddr_in sin;
09344 int nonlocal = 1;
09345 int port = IAX_DEFAULT_PORTNO;
09346 int sockfd = defaultsockfd;
09347 char *tmp;
09348 char *addr;
09349 char *portstr;
09350
09351 if (!(tmp = ast_strdupa(srcaddr)))
09352 return -1;
09353
09354 addr = strsep(&tmp, ":");
09355 portstr = tmp;
09356
09357 if (portstr) {
09358 port = atoi(portstr);
09359 if (port < 1)
09360 port = IAX_DEFAULT_PORTNO;
09361 }
09362
09363 if (!ast_get_ip(&sin, addr)) {
09364 struct ast_netsock *sock;
09365 int res;
09366
09367 sin.sin_port = 0;
09368 sin.sin_family = AF_INET;
09369 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09370 if (res == 0) {
09371
09372 sin.sin_port = htons(port);
09373 if (!(sock = ast_netsock_find(netsock, &sin)))
09374 sock = ast_netsock_find(outsock, &sin);
09375 if (sock) {
09376 sockfd = ast_netsock_sockfd(sock);
09377 nonlocal = 0;
09378 } else {
09379 unsigned int orig_saddr = sin.sin_addr.s_addr;
09380
09381 sin.sin_addr.s_addr = INADDR_ANY;
09382 if (ast_netsock_find(netsock, &sin)) {
09383 sin.sin_addr.s_addr = orig_saddr;
09384 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09385 if (sock) {
09386 sockfd = ast_netsock_sockfd(sock);
09387 ast_netsock_unref(sock);
09388 nonlocal = 0;
09389 } else {
09390 nonlocal = 2;
09391 }
09392 }
09393 }
09394 }
09395 }
09396
09397 peer->sockfd = sockfd;
09398
09399 if (nonlocal == 1) {
09400 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09401 srcaddr, peer->name);
09402 return -1;
09403 } else if (nonlocal == 2) {
09404 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09405 srcaddr, peer->name);
09406 return -1;
09407 } else {
09408 if (option_debug)
09409 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09410 return 0;
09411 }
09412 }
09413
09414 static void peer_destructor(void *obj)
09415 {
09416 struct iax2_peer *peer = obj;
09417 int callno = peer->callno;
09418
09419 ast_free_ha(peer->ha);
09420
09421 if (callno > 0) {
09422 ast_mutex_lock(&iaxsl[callno]);
09423 iax2_destroy(callno);
09424 ast_mutex_unlock(&iaxsl[callno]);
09425 }
09426
09427 register_peer_exten(peer, 0);
09428
09429 if (peer->dnsmgr)
09430 ast_dnsmgr_release(peer->dnsmgr);
09431
09432 ast_string_field_free_memory(peer);
09433 }
09434
09435
09436 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09437 {
09438 struct iax2_peer *peer = NULL;
09439 struct ast_ha *oldha = NULL;
09440 int maskfound=0;
09441 int found=0;
09442 int firstpass=1;
09443 struct iax2_peer tmp_peer = {
09444 .name = name,
09445 };
09446
09447 if (!temponly) {
09448 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09449 if (peer && !ast_test_flag(peer, IAX_DELME))
09450 firstpass = 0;
09451 }
09452
09453 if (peer) {
09454 found++;
09455 if (firstpass) {
09456 oldha = peer->ha;
09457 peer->ha = NULL;
09458 }
09459 unlink_peer(peer);
09460 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09461 peer->expire = -1;
09462 peer->pokeexpire = -1;
09463 peer->sockfd = defaultsockfd;
09464 if (ast_string_field_init(peer, 32))
09465 peer = peer_unref(peer);
09466 }
09467
09468 if (peer) {
09469 if (firstpass) {
09470 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09471 peer->encmethods = iax2_encryption;
09472 peer->adsi = adsi;
09473 ast_string_field_set(peer,secret,"");
09474 if (!found) {
09475 ast_string_field_set(peer, name, name);
09476 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09477 peer->expiry = min_reg_expire;
09478 }
09479 peer->prefs = prefs;
09480 peer->capability = iax2_capability;
09481 peer->smoothing = 0;
09482 peer->pokefreqok = DEFAULT_FREQ_OK;
09483 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09484 ast_string_field_set(peer,context,"");
09485 ast_string_field_set(peer,peercontext,"");
09486 ast_clear_flag(peer, IAX_HASCALLERID);
09487 ast_string_field_set(peer, cid_name, "");
09488 ast_string_field_set(peer, cid_num, "");
09489 }
09490
09491 if (!v) {
09492 v = alt;
09493 alt = NULL;
09494 }
09495 while(v) {
09496 if (!strcasecmp(v->name, "secret")) {
09497 ast_string_field_set(peer, secret, v->value);
09498 } else if (!strcasecmp(v->name, "mailbox")) {
09499 ast_string_field_set(peer, mailbox, v->value);
09500 } else if (!strcasecmp(v->name, "hasvoicemail")) {
09501 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
09502 ast_string_field_set(peer, mailbox, name);
09503 }
09504 } else if (!strcasecmp(v->name, "mohinterpret")) {
09505 ast_string_field_set(peer, mohinterpret, v->value);
09506 } else if (!strcasecmp(v->name, "mohsuggest")) {
09507 ast_string_field_set(peer, mohsuggest, v->value);
09508 } else if (!strcasecmp(v->name, "dbsecret")) {
09509 ast_string_field_set(peer, dbsecret, v->value);
09510 } else if (!strcasecmp(v->name, "trunk")) {
09511 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
09512 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09513 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without timing\n", peer->name);
09514 ast_clear_flag(peer, IAX_TRUNK);
09515 }
09516 } else if (!strcasecmp(v->name, "auth")) {
09517 peer->authmethods = get_auth_methods(v->value);
09518 } else if (!strcasecmp(v->name, "encryption")) {
09519 peer->encmethods = get_encrypt_methods(v->value);
09520 } else if (!strcasecmp(v->name, "notransfer")) {
09521 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09522 ast_clear_flag(peer, IAX_TRANSFERMEDIA);
09523 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER);
09524 } else if (!strcasecmp(v->name, "transfer")) {
09525 if (!strcasecmp(v->value, "mediaonly")) {
09526 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
09527 } else if (ast_true(v->value)) {
09528 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09529 } else
09530 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09531 } else if (!strcasecmp(v->name, "jitterbuffer")) {
09532 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
09533 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09534 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
09535 } else if (!strcasecmp(v->name, "host")) {
09536 if (!strcasecmp(v->value, "dynamic")) {
09537
09538 ast_set_flag(peer, IAX_DYNAMIC);
09539 if (!found) {
09540
09541
09542 memset(&peer->addr.sin_addr, 0, 4);
09543 if (peer->addr.sin_port) {
09544
09545 peer->defaddr.sin_port = peer->addr.sin_port;
09546 peer->addr.sin_port = 0;
09547 }
09548 }
09549 } else {
09550
09551 AST_SCHED_DEL(sched, peer->expire);
09552 ast_clear_flag(peer, IAX_DYNAMIC);
09553 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09554 return peer_unref(peer);
09555 if (!peer->addr.sin_port)
09556 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09557 }
09558 if (!maskfound)
09559 inet_aton("255.255.255.255", &peer->mask);
09560 } else if (!strcasecmp(v->name, "defaultip")) {
09561 if (ast_get_ip(&peer->defaddr, v->value))
09562 return peer_unref(peer);
09563 } else if (!strcasecmp(v->name, "sourceaddress")) {
09564 peer_set_srcaddr(peer, v->value);
09565 } else if (!strcasecmp(v->name, "permit") ||
09566 !strcasecmp(v->name, "deny")) {
09567 peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09568 } else if (!strcasecmp(v->name, "mask")) {
09569 maskfound++;
09570 inet_aton(v->value, &peer->mask);
09571 } else if (!strcasecmp(v->name, "context")) {
09572 ast_string_field_set(peer, context, v->value);
09573 } else if (!strcasecmp(v->name, "regexten")) {
09574 ast_string_field_set(peer, regexten, v->value);
09575 } else if (!strcasecmp(v->name, "peercontext")) {
09576 ast_string_field_set(peer, peercontext, v->value);
09577 } else if (!strcasecmp(v->name, "port")) {
09578 if (ast_test_flag(peer, IAX_DYNAMIC))
09579 peer->defaddr.sin_port = htons(atoi(v->value));
09580 else
09581 peer->addr.sin_port = htons(atoi(v->value));
09582 } else if (!strcasecmp(v->name, "username")) {
09583 ast_string_field_set(peer, username, v->value);
09584 } else if (!strcasecmp(v->name, "allow")) {
09585 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09586 } else if (!strcasecmp(v->name, "disallow")) {
09587 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09588 } else if (!strcasecmp(v->name, "callerid")) {
09589 if (!ast_strlen_zero(v->value)) {
09590 char name2[80];
09591 char num2[80];
09592 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09593 ast_string_field_set(peer, cid_name, name2);
09594 ast_string_field_set(peer, cid_num, num2);
09595 } else {
09596 ast_string_field_set(peer, cid_name, "");
09597 ast_string_field_set(peer, cid_num, "");
09598 }
09599 ast_set_flag(peer, IAX_HASCALLERID);
09600 } else if (!strcasecmp(v->name, "fullname")) {
09601 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
09602 ast_set_flag(peer, IAX_HASCALLERID);
09603 } else if (!strcasecmp(v->name, "cid_number")) {
09604 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
09605 ast_set_flag(peer, IAX_HASCALLERID);
09606 } else if (!strcasecmp(v->name, "sendani")) {
09607 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
09608 } else if (!strcasecmp(v->name, "inkeys")) {
09609 ast_string_field_set(peer, inkeys, v->value);
09610 } else if (!strcasecmp(v->name, "outkey")) {
09611 ast_string_field_set(peer, outkey, v->value);
09612 } else if (!strcasecmp(v->name, "qualify")) {
09613 if (!strcasecmp(v->value, "no")) {
09614 peer->maxms = 0;
09615 } else if (!strcasecmp(v->value, "yes")) {
09616 peer->maxms = DEFAULT_MAXMS;
09617 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09618 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);
09619 peer->maxms = 0;
09620 }
09621 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09622 peer->smoothing = ast_true(v->value);
09623 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09624 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09625 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);
09626 }
09627 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09628 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09629 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);
09630 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09631 } else if (!strcasecmp(v->name, "timezone")) {
09632 ast_string_field_set(peer, zonetag, v->value);
09633 } else if (!strcasecmp(v->name, "adsi")) {
09634 peer->adsi = ast_true(v->value);
09635 }
09636
09637 v = v->next;
09638 if (!v) {
09639 v = alt;
09640 alt = NULL;
09641 }
09642 }
09643 if (!peer->authmethods)
09644 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09645 ast_clear_flag(peer, IAX_DELME);
09646
09647 peer->addr.sin_family = AF_INET;
09648 }
09649 if (oldha)
09650 ast_free_ha(oldha);
09651 return peer;
09652 }
09653
09654 static void user_destructor(void *obj)
09655 {
09656 struct iax2_user *user = obj;
09657
09658 ast_free_ha(user->ha);
09659 free_context(user->contexts);
09660 if(user->vars) {
09661 ast_variables_destroy(user->vars);
09662 user->vars = NULL;
09663 }
09664 ast_string_field_free_memory(user);
09665 }
09666
09667
09668 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09669 {
09670 struct iax2_user *user = NULL;
09671 struct iax2_context *con, *conl = NULL;
09672 struct ast_ha *oldha = NULL;
09673 struct iax2_context *oldcon = NULL;
09674 int format;
09675 int firstpass=1;
09676 int oldcurauthreq = 0;
09677 char *varname = NULL, *varval = NULL;
09678 struct ast_variable *tmpvar = NULL;
09679 struct iax2_user tmp_user = {
09680 .name = name,
09681 };
09682
09683 if (!temponly) {
09684 user = ao2_find(users, &tmp_user, OBJ_POINTER);
09685 if (user && !ast_test_flag(user, IAX_DELME))
09686 firstpass = 0;
09687 }
09688
09689 if (user) {
09690 if (firstpass) {
09691 oldcurauthreq = user->curauthreq;
09692 oldha = user->ha;
09693 oldcon = user->contexts;
09694 user->ha = NULL;
09695 user->contexts = NULL;
09696 }
09697
09698 ao2_unlink(users, user);
09699 } else {
09700 user = ao2_alloc(sizeof(*user), user_destructor);
09701 }
09702
09703 if (user) {
09704 if (firstpass) {
09705 ast_string_field_free_memory(user);
09706 memset(user, 0, sizeof(struct iax2_user));
09707 if (ast_string_field_init(user, 32)) {
09708 user = user_unref(user);
09709 goto cleanup;
09710 }
09711 user->maxauthreq = maxauthreq;
09712 user->curauthreq = oldcurauthreq;
09713 user->prefs = prefs;
09714 user->capability = iax2_capability;
09715 user->encmethods = iax2_encryption;
09716 user->adsi = adsi;
09717 ast_string_field_set(user, name, name);
09718 ast_string_field_set(user, language, language);
09719 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
09720 ast_clear_flag(user, IAX_HASCALLERID);
09721 ast_string_field_set(user, cid_name, "");
09722 ast_string_field_set(user, cid_num, "");
09723 }
09724 if (!v) {
09725 v = alt;
09726 alt = NULL;
09727 }
09728 while(v) {
09729 if (!strcasecmp(v->name, "context")) {
09730 con = build_context(v->value);
09731 if (con) {
09732 if (conl)
09733 conl->next = con;
09734 else
09735 user->contexts = con;
09736 conl = con;
09737 }
09738 } else if (!strcasecmp(v->name, "permit") ||
09739 !strcasecmp(v->name, "deny")) {
09740 user->ha = ast_append_ha(v->name, v->value, user->ha);
09741 } else if (!strcasecmp(v->name, "setvar")) {
09742 varname = ast_strdupa(v->value);
09743 if (varname && (varval = strchr(varname,'='))) {
09744 *varval = '\0';
09745 varval++;
09746 if((tmpvar = ast_variable_new(varname, varval))) {
09747 tmpvar->next = user->vars;
09748 user->vars = tmpvar;
09749 }
09750 }
09751 } else if (!strcasecmp(v->name, "allow")) {
09752 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09753 } else if (!strcasecmp(v->name, "disallow")) {
09754 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09755 } else if (!strcasecmp(v->name, "trunk")) {
09756 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
09757 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09758 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without timing\n", user->name);
09759 ast_clear_flag(user, IAX_TRUNK);
09760 }
09761 } else if (!strcasecmp(v->name, "auth")) {
09762 user->authmethods = get_auth_methods(v->value);
09763 } else if (!strcasecmp(v->name, "encryption")) {
09764 user->encmethods = get_encrypt_methods(v->value);
09765 } else if (!strcasecmp(v->name, "notransfer")) {
09766 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09767 ast_clear_flag(user, IAX_TRANSFERMEDIA);
09768 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER);
09769 } else if (!strcasecmp(v->name, "transfer")) {
09770 if (!strcasecmp(v->value, "mediaonly")) {
09771 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
09772 } else if (ast_true(v->value)) {
09773 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09774 } else
09775 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09776 } else if (!strcasecmp(v->name, "codecpriority")) {
09777 if(!strcasecmp(v->value, "caller"))
09778 ast_set_flag(user, IAX_CODEC_USER_FIRST);
09779 else if(!strcasecmp(v->value, "disabled"))
09780 ast_set_flag(user, IAX_CODEC_NOPREFS);
09781 else if(!strcasecmp(v->value, "reqonly")) {
09782 ast_set_flag(user, IAX_CODEC_NOCAP);
09783 ast_set_flag(user, IAX_CODEC_NOPREFS);
09784 }
09785 } else if (!strcasecmp(v->name, "jitterbuffer")) {
09786 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09787 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09788 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09789 } else if (!strcasecmp(v->name, "dbsecret")) {
09790 ast_string_field_set(user, dbsecret, v->value);
09791 } else if (!strcasecmp(v->name, "secret")) {
09792 if (!ast_strlen_zero(user->secret)) {
09793 char *old = ast_strdupa(user->secret);
09794
09795 ast_string_field_build(user, secret, "%s;%s", old, v->value);
09796 } else
09797 ast_string_field_set(user, secret, v->value);
09798 } else if (!strcasecmp(v->name, "callerid")) {
09799 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09800 char name2[80];
09801 char num2[80];
09802 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09803 ast_string_field_set(user, cid_name, name2);
09804 ast_string_field_set(user, cid_num, num2);
09805 ast_set_flag(user, IAX_HASCALLERID);
09806 } else {
09807 ast_clear_flag(user, IAX_HASCALLERID);
09808 ast_string_field_set(user, cid_name, "");
09809 ast_string_field_set(user, cid_num, "");
09810 }
09811 } else if (!strcasecmp(v->name, "fullname")) {
09812 if (!ast_strlen_zero(v->value)) {
09813 ast_string_field_set(user, cid_name, v->value);
09814 ast_set_flag(user, IAX_HASCALLERID);
09815 } else {
09816 ast_string_field_set(user, cid_name, "");
09817 if (ast_strlen_zero(user->cid_num))
09818 ast_clear_flag(user, IAX_HASCALLERID);
09819 }
09820 } else if (!strcasecmp(v->name, "cid_number")) {
09821 if (!ast_strlen_zero(v->value)) {
09822 ast_string_field_set(user, cid_num, v->value);
09823 ast_set_flag(user, IAX_HASCALLERID);
09824 } else {
09825 ast_string_field_set(user, cid_num, "");
09826 if (ast_strlen_zero(user->cid_name))
09827 ast_clear_flag(user, IAX_HASCALLERID);
09828 }
09829 } else if (!strcasecmp(v->name, "accountcode")) {
09830 ast_string_field_set(user, accountcode, v->value);
09831 } else if (!strcasecmp(v->name, "mohinterpret")) {
09832 ast_string_field_set(user, mohinterpret, v->value);
09833 } else if (!strcasecmp(v->name, "mohsuggest")) {
09834 ast_string_field_set(user, mohsuggest, v->value);
09835 } else if (!strcasecmp(v->name, "language")) {
09836 ast_string_field_set(user, language, v->value);
09837 } else if (!strcasecmp(v->name, "amaflags")) {
09838 format = ast_cdr_amaflags2int(v->value);
09839 if (format < 0) {
09840 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09841 } else {
09842 user->amaflags = format;
09843 }
09844 } else if (!strcasecmp(v->name, "inkeys")) {
09845 ast_string_field_set(user, inkeys, v->value);
09846 } else if (!strcasecmp(v->name, "maxauthreq")) {
09847 user->maxauthreq = atoi(v->value);
09848 if (user->maxauthreq < 0)
09849 user->maxauthreq = 0;
09850 } else if (!strcasecmp(v->name, "adsi")) {
09851 user->adsi = ast_true(v->value);
09852 }
09853
09854 v = v->next;
09855 if (!v) {
09856 v = alt;
09857 alt = NULL;
09858 }
09859 }
09860 if (!user->authmethods) {
09861 if (!ast_strlen_zero(user->secret)) {
09862 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09863 if (!ast_strlen_zero(user->inkeys))
09864 user->authmethods |= IAX_AUTH_RSA;
09865 } else if (!ast_strlen_zero(user->inkeys)) {
09866 user->authmethods = IAX_AUTH_RSA;
09867 } else {
09868 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09869 }
09870 }
09871 ast_clear_flag(user, IAX_DELME);
09872 }
09873 cleanup:
09874 if (oldha)
09875 ast_free_ha(oldha);
09876 if (oldcon)
09877 free_context(oldcon);
09878 return user;
09879 }
09880
09881 static int peer_delme_cb(void *obj, void *arg, int flags)
09882 {
09883 struct iax2_peer *peer = obj;
09884
09885 ast_set_flag(peer, IAX_DELME);
09886
09887 return 0;
09888 }
09889
09890 static int user_delme_cb(void *obj, void *arg, int flags)
09891 {
09892 struct iax2_user *user = obj;
09893
09894 ast_set_flag(user, IAX_DELME);
09895
09896 return 0;
09897 }
09898
09899 static void delete_users(void)
09900 {
09901 struct iax2_registry *reg;
09902
09903 ao2_callback(users, 0, user_delme_cb, NULL);
09904
09905 AST_LIST_LOCK(®istrations);
09906 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
09907 ast_sched_del(sched, reg->expire);
09908 if (reg->callno) {
09909 int callno = reg->callno;
09910 ast_mutex_lock(&iaxsl[callno]);
09911 if (iaxs[callno]) {
09912 iaxs[callno]->reg = NULL;
09913 iax2_destroy(callno);
09914 }
09915 ast_mutex_unlock(&iaxsl[callno]);
09916 }
09917 if (reg->dnsmgr)
09918 ast_dnsmgr_release(reg->dnsmgr);
09919 free(reg);
09920 }
09921 AST_LIST_UNLOCK(®istrations);
09922
09923 ao2_callback(peers, 0, peer_delme_cb, NULL);
09924 }
09925
09926 static void prune_users(void)
09927 {
09928 struct iax2_user *user;
09929 struct ao2_iterator i;
09930
09931 i = ao2_iterator_init(users, 0);
09932 while ((user = ao2_iterator_next(&i))) {
09933 if (ast_test_flag(user, IAX_DELME))
09934 ao2_unlink(users, user);
09935 user_unref(user);
09936 }
09937 }
09938
09939
09940 static void prune_peers(void)
09941 {
09942 struct iax2_peer *peer;
09943 struct ao2_iterator i;
09944
09945 i = ao2_iterator_init(peers, 0);
09946 while ((peer = ao2_iterator_next(&i))) {
09947 if (ast_test_flag(peer, IAX_DELME))
09948 unlink_peer(peer);
09949 peer_unref(peer);
09950 }
09951 }
09952
09953 static void set_timing(void)
09954 {
09955 #ifdef HAVE_DAHDI
09956 int bs = trunkfreq * 8;
09957 if (timingfd > -1) {
09958 if (
09959 #ifdef DAHDI_TIMERACK
09960 ioctl(timingfd, DAHDI_TIMERCONFIG, &bs) &&
09961 #endif
09962 ioctl(timingfd, DAHDI_SET_BLOCKSIZE, &bs))
09963 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09964 }
09965 #endif
09966 }
09967
09968 static void set_config_destroy(void)
09969 {
09970 strcpy(accountcode, "");
09971 strcpy(language, "");
09972 strcpy(mohinterpret, "default");
09973 strcpy(mohsuggest, "");
09974 amaflags = 0;
09975 delayreject = 0;
09976 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
09977 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
09978 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
09979 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
09980 delete_users();
09981 }
09982
09983
09984 static int set_config(char *config_file, int reload)
09985 {
09986 struct ast_config *cfg, *ucfg;
09987 int capability=iax2_capability;
09988 struct ast_variable *v;
09989 char *cat;
09990 const char *utype;
09991 const char *tosval;
09992 int format;
09993 int portno = IAX_DEFAULT_PORTNO;
09994 int x;
09995 struct iax2_user *user;
09996 struct iax2_peer *peer;
09997 struct ast_netsock *ns;
09998 #if 0
09999 static unsigned short int last_port=0;
10000 #endif
10001
10002 cfg = ast_config_load(config_file);
10003
10004 if (!cfg) {
10005 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
10006 return -1;
10007 }
10008
10009 if (reload) {
10010 set_config_destroy();
10011 }
10012
10013
10014 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
10015
10016
10017 memset(&globalflags, 0, sizeof(globalflags));
10018 ast_set_flag(&globalflags, IAX_RTUPDATE);
10019
10020 #ifdef SO_NO_CHECK
10021 nochecksums = 0;
10022 #endif
10023
10024 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
10025 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
10026
10027 maxauthreq = 3;
10028
10029 v = ast_variable_browse(cfg, "general");
10030
10031
10032 tosval = ast_variable_retrieve(cfg, "general", "tos");
10033 if (tosval) {
10034 if (ast_str2tos(tosval, &tos))
10035 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
10036 }
10037 while(v) {
10038 if (!strcasecmp(v->name, "bindport")){
10039 if (reload)
10040 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
10041 else
10042 portno = atoi(v->value);
10043 } else if (!strcasecmp(v->name, "pingtime"))
10044 ping_time = atoi(v->value);
10045 else if (!strcasecmp(v->name, "iaxthreadcount")) {
10046 if (reload) {
10047 if (atoi(v->value) != iaxthreadcount)
10048 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
10049 } else {
10050 iaxthreadcount = atoi(v->value);
10051 if (iaxthreadcount < 1) {
10052 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
10053 iaxthreadcount = 1;
10054 } else if (iaxthreadcount > 256) {
10055 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
10056 iaxthreadcount = 256;
10057 }
10058 }
10059 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
10060 if (reload) {
10061 AST_LIST_LOCK(&dynamic_list);
10062 iaxmaxthreadcount = atoi(v->value);
10063 AST_LIST_UNLOCK(&dynamic_list);
10064 } else {
10065 iaxmaxthreadcount = atoi(v->value);
10066 if (iaxmaxthreadcount < 0) {
10067 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
10068 iaxmaxthreadcount = 0;
10069 } else if (iaxmaxthreadcount > 256) {
10070 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
10071 iaxmaxthreadcount = 256;
10072 }
10073 }
10074 } else if (!strcasecmp(v->name, "nochecksums")) {
10075 #ifdef SO_NO_CHECK
10076 if (ast_true(v->value))
10077 nochecksums = 1;
10078 else
10079 nochecksums = 0;
10080 #else
10081 if (ast_true(v->value))
10082 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
10083 #endif
10084 }
10085 else if (!strcasecmp(v->name, "maxjitterbuffer"))
10086 maxjitterbuffer = atoi(v->value);
10087 else if (!strcasecmp(v->name, "resyncthreshold"))
10088 resyncthreshold = atoi(v->value);
10089 else if (!strcasecmp(v->name, "maxjitterinterps"))
10090 maxjitterinterps = atoi(v->value);
10091 else if (!strcasecmp(v->name, "lagrqtime"))
10092 lagrq_time = atoi(v->value);
10093 else if (!strcasecmp(v->name, "maxregexpire"))
10094 max_reg_expire = atoi(v->value);
10095 else if (!strcasecmp(v->name, "minregexpire"))
10096 min_reg_expire = atoi(v->value);
10097 else if (!strcasecmp(v->name, "bindaddr")) {
10098 if (reload) {
10099 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
10100 } else {
10101 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
10102 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
10103 } else {
10104 if (option_verbose > 1) {
10105 if (strchr(v->value, ':'))
10106 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
10107 else
10108 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
10109 }
10110 if (defaultsockfd < 0)
10111 defaultsockfd = ast_netsock_sockfd(ns);
10112 ast_netsock_unref(ns);
10113 }
10114 }
10115 } else if (!strcasecmp(v->name, "authdebug"))
10116 authdebug = ast_true(v->value);
10117 else if (!strcasecmp(v->name, "encryption"))
10118 iax2_encryption = get_encrypt_methods(v->value);
10119 else if (!strcasecmp(v->name, "notransfer")) {
10120 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10121 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
10122 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);
10123 } else if (!strcasecmp(v->name, "transfer")) {
10124 if (!strcasecmp(v->value, "mediaonly")) {
10125 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
10126 } else if (ast_true(v->value)) {
10127 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10128 } else
10129 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10130 } else if (!strcasecmp(v->name, "codecpriority")) {
10131 if(!strcasecmp(v->value, "caller"))
10132 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
10133 else if(!strcasecmp(v->value, "disabled"))
10134 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10135 else if(!strcasecmp(v->value, "reqonly")) {
10136 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10137 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10138 }
10139 } else if (!strcasecmp(v->name, "jitterbuffer"))
10140 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
10141 else if (!strcasecmp(v->name, "forcejitterbuffer"))
10142 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
10143 else if (!strcasecmp(v->name, "delayreject"))
10144 delayreject = ast_true(v->value);
10145 else if (!strcasecmp(v->name, "allowfwdownload"))
10146 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10147 else if (!strcasecmp(v->name, "rtcachefriends"))
10148 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
10149 else if (!strcasecmp(v->name, "rtignoreregexpire"))
10150 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
10151 else if (!strcasecmp(v->name, "rtupdate"))
10152 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10153 else if (!strcasecmp(v->name, "trunktimestamps"))
10154 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10155 else if (!strcasecmp(v->name, "rtautoclear")) {
10156 int i = atoi(v->value);
10157 if(i > 0)
10158 global_rtautoclear = i;
10159 else
10160 i = 0;
10161 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
10162 } else if (!strcasecmp(v->name, "trunkfreq")) {
10163 trunkfreq = atoi(v->value);
10164 if (trunkfreq < 10)
10165 trunkfreq = 10;
10166 } else if (!strcasecmp(v->name, "autokill")) {
10167 if (sscanf(v->value, "%d", &x) == 1) {
10168 if (x >= 0)
10169 autokill = x;
10170 else
10171 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10172 } else if (ast_true(v->value)) {
10173 autokill = DEFAULT_MAXMS;
10174 } else {
10175 autokill = 0;
10176 }
10177 } else if (!strcasecmp(v->name, "bandwidth")) {
10178 if (!strcasecmp(v->value, "low")) {
10179 capability = IAX_CAPABILITY_LOWBANDWIDTH;
10180 } else if (!strcasecmp(v->value, "medium")) {
10181 capability = IAX_CAPABILITY_MEDBANDWIDTH;
10182 } else if (!strcasecmp(v->value, "high")) {
10183 capability = IAX_CAPABILITY_FULLBANDWIDTH;
10184 } else
10185 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10186 } else if (!strcasecmp(v->name, "allow")) {
10187 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10188 } else if (!strcasecmp(v->name, "disallow")) {
10189 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10190 } else if (!strcasecmp(v->name, "register")) {
10191 iax2_register(v->value, v->lineno);
10192 } else if (!strcasecmp(v->name, "iaxcompat")) {
10193 iaxcompat = ast_true(v->value);
10194 } else if (!strcasecmp(v->name, "regcontext")) {
10195 ast_copy_string(regcontext, v->value, sizeof(regcontext));
10196
10197 if (!ast_context_find(regcontext))
10198 ast_context_create(NULL, regcontext, "IAX2");
10199 } else if (!strcasecmp(v->name, "tos")) {
10200 if (ast_str2tos(v->value, &tos))
10201 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10202 } else if (!strcasecmp(v->name, "accountcode")) {
10203 ast_copy_string(accountcode, v->value, sizeof(accountcode));
10204 } else if (!strcasecmp(v->name, "mohinterpret")) {
10205 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
10206 } else if (!strcasecmp(v->name, "mohsuggest")) {
10207 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
10208 } else if (!strcasecmp(v->name, "amaflags")) {
10209 format = ast_cdr_amaflags2int(v->value);
10210 if (format < 0) {
10211 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10212 } else {
10213 amaflags = format;
10214 }
10215 } else if (!strcasecmp(v->name, "language")) {
10216 ast_copy_string(language, v->value, sizeof(language));
10217 } else if (!strcasecmp(v->name, "maxauthreq")) {
10218 maxauthreq = atoi(v->value);
10219 if (maxauthreq < 0)
10220 maxauthreq = 0;
10221 } else if (!strcasecmp(v->name, "adsi")) {
10222 adsi = ast_true(v->value);
10223 }
10224
10225 v = v->next;
10226 }
10227
10228 if (defaultsockfd < 0) {
10229 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10230 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10231 } else {
10232 if (option_verbose > 1)
10233 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10234 defaultsockfd = ast_netsock_sockfd(ns);
10235 ast_netsock_unref(ns);
10236 }
10237 }
10238 if (reload) {
10239 ast_netsock_release(outsock);
10240 outsock = ast_netsock_list_alloc();
10241 if (!outsock) {
10242 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10243 return -1;
10244 }
10245 ast_netsock_init(outsock);
10246 }
10247
10248 if (min_reg_expire > max_reg_expire) {
10249 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10250 min_reg_expire, max_reg_expire, max_reg_expire);
10251 min_reg_expire = max_reg_expire;
10252 }
10253 iax2_capability = capability;
10254
10255 ucfg = ast_config_load("users.conf");
10256 if (ucfg) {
10257 struct ast_variable *gen;
10258 int genhasiax;
10259 int genregisteriax;
10260 const char *hasiax, *registeriax;
10261
10262 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10263 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10264 gen = ast_variable_browse(ucfg, "general");
10265 cat = ast_category_browse(ucfg, NULL);
10266 while (cat) {
10267 if (strcasecmp(cat, "general")) {
10268 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10269 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10270 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10271
10272 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10273 if (user) {
10274 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10275 user = user_unref(user);
10276 }
10277 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10278 if (peer) {
10279 if (ast_test_flag(peer, IAX_DYNAMIC))
10280 reg_source_db(peer);
10281 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10282 peer = peer_unref(peer);
10283 }
10284 }
10285 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10286 char tmp[256];
10287 const char *host = ast_variable_retrieve(ucfg, cat, "host");
10288 const char *username = ast_variable_retrieve(ucfg, cat, "username");
10289 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10290 if (!host)
10291 host = ast_variable_retrieve(ucfg, "general", "host");
10292 if (!username)
10293 username = ast_variable_retrieve(ucfg, "general", "username");
10294 if (!secret)
10295 secret = ast_variable_retrieve(ucfg, "general", "secret");
10296 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10297 if (!ast_strlen_zero(secret))
10298 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10299 else
10300 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10301 iax2_register(tmp, 0);
10302 }
10303 }
10304 }
10305 cat = ast_category_browse(ucfg, cat);
10306 }
10307 ast_config_destroy(ucfg);
10308 }
10309
10310 cat = ast_category_browse(cfg, NULL);
10311 while(cat) {
10312 if (strcasecmp(cat, "general")) {
10313 utype = ast_variable_retrieve(cfg, cat, "type");
10314 if (utype) {
10315 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10316 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10317 if (user) {
10318 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10319 user = user_unref(user);
10320 }
10321 }
10322 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10323 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10324 if (peer) {
10325 if (ast_test_flag(peer, IAX_DYNAMIC))
10326 reg_source_db(peer);
10327 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10328 peer = peer_unref(peer);
10329 }
10330 } else if (strcasecmp(utype, "user")) {
10331 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10332 }
10333 } else
10334 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10335 }
10336 cat = ast_category_browse(cfg, cat);
10337 }
10338 ast_config_destroy(cfg);
10339 set_timing();
10340 return 1;
10341 }
10342
10343 static void poke_all_peers(void)
10344 {
10345 struct ao2_iterator i;
10346 struct iax2_peer *peer;
10347
10348 i = ao2_iterator_init(peers, 0);
10349 while ((peer = ao2_iterator_next(&i))) {
10350 iax2_poke_peer(peer, 0);
10351 peer_unref(peer);
10352 }
10353 }
10354 static int reload_config(void)
10355 {
10356 char *config = "iax.conf";
10357 struct iax2_registry *reg;
10358
10359 if (set_config(config, 1) > 0) {
10360 prune_peers();
10361 prune_users();
10362 AST_LIST_LOCK(®istrations);
10363 AST_LIST_TRAVERSE(®istrations, reg, entry)
10364 iax2_do_register(reg);
10365 AST_LIST_UNLOCK(®istrations);
10366
10367 poke_all_peers();
10368 }
10369 reload_firmware(0);
10370 iax_provision_reload();
10371
10372 return 0;
10373 }
10374
10375 static int iax2_reload(int fd, int argc, char *argv[])
10376 {
10377 return reload_config();
10378 }
10379
10380 static int reload(void)
10381 {
10382 return reload_config();
10383 }
10384
10385 static int cache_get_callno_locked(const char *data)
10386 {
10387 struct sockaddr_in sin;
10388 int x;
10389 int callno;
10390 struct iax_ie_data ied;
10391 struct create_addr_info cai;
10392 struct parsed_dial_string pds;
10393 char *tmpstr;
10394
10395 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10396
10397
10398 if (!ast_mutex_trylock(&iaxsl[x])) {
10399 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10400 return x;
10401 ast_mutex_unlock(&iaxsl[x]);
10402 }
10403 }
10404
10405
10406
10407 memset(&cai, 0, sizeof(cai));
10408 memset(&ied, 0, sizeof(ied));
10409 memset(&pds, 0, sizeof(pds));
10410
10411 tmpstr = ast_strdupa(data);
10412 parse_dial_string(tmpstr, &pds);
10413
10414 if (ast_strlen_zero(pds.peer)) {
10415 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10416 return -1;
10417 }
10418
10419
10420 if (create_addr(pds.peer, NULL, &sin, &cai))
10421 return -1;
10422
10423 if (option_debug)
10424 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10425 pds.peer, pds.username, pds.password, pds.context);
10426
10427 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10428 if (callno < 1) {
10429 ast_log(LOG_WARNING, "Unable to create call\n");
10430 return -1;
10431 }
10432
10433 ast_string_field_set(iaxs[callno], dproot, data);
10434 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10435
10436 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10437 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10438
10439
10440
10441 if (pds.exten)
10442 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10443 if (pds.username)
10444 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10445 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10446 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10447
10448 if (pds.password)
10449 ast_string_field_set(iaxs[callno], secret, pds.password);
10450 if (pds.key)
10451 ast_string_field_set(iaxs[callno], outkey, pds.key);
10452
10453 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10454
10455 return callno;
10456 }
10457
10458 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10459 {
10460 struct iax2_dpcache *dp, *prev = NULL, *next;
10461 struct timeval tv;
10462 int x;
10463 int com[2];
10464 int timeout;
10465 int old=0;
10466 int outfd;
10467 int abort;
10468 int callno;
10469 struct ast_channel *c;
10470 struct ast_frame *f;
10471 gettimeofday(&tv, NULL);
10472 dp = dpcache;
10473 while(dp) {
10474 next = dp->next;
10475
10476 if (ast_tvcmp(tv, dp->expiry) > 0) {
10477
10478 if (prev)
10479 prev->next = dp->next;
10480 else
10481 dpcache = dp->next;
10482 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10483
10484 free(dp);
10485 } else {
10486 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = %p callno = %d)\n", dp->flags, dp->peer, dp->callno);
10487 }
10488 dp = next;
10489 continue;
10490 }
10491
10492 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
10493 break;
10494 prev = dp;
10495 dp = next;
10496 }
10497 if (!dp) {
10498
10499
10500 callno = cache_get_callno_locked(data);
10501 if (callno < 0) {
10502 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10503 return NULL;
10504 }
10505 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10506 ast_mutex_unlock(&iaxsl[callno]);
10507 return NULL;
10508 }
10509 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10510 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10511 gettimeofday(&dp->expiry, NULL);
10512 dp->orig = dp->expiry;
10513
10514 dp->expiry.tv_sec += iaxdefaultdpcache;
10515 dp->next = dpcache;
10516 dp->flags = CACHE_FLAG_PENDING;
10517 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10518 dp->waiters[x] = -1;
10519 dpcache = dp;
10520 dp->peer = iaxs[callno]->dpentries;
10521 iaxs[callno]->dpentries = dp;
10522
10523 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10524 iax2_dprequest(dp, callno);
10525 ast_mutex_unlock(&iaxsl[callno]);
10526 }
10527
10528 if (dp->flags & CACHE_FLAG_PENDING) {
10529
10530
10531 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10532
10533 if (dp->waiters[x] < 0)
10534 break;
10535 }
10536 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10537 ast_log(LOG_WARNING, "No more waiter positions available\n");
10538 return NULL;
10539 }
10540 if (pipe(com)) {
10541 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10542 return NULL;
10543 }
10544 dp->waiters[x] = com[1];
10545
10546 timeout = iaxdefaulttimeout * 1000;
10547
10548 ast_mutex_unlock(&dpcache_lock);
10549
10550 if (chan)
10551 old = ast_channel_defer_dtmf(chan);
10552 abort = 0;
10553 while(timeout) {
10554 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10555 if (outfd > -1) {
10556 break;
10557 }
10558 if (c) {
10559 f = ast_read(c);
10560 if (f)
10561 ast_frfree(f);
10562 else {
10563
10564 break;
10565 abort = 1;
10566 }
10567 }
10568 }
10569 if (!timeout) {
10570 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10571 }
10572 ast_mutex_lock(&dpcache_lock);
10573 dp->waiters[x] = -1;
10574 close(com[1]);
10575 close(com[0]);
10576 if (abort) {
10577
10578
10579 if (!old && chan)
10580 ast_channel_undefer_dtmf(chan);
10581 return NULL;
10582 }
10583 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10584
10585 if (dp->flags & CACHE_FLAG_PENDING) {
10586
10587
10588 dp->flags &= ~CACHE_FLAG_PENDING;
10589 dp->flags |= CACHE_FLAG_TIMEOUT;
10590
10591
10592 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10593 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
10594 if (dp->waiters[x] > -1) {
10595 if (write(dp->waiters[x], "asdf", 4) < 0) {
10596 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
10597 }
10598 }
10599 }
10600 }
10601 }
10602
10603 if (!old && chan)
10604 ast_channel_undefer_dtmf(chan);
10605 }
10606 return dp;
10607 }
10608
10609
10610 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10611 {
10612 struct iax2_dpcache *dp;
10613 int res = 0;
10614 #if 0
10615 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10616 #endif
10617 if ((priority != 1) && (priority != 2))
10618 return 0;
10619 ast_mutex_lock(&dpcache_lock);
10620 dp = find_cache(chan, data, context, exten, priority);
10621 if (dp) {
10622 if (dp->flags & CACHE_FLAG_EXISTS)
10623 res= 1;
10624 }
10625 ast_mutex_unlock(&dpcache_lock);
10626 if (!dp) {
10627 ast_log(LOG_WARNING, "Unable to make DP cache\n");
10628 }
10629 return res;
10630 }
10631
10632
10633 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10634 {
10635 int res = 0;
10636 struct iax2_dpcache *dp;
10637 #if 0
10638 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10639 #endif
10640 if ((priority != 1) && (priority != 2))
10641 return 0;
10642 ast_mutex_lock(&dpcache_lock);
10643 dp = find_cache(chan, data, context, exten, priority);
10644 if (dp) {
10645 if (dp->flags & CACHE_FLAG_CANEXIST)
10646 res= 1;
10647 }
10648 ast_mutex_unlock(&dpcache_lock);
10649 if (!dp) {
10650 ast_log(LOG_WARNING, "Unable to make DP cache\n");
10651 }
10652 return res;
10653 }
10654
10655
10656 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10657 {
10658 int res = 0;
10659 struct iax2_dpcache *dp;
10660 #if 0
10661 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10662 #endif
10663 if ((priority != 1) && (priority != 2))
10664 return 0;
10665 ast_mutex_lock(&dpcache_lock);
10666 dp = find_cache(chan, data, context, exten, priority);
10667 if (dp) {
10668 if (dp->flags & CACHE_FLAG_MATCHMORE)
10669 res= 1;
10670 }
10671 ast_mutex_unlock(&dpcache_lock);
10672 if (!dp) {
10673 ast_log(LOG_WARNING, "Unable to make DP cache\n");
10674 }
10675 return res;
10676 }
10677
10678
10679 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10680 {
10681 char odata[256];
10682 char req[256];
10683 char *ncontext;
10684 struct iax2_dpcache *dp;
10685 struct ast_app *dial;
10686 #if 0
10687 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);
10688 #endif
10689 if (priority == 2) {
10690
10691 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10692 if (dialstatus) {
10693 dial = pbx_findapp(dialstatus);
10694 if (dial)
10695 pbx_exec(chan, dial, "");
10696 }
10697 return -1;
10698 } else if (priority != 1)
10699 return -1;
10700 ast_mutex_lock(&dpcache_lock);
10701 dp = find_cache(chan, data, context, exten, priority);
10702 if (dp) {
10703 if (dp->flags & CACHE_FLAG_EXISTS) {
10704 ast_copy_string(odata, data, sizeof(odata));
10705 ncontext = strchr(odata, '/');
10706 if (ncontext) {
10707 *ncontext = '\0';
10708 ncontext++;
10709 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10710 } else {
10711 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10712 }
10713 if (option_verbose > 2)
10714 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10715 } else {
10716 ast_mutex_unlock(&dpcache_lock);
10717 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10718 return -1;
10719 }
10720 }
10721 ast_mutex_unlock(&dpcache_lock);
10722 dial = pbx_findapp("Dial");
10723 if (dial) {
10724 return pbx_exec(chan, dial, req);
10725 } else {
10726 ast_log(LOG_WARNING, "No dial application registered\n");
10727 }
10728 return -1;
10729 }
10730
10731 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10732 {
10733 struct iax2_peer *peer;
10734 char *peername, *colname;
10735
10736 peername = ast_strdupa(data);
10737
10738
10739 if (!strcmp(peername,"CURRENTCHANNEL")) {
10740 unsigned short callno;
10741 if (chan->tech != &iax2_tech)
10742 return -1;
10743 callno = PTR_TO_CALLNO(chan->tech_pvt);
10744 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10745 return 0;
10746 }
10747
10748 if ((colname = strchr(peername, ':')))
10749 *colname++ = '\0';
10750 else if ((colname = strchr(peername, '|')))
10751 *colname++ = '\0';
10752 else
10753 colname = "ip";
10754
10755 if (!(peer = find_peer(peername, 1)))
10756 return -1;
10757
10758 if (!strcasecmp(colname, "ip")) {
10759 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10760 } else if (!strcasecmp(colname, "status")) {
10761 peer_status(peer, buf, len);
10762 } else if (!strcasecmp(colname, "mailbox")) {
10763 ast_copy_string(buf, peer->mailbox, len);
10764 } else if (!strcasecmp(colname, "context")) {
10765 ast_copy_string(buf, peer->context, len);
10766 } else if (!strcasecmp(colname, "expire")) {
10767 snprintf(buf, len, "%d", peer->expire);
10768 } else if (!strcasecmp(colname, "dynamic")) {
10769 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10770 } else if (!strcasecmp(colname, "callerid_name")) {
10771 ast_copy_string(buf, peer->cid_name, len);
10772 } else if (!strcasecmp(colname, "callerid_num")) {
10773 ast_copy_string(buf, peer->cid_num, len);
10774 } else if (!strcasecmp(colname, "codecs")) {
10775 ast_getformatname_multiple(buf, len -1, peer->capability);
10776 } else if (!strncasecmp(colname, "codec[", 6)) {
10777 char *codecnum, *ptr;
10778 int index = 0, codec = 0;
10779
10780 codecnum = strchr(colname, '[');
10781 *codecnum = '\0';
10782 codecnum++;
10783 if ((ptr = strchr(codecnum, ']'))) {
10784 *ptr = '\0';
10785 }
10786 index = atoi(codecnum);
10787 if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10788 ast_copy_string(buf, ast_getformatname(codec), len);
10789 } else {
10790 buf[0] = '\0';
10791 }
10792 } else {
10793 buf[0] = '\0';
10794 }
10795
10796 peer_unref(peer);
10797
10798 return 0;
10799 }
10800
10801 struct ast_custom_function iaxpeer_function = {
10802 .name = "IAXPEER",
10803 .synopsis = "Gets IAX peer information",
10804 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10805 .read = function_iaxpeer,
10806 .desc = "If peername specified, valid items are:\n"
10807 "- ip (default) The IP address.\n"
10808 "- status The peer's status (if qualify=yes)\n"
10809 "- mailbox The configured mailbox.\n"
10810 "- context The configured context.\n"
10811 "- expire The epoch time of the next expire.\n"
10812 "- dynamic Is it dynamic? (yes/no).\n"
10813 "- callerid_name The configured Caller ID name.\n"
10814 "- callerid_num The configured Caller ID number.\n"
10815 "- codecs The configured codecs.\n"
10816 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
10817 "\n"
10818 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10819 "\n"
10820 };
10821
10822
10823
10824 static int iax2_devicestate(void *data)
10825 {
10826 struct parsed_dial_string pds;
10827 char *tmp = ast_strdupa(data);
10828 struct iax2_peer *p;
10829 int res = AST_DEVICE_INVALID;
10830
10831 memset(&pds, 0, sizeof(pds));
10832 parse_dial_string(tmp, &pds);
10833
10834 if (ast_strlen_zero(pds.peer)) {
10835 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10836 return res;
10837 }
10838
10839 if (option_debug > 2)
10840 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10841
10842
10843 if (!(p = find_peer(pds.peer, 1)))
10844 return res;
10845
10846 res = AST_DEVICE_UNAVAILABLE;
10847 if (option_debug > 2)
10848 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10849 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10850
10851 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10852 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10853
10854
10855 if (p->historicms == 0 || p->historicms <= p->maxms)
10856
10857 res = AST_DEVICE_UNKNOWN;
10858 }
10859
10860 peer_unref(p);
10861
10862 return res;
10863 }
10864
10865 static struct ast_switch iax2_switch =
10866 {
10867 name: "IAX2",
10868 description: "IAX Remote Dialplan Switch",
10869 exists: iax2_exists,
10870 canmatch: iax2_canmatch,
10871 exec: iax2_exec,
10872 matchmore: iax2_matchmore,
10873 };
10874
10875 static char show_stats_usage[] =
10876 "Usage: iax2 show stats\n"
10877 " Display statistics on IAX channel driver.\n";
10878
10879 static char show_cache_usage[] =
10880 "Usage: iax2 show cache\n"
10881 " Display currently cached IAX Dialplan results.\n";
10882
10883 static char show_peer_usage[] =
10884 "Usage: iax2 show peer <name>\n"
10885 " Display details on specific IAX peer\n";
10886
10887 static char prune_realtime_usage[] =
10888 "Usage: iax2 prune realtime [<peername>|all]\n"
10889 " Prunes object(s) from the cache\n";
10890
10891 static char iax2_reload_usage[] =
10892 "Usage: iax2 reload\n"
10893 " Reloads IAX configuration from iax.conf\n";
10894
10895 static char show_prov_usage[] =
10896 "Usage: iax2 provision <host> <template> [forced]\n"
10897 " Provisions the given peer or IP address using a template\n"
10898 " matching either 'template' or '*' if the template is not\n"
10899 " found. If 'forced' is specified, even empty provisioning\n"
10900 " fields will be provisioned as empty fields.\n";
10901
10902 static char show_users_usage[] =
10903 "Usage: iax2 show users [like <pattern>]\n"
10904 " Lists all known IAX2 users.\n"
10905 " Optional regular expression pattern is used to filter the user list.\n";
10906
10907 static char show_channels_usage[] =
10908 "Usage: iax2 show channels\n"
10909 " Lists all currently active IAX channels.\n";
10910
10911 static char show_netstats_usage[] =
10912 "Usage: iax2 show netstats\n"
10913 " Lists network status for all currently active IAX channels.\n";
10914
10915 static char show_threads_usage[] =
10916 "Usage: iax2 show threads\n"
10917 " Lists status of IAX helper threads\n";
10918
10919 static char show_peers_usage[] =
10920 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10921 " Lists all known IAX2 peers.\n"
10922 " Optional 'registered' argument lists only peers with known addresses.\n"
10923 " Optional regular expression pattern is used to filter the peer list.\n";
10924
10925 static char show_firmware_usage[] =
10926 "Usage: iax2 show firmware\n"
10927 " Lists all known IAX firmware images.\n";
10928
10929 static char show_reg_usage[] =
10930 "Usage: iax2 show registry\n"
10931 " Lists all registration requests and status.\n";
10932
10933 static char debug_usage[] =
10934 "Usage: iax2 set debug\n"
10935 " Enables dumping of IAX packets for debugging purposes\n";
10936
10937 static char no_debug_usage[] =
10938 "Usage: iax2 set debug off\n"
10939 " Disables dumping of IAX packets for debugging purposes\n";
10940
10941 static char debug_trunk_usage[] =
10942 "Usage: iax2 set debug trunk\n"
10943 " Requests current status of IAX trunking\n";
10944
10945 static char no_debug_trunk_usage[] =
10946 "Usage: iax2 set debug trunk off\n"
10947 " Requests current status of IAX trunking\n";
10948
10949 static char debug_jb_usage[] =
10950 "Usage: iax2 set debug jb\n"
10951 " Enables jitterbuffer debugging information\n";
10952
10953 static char no_debug_jb_usage[] =
10954 "Usage: iax2 set debug jb off\n"
10955 " Disables jitterbuffer debugging information\n";
10956
10957 static char iax2_test_losspct_usage[] =
10958 "Usage: iax2 test losspct <percentage>\n"
10959 " For testing, throws away <percentage> percent of incoming packets\n";
10960
10961 #ifdef IAXTESTS
10962 static char iax2_test_late_usage[] =
10963 "Usage: iax2 test late <ms>\n"
10964 " For testing, count the next frame as <ms> ms late\n";
10965
10966 static char iax2_test_resync_usage[] =
10967 "Usage: iax2 test resync <ms>\n"
10968 " For testing, adjust all future frames by <ms> ms\n";
10969
10970 static char iax2_test_jitter_usage[] =
10971 "Usage: iax2 test jitter <ms> <pct>\n"
10972 " For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10973 #endif
10974
10975 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10976 { "iax2", "trunk", "debug", NULL },
10977 iax2_do_trunk_debug, NULL,
10978 NULL };
10979
10980 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10981 { "iax2", "jb", "debug", NULL },
10982 iax2_do_jb_debug, NULL,
10983 NULL };
10984
10985 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10986 { "iax2", "no", "debug", NULL },
10987 iax2_no_debug, NULL,
10988 NULL };
10989
10990 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10991 { "iax2", "no", "trunk", "debug", NULL },
10992 iax2_no_trunk_debug, NULL,
10993 NULL };
10994
10995 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10996 { "iax2", "no", "jb", "debug", NULL },
10997 iax2_no_jb_debug, NULL,
10998 NULL };
10999
11000 static struct ast_cli_entry cli_iax2[] = {
11001 { { "iax2", "show", "cache", NULL },
11002 iax2_show_cache, "Display IAX cached dialplan",
11003 show_cache_usage, NULL, },
11004
11005 { { "iax2", "show", "channels", NULL },
11006 iax2_show_channels, "List active IAX channels",
11007 show_channels_usage, NULL, },
11008
11009 { { "iax2", "show", "firmware", NULL },
11010 iax2_show_firmware, "List available IAX firmwares",
11011 show_firmware_usage, NULL, },
11012
11013 { { "iax2", "show", "netstats", NULL },
11014 iax2_show_netstats, "List active IAX channel netstats",
11015 show_netstats_usage, NULL, },
11016
11017 { { "iax2", "show", "peers", NULL },
11018 iax2_show_peers, "List defined IAX peers",
11019 show_peers_usage, NULL, },
11020
11021 { { "iax2", "show", "registry", NULL },
11022 iax2_show_registry, "Display IAX registration status",
11023 show_reg_usage, NULL, },
11024
11025 { { "iax2", "show", "stats", NULL },
11026 iax2_show_stats, "Display IAX statistics",
11027 show_stats_usage, NULL, },
11028
11029 { { "iax2", "show", "threads", NULL },
11030 iax2_show_threads, "Display IAX helper thread info",
11031 show_threads_usage, NULL, },
11032
11033 { { "iax2", "show", "users", NULL },
11034 iax2_show_users, "List defined IAX users",
11035 show_users_usage, NULL, },
11036
11037 { { "iax2", "prune", "realtime", NULL },
11038 iax2_prune_realtime, "Prune a cached realtime lookup",
11039 prune_realtime_usage, complete_iax2_show_peer },
11040
11041 { { "iax2", "reload", NULL },
11042 iax2_reload, "Reload IAX configuration",
11043 iax2_reload_usage },
11044
11045 { { "iax2", "show", "peer", NULL },
11046 iax2_show_peer, "Show details on specific IAX peer",
11047 show_peer_usage, complete_iax2_show_peer },
11048
11049 { { "iax2", "set", "debug", NULL },
11050 iax2_do_debug, "Enable IAX debugging",
11051 debug_usage },
11052
11053 { { "iax2", "set", "debug", "trunk", NULL },
11054 iax2_do_trunk_debug, "Enable IAX trunk debugging",
11055 debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
11056
11057 { { "iax2", "set", "debug", "jb", NULL },
11058 iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
11059 debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
11060
11061 { { "iax2", "set", "debug", "off", NULL },
11062 iax2_no_debug, "Disable IAX debugging",
11063 no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
11064
11065 { { "iax2", "set", "debug", "trunk", "off", NULL },
11066 iax2_no_trunk_debug, "Disable IAX trunk debugging",
11067 no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
11068
11069 { { "iax2", "set", "debug", "jb", "off", NULL },
11070 iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
11071 no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
11072
11073 { { "iax2", "test", "losspct", NULL },
11074 iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
11075 iax2_test_losspct_usage },
11076
11077 { { "iax2", "provision", NULL },
11078 iax2_prov_cmd, "Provision an IAX device",
11079 show_prov_usage, iax2_prov_complete_template_3rd },
11080
11081 #ifdef IAXTESTS
11082 { { "iax2", "test", "late", NULL },
11083 iax2_test_late, "Test the receipt of a late frame",
11084 iax2_test_late_usage },
11085
11086 { { "iax2", "test", "resync", NULL },
11087 iax2_test_resync, "Test a resync in received timestamps",
11088 iax2_test_resync_usage },
11089
11090 { { "iax2", "test", "jitter", NULL },
11091 iax2_test_jitter, "Simulates jitter for testing",
11092 iax2_test_jitter_usage },
11093 #endif
11094 };
11095
11096 static int __unload_module(void)
11097 {
11098 struct iax2_thread *thread = NULL;
11099 int x;
11100
11101
11102
11103
11104
11105 if (netthreadid != AST_PTHREADT_NULL) {
11106 AST_LIST_LOCK(&iaxq.queue);
11107 ast_mutex_lock(&sched_lock);
11108 pthread_cancel(netthreadid);
11109 ast_cond_signal(&sched_cond);
11110 ast_mutex_unlock(&sched_lock);
11111 AST_LIST_UNLOCK(&iaxq.queue);
11112 pthread_join(netthreadid, NULL);
11113 }
11114 if (schedthreadid != AST_PTHREADT_NULL) {
11115 ast_mutex_lock(&sched_lock);
11116 pthread_cancel(schedthreadid);
11117 ast_cond_signal(&sched_cond);
11118 ast_mutex_unlock(&sched_lock);
11119 pthread_join(schedthreadid, NULL);
11120 }
11121
11122
11123 AST_LIST_LOCK(&idle_list);
11124 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
11125 AST_LIST_REMOVE_CURRENT(&idle_list, list);
11126 pthread_cancel(thread->threadid);
11127 }
11128 AST_LIST_TRAVERSE_SAFE_END
11129 AST_LIST_UNLOCK(&idle_list);
11130
11131 AST_LIST_LOCK(&active_list);
11132 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
11133 AST_LIST_REMOVE_CURRENT(&active_list, list);
11134 pthread_cancel(thread->threadid);
11135 }
11136 AST_LIST_TRAVERSE_SAFE_END
11137 AST_LIST_UNLOCK(&active_list);
11138
11139 AST_LIST_LOCK(&dynamic_list);
11140 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
11141 AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
11142 pthread_cancel(thread->threadid);
11143 }
11144 AST_LIST_TRAVERSE_SAFE_END
11145 AST_LIST_UNLOCK(&dynamic_list);
11146
11147 AST_LIST_HEAD_DESTROY(&iaxq.queue);
11148
11149
11150 while(0 < iaxactivethreadcount)
11151 usleep(10000);
11152
11153 ast_netsock_release(netsock);
11154 ast_netsock_release(outsock);
11155 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11156 if (iaxs[x]) {
11157 iax2_destroy(x);
11158 }
11159 }
11160 ast_manager_unregister( "IAXpeers" );
11161 ast_manager_unregister( "IAXnetstats" );
11162 ast_unregister_application(papp);
11163 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11164 ast_unregister_switch(&iax2_switch);
11165 ast_channel_unregister(&iax2_tech);
11166 delete_users();
11167 iax_provision_unload();
11168 sched_context_destroy(sched);
11169 reload_firmware(1);
11170
11171 ast_mutex_destroy(&waresl.lock);
11172
11173 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11174 ast_mutex_destroy(&iaxsl[x]);
11175 }
11176
11177 ao2_ref(peers, -1);
11178 ao2_ref(users, -1);
11179 ao2_ref(iax_peercallno_pvts, -1);
11180
11181 return 0;
11182 }
11183
11184 static int unload_module(void)
11185 {
11186 ast_custom_function_unregister(&iaxpeer_function);
11187 return __unload_module();
11188 }
11189
11190 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11191 {
11192 struct iax2_peer *peer = obj;
11193
11194 if (peer->sockfd < 0)
11195 peer->sockfd = defaultsockfd;
11196
11197 return 0;
11198 }
11199
11200 static int pvt_hash_cb(const void *obj, const int flags)
11201 {
11202 const struct chan_iax2_pvt *pvt = obj;
11203
11204 return pvt->peercallno;
11205 }
11206
11207 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11208 {
11209 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11210
11211
11212
11213
11214 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
11215 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
11216 }
11217
11218
11219 static int load_module(void)
11220 {
11221 char *config = "iax.conf";
11222 int res = 0;
11223 int x;
11224 struct iax2_registry *reg = NULL;
11225
11226 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11227 if (!peers)
11228 return AST_MODULE_LOAD_FAILURE;
11229 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11230 if (!users) {
11231 ao2_ref(peers, -1);
11232 return AST_MODULE_LOAD_FAILURE;
11233 }
11234 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11235 if (!iax_peercallno_pvts) {
11236 ao2_ref(peers, -1);
11237 ao2_ref(users, -1);
11238 return AST_MODULE_LOAD_FAILURE;
11239 }
11240
11241 ast_custom_function_register(&iaxpeer_function);
11242
11243 iax_set_output(iax_debug_output);
11244 iax_set_error(iax_error_output);
11245 jb_setoutput(jb_error_output, jb_warning_output, NULL);
11246
11247 #ifdef HAVE_DAHDI
11248 #ifdef DAHDI_TIMERACK
11249 timingfd = open(DAHDI_FILE_TIMER, O_RDWR);
11250 if (timingfd < 0)
11251 #endif
11252 timingfd = open(DAHDI_FILE_PSEUDO, O_RDWR);
11253 if (timingfd < 0)
11254 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11255 #endif
11256
11257 memset(iaxs, 0, sizeof(iaxs));
11258
11259 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11260 ast_mutex_init(&iaxsl[x]);
11261 }
11262
11263 ast_cond_init(&sched_cond, NULL);
11264
11265 io = io_context_create();
11266 sched = sched_context_create();
11267
11268 if (!io || !sched) {
11269 ast_log(LOG_ERROR, "Out of memory\n");
11270 return -1;
11271 }
11272
11273 netsock = ast_netsock_list_alloc();
11274 if (!netsock) {
11275 ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11276 return -1;
11277 }
11278 ast_netsock_init(netsock);
11279
11280 outsock = ast_netsock_list_alloc();
11281 if (!outsock) {
11282 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11283 return -1;
11284 }
11285 ast_netsock_init(outsock);
11286
11287 ast_mutex_init(&waresl.lock);
11288
11289 AST_LIST_HEAD_INIT(&iaxq.queue);
11290
11291 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11292
11293 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11294
11295 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11296 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11297
11298 if(set_config(config, 0) == -1)
11299 return AST_MODULE_LOAD_DECLINE;
11300
11301 if (ast_channel_register(&iax2_tech)) {
11302 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11303 __unload_module();
11304 return -1;
11305 }
11306
11307 if (ast_register_switch(&iax2_switch))
11308 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11309
11310 res = start_network_thread();
11311 if (!res) {
11312 if (option_verbose > 1)
11313 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11314 } else {
11315 ast_log(LOG_ERROR, "Unable to start network thread\n");
11316 ast_netsock_release(netsock);
11317 ast_netsock_release(outsock);
11318 }
11319
11320 AST_LIST_LOCK(®istrations);
11321 AST_LIST_TRAVERSE(®istrations, reg, entry)
11322 iax2_do_register(reg);
11323 AST_LIST_UNLOCK(®istrations);
11324
11325 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11326 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11327
11328 reload_firmware(0);
11329 iax_provision_reload();
11330 return res;
11331 }
11332
11333 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11334 .load = load_module,
11335 .unload = unload_module,
11336 .reload = reload,
11337 );