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