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