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