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