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