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