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