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