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