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
03418
03419
03420
03421 case AST_OPTION_TONE_VERIFY:
03422 case AST_OPTION_TDD:
03423 case AST_OPTION_RELAXDTMF:
03424 case AST_OPTION_AUDIO_MODE:
03425 if (!(h = ast_malloc(datalen + sizeof(*h))))
03426 return -1;
03427
03428 h->flag = AST_OPTION_FLAG_REQUEST;
03429 h->option = htons(option);
03430 memcpy(h->data, data, datalen);
03431 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03432 AST_CONTROL_OPTION, 0, (unsigned char *) h,
03433 datalen + sizeof(*h), -1);
03434 free(h);
03435 return res;
03436 default:
03437 return -1;
03438 }
03439
03440
03441 return -1;
03442 }
03443
03444 static struct ast_frame *iax2_read(struct ast_channel *c)
03445 {
03446 if (option_verbose > 3)
03447 ast_log(LOG_NOTICE, "I should never be called!\n");
03448 return &ast_null_frame;
03449 }
03450
03451 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03452 {
03453 int res;
03454 struct iax_ie_data ied0;
03455 struct iax_ie_data ied1;
03456 unsigned int transferid = (unsigned int)ast_random();
03457 memset(&ied0, 0, sizeof(ied0));
03458 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03459 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03460 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03461
03462 memset(&ied1, 0, sizeof(ied1));
03463 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03464 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03465 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03466
03467 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03468 if (res)
03469 return -1;
03470 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03471 if (res)
03472 return -1;
03473 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03474 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03475 return 0;
03476 }
03477
03478 static void lock_both(unsigned short callno0, unsigned short callno1)
03479 {
03480 ast_mutex_lock(&iaxsl[callno0]);
03481 while (ast_mutex_trylock(&iaxsl[callno1])) {
03482 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
03483 }
03484 }
03485
03486 static void unlock_both(unsigned short callno0, unsigned short callno1)
03487 {
03488 ast_mutex_unlock(&iaxsl[callno1]);
03489 ast_mutex_unlock(&iaxsl[callno0]);
03490 }
03491
03492 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)
03493 {
03494 struct ast_channel *cs[3];
03495 struct ast_channel *who, *other;
03496 int to = -1;
03497 int res = -1;
03498 int transferstarted=0;
03499 struct ast_frame *f;
03500 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03501 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03502 struct timeval waittimer = {0, 0}, tv;
03503
03504 lock_both(callno0, callno1);
03505 if (!iaxs[callno0] || !iaxs[callno1]) {
03506 unlock_both(callno0, callno1);
03507 return AST_BRIDGE_FAILED;
03508 }
03509
03510 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03511 iaxs[callno0]->bridgecallno = callno1;
03512 iaxs[callno1]->bridgecallno = callno0;
03513 }
03514 unlock_both(callno0, callno1);
03515
03516
03517 cs[0] = c0;
03518 cs[1] = c1;
03519 for (;;) {
03520
03521 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03522 if (option_verbose > 2)
03523 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03524
03525 if (c0->tech == &iax2_tech) {
03526 ast_mutex_lock(&iaxsl[callno0]);
03527 iaxs[callno0]->bridgecallno = 0;
03528 ast_mutex_unlock(&iaxsl[callno0]);
03529 }
03530 if (c1->tech == &iax2_tech) {
03531 ast_mutex_lock(&iaxsl[callno1]);
03532 iaxs[callno1]->bridgecallno = 0;
03533 ast_mutex_unlock(&iaxsl[callno1]);
03534 }
03535 return AST_BRIDGE_FAILED_NOWARN;
03536 }
03537 if (c0->nativeformats != c1->nativeformats) {
03538 if (option_verbose > 2) {
03539 char buf0[255];
03540 char buf1[255];
03541 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03542 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03543 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03544 }
03545
03546 lock_both(callno0, callno1);
03547 if (iaxs[callno0])
03548 iaxs[callno0]->bridgecallno = 0;
03549 if (iaxs[callno1])
03550 iaxs[callno1]->bridgecallno = 0;
03551 unlock_both(callno0, callno1);
03552 return AST_BRIDGE_FAILED_NOWARN;
03553 }
03554
03555 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03556
03557 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03558 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03559 ast_log(LOG_WARNING, "Unable to start the transfer\n");
03560 transferstarted = 1;
03561 }
03562 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03563
03564 gettimeofday(&tv, NULL);
03565 if (ast_tvzero(waittimer)) {
03566 waittimer = tv;
03567 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03568 c0->_softhangup |= AST_SOFTHANGUP_DEV;
03569 c1->_softhangup |= AST_SOFTHANGUP_DEV;
03570 *fo = NULL;
03571 *rc = c0;
03572 res = AST_BRIDGE_COMPLETE;
03573 break;
03574 }
03575 }
03576 to = 1000;
03577 who = ast_waitfor_n(cs, 2, &to);
03578 if (timeoutms > -1) {
03579 timeoutms -= (1000 - to);
03580 if (timeoutms < 0)
03581 timeoutms = 0;
03582 }
03583 if (!who) {
03584 if (!timeoutms) {
03585 res = AST_BRIDGE_RETRY;
03586 break;
03587 }
03588 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03589 res = AST_BRIDGE_FAILED;
03590 break;
03591 }
03592 continue;
03593 }
03594 f = ast_read(who);
03595 if (!f) {
03596 *fo = NULL;
03597 *rc = who;
03598 res = AST_BRIDGE_COMPLETE;
03599 break;
03600 }
03601 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03602 *fo = f;
03603 *rc = who;
03604 res = AST_BRIDGE_COMPLETE;
03605 break;
03606 }
03607 other = (who == c0) ? c1 : c0;
03608 if ((f->frametype == AST_FRAME_VOICE) ||
03609 (f->frametype == AST_FRAME_TEXT) ||
03610 (f->frametype == AST_FRAME_VIDEO) ||
03611 (f->frametype == AST_FRAME_IMAGE) ||
03612 (f->frametype == AST_FRAME_DTMF)) {
03613
03614
03615
03616 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03617 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03618 *rc = who;
03619 *fo = f;
03620 res = AST_BRIDGE_COMPLETE;
03621
03622 break;
03623 }
03624
03625 ast_write(other, f);
03626 }
03627 ast_frfree(f);
03628
03629 cs[2] = cs[0];
03630 cs[0] = cs[1];
03631 cs[1] = cs[2];
03632 }
03633 lock_both(callno0, callno1);
03634 if(iaxs[callno0])
03635 iaxs[callno0]->bridgecallno = 0;
03636 if(iaxs[callno1])
03637 iaxs[callno1]->bridgecallno = 0;
03638 unlock_both(callno0, callno1);
03639 return res;
03640 }
03641
03642 static int iax2_answer(struct ast_channel *c)
03643 {
03644 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03645 if (option_debug)
03646 ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03647 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03648 }
03649
03650 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03651 {
03652 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03653 struct chan_iax2_pvt *pvt;
03654 int res = 0;
03655
03656 if (option_debug && iaxdebug)
03657 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03658
03659 ast_mutex_lock(&iaxsl[callno]);
03660 pvt = iaxs[callno];
03661
03662 if (!pvt->peercallno) {
03663
03664 int count = 10;
03665 while (count-- && pvt && !pvt->peercallno) {
03666 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03667 pvt = iaxs[callno];
03668 }
03669 if (!pvt->peercallno) {
03670 res = -1;
03671 goto done;
03672 }
03673 }
03674
03675 switch (condition) {
03676 case AST_CONTROL_HOLD:
03677 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03678 ast_moh_start(c, data, pvt->mohinterpret);
03679 goto done;
03680 }
03681 break;
03682 case AST_CONTROL_UNHOLD:
03683 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
03684 ast_moh_stop(c);
03685 goto done;
03686 }
03687 }
03688
03689 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03690
03691 done:
03692 ast_mutex_unlock(&iaxsl[callno]);
03693
03694 return res;
03695 }
03696
03697 static int iax2_transfer(struct ast_channel *c, const char *dest)
03698 {
03699 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03700 struct iax_ie_data ied;
03701 char tmp[256], *context;
03702 ast_copy_string(tmp, dest, sizeof(tmp));
03703 context = strchr(tmp, '@');
03704 if (context) {
03705 *context = '\0';
03706 context++;
03707 }
03708 memset(&ied, 0, sizeof(ied));
03709 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03710 if (context)
03711 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03712 if (option_debug)
03713 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03714 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03715 }
03716
03717 static int iax2_getpeertrunk(struct sockaddr_in sin)
03718 {
03719 struct iax2_peer *peer;
03720 int res = 0;
03721 struct ao2_iterator i;
03722
03723 i = ao2_iterator_init(peers, 0);
03724 while ((peer = ao2_iterator_next(&i))) {
03725 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03726 (peer->addr.sin_port == sin.sin_port)) {
03727 res = ast_test_flag(peer, IAX_TRUNK);
03728 peer_unref(peer);
03729 break;
03730 }
03731 peer_unref(peer);
03732 }
03733
03734 return res;
03735 }
03736
03737
03738 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03739 {
03740 struct ast_channel *tmp;
03741 struct chan_iax2_pvt *i;
03742 struct ast_variable *v = NULL;
03743
03744 if (!(i = iaxs[callno])) {
03745 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03746 return NULL;
03747 }
03748
03749
03750 ast_mutex_unlock(&iaxsl[callno]);
03751 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);
03752 ast_mutex_lock(&iaxsl[callno]);
03753 if (!iaxs[callno]) {
03754 if (tmp) {
03755 ast_channel_free(tmp);
03756 }
03757 ast_mutex_unlock(&iaxsl[callno]);
03758 return NULL;
03759 }
03760
03761 if (!tmp)
03762 return NULL;
03763 tmp->tech = &iax2_tech;
03764
03765 tmp->nativeformats = capability;
03766 tmp->readformat = ast_best_codec(capability);
03767 tmp->writeformat = ast_best_codec(capability);
03768 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03769
03770
03771
03772 if (!ast_strlen_zero(i->ani))
03773 tmp->cid.cid_ani = ast_strdup(i->ani);
03774 else
03775 tmp->cid.cid_ani = ast_strdup(i->cid_num);
03776 tmp->cid.cid_dnid = ast_strdup(i->dnid);
03777 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03778 tmp->cid.cid_pres = i->calling_pres;
03779 tmp->cid.cid_ton = i->calling_ton;
03780 tmp->cid.cid_tns = i->calling_tns;
03781 if (!ast_strlen_zero(i->language))
03782 ast_string_field_set(tmp, language, i->language);
03783 if (!ast_strlen_zero(i->accountcode))
03784 ast_string_field_set(tmp, accountcode, i->accountcode);
03785 if (i->amaflags)
03786 tmp->amaflags = i->amaflags;
03787 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03788 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03789 if (i->adsi)
03790 tmp->adsicpe = i->peeradsicpe;
03791 else
03792 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03793 i->owner = tmp;
03794 i->capability = capability;
03795
03796 for (v = i->vars ; v ; v = v->next)
03797 pbx_builtin_setvar_helper(tmp, v->name, v->value);
03798
03799 if (state != AST_STATE_DOWN) {
03800 if (ast_pbx_start(tmp)) {
03801 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03802 ast_hangup(tmp);
03803 i->owner = NULL;
03804 return NULL;
03805 }
03806 }
03807
03808 ast_module_ref(ast_module_info->self);
03809
03810 return tmp;
03811 }
03812
03813 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03814 {
03815 unsigned long int mssincetx;
03816 long int ms, pred;
03817
03818 tpeer->trunkact = *tv;
03819 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03820 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03821
03822 tpeer->txtrunktime = *tv;
03823 tpeer->lastsent = 999999;
03824 }
03825
03826 tpeer->lasttxtime = *tv;
03827
03828
03829 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03830
03831 pred = tpeer->lastsent + sampms;
03832 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03833 ms = pred;
03834
03835
03836 if (ms == tpeer->lastsent)
03837 ms = tpeer->lastsent + 1;
03838 tpeer->lastsent = ms;
03839 return ms;
03840 }
03841
03842 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03843 {
03844 long ms;
03845 if (ast_tvzero(iaxs[callno]->rxcore)) {
03846
03847 gettimeofday(&iaxs[callno]->rxcore, NULL);
03848
03849 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03850 }
03851
03852 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03853
03854 return ms + ts;
03855 }
03856
03857 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03858 {
03859 int ms;
03860 int voice = 0;
03861 int genuine = 0;
03862 int adjust;
03863 struct timeval *delivery = NULL;
03864
03865
03866
03867
03868
03869
03870
03871
03872 if (f) {
03873 if (f->frametype == AST_FRAME_VOICE) {
03874 voice = 1;
03875 delivery = &f->delivery;
03876 } else if (f->frametype == AST_FRAME_IAX) {
03877 genuine = 1;
03878 } else if (f->frametype == AST_FRAME_CNG) {
03879 p->notsilenttx = 0;
03880 }
03881 }
03882 if (ast_tvzero(p->offset)) {
03883 gettimeofday(&p->offset, NULL);
03884
03885 p->offset.tv_usec -= p->offset.tv_usec % 20000;
03886 }
03887
03888 if (ts)
03889 return ts;
03890
03891 if (delivery && !ast_tvzero(*delivery)) {
03892 ms = ast_tvdiff_ms(*delivery, p->offset);
03893 if (option_debug > 2 && iaxdebug)
03894 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03895 } else {
03896 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03897 if (ms < 0)
03898 ms = 0;
03899 if (voice) {
03900
03901 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919
03920 adjust = (ms - p->nextpred);
03921 if (adjust < 0)
03922 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03923 else if (adjust > 0)
03924 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03925
03926 if (!p->nextpred) {
03927 p->nextpred = ms;
03928 if (p->nextpred <= p->lastsent)
03929 p->nextpred = p->lastsent + 3;
03930 }
03931 ms = p->nextpred;
03932 } else {
03933
03934
03935
03936
03937
03938
03939
03940
03941
03942 if (option_debug && iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03943 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03944 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03945
03946 if (f->samples >= 8)
03947 {
03948 int diff = ms % (f->samples / 8);
03949 if (diff)
03950 ms += f->samples/8 - diff;
03951 }
03952
03953 p->nextpred = ms;
03954 p->notsilenttx = 1;
03955 }
03956 } else if ( f->frametype == AST_FRAME_VIDEO ) {
03957
03958
03959
03960
03961
03962
03963
03964
03965 if ( (unsigned int)ms < p->lastsent )
03966 ms = p->lastsent;
03967 } else {
03968
03969
03970 if (genuine) {
03971
03972 if (ms <= p->lastsent)
03973 ms = p->lastsent + 3;
03974 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03975
03976 ms = p->lastsent + 3;
03977 }
03978 }
03979 }
03980 p->lastsent = ms;
03981 if (voice)
03982 p->nextpred = p->nextpred + f->samples / 8;
03983 return ms;
03984 }
03985
03986 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03987 {
03988
03989
03990 int ms;
03991 #ifdef IAXTESTS
03992 int jit;
03993 #endif
03994
03995 if (ast_tvzero(p->rxcore)) {
03996 p->rxcore = ast_tvnow();
03997 if (option_debug && iaxdebug)
03998 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03999 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04000 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04001 #if 1
04002 if (option_debug && iaxdebug)
04003 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04004 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04005 #endif
04006 }
04007
04008 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04009 #ifdef IAXTESTS
04010 if (test_jit) {
04011 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04012 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04013 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04014 jit = -jit;
04015 ms += jit;
04016 }
04017 }
04018 if (test_late) {
04019 ms += test_late;
04020 test_late = 0;
04021 }
04022 #endif
04023 return ms;
04024 }
04025
04026 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04027 {
04028 struct iax2_trunk_peer *tpeer;
04029
04030
04031 ast_mutex_lock(&tpeerlock);
04032 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
04033
04034 if (!inaddrcmp(&tpeer->addr, sin)) {
04035 ast_mutex_lock(&tpeer->lock);
04036 break;
04037 }
04038 }
04039 if (!tpeer) {
04040 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04041 ast_mutex_init(&tpeer->lock);
04042 tpeer->lastsent = 9999;
04043 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04044 tpeer->trunkact = ast_tvnow();
04045 ast_mutex_lock(&tpeer->lock);
04046 tpeer->next = tpeers;
04047 tpeer->sockfd = fd;
04048 tpeers = tpeer;
04049 #ifdef SO_NO_CHECK
04050 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04051 #endif
04052 if (option_debug)
04053 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04054 }
04055 }
04056 ast_mutex_unlock(&tpeerlock);
04057 return tpeer;
04058 }
04059
04060 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04061 {
04062 struct ast_frame *f;
04063 struct iax2_trunk_peer *tpeer;
04064 void *tmp, *ptr;
04065 struct ast_iax2_meta_trunk_entry *met;
04066 struct ast_iax2_meta_trunk_mini *mtm;
04067
04068 f = &fr->af;
04069 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04070 if (tpeer) {
04071 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04072
04073 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
04074 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04075 ast_mutex_unlock(&tpeer->lock);
04076 return -1;
04077 }
04078
04079 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04080 tpeer->trunkdata = tmp;
04081 if (option_debug)
04082 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);
04083 } else {
04084 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));
04085 ast_mutex_unlock(&tpeer->lock);
04086 return -1;
04087 }
04088 }
04089
04090
04091 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04092 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04093 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04094 mtm->len = htons(f->datalen);
04095 mtm->mini.callno = htons(pvt->callno);
04096 mtm->mini.ts = htons(0xffff & fr->ts);
04097 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04098 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04099 } else {
04100 met = (struct ast_iax2_meta_trunk_entry *)ptr;
04101
04102 met->callno = htons(pvt->callno);
04103 met->len = htons(f->datalen);
04104
04105 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04106 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04107 }
04108
04109 memcpy(ptr, f->data, f->datalen);
04110 tpeer->trunkdatalen += f->datalen;
04111
04112 tpeer->calls++;
04113 ast_mutex_unlock(&tpeer->lock);
04114 }
04115 return 0;
04116 }
04117
04118 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
04119 {
04120 aes_encrypt_key128(digest, ecx);
04121 aes_decrypt_key128(digest, dcx);
04122 }
04123
04124 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
04125 {
04126 #if 0
04127
04128 int x;
04129 if (len % 16)
04130 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04131 for (x=0;x<len;x++)
04132 dst[x] = src[x] ^ 0xff;
04133 #else
04134 unsigned char lastblock[16] = { 0 };
04135 int x;
04136 while(len > 0) {
04137 aes_decrypt(src, dst, dcx);
04138 for (x=0;x<16;x++)
04139 dst[x] ^= lastblock[x];
04140 memcpy(lastblock, src, sizeof(lastblock));
04141 dst += 16;
04142 src += 16;
04143 len -= 16;
04144 }
04145 #endif
04146 }
04147
04148 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
04149 {
04150 #if 0
04151
04152 int x;
04153 if (len % 16)
04154 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04155 for (x=0;x<len;x++)
04156 dst[x] = src[x] ^ 0xff;
04157 #else
04158 unsigned char curblock[16] = { 0 };
04159 int x;
04160 while(len > 0) {
04161 for (x=0;x<16;x++)
04162 curblock[x] ^= src[x];
04163 aes_encrypt(curblock, dst, ecx);
04164 memcpy(curblock, dst, sizeof(curblock));
04165 dst += 16;
04166 src += 16;
04167 len -= 16;
04168 }
04169 #endif
04170 }
04171
04172 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04173 {
04174 int padding;
04175 unsigned char *workspace;
04176
04177 workspace = alloca(*datalen);
04178 memset(f, 0, sizeof(*f));
04179 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04180 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04181 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04182 return -1;
04183
04184 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04185
04186 padding = 16 + (workspace[15] & 0xf);
04187 if (option_debug && iaxdebug)
04188 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04189 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04190 return -1;
04191
04192 *datalen -= padding;
04193 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04194 f->frametype = fh->type;
04195 if (f->frametype == AST_FRAME_VIDEO) {
04196 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04197 } else {
04198 f->subclass = uncompress_subclass(fh->csub);
04199 }
04200 } else {
04201 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04202 if (option_debug && iaxdebug)
04203 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
04204 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04205 return -1;
04206
04207 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04208 padding = 16 + (workspace[15] & 0x0f);
04209 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04210 return -1;
04211 *datalen -= padding;
04212 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04213 }
04214 return 0;
04215 }
04216
04217 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04218 {
04219 int padding;
04220 unsigned char *workspace;
04221 workspace = alloca(*datalen + 32);
04222 if (!workspace)
04223 return -1;
04224 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04225 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04226 if (option_debug && iaxdebug)
04227 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04228 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04229 padding = 16 + (padding & 0xf);
04230 memcpy(workspace, poo, padding);
04231 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04232 workspace[15] &= 0xf0;
04233 workspace[15] |= (padding & 0xf);
04234 if (option_debug && iaxdebug)
04235 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]);
04236 *datalen += padding;
04237 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04238 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04239 memcpy(poo, workspace + *datalen - 32, 32);
04240 } else {
04241 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04242 if (option_debug && iaxdebug)
04243 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
04244 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04245 padding = 16 + (padding & 0xf);
04246 memcpy(workspace, poo, padding);
04247 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04248 workspace[15] &= 0xf0;
04249 workspace[15] |= (padding & 0x0f);
04250 *datalen += padding;
04251 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04252 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04253 memcpy(poo, workspace + *datalen - 32, 32);
04254 }
04255 return 0;
04256 }
04257
04258 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04259 {
04260 int res=-1;
04261 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04262
04263 struct MD5Context md5;
04264 unsigned char digest[16];
04265 char *tmppw, *stringp;
04266
04267 tmppw = ast_strdupa(iaxs[callno]->secret);
04268 stringp = tmppw;
04269 while ((tmppw = strsep(&stringp, ";"))) {
04270 MD5Init(&md5);
04271 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04272 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04273 MD5Final(digest, &md5);
04274 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
04275 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04276 if (!res) {
04277 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04278 break;
04279 }
04280 }
04281 } else
04282 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04283 return res;
04284 }
04285
04286 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04287 {
04288
04289
04290
04291 struct ast_iax2_full_hdr *fh;
04292 struct ast_iax2_mini_hdr *mh;
04293 struct ast_iax2_video_hdr *vh;
04294 struct {
04295 struct iax_frame fr2;
04296 unsigned char buffer[4096];
04297 } frb;
04298 struct iax_frame *fr;
04299 int res;
04300 int sendmini=0;
04301 unsigned int lastsent;
04302 unsigned int fts;
04303
04304 frb.fr2.afdatalen = sizeof(frb.buffer);
04305
04306 if (!pvt) {
04307 ast_log(LOG_WARNING, "No private structure for packet?\n");
04308 return -1;
04309 }
04310
04311 lastsent = pvt->lastsent;
04312
04313
04314 fts = calc_timestamp(pvt, ts, f);
04315
04316
04317
04318
04319 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04320 return 0;
04321
04322
04323 if ((ast_test_flag(pvt, IAX_TRUNK) ||
04324 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04325 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04326 &&
04327 (f->frametype == AST_FRAME_VOICE)
04328 &&
04329 (f->subclass == pvt->svoiceformat)
04330 ) {
04331
04332 now = 1;
04333
04334 sendmini = 1;
04335 }
04336 if ( f->frametype == AST_FRAME_VIDEO ) {
04337
04338
04339
04340
04341
04342 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
04343 ((f->subclass & ~0x1) == pvt->svideoformat)
04344 ) {
04345 now = 1;
04346 sendmini = 1;
04347 } else {
04348 now = 0;
04349 sendmini = 0;
04350 }
04351 pvt->lastvsent = fts;
04352 }
04353
04354 if (now) {
04355 fr = &frb.fr2;
04356 } else
04357 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));
04358 if (!fr) {
04359 ast_log(LOG_WARNING, "Out of memory\n");
04360 return -1;
04361 }
04362
04363 iax_frame_wrap(fr, f);
04364
04365 fr->ts = fts;
04366 fr->callno = pvt->callno;
04367 fr->transfer = transfer;
04368 fr->final = final;
04369 if (!sendmini) {
04370
04371 if (seqno > -1)
04372 fr->oseqno = seqno;
04373 else
04374 fr->oseqno = pvt->oseqno++;
04375 fr->iseqno = pvt->iseqno;
04376 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
04377 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
04378 fh->ts = htonl(fr->ts);
04379 fh->oseqno = fr->oseqno;
04380 if (transfer) {
04381 fh->iseqno = 0;
04382 } else
04383 fh->iseqno = fr->iseqno;
04384
04385 if (!transfer)
04386 pvt->aseqno = fr->iseqno;
04387 fh->type = fr->af.frametype & 0xFF;
04388 if (fr->af.frametype == AST_FRAME_VIDEO)
04389 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
04390 else
04391 fh->csub = compress_subclass(fr->af.subclass);
04392 if (transfer) {
04393 fr->dcallno = pvt->transfercallno;
04394 } else
04395 fr->dcallno = pvt->peercallno;
04396 fh->dcallno = htons(fr->dcallno);
04397 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
04398 fr->data = fh;
04399 fr->retries = 0;
04400
04401 fr->retrytime = pvt->pingtime * 2;
04402 if (fr->retrytime < MIN_RETRY_TIME)
04403 fr->retrytime = MIN_RETRY_TIME;
04404 if (fr->retrytime > MAX_RETRY_TIME)
04405 fr->retrytime = MAX_RETRY_TIME;
04406
04407 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
04408 fr->retries = -1;
04409 else if (f->frametype == AST_FRAME_VOICE)
04410 pvt->svoiceformat = f->subclass;
04411 else if (f->frametype == AST_FRAME_VIDEO)
04412 pvt->svideoformat = f->subclass & ~0x1;
04413 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04414 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04415 if (iaxdebug) {
04416 if (fr->transfer)
04417 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04418 else
04419 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
04420 }
04421 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
04422 } else
04423 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04424 }
04425
04426 if (now) {
04427 res = send_packet(fr);
04428 } else
04429 res = iax2_transmit(fr);
04430 } else {
04431 if (ast_test_flag(pvt, IAX_TRUNK)) {
04432 iax2_trunk_queue(pvt, fr);
04433 res = 0;
04434 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
04435
04436 fr->oseqno = -1;
04437 fr->iseqno = -1;
04438 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
04439 vh->zeros = 0;
04440 vh->callno = htons(0x8000 | fr->callno);
04441 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
04442 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
04443 fr->data = vh;
04444 fr->retries = -1;
04445 res = send_packet(fr);
04446 } else {
04447
04448 fr->oseqno = -1;
04449 fr->iseqno = -1;
04450
04451 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
04452 mh->callno = htons(fr->callno);
04453 mh->ts = htons(fr->ts & 0xFFFF);
04454 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
04455 fr->data = mh;
04456 fr->retries = -1;
04457 if (pvt->transferring == TRANSFER_MEDIAPASS)
04458 fr->transfer = 1;
04459 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
04460 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
04461 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
04462 } else
04463 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
04464 }
04465 res = send_packet(fr);
04466 }
04467 }
04468 return res;
04469 }
04470
04471 static int iax2_show_users(int fd, int argc, char *argv[])
04472 {
04473 regex_t regexbuf;
04474 int havepattern = 0;
04475
04476 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
04477 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
04478
04479 struct iax2_user *user = NULL;
04480 char auth[90];
04481 char *pstr = "";
04482 struct ao2_iterator i;
04483
04484 switch (argc) {
04485 case 5:
04486 if (!strcasecmp(argv[3], "like")) {
04487 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04488 return RESULT_SHOWUSAGE;
04489 havepattern = 1;
04490 } else
04491 return RESULT_SHOWUSAGE;
04492 case 3:
04493 break;
04494 default:
04495 return RESULT_SHOWUSAGE;
04496 }
04497
04498 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04499 i = ao2_iterator_init(users, 0);
04500 for (user = ao2_iterator_next(&i); user;
04501 user_unref(user), user = ao2_iterator_next(&i)) {
04502 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
04503 continue;
04504
04505 if (!ast_strlen_zero(user->secret)) {
04506 ast_copy_string(auth,user->secret,sizeof(auth));
04507 } else if (!ast_strlen_zero(user->inkeys)) {
04508 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04509 } else
04510 ast_copy_string(auth, "-no secret-", sizeof(auth));
04511
04512 if(ast_test_flag(user,IAX_CODEC_NOCAP))
04513 pstr = "REQ Only";
04514 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04515 pstr = "Disabled";
04516 else
04517 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04518
04519 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods,
04520 user->contexts ? user->contexts->context : context,
04521 user->ha ? "Yes" : "No", pstr);
04522 }
04523
04524 if (havepattern)
04525 regfree(®exbuf);
04526
04527 return RESULT_SUCCESS;
04528 #undef FORMAT
04529 #undef FORMAT2
04530 }
04531
04532 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04533 {
04534 regex_t regexbuf;
04535 int havepattern = 0;
04536 int total_peers = 0;
04537 int online_peers = 0;
04538 int offline_peers = 0;
04539 int unmonitored_peers = 0;
04540 struct ao2_iterator i;
04541
04542 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
04543 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
04544
04545 struct iax2_peer *peer = NULL;
04546 char name[256];
04547 int registeredonly=0;
04548 char *term = manager ? "\r\n" : "\n";
04549
04550 switch (argc) {
04551 case 6:
04552 if (!strcasecmp(argv[3], "registered"))
04553 registeredonly = 1;
04554 else
04555 return RESULT_SHOWUSAGE;
04556 if (!strcasecmp(argv[4], "like")) {
04557 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04558 return RESULT_SHOWUSAGE;
04559 havepattern = 1;
04560 } else
04561 return RESULT_SHOWUSAGE;
04562 break;
04563 case 5:
04564 if (!strcasecmp(argv[3], "like")) {
04565 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04566 return RESULT_SHOWUSAGE;
04567 havepattern = 1;
04568 } else
04569 return RESULT_SHOWUSAGE;
04570 break;
04571 case 4:
04572 if (!strcasecmp(argv[3], "registered"))
04573 registeredonly = 1;
04574 else
04575 return RESULT_SHOWUSAGE;
04576 break;
04577 case 3:
04578 break;
04579 default:
04580 return RESULT_SHOWUSAGE;
04581 }
04582
04583
04584 if (s)
04585 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
04586 else
04587 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
04588
04589 i = ao2_iterator_init(peers, 0);
04590 for (peer = ao2_iterator_next(&i); peer;
04591 peer_unref(peer), peer = ao2_iterator_next(&i)) {
04592 char nm[20];
04593 char status[20];
04594 char srch[2000];
04595 int retstatus;
04596
04597 if (registeredonly && !peer->addr.sin_addr.s_addr)
04598 continue;
04599 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
04600 continue;
04601
04602 if (!ast_strlen_zero(peer->username))
04603 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04604 else
04605 ast_copy_string(name, peer->name, sizeof(name));
04606
04607 retstatus = peer_status(peer, status, sizeof(status));
04608 if (retstatus > 0)
04609 online_peers++;
04610 else if (!retstatus)
04611 offline_peers++;
04612 else
04613 unmonitored_peers++;
04614
04615 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04616
04617 snprintf(srch, sizeof(srch), FORMAT, name,
04618 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04619 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04620 nm,
04621 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04622 peer->encmethods ? "(E)" : " ", status, term);
04623
04624 if (s)
04625 astman_append(s, FORMAT, name,
04626 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04627 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04628 nm,
04629 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04630 peer->encmethods ? "(E)" : " ", status, term);
04631 else
04632 ast_cli(fd, FORMAT, name,
04633 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04634 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04635 nm,
04636 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04637 peer->encmethods ? "(E)" : " ", status, term);
04638 total_peers++;
04639 }
04640
04641 if (s)
04642 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04643 else
04644 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04645
04646 if (havepattern)
04647 regfree(®exbuf);
04648
04649 return RESULT_SUCCESS;
04650 #undef FORMAT
04651 #undef FORMAT2
04652 }
04653
04654 static int iax2_show_threads(int fd, int argc, char *argv[])
04655 {
04656 struct iax2_thread *thread = NULL;
04657 time_t t;
04658 int threadcount = 0, dynamiccount = 0;
04659 char type;
04660
04661 if (argc != 3)
04662 return RESULT_SHOWUSAGE;
04663
04664 ast_cli(fd, "IAX2 Thread Information\n");
04665 time(&t);
04666 ast_cli(fd, "Idle Threads:\n");
04667 AST_LIST_LOCK(&idle_list);
04668 AST_LIST_TRAVERSE(&idle_list, thread, list) {
04669 #ifdef DEBUG_SCHED_MULTITHREAD
04670 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04671 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04672 #else
04673 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04674 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04675 #endif
04676 threadcount++;
04677 }
04678 AST_LIST_UNLOCK(&idle_list);
04679 ast_cli(fd, "Active Threads:\n");
04680 AST_LIST_LOCK(&active_list);
04681 AST_LIST_TRAVERSE(&active_list, thread, list) {
04682 if (thread->type == IAX_TYPE_DYNAMIC)
04683 type = 'D';
04684 else
04685 type = 'P';
04686 #ifdef DEBUG_SCHED_MULTITHREAD
04687 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
04688 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04689 #else
04690 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
04691 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04692 #endif
04693 threadcount++;
04694 }
04695 AST_LIST_UNLOCK(&active_list);
04696 ast_cli(fd, "Dynamic Threads:\n");
04697 AST_LIST_LOCK(&dynamic_list);
04698 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04699 #ifdef DEBUG_SCHED_MULTITHREAD
04700 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04701 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04702 #else
04703 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04704 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04705 #endif
04706 dynamiccount++;
04707 }
04708 AST_LIST_UNLOCK(&dynamic_list);
04709 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04710 return RESULT_SUCCESS;
04711 }
04712
04713 static int iax2_show_peers(int fd, int argc, char *argv[])
04714 {
04715 return __iax2_show_peers(0, fd, NULL, argc, argv);
04716 }
04717 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04718 {
04719 ast_cli_netstats(s, -1, 0);
04720 astman_append(s, "\r\n");
04721 return RESULT_SUCCESS;
04722 }
04723
04724 static int iax2_show_firmware(int fd, int argc, char *argv[])
04725 {
04726 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
04727 #if !defined(__FreeBSD__)
04728 #define FORMAT "%-15.15s %-15d %-15d\n"
04729 #else
04730 #define FORMAT "%-15.15s %-15d %-15d\n"
04731 #endif
04732 struct iax_firmware *cur;
04733 if ((argc != 3) && (argc != 4))
04734 return RESULT_SHOWUSAGE;
04735 ast_mutex_lock(&waresl.lock);
04736
04737 ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04738 for (cur = waresl.wares;cur;cur = cur->next) {
04739 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))
04740 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04741 (int)ntohl(cur->fwh->datalen));
04742 }
04743 ast_mutex_unlock(&waresl.lock);
04744 return RESULT_SUCCESS;
04745 #undef FORMAT
04746 #undef FORMAT2
04747 }
04748
04749
04750 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04751 {
04752 char *a[] = { "iax2", "show", "users" };
04753 int ret;
04754 const char *id = astman_get_header(m,"ActionID");
04755
04756 if (!ast_strlen_zero(id))
04757 astman_append(s, "ActionID: %s\r\n",id);
04758 ret = __iax2_show_peers(1, -1, s, 3, a );
04759 astman_append(s, "\r\n\r\n" );
04760 return ret;
04761 }
04762
04763 static char *regstate2str(int regstate)
04764 {
04765 switch(regstate) {
04766 case REG_STATE_UNREGISTERED:
04767 return "Unregistered";
04768 case REG_STATE_REGSENT:
04769 return "Request Sent";
04770 case REG_STATE_AUTHSENT:
04771 return "Auth. Sent";
04772 case REG_STATE_REGISTERED:
04773 return "Registered";
04774 case REG_STATE_REJECTED:
04775 return "Rejected";
04776 case REG_STATE_TIMEOUT:
04777 return "Timeout";
04778 case REG_STATE_NOAUTH:
04779 return "No Authentication";
04780 default:
04781 return "Unknown";
04782 }
04783 }
04784
04785 static int iax2_show_registry(int fd, int argc, char *argv[])
04786 {
04787 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
04788 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
04789 struct iax2_registry *reg = NULL;
04790
04791 char host[80];
04792 char perceived[80];
04793 if (argc != 3)
04794 return RESULT_SHOWUSAGE;
04795 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04796 AST_LIST_LOCK(®istrations);
04797 AST_LIST_TRAVERSE(®istrations, reg, entry) {
04798 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04799 if (reg->us.sin_addr.s_addr)
04800 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04801 else
04802 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04803 ast_cli(fd, FORMAT, host,
04804 (reg->dnsmgr) ? "Y" : "N",
04805 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04806 }
04807 AST_LIST_UNLOCK(®istrations);
04808 return RESULT_SUCCESS;
04809 #undef FORMAT
04810 #undef FORMAT2
04811 }
04812
04813 static int iax2_show_channels(int fd, int argc, char *argv[])
04814 {
04815 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
04816 #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"
04817 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
04818 int x;
04819 int numchans = 0;
04820
04821 if (argc != 3)
04822 return RESULT_SHOWUSAGE;
04823 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04824 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04825 ast_mutex_lock(&iaxsl[x]);
04826 if (iaxs[x]) {
04827 int lag, jitter, localdelay;
04828 jb_info jbinfo;
04829
04830 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04831 jb_getinfo(iaxs[x]->jb, &jbinfo);
04832 jitter = jbinfo.jitter;
04833 localdelay = jbinfo.current - jbinfo.min;
04834 } else {
04835 jitter = -1;
04836 localdelay = 0;
04837 }
04838 lag = iaxs[x]->remote_rr.delay;
04839 ast_cli(fd, FORMAT,
04840 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04841 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
04842 S_OR(iaxs[x]->username, "(None)"),
04843 iaxs[x]->callno, iaxs[x]->peercallno,
04844 iaxs[x]->oseqno, iaxs[x]->iseqno,
04845 lag,
04846 jitter,
04847 localdelay,
04848 ast_getformatname(iaxs[x]->voiceformat) );
04849 numchans++;
04850 }
04851 ast_mutex_unlock(&iaxsl[x]);
04852 }
04853 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04854 return RESULT_SUCCESS;
04855 #undef FORMAT
04856 #undef FORMAT2
04857 #undef FORMATB
04858 }
04859
04860 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04861 {
04862 int x;
04863 int numchans = 0;
04864 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
04865 ast_mutex_lock(&iaxsl[x]);
04866 if (iaxs[x]) {
04867 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04868 char *fmt;
04869 jb_info jbinfo;
04870
04871 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04872 jb_getinfo(iaxs[x]->jb, &jbinfo);
04873 localjitter = jbinfo.jitter;
04874 localdelay = jbinfo.current - jbinfo.min;
04875 locallost = jbinfo.frames_lost;
04876 locallosspct = jbinfo.losspct/1000;
04877 localdropped = jbinfo.frames_dropped;
04878 localooo = jbinfo.frames_ooo;
04879 } else {
04880 localjitter = -1;
04881 localdelay = 0;
04882 locallost = -1;
04883 locallosspct = -1;
04884 localdropped = 0;
04885 localooo = -1;
04886 }
04887 if (limit_fmt)
04888 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04889 else
04890 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04891 if (s)
04892
04893 astman_append(s, fmt,
04894 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04895 iaxs[x]->pingtime,
04896 localjitter,
04897 localdelay,
04898 locallost,
04899 locallosspct,
04900 localdropped,
04901 localooo,
04902 iaxs[x]->frames_received/1000,
04903 iaxs[x]->remote_rr.jitter,
04904 iaxs[x]->remote_rr.delay,
04905 iaxs[x]->remote_rr.losscnt,
04906 iaxs[x]->remote_rr.losspct,
04907 iaxs[x]->remote_rr.dropped,
04908 iaxs[x]->remote_rr.ooo,
04909 iaxs[x]->remote_rr.packets/1000);
04910 else
04911 ast_cli(fd, fmt,
04912 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04913 iaxs[x]->pingtime,
04914 localjitter,
04915 localdelay,
04916 locallost,
04917 locallosspct,
04918 localdropped,
04919 localooo,
04920 iaxs[x]->frames_received/1000,
04921 iaxs[x]->remote_rr.jitter,
04922 iaxs[x]->remote_rr.delay,
04923 iaxs[x]->remote_rr.losscnt,
04924 iaxs[x]->remote_rr.losspct,
04925 iaxs[x]->remote_rr.dropped,
04926 iaxs[x]->remote_rr.ooo,
04927 iaxs[x]->remote_rr.packets/1000
04928 );
04929 numchans++;
04930 }
04931 ast_mutex_unlock(&iaxsl[x]);
04932 }
04933 return numchans;
04934 }
04935
04936 static int iax2_show_netstats(int fd, int argc, char *argv[])
04937 {
04938 int numchans = 0;
04939 if (argc != 3)
04940 return RESULT_SHOWUSAGE;
04941 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
04942 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
04943 numchans = ast_cli_netstats(NULL, fd, 1);
04944 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04945 return RESULT_SUCCESS;
04946 }
04947
04948 static int iax2_do_debug(int fd, int argc, char *argv[])
04949 {
04950 if (argc < 2 || argc > 3)
04951 return RESULT_SHOWUSAGE;
04952 iaxdebug = 1;
04953 ast_cli(fd, "IAX2 Debugging Enabled\n");
04954 return RESULT_SUCCESS;
04955 }
04956
04957 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04958 {
04959 if (argc < 3 || argc > 4)
04960 return RESULT_SHOWUSAGE;
04961 iaxtrunkdebug = 1;
04962 ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04963 return RESULT_SUCCESS;
04964 }
04965
04966 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04967 {
04968 if (argc < 3 || argc > 4)
04969 return RESULT_SHOWUSAGE;
04970 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04971 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04972 return RESULT_SUCCESS;
04973 }
04974
04975 static int iax2_no_debug(int fd, int argc, char *argv[])
04976 {
04977 if (argc < 3 || argc > 4)
04978 return RESULT_SHOWUSAGE;
04979 iaxdebug = 0;
04980 ast_cli(fd, "IAX2 Debugging Disabled\n");
04981 return RESULT_SUCCESS;
04982 }
04983
04984 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04985 {
04986 if (argc < 4 || argc > 5)
04987 return RESULT_SHOWUSAGE;
04988 iaxtrunkdebug = 0;
04989 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04990 return RESULT_SUCCESS;
04991 }
04992
04993 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04994 {
04995 if (argc < 4 || argc > 5)
04996 return RESULT_SHOWUSAGE;
04997 jb_setoutput(jb_error_output, jb_warning_output, NULL);
04998 jb_debug_output("\n");
04999 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05000 return RESULT_SUCCESS;
05001 }
05002
05003 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05004 {
05005 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05006 int res = -1;
05007 ast_mutex_lock(&iaxsl[callno]);
05008 if (iaxs[callno]) {
05009
05010 if (!iaxs[callno]->error) {
05011 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05012 res = 0;
05013
05014 else if (f->frametype == AST_FRAME_NULL)
05015 res = 0;
05016 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05017 res = 0;
05018 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05019 res = 0;
05020 else
05021
05022 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05023 } else {
05024 if (option_debug)
05025 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
05026 }
05027 }
05028
05029 ast_mutex_unlock(&iaxsl[callno]);
05030 return res;
05031 }
05032
05033 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
05034 int now, int transfer, int final)
05035 {
05036 struct ast_frame f = { 0, };
05037
05038 f.frametype = type;
05039 f.subclass = command;
05040 f.datalen = datalen;
05041 f.src = __FUNCTION__;
05042 f.data = (void *) data;
05043
05044 return iax2_send(i, &f, ts, seqno, now, transfer, final);
05045 }
05046
05047 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05048 {
05049 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05050 }
05051
05052 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05053 {
05054 int res;
05055 ast_mutex_lock(&iaxsl[callno]);
05056 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05057 ast_mutex_unlock(&iaxsl[callno]);
05058 return res;
05059 }
05060
05061
05062
05063
05064
05065
05066 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)
05067 {
05068 int call_num = i->callno;
05069
05070 iax2_predestroy(i->callno);
05071 if (!iaxs[call_num])
05072 return -1;
05073 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05074 }
05075
05076 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)
05077 {
05078 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05079 }
05080
05081 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
05082 {
05083 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
05084 }
05085
05086 static int apply_context(struct iax2_context *con, const char *context)
05087 {
05088 while(con) {
05089 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
05090 return -1;
05091 con = con->next;
05092 }
05093 return 0;
05094 }
05095
05096
05097 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05098 {
05099
05100 int res = -1;
05101 int version = 2;
05102 struct iax2_user *user = NULL, *best = NULL;
05103 int bestscore = 0;
05104 int gotcapability = 0;
05105 struct ast_variable *v = NULL, *tmpvar = NULL;
05106 struct ao2_iterator i;
05107
05108 if (!iaxs[callno])
05109 return res;
05110 if (ies->called_number)
05111 ast_string_field_set(iaxs[callno], exten, ies->called_number);
05112 if (ies->calling_number) {
05113 ast_shrink_phone_number(ies->calling_number);
05114 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
05115 }
05116 if (ies->calling_name)
05117 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
05118 if (ies->calling_ani)
05119 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
05120 if (ies->dnid)
05121 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
05122 if (ies->rdnis)
05123 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
05124 if (ies->called_context)
05125 ast_string_field_set(iaxs[callno], context, ies->called_context);
05126 if (ies->language)
05127 ast_string_field_set(iaxs[callno], language, ies->language);
05128 if (ies->username)
05129 ast_string_field_set(iaxs[callno], username, ies->username);
05130 if (ies->calling_ton > -1)
05131 iaxs[callno]->calling_ton = ies->calling_ton;
05132 if (ies->calling_tns > -1)
05133 iaxs[callno]->calling_tns = ies->calling_tns;
05134 if (ies->calling_pres > -1)
05135 iaxs[callno]->calling_pres = ies->calling_pres;
05136 if (ies->format)
05137 iaxs[callno]->peerformat = ies->format;
05138 if (ies->adsicpe)
05139 iaxs[callno]->peeradsicpe = ies->adsicpe;
05140 if (ies->capability) {
05141 gotcapability = 1;
05142 iaxs[callno]->peercapability = ies->capability;
05143 }
05144 if (ies->version)
05145 version = ies->version;
05146
05147
05148 if(ies->codec_prefs) {
05149 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
05150 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
05151 }
05152
05153 if (!gotcapability)
05154 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
05155 if (version > IAX_PROTO_VERSION) {
05156 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
05157 ast_inet_ntoa(sin->sin_addr), version);
05158 return res;
05159 }
05160
05161 i = ao2_iterator_init(users, 0);
05162 while ((user = ao2_iterator_next(&i))) {
05163 if ((ast_strlen_zero(iaxs[callno]->username) ||
05164 !strcmp(iaxs[callno]->username, user->name))
05165 && ast_apply_ha(user->ha, sin)
05166 && (ast_strlen_zero(iaxs[callno]->context) ||
05167 apply_context(user->contexts, iaxs[callno]->context))) {
05168 if (!ast_strlen_zero(iaxs[callno]->username)) {
05169
05170 if (best)
05171 user_unref(best);
05172 best = user;
05173 break;
05174 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
05175
05176 if (user->ha) {
05177
05178 if (bestscore < 4) {
05179 bestscore = 4;
05180 if (best)
05181 user_unref(best);
05182 best = user;
05183 continue;
05184 }
05185 } else {
05186
05187 if (bestscore < 3) {
05188 bestscore = 3;
05189 if (best)
05190 user_unref(best);
05191 best = user;
05192 continue;
05193 }
05194 }
05195 } else {
05196 if (user->ha) {
05197
05198 if (bestscore < 2) {
05199 bestscore = 2;
05200 if (best)
05201 user_unref(best);
05202 best = user;
05203 continue;
05204 }
05205 } else {
05206
05207 if (bestscore < 1) {
05208 bestscore = 1;
05209 if (best)
05210 user_unref(best);
05211 best = user;
05212 continue;
05213 }
05214 }
05215 }
05216 }
05217 user_unref(user);
05218 }
05219 user = best;
05220 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
05221 user = realtime_user(iaxs[callno]->username, sin);
05222 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
05223 !apply_context(user->contexts, iaxs[callno]->context)) {
05224 user = user_unref(user);
05225 }
05226 }
05227 if (user) {
05228
05229
05230 for (v = user->vars ; v ; v = v->next) {
05231 if((tmpvar = ast_variable_new(v->name, v->value))) {
05232 tmpvar->next = iaxs[callno]->vars;
05233 iaxs[callno]->vars = tmpvar;
05234 }
05235 }
05236
05237 if (user->maxauthreq > 0)
05238 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
05239 iaxs[callno]->prefs = user->prefs;
05240 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
05241 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
05242 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
05243 iaxs[callno]->encmethods = user->encmethods;
05244
05245 if (ast_strlen_zero(iaxs[callno]->username))
05246 ast_string_field_set(iaxs[callno], username, user->name);
05247
05248 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
05249 iaxs[callno]->capability = user->capability;
05250
05251 if (ast_strlen_zero(iaxs[callno]->context)) {
05252 if (user->contexts)
05253 ast_string_field_set(iaxs[callno], context, user->contexts->context);
05254 else
05255 ast_string_field_set(iaxs[callno], context, context);
05256 }
05257
05258 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
05259
05260 iaxs[callno]->authmethods = user->authmethods;
05261 iaxs[callno]->adsi = user->adsi;
05262
05263 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
05264 if (ast_test_flag(user, IAX_HASCALLERID)) {
05265 iaxs[callno]->calling_tns = 0;
05266 iaxs[callno]->calling_ton = 0;
05267 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
05268 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
05269 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
05270 }
05271 if (ast_strlen_zero(iaxs[callno]->ani))
05272 ast_string_field_set(iaxs[callno], ani, user->cid_num);
05273 } else {
05274 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
05275 }
05276 if (!ast_strlen_zero(user->accountcode))
05277 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
05278 if (!ast_strlen_zero(user->mohinterpret))
05279 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
05280 if (!ast_strlen_zero(user->mohsuggest))
05281 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
05282 if (user->amaflags)
05283 iaxs[callno]->amaflags = user->amaflags;
05284 if (!ast_strlen_zero(user->language))
05285 ast_string_field_set(iaxs[callno], language, user->language);
05286 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
05287
05288 if (!ast_strlen_zero(user->dbsecret)) {
05289 char *family, *key=NULL;
05290 char buf[80];
05291 family = ast_strdupa(user->dbsecret);
05292 key = strchr(family, '/');
05293 if (key) {
05294 *key = '\0';
05295 key++;
05296 }
05297 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
05298 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
05299 else
05300 ast_string_field_set(iaxs[callno], secret, buf);
05301 } else
05302 ast_string_field_set(iaxs[callno], secret, user->secret);
05303 res = 0;
05304 user = user_unref(user);
05305 } else {
05306
05307
05308
05309
05310 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
05311 ast_string_field_set(iaxs[callno], secret, "badsecret");
05312 iaxs[callno]->authrej = 1;
05313 if (!ast_strlen_zero(iaxs[callno]->username)) {
05314
05315 res = 0;
05316 }
05317 }
05318 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
05319 return res;
05320 }
05321
05322 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
05323 {
05324 struct ast_iax2_full_hdr fh;
05325 fh.scallno = htons(src | IAX_FLAG_FULL);
05326 fh.dcallno = htons(dst);
05327 fh.ts = 0;
05328 fh.oseqno = 0;
05329 fh.iseqno = 0;
05330 fh.type = AST_FRAME_IAX;
05331 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
05332 if (iaxdebug)
05333 iax_showframe(NULL, &fh, 0, sin, 0);
05334 if (option_debug)
05335 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
05336 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
05337 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
05338 }
05339
05340 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
05341 {
05342
05343 p->encmethods &= enc;
05344 if (p->encmethods) {
05345 if (p->encmethods & IAX_ENCRYPT_AES128)
05346 p->encmethods = IAX_ENCRYPT_AES128;
05347 else
05348 p->encmethods = 0;
05349 }
05350 }
05351
05352
05353
05354
05355
05356
05357
05358 static int authenticate_request(int call_num)
05359 {
05360 struct iax_ie_data ied;
05361 int res = -1, authreq_restrict = 0;
05362 char challenge[10];
05363 struct chan_iax2_pvt *p = iaxs[call_num];
05364
05365 memset(&ied, 0, sizeof(ied));
05366
05367
05368 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05369 struct iax2_user *user, tmp_user = {
05370 .name = p->username,
05371 };
05372
05373 user = ao2_find(users, &tmp_user, OBJ_POINTER);
05374 if (user) {
05375 if (user->curauthreq == user->maxauthreq)
05376 authreq_restrict = 1;
05377 else
05378 user->curauthreq++;
05379 user = user_unref(user);
05380 }
05381 }
05382
05383
05384 if (authreq_restrict) {
05385 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
05386 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
05387 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
05388 return 0;
05389 }
05390
05391 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05392 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
05393 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05394 ast_string_field_set(p, challenge, challenge);
05395
05396 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
05397 }
05398 if (p->encmethods)
05399 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
05400
05401 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
05402
05403 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
05404
05405 if (p->encmethods)
05406 ast_set_flag(p, IAX_ENCRYPTED);
05407
05408 return res;
05409 }
05410
05411 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
05412 {
05413 char requeststr[256];
05414 char md5secret[256] = "";
05415 char secret[256] = "";
05416 char rsasecret[256] = "";
05417 int res = -1;
05418 int x;
05419 struct iax2_user *user, tmp_user = {
05420 .name = p->username,
05421 };
05422
05423 if (p->authrej) {
05424 return res;
05425 }
05426 user = ao2_find(users, &tmp_user, OBJ_POINTER);
05427 if (user) {
05428 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
05429 ast_atomic_fetchadd_int(&user->curauthreq, -1);
05430 ast_clear_flag(p, IAX_MAXAUTHREQ);
05431 }
05432 ast_string_field_set(p, host, user->name);
05433 user = user_unref(user);
05434 }
05435
05436 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
05437 return res;
05438 if (ies->password)
05439 ast_copy_string(secret, ies->password, sizeof(secret));
05440 if (ies->md5_result)
05441 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05442 if (ies->rsa_result)
05443 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05444 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
05445 struct ast_key *key;
05446 char *keyn;
05447 char tmpkey[256];
05448 char *stringp=NULL;
05449 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
05450 stringp=tmpkey;
05451 keyn = strsep(&stringp, ":");
05452 while(keyn) {
05453 key = ast_key_get(keyn, AST_KEY_PUBLIC);
05454 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
05455 res = 0;
05456 break;
05457 } else if (!key)
05458 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
05459 keyn = strsep(&stringp, ":");
05460 }
05461 } else if (p->authmethods & IAX_AUTH_MD5) {
05462 struct MD5Context md5;
05463 unsigned char digest[16];
05464 char *tmppw, *stringp;
05465
05466 tmppw = ast_strdupa(p->secret);
05467 stringp = tmppw;
05468 while((tmppw = strsep(&stringp, ";"))) {
05469 MD5Init(&md5);
05470 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
05471 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05472 MD5Final(digest, &md5);
05473
05474 for (x=0;x<16;x++)
05475 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
05476 if (!strcasecmp(requeststr, md5secret)) {
05477 res = 0;
05478 break;
05479 }
05480 }
05481 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
05482 if (!strcmp(secret, p->secret))
05483 res = 0;
05484 }
05485 return res;
05486 }
05487
05488
05489 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
05490 {
05491 char requeststr[256] = "";
05492 char peer[256] = "";
05493 char md5secret[256] = "";
05494 char rsasecret[256] = "";
05495 char secret[256] = "";
05496 struct iax2_peer *p = NULL;
05497 struct ast_key *key;
05498 char *keyn;
05499 int x;
05500 int expire = 0;
05501 int res = -1;
05502
05503 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05504
05505 if (ies->username)
05506 ast_copy_string(peer, ies->username, sizeof(peer));
05507 if (ies->password)
05508 ast_copy_string(secret, ies->password, sizeof(secret));
05509 if (ies->md5_result)
05510 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
05511 if (ies->rsa_result)
05512 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
05513 if (ies->refresh)
05514 expire = ies->refresh;
05515
05516 if (ast_strlen_zero(peer)) {
05517 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05518 return -1;
05519 }
05520
05521
05522 ast_mutex_unlock(&iaxsl[callno]);
05523 p = find_peer(peer, 1);
05524 ast_mutex_lock(&iaxsl[callno]);
05525 if (!p || !iaxs[callno]) {
05526 if (iaxs[callno]) {
05527 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
05528
05529 ast_string_field_set(iaxs[callno], secret, "badsecret");
05530
05531
05532
05533
05534
05535
05536
05537
05538
05539
05540 if (ast_strlen_zero(iaxs[callno]->challenge) &&
05541 !(!ast_strlen_zero(secret) && plaintext)) {
05542
05543 res = 0;
05544 }
05545 }
05546 if (authdebug && !p)
05547 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05548
05549 goto return_unref;
05550 }
05551
05552 if (!ast_test_flag(p, IAX_DYNAMIC)) {
05553 if (authdebug)
05554 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05555 goto return_unref;
05556 }
05557
05558 if (!ast_apply_ha(p->ha, sin)) {
05559 if (authdebug)
05560 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05561 goto return_unref;
05562 }
05563 ast_string_field_set(iaxs[callno], secret, p->secret);
05564 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05565
05566 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05567 if (!ast_strlen_zero(p->inkeys)) {
05568 char tmpkeys[256];
05569 char *stringp=NULL;
05570 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05571 stringp=tmpkeys;
05572 keyn = strsep(&stringp, ":");
05573 while(keyn) {
05574 key = ast_key_get(keyn, AST_KEY_PUBLIC);
05575 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05576 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05577 break;
05578 } else if (!key)
05579 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05580 keyn = strsep(&stringp, ":");
05581 }
05582 if (!keyn) {
05583 if (authdebug)
05584 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05585 goto return_unref;
05586 }
05587 } else {
05588 if (authdebug)
05589 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05590 goto return_unref;
05591 }
05592 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05593 struct MD5Context md5;
05594 unsigned char digest[16];
05595 char *tmppw, *stringp;
05596
05597 tmppw = ast_strdupa(p->secret);
05598 stringp = tmppw;
05599 while((tmppw = strsep(&stringp, ";"))) {
05600 MD5Init(&md5);
05601 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05602 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05603 MD5Final(digest, &md5);
05604 for (x=0;x<16;x++)
05605 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
05606 if (!strcasecmp(requeststr, md5secret))
05607 break;
05608 }
05609 if (tmppw) {
05610 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05611 } else {
05612 if (authdebug)
05613 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05614 goto return_unref;
05615 }
05616 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05617
05618 if (strcmp(secret, p->secret)) {
05619 if (authdebug)
05620 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05621 goto return_unref;
05622 } else
05623 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05624 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
05625
05626 goto return_unref;
05627 }
05628 ast_device_state_changed("IAX2/%s", p->name);
05629
05630
05631 res = 0;
05632 return_unref:
05633 if (iaxs[callno]) {
05634 ast_string_field_set(iaxs[callno], peer, peer);
05635 }
05636
05637 if (expire && (expire < iaxs[callno]->expiry)) {
05638 iaxs[callno]->expiry = expire;
05639 }
05640
05641 if (p)
05642 peer_unref(p);
05643 return res;
05644 }
05645
05646 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
05647 {
05648 int res = -1;
05649 int x;
05650 if (!ast_strlen_zero(keyn)) {
05651 if (!(authmethods & IAX_AUTH_RSA)) {
05652 if (ast_strlen_zero(secret))
05653 ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr));
05654 } else if (ast_strlen_zero(challenge)) {
05655 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05656 } else {
05657 char sig[256];
05658 struct ast_key *key;
05659 key = ast_key_get(keyn, AST_KEY_PRIVATE);
05660 if (!key) {
05661 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05662 } else {
05663 if (ast_sign(key, (char*)challenge, sig)) {
05664 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05665 res = -1;
05666 } else {
05667 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05668 res = 0;
05669 }
05670 }
05671 }
05672 }
05673
05674 if (res && !ast_strlen_zero(secret)) {
05675 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05676 struct MD5Context md5;
05677 unsigned char digest[16];
05678 char digres[128];
05679 MD5Init(&md5);
05680 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05681 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05682 MD5Final(digest, &md5);
05683
05684 for (x=0;x<16;x++)
05685 sprintf(digres + (x << 1), "%2.2x", digest[x]);
05686 if (ecx && dcx)
05687 build_enc_keys(digest, ecx, dcx);
05688 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05689 res = 0;
05690 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05691 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05692 res = 0;
05693 } else
05694 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05695 }
05696 return res;
05697 }
05698
05699
05700
05701
05702
05703 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05704 {
05705 struct iax2_peer *peer = NULL;
05706
05707 int res = -1;
05708 int authmethods = 0;
05709 struct iax_ie_data ied;
05710 uint16_t callno = p->callno;
05711
05712 memset(&ied, 0, sizeof(ied));
05713
05714 if (ies->username)
05715 ast_string_field_set(p, username, ies->username);
05716 if (ies->challenge)
05717 ast_string_field_set(p, challenge, ies->challenge);
05718 if (ies->authmethods)
05719 authmethods = ies->authmethods;
05720 if (authmethods & IAX_AUTH_MD5)
05721 merge_encryption(p, ies->encmethods);
05722 else
05723 p->encmethods = 0;
05724
05725
05726 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05727
05728 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05729 } else {
05730 struct ao2_iterator i = ao2_iterator_init(peers, 0);
05731 while ((peer = ao2_iterator_next(&i))) {
05732 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
05733
05734 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05735
05736 && (!peer->addr.sin_addr.s_addr || ((sin->sin_addr.s_addr & peer->mask.s_addr) == (peer->addr.sin_addr.s_addr & peer->mask.s_addr)))
05737
05738 ) {
05739 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05740 if (!res) {
05741 peer_unref(peer);
05742 break;
05743 }
05744 }
05745 peer_unref(peer);
05746 }
05747 if (!peer) {
05748
05749
05750 const char *peer_name = ast_strdupa(p->peer);
05751 ast_mutex_unlock(&iaxsl[callno]);
05752 if ((peer = realtime_peer(peer_name, NULL))) {
05753 ast_mutex_lock(&iaxsl[callno]);
05754 if (!(p = iaxs[callno])) {
05755 peer_unref(peer);
05756 return -1;
05757 }
05758 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05759 peer_unref(peer);
05760 }
05761 if (!peer) {
05762 ast_mutex_lock(&iaxsl[callno]);
05763 if (!(p = iaxs[callno]))
05764 return -1;
05765 }
05766 }
05767 }
05768 if (ies->encmethods)
05769 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05770 if (!res)
05771 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05772 return res;
05773 }
05774
05775 static int iax2_do_register(struct iax2_registry *reg);
05776
05777 static void __iax2_do_register_s(const void *data)
05778 {
05779 struct iax2_registry *reg = (struct iax2_registry *)data;
05780 reg->expire = -1;
05781 iax2_do_register(reg);
05782 }
05783
05784 static int iax2_do_register_s(const void *data)
05785 {
05786 #ifdef SCHED_MULTITHREADED
05787 if (schedule_action(__iax2_do_register_s, data))
05788 #endif
05789 __iax2_do_register_s(data);
05790 return 0;
05791 }
05792
05793 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05794 {
05795 int newcall = 0;
05796 char newip[256];
05797 struct iax_ie_data ied;
05798 struct sockaddr_in new;
05799
05800
05801 memset(&ied, 0, sizeof(ied));
05802 if (ies->apparent_addr)
05803 bcopy(ies->apparent_addr, &new, sizeof(new));
05804 if (ies->callno)
05805 newcall = ies->callno;
05806 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05807 ast_log(LOG_WARNING, "Invalid transfer request\n");
05808 return -1;
05809 }
05810 pvt->transfercallno = newcall;
05811 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05812 inet_aton(newip, &pvt->transfer.sin_addr);
05813 pvt->transfer.sin_family = AF_INET;
05814 pvt->transferring = TRANSFER_BEGIN;
05815 pvt->transferid = ies->transferid;
05816 if (ies->transferid)
05817 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05818 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05819 return 0;
05820 }
05821
05822 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05823 {
05824 char exten[256] = "";
05825 int status = CACHE_FLAG_UNKNOWN;
05826 int expiry = iaxdefaultdpcache;
05827 int x;
05828 int matchmore = 0;
05829 struct iax2_dpcache *dp, *prev;
05830
05831 if (ies->called_number)
05832 ast_copy_string(exten, ies->called_number, sizeof(exten));
05833
05834 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05835 status = CACHE_FLAG_EXISTS;
05836 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05837 status = CACHE_FLAG_CANEXIST;
05838 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05839 status = CACHE_FLAG_NONEXISTENT;
05840
05841 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05842
05843 }
05844 if (ies->refresh)
05845 expiry = ies->refresh;
05846 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05847 matchmore = CACHE_FLAG_MATCHMORE;
05848 ast_mutex_lock(&dpcache_lock);
05849 prev = NULL;
05850 dp = pvt->dpentries;
05851 while(dp) {
05852 if (!strcmp(dp->exten, exten)) {
05853
05854 if (prev)
05855 prev->peer = dp->peer;
05856 else
05857 pvt->dpentries = dp->peer;
05858 dp->peer = NULL;
05859 dp->callno = 0;
05860 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05861 if (dp->flags & CACHE_FLAG_PENDING) {
05862 dp->flags &= ~CACHE_FLAG_PENDING;
05863 dp->flags |= status;
05864 dp->flags |= matchmore;
05865 }
05866
05867 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05868 if (dp->waiters[x] > -1)
05869 write(dp->waiters[x], "asdf", 4);
05870 }
05871 prev = dp;
05872 dp = dp->peer;
05873 }
05874 ast_mutex_unlock(&dpcache_lock);
05875 return 0;
05876 }
05877
05878 static int complete_transfer(int callno, struct iax_ies *ies)
05879 {
05880 int peercallno = 0;
05881 struct chan_iax2_pvt *pvt = iaxs[callno];
05882 struct iax_frame *cur;
05883 jb_frame frame;
05884
05885 if (ies->callno)
05886 peercallno = ies->callno;
05887
05888 if (peercallno < 1) {
05889 ast_log(LOG_WARNING, "Invalid transfer request\n");
05890 return -1;
05891 }
05892 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05893 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05894
05895 pvt->oseqno = 0;
05896 pvt->rseqno = 0;
05897 pvt->iseqno = 0;
05898 pvt->aseqno = 0;
05899
05900 if (pvt->peercallno) {
05901 remove_by_peercallno(pvt);
05902 }
05903 pvt->peercallno = peercallno;
05904 store_by_peercallno(pvt);
05905
05906 pvt->transferring = TRANSFER_NONE;
05907 pvt->svoiceformat = -1;
05908 pvt->voiceformat = 0;
05909 pvt->svideoformat = -1;
05910 pvt->videoformat = 0;
05911 pvt->transfercallno = -1;
05912 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05913 memset(&pvt->offset, 0, sizeof(pvt->offset));
05914
05915 while(jb_getall(pvt->jb,&frame) == JB_OK)
05916 iax2_frame_free(frame.data);
05917 jb_reset(pvt->jb);
05918 pvt->lag = 0;
05919 pvt->last = 0;
05920 pvt->lastsent = 0;
05921 pvt->nextpred = 0;
05922 pvt->pingtime = DEFAULT_RETRY_TIME;
05923 AST_LIST_LOCK(&iaxq.queue);
05924 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05925
05926
05927
05928 if (callno == cur->callno)
05929 cur->retries = -1;
05930 }
05931 AST_LIST_UNLOCK(&iaxq.queue);
05932 return 0;
05933 }
05934
05935
05936 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05937 {
05938 struct iax2_registry *reg;
05939
05940 char peer[256] = "";
05941 char msgstatus[60];
05942 int refresh = 60;
05943 char ourip[256] = "<Unspecified>";
05944 struct sockaddr_in oldus;
05945 struct sockaddr_in us;
05946 int oldmsgs;
05947
05948 memset(&us, 0, sizeof(us));
05949 if (ies->apparent_addr)
05950 bcopy(ies->apparent_addr, &us, sizeof(us));
05951 if (ies->username)
05952 ast_copy_string(peer, ies->username, sizeof(peer));
05953 if (ies->refresh)
05954 refresh = ies->refresh;
05955 if (ies->calling_number) {
05956
05957 }
05958 reg = iaxs[callno]->reg;
05959 if (!reg) {
05960 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05961 return -1;
05962 }
05963 memcpy(&oldus, ®->us, sizeof(oldus));
05964 oldmsgs = reg->messages;
05965 if (inaddrcmp(®->addr, sin)) {
05966 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05967 return -1;
05968 }
05969 memcpy(®->us, &us, sizeof(reg->us));
05970 if (ies->msgcount >= 0)
05971 reg->messages = ies->msgcount & 0xffff;
05972
05973
05974
05975 reg->refresh = refresh;
05976 AST_SCHED_DEL(sched, reg->expire);
05977 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05978 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
05979 if (option_verbose > 2) {
05980 if (reg->messages > 255)
05981 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05982 else if (reg->messages > 1)
05983 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05984 else if (reg->messages > 0)
05985 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05986 else
05987 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05988 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05989 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05990 }
05991 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05992 }
05993 reg->regstate = REG_STATE_REGISTERED;
05994 return 0;
05995 }
05996
05997 static int iax2_register(char *value, int lineno)
05998 {
05999 struct iax2_registry *reg;
06000 char copy[256];
06001 char *username, *hostname, *secret;
06002 char *porta;
06003 char *stringp=NULL;
06004
06005 if (!value)
06006 return -1;
06007 ast_copy_string(copy, value, sizeof(copy));
06008 stringp=copy;
06009 username = strsep(&stringp, "@");
06010 hostname = strsep(&stringp, "@");
06011 if (!hostname) {
06012 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06013 return -1;
06014 }
06015 stringp=username;
06016 username = strsep(&stringp, ":");
06017 secret = strsep(&stringp, ":");
06018 stringp=hostname;
06019 hostname = strsep(&stringp, ":");
06020 porta = strsep(&stringp, ":");
06021
06022 if (porta && !atoi(porta)) {
06023 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
06024 return -1;
06025 }
06026 if (!(reg = ast_calloc(1, sizeof(*reg))))
06027 return -1;
06028 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) {
06029 free(reg);
06030 return -1;
06031 }
06032 ast_copy_string(reg->username, username, sizeof(reg->username));
06033 if (secret)
06034 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06035 reg->expire = -1;
06036 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06037 reg->addr.sin_family = AF_INET;
06038 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06039 AST_LIST_LOCK(®istrations);
06040 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
06041 AST_LIST_UNLOCK(®istrations);
06042
06043 return 0;
06044 }
06045
06046 static void register_peer_exten(struct iax2_peer *peer, int onoff)
06047 {
06048 char multi[256];
06049 char *stringp, *ext;
06050 if (!ast_strlen_zero(regcontext)) {
06051 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
06052 stringp = multi;
06053 while((ext = strsep(&stringp, "&"))) {
06054 if (onoff) {
06055 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
06056 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
06057 "Noop", ast_strdup(peer->name), ast_free, "IAX2");
06058 } else
06059 ast_context_remove_extension(regcontext, ext, 1, NULL);
06060 }
06061 }
06062 }
06063 static void prune_peers(void);
06064
06065 static void unlink_peer(struct iax2_peer *peer)
06066 {
06067 if (peer->expire > -1) {
06068 if (!ast_sched_del(sched, peer->expire)) {
06069 peer->expire = -1;
06070 peer_unref(peer);
06071 }
06072 }
06073
06074 if (peer->pokeexpire > -1) {
06075 if (!ast_sched_del(sched, peer->pokeexpire)) {
06076 peer->pokeexpire = -1;
06077 peer_unref(peer);
06078 }
06079 }
06080
06081 ao2_unlink(peers, peer);
06082 }
06083
06084 static void __expire_registry(const void *data)
06085 {
06086 struct iax2_peer *peer = (struct iax2_peer *) data;
06087
06088 if (!peer)
06089 return;
06090
06091 peer->expire = -1;
06092
06093 if (option_debug)
06094 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", peer->name);
06095 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
06096 realtime_update_peer(peer->name, &peer->addr, 0);
06097 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
06098
06099 memset(&peer->addr, 0, sizeof(peer->addr));
06100
06101 peer->expiry = min_reg_expire;
06102 if (!ast_test_flag(peer, IAX_TEMPONLY))
06103 ast_db_del("IAX/Registry", peer->name);
06104 register_peer_exten(peer, 0);
06105 ast_device_state_changed("IAX2/%s", peer->name);
06106 if (iax2_regfunk)
06107 iax2_regfunk(peer->name, 0);
06108
06109 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
06110 unlink_peer(peer);
06111
06112 peer_unref(peer);
06113 }
06114
06115 static int expire_registry(const void *data)
06116 {
06117 #ifdef SCHED_MULTITHREADED
06118 if (schedule_action(__expire_registry, data))
06119 #endif
06120 __expire_registry(data);
06121 return 0;
06122 }
06123
06124 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
06125
06126 static void reg_source_db(struct iax2_peer *p)
06127 {
06128 char data[80];
06129 struct in_addr in;
06130 char *c, *d;
06131 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
06132 c = strchr(data, ':');
06133 if (c) {
06134 *c = '\0';
06135 c++;
06136 if (inet_aton(data, &in)) {
06137 d = strchr(c, ':');
06138 if (d) {
06139 *d = '\0';
06140 d++;
06141 if (option_verbose > 2)
06142 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name,
06143 ast_inet_ntoa(in), atoi(c), atoi(d));
06144 iax2_poke_peer(p, 0);
06145 p->expiry = atoi(d);
06146 memset(&p->addr, 0, sizeof(p->addr));
06147 p->addr.sin_family = AF_INET;
06148 p->addr.sin_addr = in;
06149 p->addr.sin_port = htons(atoi(c));
06150 if (p->expire > -1) {
06151 if (!ast_sched_del(sched, p->expire)) {
06152 p->expire = -1;
06153 peer_unref(p);
06154 }
06155 }
06156 ast_device_state_changed("IAX2/%s", p->name);
06157 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06158 if (p->expire == -1)
06159 peer_unref(p);
06160 if (iax2_regfunk)
06161 iax2_regfunk(p->name, 1);
06162 register_peer_exten(p, 1);
06163 }
06164
06165 }
06166 }
06167 }
06168 }
06169
06170
06171
06172
06173
06174
06175
06176 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
06177 {
06178
06179 struct iax_ie_data ied;
06180 struct iax2_peer *p;
06181 int msgcount;
06182 char data[80];
06183 int version;
06184 const char *peer_name;
06185 int res = -1;
06186
06187 memset(&ied, 0, sizeof(ied));
06188
06189 peer_name = ast_strdupa(iaxs[callno]->peer);
06190
06191
06192 ast_mutex_unlock(&iaxsl[callno]);
06193 if (!(p = find_peer(peer_name, 1))) {
06194 ast_mutex_lock(&iaxsl[callno]);
06195 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
06196 return -1;
06197 }
06198 ast_mutex_lock(&iaxsl[callno]);
06199 if (!iaxs[callno])
06200 goto return_unref;
06201
06202 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
06203 if (sin->sin_addr.s_addr) {
06204 time_t nowtime;
06205 time(&nowtime);
06206 realtime_update_peer(peer_name, sin, nowtime);
06207 } else {
06208 realtime_update_peer(peer_name, sin, 0);
06209 }
06210 }
06211 if (inaddrcmp(&p->addr, sin)) {
06212 if (iax2_regfunk)
06213 iax2_regfunk(p->name, 1);
06214
06215 memcpy(&p->addr, sin, sizeof(p->addr));
06216 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
06217 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
06218 ast_db_put("IAX/Registry", p->name, data);
06219 if (option_verbose > 2)
06220 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
06221 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
06222 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
06223 register_peer_exten(p, 1);
06224 ast_device_state_changed("IAX2/%s", p->name);
06225 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
06226 if (option_verbose > 2)
06227 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name,
06228 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
06229 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
06230 register_peer_exten(p, 0);
06231 ast_db_del("IAX/Registry", p->name);
06232 ast_device_state_changed("IAX2/%s", p->name);
06233 }
06234
06235
06236 iax2_poke_peer(p, callno);
06237 }
06238
06239
06240 if (!iaxs[callno]) {
06241 res = 0;
06242 goto return_unref;
06243 }
06244
06245
06246 p->sockfd = fd;
06247
06248 if (p->expire > -1) {
06249 if (!ast_sched_del(sched, p->expire)) {
06250 p->expire = -1;
06251 peer_unref(p);
06252 }
06253 }
06254
06255 if (!refresh)
06256 refresh = min_reg_expire;
06257 if (refresh > max_reg_expire) {
06258 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06259 p->name, max_reg_expire, refresh);
06260 p->expiry = max_reg_expire;
06261 } else if (refresh < min_reg_expire) {
06262 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
06263 p->name, min_reg_expire, refresh);
06264 p->expiry = min_reg_expire;
06265 } else {
06266 p->expiry = refresh;
06267 }
06268 if (p->expiry && sin->sin_addr.s_addr) {
06269 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
06270 if (p->expire == -1)
06271 peer_unref(p);
06272 }
06273 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
06274 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
06275 if (sin->sin_addr.s_addr) {
06276 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
06277 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
06278 if (!ast_strlen_zero(p->mailbox)) {
06279 int new, old;
06280 ast_app_inboxcount(p->mailbox, &new, &old);
06281 if (new > 255)
06282 new = 255;
06283 if (old > 255)
06284 old = 255;
06285 msgcount = (old << 8) | new;
06286 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
06287 }
06288 if (ast_test_flag(p, IAX_HASCALLERID)) {
06289 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
06290 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
06291 }
06292 }
06293 version = iax_check_version(devtype);
06294 if (version)
06295 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
06296
06297 res = 0;
06298
06299 return_unref:
06300 peer_unref(p);
06301
06302 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
06303 }
06304
06305 static int registry_authrequest(int callno)
06306 {
06307 struct iax_ie_data ied;
06308 struct iax2_peer *p;
06309 char challenge[10];
06310 const char *peer_name;
06311 int sentauthmethod;
06312
06313 peer_name = ast_strdupa(iaxs[callno]->peer);
06314
06315
06316 ast_mutex_unlock(&iaxsl[callno]);
06317 if ((p = find_peer(peer_name, 1))) {
06318 last_authmethod = p->authmethods;
06319 }
06320
06321 ast_mutex_lock(&iaxsl[callno]);
06322 if (!iaxs[callno])
06323 goto return_unref;
06324
06325 memset(&ied, 0, sizeof(ied));
06326
06327
06328
06329
06330
06331
06332 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06333 if (!p) {
06334 iaxs[callno]->authmethods = sentauthmethod;
06335 }
06336 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
06337 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
06338
06339 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06340 ast_string_field_set(iaxs[callno], challenge, challenge);
06341 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
06342 }
06343 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
06344
06345 return_unref:
06346 if (p) {
06347 peer_unref(p);
06348 }
06349
06350 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
06351 }
06352
06353 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
06354 {
06355 struct iax2_registry *reg;
06356
06357 struct iax_ie_data ied;
06358 char peer[256] = "";
06359 char challenge[256] = "";
06360 int res;
06361 int authmethods = 0;
06362 if (ies->authmethods)
06363 authmethods = ies->authmethods;
06364 if (ies->username)
06365 ast_copy_string(peer, ies->username, sizeof(peer));
06366 if (ies->challenge)
06367 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
06368 memset(&ied, 0, sizeof(ied));
06369 reg = iaxs[callno]->reg;
06370 if (reg) {
06371 if (inaddrcmp(®->addr, sin)) {
06372 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06373 return -1;
06374 }
06375 if (ast_strlen_zero(reg->secret)) {
06376 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
06377 reg->regstate = REG_STATE_NOAUTH;
06378 return -1;
06379 }
06380 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
06381 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
06382 if (reg->secret[0] == '[') {
06383 char tmpkey[256];
06384 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
06385 tmpkey[strlen(tmpkey) - 1] = '\0';
06386 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
06387 } else
06388 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
06389 if (!res) {
06390 reg->regstate = REG_STATE_AUTHSENT;
06391 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
06392 } else
06393 return -1;
06394 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
06395 } else
06396 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
06397 return -1;
06398 }
06399
06400 static void stop_stuff(int callno)
06401 {
06402 iax2_destroy_helper(iaxs[callno]);
06403 }
06404
06405 static void __auth_reject(const void *nothing)
06406 {
06407
06408 int callno = (int)(long)(nothing);
06409 struct iax_ie_data ied;
06410 ast_mutex_lock(&iaxsl[callno]);
06411 if (iaxs[callno]) {
06412 memset(&ied, 0, sizeof(ied));
06413 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
06414 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
06415 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
06416 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
06417 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
06418 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
06419 }
06420 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
06421 }
06422 ast_mutex_unlock(&iaxsl[callno]);
06423 }
06424
06425 static int auth_reject(const void *data)
06426 {
06427 int callno = (int)(long)(data);
06428 ast_mutex_lock(&iaxsl[callno]);
06429 if (iaxs[callno])
06430 iaxs[callno]->authid = -1;
06431 ast_mutex_unlock(&iaxsl[callno]);
06432 #ifdef SCHED_MULTITHREADED
06433 if (schedule_action(__auth_reject, data))
06434 #endif
06435 __auth_reject(data);
06436 return 0;
06437 }
06438
06439 static int auth_fail(int callno, int failcode)
06440 {
06441
06442
06443 if (iaxs[callno]) {
06444 iaxs[callno]->authfail = failcode;
06445 if (delayreject) {
06446 AST_SCHED_DEL(sched, iaxs[callno]->authid);
06447 iaxs[callno]->authid = iax2_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
06448 } else
06449 auth_reject((void *)(long)callno);
06450 }
06451 return 0;
06452 }
06453
06454 static void __auto_hangup(const void *nothing)
06455 {
06456
06457 int callno = (int)(long)(nothing);
06458 struct iax_ie_data ied;
06459 ast_mutex_lock(&iaxsl[callno]);
06460 if (iaxs[callno]) {
06461 memset(&ied, 0, sizeof(ied));
06462 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
06463 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
06464 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
06465 }
06466 ast_mutex_unlock(&iaxsl[callno]);
06467 }
06468
06469 static int auto_hangup(const void *data)
06470 {
06471 int callno = (int)(long)(data);
06472 ast_mutex_lock(&iaxsl[callno]);
06473 if (iaxs[callno]) {
06474 iaxs[callno]->autoid = -1;
06475 }
06476 ast_mutex_unlock(&iaxsl[callno]);
06477 #ifdef SCHED_MULTITHREADED
06478 if (schedule_action(__auto_hangup, data))
06479 #endif
06480 __auto_hangup(data);
06481 return 0;
06482 }
06483
06484 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
06485 {
06486 struct iax_ie_data ied;
06487
06488 AST_SCHED_DEL(sched, iaxs[callno]->autoid);
06489 iaxs[callno]->autoid = iax2_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
06490 memset(&ied, 0, sizeof(ied));
06491 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
06492 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
06493 dp->flags |= CACHE_FLAG_TRANSMITTED;
06494 }
06495
06496 static int iax2_vnak(int callno)
06497 {
06498 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
06499 }
06500
06501 static void vnak_retransmit(int callno, int last)
06502 {
06503 struct iax_frame *f;
06504
06505 AST_LIST_LOCK(&iaxq.queue);
06506 AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
06507
06508 if ((f->callno == callno) && iaxs[f->callno] &&
06509 ((unsigned char ) (f->oseqno - last) < 128) &&
06510 (f->retries >= 0)) {
06511 send_packet(f);
06512 }
06513 }
06514 AST_LIST_UNLOCK(&iaxq.queue);
06515 }
06516
06517 static void __iax2_poke_peer_s(const void *data)
06518 {
06519 struct iax2_peer *peer = (struct iax2_peer *)data;
06520 iax2_poke_peer(peer, 0);
06521 peer_unref(peer);
06522 }
06523
06524 static int iax2_poke_peer_s(const void *data)
06525 {
06526 struct iax2_peer *peer = (struct iax2_peer *)data;
06527 peer->pokeexpire = -1;
06528 #ifdef SCHED_MULTITHREADED
06529 if (schedule_action(__iax2_poke_peer_s, data))
06530 #endif
06531 __iax2_poke_peer_s(data);
06532 return 0;
06533 }
06534
06535 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
06536 {
06537 int res = 0;
06538 struct iax_frame *fr;
06539 struct ast_iax2_meta_hdr *meta;
06540 struct ast_iax2_meta_trunk_hdr *mth;
06541 int calls = 0;
06542
06543
06544 fr = (struct iax_frame *)tpeer->trunkdata;
06545
06546 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
06547 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
06548 if (tpeer->trunkdatalen) {
06549
06550 meta->zeros = 0;
06551 meta->metacmd = IAX_META_TRUNK;
06552 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
06553 meta->cmddata = IAX_META_TRUNK_MINI;
06554 else
06555 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
06556 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
06557
06558 fr->direction = DIRECTION_OUTGRESS;
06559 fr->retrans = -1;
06560 fr->transfer = 0;
06561
06562 fr->data = fr->afdata;
06563 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
06564 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
06565 calls = tpeer->calls;
06566 #if 0
06567 if (option_debug)
06568 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));
06569 #endif
06570
06571 tpeer->trunkdatalen = 0;
06572 tpeer->calls = 0;
06573 }
06574 if (res < 0)
06575 return res;
06576 return calls;
06577 }
06578
06579 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
06580 {
06581
06582 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
06583 return 1;
06584 return 0;
06585 }
06586
06587 static int timing_read(int *id, int fd, short events, void *cbdata)
06588 {
06589 char buf[1024];
06590 int res;
06591 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
06592 int processed = 0;
06593 int totalcalls = 0;
06594 #ifdef ZT_TIMERACK
06595 int x = 1;
06596 #endif
06597 struct timeval now;
06598 if (iaxtrunkdebug)
06599 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
06600 gettimeofday(&now, NULL);
06601 if (events & AST_IO_PRI) {
06602 #ifdef ZT_TIMERACK
06603
06604 if (ioctl(fd, ZT_TIMERACK, &x)) {
06605 ast_log(LOG_WARNING, "Unable to acknowledge zap timer. IAX trunking will fail!\n");
06606 usleep(1);
06607 return -1;
06608 }
06609 #endif
06610 } else {
06611
06612 res = read(fd, buf, sizeof(buf));
06613 if (res < 1) {
06614 ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06615 return 1;
06616 }
06617 }
06618
06619 ast_mutex_lock(&tpeerlock);
06620 tpeer = tpeers;
06621 while(tpeer) {
06622 processed++;
06623 res = 0;
06624 ast_mutex_lock(&tpeer->lock);
06625
06626
06627 if (!drop && iax2_trunk_expired(tpeer, &now)) {
06628
06629
06630 if (prev)
06631 prev->next = tpeer->next;
06632 else
06633 tpeers = tpeer->next;
06634 drop = tpeer;
06635 } else {
06636 res = send_trunk(tpeer, &now);
06637 if (iaxtrunkdebug)
06638 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);
06639 }
06640 totalcalls += res;
06641 res = 0;
06642 ast_mutex_unlock(&tpeer->lock);
06643 prev = tpeer;
06644 tpeer = tpeer->next;
06645 }
06646 ast_mutex_unlock(&tpeerlock);
06647 if (drop) {
06648 ast_mutex_lock(&drop->lock);
06649
06650
06651 if (option_debug)
06652 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06653 if (drop->trunkdata) {
06654 free(drop->trunkdata);
06655 drop->trunkdata = NULL;
06656 }
06657 ast_mutex_unlock(&drop->lock);
06658 ast_mutex_destroy(&drop->lock);
06659 free(drop);
06660
06661 }
06662 if (iaxtrunkdebug)
06663 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06664 iaxtrunkdebug =0;
06665 return 1;
06666 }
06667
06668 struct dpreq_data {
06669 int callno;
06670 char context[AST_MAX_EXTENSION];
06671 char callednum[AST_MAX_EXTENSION];
06672 char *callerid;
06673 };
06674
06675 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06676 {
06677 unsigned short dpstatus = 0;
06678 struct iax_ie_data ied1;
06679 int mm;
06680
06681 memset(&ied1, 0, sizeof(ied1));
06682 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06683
06684 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06685 dpstatus = IAX_DPSTATUS_EXISTS;
06686 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06687 dpstatus = IAX_DPSTATUS_CANEXIST;
06688 } else {
06689 dpstatus = IAX_DPSTATUS_NONEXISTENT;
06690 }
06691 if (ast_ignore_pattern(context, callednum))
06692 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06693 if (mm)
06694 dpstatus |= IAX_DPSTATUS_MATCHMORE;
06695 if (!skiplock)
06696 ast_mutex_lock(&iaxsl[callno]);
06697 if (iaxs[callno]) {
06698 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06699 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06700 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06701 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06702 }
06703 if (!skiplock)
06704 ast_mutex_unlock(&iaxsl[callno]);
06705 }
06706
06707 static void *dp_lookup_thread(void *data)
06708 {
06709
06710 struct dpreq_data *dpr = data;
06711 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06712 if (dpr->callerid)
06713 free(dpr->callerid);
06714 free(dpr);
06715 return NULL;
06716 }
06717
06718 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06719 {
06720 pthread_t newthread;
06721 struct dpreq_data *dpr;
06722 pthread_attr_t attr;
06723
06724 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06725 return;
06726
06727 pthread_attr_init(&attr);
06728 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06729
06730 dpr->callno = callno;
06731 ast_copy_string(dpr->context, context, sizeof(dpr->context));
06732 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06733 if (callerid)
06734 dpr->callerid = ast_strdup(callerid);
06735 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06736 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06737 }
06738
06739 pthread_attr_destroy(&attr);
06740 }
06741
06742 struct iax_dual {
06743 struct ast_channel *chan1;
06744 struct ast_channel *chan2;
06745 };
06746
06747 static void *iax_park_thread(void *stuff)
06748 {
06749 struct ast_channel *chan1, *chan2;
06750 struct iax_dual *d;
06751 struct ast_frame *f;
06752 int ext;
06753 int res;
06754 d = stuff;
06755 chan1 = d->chan1;
06756 chan2 = d->chan2;
06757 free(d);
06758 f = ast_read(chan1);
06759 if (f)
06760 ast_frfree(f);
06761 res = ast_park_call(chan1, chan2, 0, &ext);
06762 ast_hangup(chan2);
06763 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06764 return NULL;
06765 }
06766
06767 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06768 {
06769 struct iax_dual *d;
06770 struct ast_channel *chan1m, *chan2m;
06771 pthread_t th;
06772 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06773 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06774 if (chan2m && chan1m) {
06775
06776 chan1m->readformat = chan1->readformat;
06777 chan1m->writeformat = chan1->writeformat;
06778 ast_channel_masquerade(chan1m, chan1);
06779
06780 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06781 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06782 chan1m->priority = chan1->priority;
06783
06784
06785
06786
06787 chan2m->readformat = chan2->readformat;
06788 chan2m->writeformat = chan2->writeformat;
06789 ast_channel_masquerade(chan2m, chan2);
06790
06791 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06792 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06793 chan2m->priority = chan2->priority;
06794 if (ast_do_masquerade(chan2m)) {
06795 ast_log(LOG_WARNING, "Masquerade failed :(\n");
06796 ast_hangup(chan2m);
06797 return -1;
06798 }
06799 } else {
06800 if (chan1m)
06801 ast_hangup(chan1m);
06802 if (chan2m)
06803 ast_hangup(chan2m);
06804 return -1;
06805 }
06806 if ((d = ast_calloc(1, sizeof(*d)))) {
06807 pthread_attr_t attr;
06808
06809 pthread_attr_init(&attr);
06810 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06811
06812 d->chan1 = chan1m;
06813 d->chan2 = chan2m;
06814 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06815 pthread_attr_destroy(&attr);
06816 return 0;
06817 }
06818 pthread_attr_destroy(&attr);
06819 free(d);
06820 }
06821 return -1;
06822 }
06823
06824
06825 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06826
06827 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06828 {
06829 unsigned int ourver;
06830 char rsi[80];
06831 snprintf(rsi, sizeof(rsi), "si-%s", si);
06832 if (iax_provision_version(&ourver, rsi, 1))
06833 return 0;
06834 if (option_debug)
06835 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06836 if (ourver != ver)
06837 iax2_provision(sin, sockfd, NULL, rsi, 1);
06838 return 0;
06839 }
06840
06841 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
06842 {
06843 jb_info stats;
06844 jb_getinfo(pvt->jb, &stats);
06845
06846 memset(iep, 0, sizeof(*iep));
06847
06848 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06849 if(stats.frames_in == 0) stats.frames_in = 1;
06850 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06851 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06852 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06853 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06854 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06855 }
06856
06857 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
06858 {
06859 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06860 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06861 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06862 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06863 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06864 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06865 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06866 }
06867
06868 static int socket_process(struct iax2_thread *thread);
06869
06870
06871
06872
06873 static void handle_deferred_full_frames(struct iax2_thread *thread)
06874 {
06875 struct iax2_pkt_buf *pkt_buf;
06876
06877 ast_mutex_lock(&thread->lock);
06878
06879 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
06880 ast_mutex_unlock(&thread->lock);
06881
06882 thread->buf = pkt_buf->buf;
06883 thread->buf_len = pkt_buf->len;
06884 thread->buf_size = pkt_buf->len + 1;
06885
06886 socket_process(thread);
06887
06888 thread->buf = NULL;
06889 ast_free(pkt_buf);
06890
06891 ast_mutex_lock(&thread->lock);
06892 }
06893
06894 ast_mutex_unlock(&thread->lock);
06895 }
06896
06897
06898
06899
06900
06901
06902
06903 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
06904 {
06905 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
06906 struct ast_iax2_full_hdr *fh, *cur_fh;
06907
06908 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
06909 return;
06910
06911 pkt_buf->len = from_here->buf_len;
06912 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
06913
06914 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
06915 ast_mutex_lock(&to_here->lock);
06916 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
06917 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
06918 if (fh->oseqno < cur_fh->oseqno) {
06919 AST_LIST_INSERT_BEFORE_CURRENT(&to_here->full_frames, pkt_buf, entry);
06920 break;
06921 }
06922 }
06923 AST_LIST_TRAVERSE_SAFE_END
06924
06925 if (!cur_pkt_buf)
06926 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
06927
06928 ast_mutex_unlock(&to_here->lock);
06929 }
06930
06931 static int socket_read(int *id, int fd, short events, void *cbdata)
06932 {
06933 struct iax2_thread *thread;
06934 socklen_t len;
06935 time_t t;
06936 static time_t last_errtime = 0;
06937 struct ast_iax2_full_hdr *fh;
06938
06939 if (!(thread = find_idle_thread())) {
06940 time(&t);
06941 if (t != last_errtime && option_debug)
06942 ast_log(LOG_DEBUG, "Out of idle IAX2 threads for I/O, pausing!\n");
06943 last_errtime = t;
06944 usleep(1);
06945 return 1;
06946 }
06947
06948 len = sizeof(thread->iosin);
06949 thread->iofd = fd;
06950 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
06951 thread->buf_size = sizeof(thread->readbuf);
06952 thread->buf = thread->readbuf;
06953 if (thread->buf_len < 0) {
06954 if (errno != ECONNREFUSED && errno != EAGAIN)
06955 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06956 handle_error();
06957 thread->iostate = IAX_IOSTATE_IDLE;
06958 signal_condition(&thread->lock, &thread->cond);
06959 return 1;
06960 }
06961 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
06962 thread->iostate = IAX_IOSTATE_IDLE;
06963 signal_condition(&thread->lock, &thread->cond);
06964 return 1;
06965 }
06966
06967
06968
06969
06970 fh = (struct ast_iax2_full_hdr *) thread->buf;
06971 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06972 struct iax2_thread *cur = NULL;
06973 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
06974
06975 AST_LIST_LOCK(&active_list);
06976 AST_LIST_TRAVERSE(&active_list, cur, list) {
06977 if ((cur->ffinfo.callno == callno) &&
06978 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
06979 break;
06980 }
06981 if (cur) {
06982
06983
06984 defer_full_frame(thread, cur);
06985 AST_LIST_UNLOCK(&active_list);
06986 thread->iostate = IAX_IOSTATE_IDLE;
06987 signal_condition(&thread->lock, &thread->cond);
06988 return 1;
06989 } else {
06990
06991 thread->ffinfo.callno = callno;
06992 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
06993 thread->ffinfo.type = fh->type;
06994 thread->ffinfo.csub = fh->csub;
06995 }
06996 AST_LIST_UNLOCK(&active_list);
06997 }
06998
06999
07000 thread->iostate = IAX_IOSTATE_READY;
07001 #ifdef DEBUG_SCHED_MULTITHREAD
07002 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
07003 #endif
07004 signal_condition(&thread->lock, &thread->cond);
07005
07006 return 1;
07007 }
07008
07009 static int socket_process(struct iax2_thread *thread)
07010 {
07011 struct sockaddr_in sin;
07012 int res;
07013 int updatehistory=1;
07014 int new = NEW_PREVENT;
07015 void *ptr;
07016 int dcallno = 0;
07017 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
07018 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
07019 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
07020 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
07021 struct ast_iax2_meta_trunk_hdr *mth;
07022 struct ast_iax2_meta_trunk_entry *mte;
07023 struct ast_iax2_meta_trunk_mini *mtm;
07024 struct iax_frame *fr;
07025 struct iax_frame *cur;
07026 struct ast_frame f = { 0, };
07027 struct ast_channel *c;
07028 struct iax2_dpcache *dp;
07029 struct iax2_peer *peer;
07030 struct iax2_trunk_peer *tpeer;
07031 struct timeval rxtrunktime;
07032 struct iax_ies ies;
07033 struct iax_ie_data ied0, ied1;
07034 int format;
07035 int fd;
07036 int exists;
07037 int minivid = 0;
07038 unsigned int ts;
07039 char empty[32]="";
07040 struct iax_frame *duped_fr;
07041 char host_pref_buf[128];
07042 char caller_pref_buf[128];
07043 struct ast_codec_pref pref;
07044 char *using_prefs = "mine";
07045
07046
07047 fr = alloca(sizeof(*fr) + 4096);
07048 memset(fr, 0, sizeof(*fr));
07049 fr->afdatalen = 4096;
07050
07051
07052 res = thread->buf_len;
07053 fd = thread->iofd;
07054 memcpy(&sin, &thread->iosin, sizeof(sin));
07055
07056 if (res < sizeof(*mh)) {
07057 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
07058 return 1;
07059 }
07060 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
07061 if (res < sizeof(*vh)) {
07062 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));
07063 return 1;
07064 }
07065
07066
07067 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
07068 minivid = 1;
07069 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
07070 unsigned char metatype;
07071
07072 if (res < sizeof(*meta)) {
07073 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));
07074 return 1;
07075 }
07076
07077
07078 switch(meta->metacmd) {
07079 case IAX_META_TRUNK:
07080 if (res < (sizeof(*meta) + sizeof(*mth))) {
07081 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
07082 sizeof(*meta) + sizeof(*mth));
07083 return 1;
07084 }
07085 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
07086 ts = ntohl(mth->ts);
07087 metatype = meta->cmddata;
07088 res -= (sizeof(*meta) + sizeof(*mth));
07089 ptr = mth->data;
07090 tpeer = find_tpeer(&sin, fd);
07091 if (!tpeer) {
07092 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));
07093 return 1;
07094 }
07095 tpeer->trunkact = ast_tvnow();
07096 if (!ts || ast_tvzero(tpeer->rxtrunktime))
07097 tpeer->rxtrunktime = tpeer->trunkact;
07098 rxtrunktime = tpeer->rxtrunktime;
07099 ast_mutex_unlock(&tpeer->lock);
07100 while(res >= sizeof(*mte)) {
07101
07102 unsigned short callno, trunked_ts, len;
07103
07104 if (metatype == IAX_META_TRUNK_MINI) {
07105 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
07106 ptr += sizeof(*mtm);
07107 res -= sizeof(*mtm);
07108 len = ntohs(mtm->len);
07109 callno = ntohs(mtm->mini.callno);
07110 trunked_ts = ntohs(mtm->mini.ts);
07111 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
07112 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
07113 ptr += sizeof(*mte);
07114 res -= sizeof(*mte);
07115 len = ntohs(mte->len);
07116 callno = ntohs(mte->callno);
07117 trunked_ts = 0;
07118 } else {
07119 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07120 break;
07121 }
07122
07123 if (len > res)
07124 break;
07125 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, fd, 0);
07126 if (fr->callno) {
07127
07128
07129
07130 memset(&f, 0, sizeof(f));
07131 f.frametype = AST_FRAME_VOICE;
07132 if (iaxs[fr->callno]) {
07133 if (iaxs[fr->callno]->voiceformat > 0) {
07134 f.subclass = iaxs[fr->callno]->voiceformat;
07135 f.datalen = len;
07136 if (f.datalen >= 0) {
07137 if (f.datalen)
07138 f.data = ptr;
07139 if(trunked_ts) {
07140 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
07141 } else
07142 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
07143
07144 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07145
07146 f.src = "IAX2";
07147 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
07148 f.samples = ast_codec_get_samples(&f);
07149 iax_frame_wrap(fr, &f);
07150 duped_fr = iaxfrdup2(fr);
07151 if (duped_fr) {
07152 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
07153 }
07154
07155 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07156 iaxs[fr->callno]->last = fr->ts;
07157 #if 1
07158 if (option_debug && iaxdebug)
07159 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07160 #endif
07161 }
07162 }
07163 } else {
07164 ast_log(LOG_WARNING, "Datalen < 0?\n");
07165 }
07166 } else {
07167 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
07168 iax2_vnak(fr->callno);
07169 }
07170 }
07171 ast_mutex_unlock(&iaxsl[fr->callno]);
07172 }
07173 ptr += len;
07174 res -= len;
07175 }
07176
07177 }
07178 return 1;
07179 }
07180
07181 #ifdef DEBUG_SUPPORT
07182 if (iaxdebug && (res >= sizeof(*fh)))
07183 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
07184 #endif
07185 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07186 if (res < sizeof(*fh)) {
07187 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));
07188 return 1;
07189 }
07190
07191
07192 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
07193
07194 f.frametype = fh->type;
07195 if (f.frametype == AST_FRAME_VIDEO) {
07196 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
07197 } else {
07198 f.subclass = uncompress_subclass(fh->csub);
07199 }
07200
07201
07202 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
07203
07204 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->oseqno);
07205 return 1;
07206 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
07207
07208 return 1;
07209 }
07210
07211 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
07212 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
07213 (f.subclass == IAX_COMMAND_REGREL)))
07214 new = NEW_ALLOW;
07215 } else {
07216
07217 f.frametype = AST_FRAME_NULL;
07218 f.subclass = 0;
07219 }
07220
07221 if (!fr->callno) {
07222 int check_dcallno = 0;
07223
07224
07225
07226
07227
07228
07229
07230
07231
07232
07233
07234
07235
07236 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07237 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
07238 }
07239
07240 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
07241 }
07242
07243 if (fr->callno > 0)
07244 ast_mutex_lock(&iaxsl[fr->callno]);
07245
07246 if (!fr->callno || !iaxs[fr->callno]) {
07247
07248
07249 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07250
07251 if (((f.subclass != IAX_COMMAND_INVAL) &&
07252 (f.subclass != IAX_COMMAND_TXCNT) &&
07253 (f.subclass != IAX_COMMAND_TXACC) &&
07254 (f.subclass != IAX_COMMAND_FWDOWNL))||
07255 (f.frametype != AST_FRAME_IAX))
07256 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
07257 fd);
07258 }
07259 if (fr->callno > 0)
07260 ast_mutex_unlock(&iaxsl[fr->callno]);
07261 return 1;
07262 }
07263 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
07264 if (decrypt_frame(fr->callno, fh, &f, &res)) {
07265 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
07266 ast_mutex_unlock(&iaxsl[fr->callno]);
07267 return 1;
07268 }
07269 #ifdef DEBUG_SUPPORT
07270 else if (iaxdebug)
07271 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
07272 #endif
07273 }
07274
07275
07276 iaxs[fr->callno]->frames_received++;
07277
07278 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
07279 f.subclass != IAX_COMMAND_TXCNT &&
07280 f.subclass != IAX_COMMAND_TXACC) {
07281 unsigned short new_peercallno;
07282
07283 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
07284 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
07285 if (iaxs[fr->callno]->peercallno) {
07286 remove_by_peercallno(iaxs[fr->callno]);
07287 }
07288 iaxs[fr->callno]->peercallno = new_peercallno;
07289 store_by_peercallno(iaxs[fr->callno]);
07290 }
07291 }
07292 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
07293 if (option_debug && iaxdebug)
07294 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
07295
07296 fr->oseqno = fh->oseqno;
07297 fr->iseqno = fh->iseqno;
07298 fr->ts = ntohl(fh->ts);
07299 #ifdef IAXTESTS
07300 if (test_resync) {
07301 if (option_debug)
07302 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
07303 fr->ts += test_resync;
07304 }
07305 #endif
07306 #if 0
07307 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
07308 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
07309 (f.subclass == IAX_COMMAND_NEW ||
07310 f.subclass == IAX_COMMAND_AUTHREQ ||
07311 f.subclass == IAX_COMMAND_ACCEPT ||
07312 f.subclass == IAX_COMMAND_REJECT)) ) )
07313 #endif
07314 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
07315 updatehistory = 0;
07316 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
07317 (iaxs[fr->callno]->iseqno ||
07318 ((f.subclass != IAX_COMMAND_TXCNT) &&
07319 (f.subclass != IAX_COMMAND_TXREADY) &&
07320 (f.subclass != IAX_COMMAND_TXREL) &&
07321 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
07322 (f.subclass != IAX_COMMAND_TXACC)) ||
07323 (f.frametype != AST_FRAME_IAX))) {
07324 if (
07325 ((f.subclass != IAX_COMMAND_ACK) &&
07326 (f.subclass != IAX_COMMAND_INVAL) &&
07327 (f.subclass != IAX_COMMAND_TXCNT) &&
07328 (f.subclass != IAX_COMMAND_TXREADY) &&
07329 (f.subclass != IAX_COMMAND_TXREL) &&
07330 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
07331 (f.subclass != IAX_COMMAND_TXACC) &&
07332 (f.subclass != IAX_COMMAND_VNAK)) ||
07333 (f.frametype != AST_FRAME_IAX)) {
07334
07335 if (option_debug)
07336 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
07337 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
07338
07339
07340 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
07341
07342 if ((f.frametype != AST_FRAME_IAX) ||
07343 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
07344 if (option_debug)
07345 ast_log(LOG_DEBUG, "Acking anyway\n");
07346
07347
07348 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07349 }
07350 } else {
07351
07352 iax2_vnak(fr->callno);
07353 }
07354 ast_mutex_unlock(&iaxsl[fr->callno]);
07355 return 1;
07356 }
07357 } else {
07358
07359 if (((f.subclass != IAX_COMMAND_ACK) &&
07360 (f.subclass != IAX_COMMAND_INVAL) &&
07361 (f.subclass != IAX_COMMAND_TXCNT) &&
07362 (f.subclass != IAX_COMMAND_TXACC) &&
07363 (f.subclass != IAX_COMMAND_VNAK)) ||
07364 (f.frametype != AST_FRAME_IAX))
07365 iaxs[fr->callno]->iseqno++;
07366 }
07367
07368 if (res < sizeof(*fh)) {
07369 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
07370 ast_mutex_unlock(&iaxsl[fr->callno]);
07371 return 1;
07372 }
07373
07374 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
07375 if (res < thread->buf_size)
07376 thread->buf[res++] = '\0';
07377 else
07378 thread->buf[res - 1] = '\0';
07379 }
07380 f.datalen = res - sizeof(*fh);
07381
07382
07383
07384 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
07385 ((f.subclass != IAX_COMMAND_INVAL) ||
07386 (f.frametype != AST_FRAME_IAX))) {
07387 unsigned char x;
07388 int call_to_destroy;
07389
07390
07391
07392 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
07393 if (fr->iseqno == x)
07394 break;
07395 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
07396
07397
07398 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
07399
07400 if (option_debug && iaxdebug)
07401 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
07402 call_to_destroy = 0;
07403 AST_LIST_LOCK(&iaxq.queue);
07404 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07405
07406 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
07407 cur->retries = -1;
07408
07409 if (cur->final)
07410 call_to_destroy = fr->callno;
07411 }
07412 }
07413 AST_LIST_UNLOCK(&iaxq.queue);
07414 if (call_to_destroy) {
07415 if (iaxdebug && option_debug)
07416 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", call_to_destroy);
07417 ast_mutex_lock(&iaxsl[call_to_destroy]);
07418 iax2_destroy(call_to_destroy);
07419 ast_mutex_unlock(&iaxsl[call_to_destroy]);
07420 }
07421 }
07422
07423 if (iaxs[fr->callno])
07424 iaxs[fr->callno]->rseqno = fr->iseqno;
07425 else {
07426
07427 ast_mutex_unlock(&iaxsl[fr->callno]);
07428 return 1;
07429 }
07430 } else if (option_debug)
07431 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
07432 }
07433 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
07434 ((f.frametype != AST_FRAME_IAX) ||
07435 ((f.subclass != IAX_COMMAND_TXACC) &&
07436 (f.subclass != IAX_COMMAND_TXCNT)))) {
07437
07438 ast_mutex_unlock(&iaxsl[fr->callno]);
07439 return 1;
07440 }
07441
07442 if (f.datalen) {
07443 if (f.frametype == AST_FRAME_IAX) {
07444 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
07445 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
07446 ast_mutex_unlock(&iaxsl[fr->callno]);
07447 return 1;
07448 }
07449 f.data = NULL;
07450 f.datalen = 0;
07451 } else
07452 f.data = thread->buf + sizeof(*fh);
07453 } else {
07454 if (f.frametype == AST_FRAME_IAX)
07455 f.data = NULL;
07456 else
07457 f.data = empty;
07458 memset(&ies, 0, sizeof(ies));
07459 }
07460
07461
07462
07463
07464 if ((f.frametype == AST_FRAME_VOICE) ||
07465 (f.frametype == AST_FRAME_VIDEO) ||
07466 (f.frametype == AST_FRAME_IAX)) {
07467 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
07468 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07469 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
07470 ast_mutex_unlock(&iaxsl[fr->callno]);
07471 return 1;
07472 }
07473 }
07474 }
07475
07476 if (f.frametype == AST_FRAME_VOICE) {
07477 if (f.subclass != iaxs[fr->callno]->voiceformat) {
07478 iaxs[fr->callno]->voiceformat = f.subclass;
07479 if (option_debug)
07480 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
07481 if (iaxs[fr->callno]->owner) {
07482 int orignative;
07483 retryowner:
07484 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07485 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07486 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
07487 }
07488 if (iaxs[fr->callno]) {
07489 if (iaxs[fr->callno]->owner) {
07490 orignative = iaxs[fr->callno]->owner->nativeformats;
07491 iaxs[fr->callno]->owner->nativeformats = f.subclass;
07492 if (iaxs[fr->callno]->owner->readformat)
07493 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07494 iaxs[fr->callno]->owner->nativeformats = orignative;
07495 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07496 }
07497 } else {
07498 if (option_debug)
07499 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
07500 ast_mutex_unlock(&iaxsl[fr->callno]);
07501 return 1;
07502 }
07503 }
07504 }
07505 }
07506 if (f.frametype == AST_FRAME_VIDEO) {
07507 if (f.subclass != iaxs[fr->callno]->videoformat) {
07508 if (option_debug)
07509 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
07510 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
07511 }
07512 }
07513 if (f.frametype == AST_FRAME_IAX) {
07514 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
07515
07516 if (option_debug && iaxdebug)
07517 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
07518
07519
07520 if (iaxs[fr->callno]->last < fr->ts &&
07521 f.subclass != IAX_COMMAND_ACK &&
07522 f.subclass != IAX_COMMAND_PONG &&
07523 f.subclass != IAX_COMMAND_LAGRP) {
07524 iaxs[fr->callno]->last = fr->ts;
07525 if (option_debug && iaxdebug)
07526 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07527 }
07528
07529 switch(f.subclass) {
07530 case IAX_COMMAND_ACK:
07531
07532 break;
07533 case IAX_COMMAND_QUELCH:
07534 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07535
07536 if (iaxs[fr->callno]->owner) {
07537 manager_event(EVENT_FLAG_CALL, "Hold",
07538 "Channel: %s\r\n"
07539 "Uniqueid: %s\r\n",
07540 iaxs[fr->callno]->owner->name,
07541 iaxs[fr->callno]->owner->uniqueid);
07542 }
07543
07544 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
07545 if (ies.musiconhold) {
07546 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07547 const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
07548 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
07549 S_OR(mohsuggest, NULL),
07550 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
07551 if (!iaxs[fr->callno]) {
07552 ast_mutex_unlock(&iaxsl[fr->callno]);
07553 return 1;
07554 }
07555 }
07556 }
07557 }
07558 break;
07559 case IAX_COMMAND_UNQUELCH:
07560 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07561
07562 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
07563 manager_event(EVENT_FLAG_CALL, "Unhold",
07564 "Channel: %s\r\n"
07565 "Uniqueid: %s\r\n",
07566 iaxs[fr->callno]->owner->name,
07567 iaxs[fr->callno]->owner->uniqueid);
07568 }
07569
07570 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
07571 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
07572 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
07573 if (!iaxs[fr->callno]) {
07574 ast_mutex_unlock(&iaxsl[fr->callno]);
07575 return 1;
07576 }
07577 }
07578 }
07579 break;
07580 case IAX_COMMAND_TXACC:
07581 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
07582
07583 AST_LIST_LOCK(&iaxq.queue);
07584 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
07585
07586 if ((fr->callno == cur->callno) && (cur->transfer))
07587 cur->retries = -1;
07588 }
07589 AST_LIST_UNLOCK(&iaxq.queue);
07590 memset(&ied1, 0, sizeof(ied1));
07591 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
07592 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
07593 iaxs[fr->callno]->transferring = TRANSFER_READY;
07594 }
07595 break;
07596 case IAX_COMMAND_NEW:
07597
07598 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
07599 break;
07600 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
07601 ast_mutex_unlock(&iaxsl[fr->callno]);
07602 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07603 ast_mutex_lock(&iaxsl[fr->callno]);
07604 if (!iaxs[fr->callno]) {
07605 ast_mutex_unlock(&iaxsl[fr->callno]);
07606 return 1;
07607 }
07608 }
07609
07610 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
07611 int new_callno;
07612 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
07613 fr->callno = new_callno;
07614 }
07615
07616 if (delayreject)
07617 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07618 if (check_access(fr->callno, &sin, &ies)) {
07619
07620 auth_fail(fr->callno, IAX_COMMAND_REJECT);
07621 if (authdebug)
07622 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);
07623 break;
07624 }
07625 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07626 const char *context, *exten, *cid_num;
07627
07628 context = ast_strdupa(iaxs[fr->callno]->context);
07629 exten = ast_strdupa(iaxs[fr->callno]->exten);
07630 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
07631
07632
07633 ast_mutex_unlock(&iaxsl[fr->callno]);
07634 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
07635 ast_mutex_lock(&iaxsl[fr->callno]);
07636
07637 if (!iaxs[fr->callno]) {
07638 ast_mutex_unlock(&iaxsl[fr->callno]);
07639 return 1;
07640 }
07641 } else
07642 exists = 0;
07643 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
07644 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07645 memset(&ied0, 0, sizeof(ied0));
07646 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07647 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07648 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07649 if (!iaxs[fr->callno]) {
07650 ast_mutex_unlock(&iaxsl[fr->callno]);
07651 return 1;
07652 }
07653 if (authdebug)
07654 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);
07655 } else {
07656
07657
07658 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07659 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07660 using_prefs = "reqonly";
07661 } else {
07662 using_prefs = "disabled";
07663 }
07664 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07665 memset(&pref, 0, sizeof(pref));
07666 strcpy(caller_pref_buf, "disabled");
07667 strcpy(host_pref_buf, "disabled");
07668 } else {
07669 using_prefs = "mine";
07670
07671 if (ies.codec_prefs)
07672 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07673 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07674
07675 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07676 pref = iaxs[fr->callno]->rprefs;
07677 using_prefs = "caller";
07678 } else {
07679 pref = iaxs[fr->callno]->prefs;
07680 }
07681 } else
07682 pref = iaxs[fr->callno]->prefs;
07683
07684 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07685 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07686 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07687 }
07688 if (!format) {
07689 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07690 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07691 if (!format) {
07692 memset(&ied0, 0, sizeof(ied0));
07693 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07694 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07695 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07696 if (!iaxs[fr->callno]) {
07697 ast_mutex_unlock(&iaxsl[fr->callno]);
07698 return 1;
07699 }
07700 if (authdebug) {
07701 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07702 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);
07703 else
07704 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);
07705 }
07706 } else {
07707
07708 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07709 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07710 format = 0;
07711 } else {
07712 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07713 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07714 memset(&pref, 0, sizeof(pref));
07715 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07716 strcpy(caller_pref_buf,"disabled");
07717 strcpy(host_pref_buf,"disabled");
07718 } else {
07719 using_prefs = "mine";
07720 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07721
07722 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07723 pref = iaxs[fr->callno]->prefs;
07724 } else {
07725 pref = iaxs[fr->callno]->rprefs;
07726 using_prefs = "caller";
07727 }
07728 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07729
07730 } else
07731 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07732 }
07733 }
07734
07735 if (!format) {
07736 memset(&ied0, 0, sizeof(ied0));
07737 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07738 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07739 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07740 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07741 if (!iaxs[fr->callno]) {
07742 ast_mutex_unlock(&iaxsl[fr->callno]);
07743 return 1;
07744 }
07745 if (authdebug)
07746 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);
07747 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07748 break;
07749 }
07750 }
07751 }
07752 if (format) {
07753
07754 memset(&ied1, 0, sizeof(ied1));
07755 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07756 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07757 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07758 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07759 if (option_verbose > 2)
07760 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
07761 "%srequested format = %s,\n"
07762 "%srequested prefs = %s,\n"
07763 "%sactual format = %s,\n"
07764 "%shost prefs = %s,\n"
07765 "%spriority = %s\n",
07766 ast_inet_ntoa(sin.sin_addr),
07767 VERBOSE_PREFIX_4,
07768 ast_getformatname(iaxs[fr->callno]->peerformat),
07769 VERBOSE_PREFIX_4,
07770 caller_pref_buf,
07771 VERBOSE_PREFIX_4,
07772 ast_getformatname(format),
07773 VERBOSE_PREFIX_4,
07774 host_pref_buf,
07775 VERBOSE_PREFIX_4,
07776 using_prefs);
07777
07778 iaxs[fr->callno]->chosenformat = format;
07779 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
07780 } else {
07781 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07782
07783 if (option_verbose > 2)
07784 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07785 }
07786 }
07787 }
07788 break;
07789 }
07790 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07791 merge_encryption(iaxs[fr->callno],ies.encmethods);
07792 else
07793 iaxs[fr->callno]->encmethods = 0;
07794 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
07795 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07796 if (!iaxs[fr->callno]) {
07797 ast_mutex_unlock(&iaxsl[fr->callno]);
07798 return 1;
07799 }
07800 break;
07801 case IAX_COMMAND_DPREQ:
07802
07803 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07804 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07805 if (iaxcompat) {
07806
07807 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07808 } else {
07809
07810 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07811 }
07812 }
07813 break;
07814 case IAX_COMMAND_HANGUP:
07815 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07816 if (option_debug)
07817 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07818
07819 if (ies.causecode && iaxs[fr->callno]->owner)
07820 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07821
07822 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07823 iax2_destroy(fr->callno);
07824 break;
07825 case IAX_COMMAND_REJECT:
07826
07827 if (ies.causecode && iaxs[fr->callno]->owner)
07828 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07829
07830 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07831 if (iaxs[fr->callno]->owner && authdebug)
07832 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07833 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07834 ies.cause ? ies.cause : "<Unknown>");
07835 if (option_debug)
07836 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07837 fr->callno);
07838 }
07839
07840 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07841 fr->ts, NULL, 0, fr->iseqno);
07842 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07843 iaxs[fr->callno]->error = EPERM;
07844 iax2_destroy(fr->callno);
07845 break;
07846 case IAX_COMMAND_TRANSFER:
07847 {
07848 struct ast_channel *bridged_chan;
07849
07850 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
07851
07852
07853 ast_mutex_unlock(&iaxsl[fr->callno]);
07854 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
07855 ast_mutex_lock(&iaxsl[fr->callno]);
07856 if (!iaxs[fr->callno]) {
07857 ast_mutex_unlock(&iaxsl[fr->callno]);
07858 return 1;
07859 }
07860
07861 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07862 if (!strcmp(ies.called_number, ast_parking_ext())) {
07863 if (iax_park(bridged_chan, iaxs[fr->callno]->owner)) {
07864 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
07865 } else {
07866 ast_log(LOG_DEBUG, "Parked call on '%s'\n", bridged_chan->name);
07867 }
07868 } else {
07869 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
07870 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
07871 ies.called_number, iaxs[fr->callno]->context);
07872 else
07873 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
07874 ies.called_number, iaxs[fr->callno]->context);
07875 }
07876 } else
07877 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07878
07879 break;
07880 }
07881 case IAX_COMMAND_ACCEPT:
07882
07883 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07884 break;
07885 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07886
07887 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07888 iax2_destroy(fr->callno);
07889 break;
07890 }
07891 if (ies.format) {
07892 iaxs[fr->callno]->peerformat = ies.format;
07893 } else {
07894 if (iaxs[fr->callno]->owner)
07895 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07896 else
07897 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07898 }
07899 if (option_verbose > 2)
07900 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));
07901 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07902 memset(&ied0, 0, sizeof(ied0));
07903 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07904 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07905 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07906 if (!iaxs[fr->callno]) {
07907 ast_mutex_unlock(&iaxsl[fr->callno]);
07908 return 1;
07909 }
07910 if (authdebug)
07911 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);
07912 } else {
07913 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07914 if (iaxs[fr->callno]->owner) {
07915
07916 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07917 if (option_verbose > 2)
07918 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07919 retryowner2:
07920 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07921 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
07922 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07923 }
07924
07925 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07926
07927 if (iaxs[fr->callno]->owner->writeformat)
07928 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
07929 if (iaxs[fr->callno]->owner->readformat)
07930 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07931 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07932 }
07933 }
07934 }
07935 if (iaxs[fr->callno]) {
07936 ast_mutex_lock(&dpcache_lock);
07937 dp = iaxs[fr->callno]->dpentries;
07938 while(dp) {
07939 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07940 iax2_dprequest(dp, fr->callno);
07941 }
07942 dp = dp->peer;
07943 }
07944 ast_mutex_unlock(&dpcache_lock);
07945 }
07946 break;
07947 case IAX_COMMAND_POKE:
07948
07949 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07950 if (!iaxs[fr->callno]) {
07951 ast_mutex_unlock(&iaxsl[fr->callno]);
07952 return 1;
07953 }
07954 break;
07955 case IAX_COMMAND_PING:
07956 {
07957 struct iax_ie_data pingied;
07958 construct_rr(iaxs[fr->callno], &pingied);
07959
07960 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07961 }
07962 break;
07963 case IAX_COMMAND_PONG:
07964
07965 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07966
07967 save_rr(fr, &ies);
07968
07969 if (iaxs[fr->callno]->peerpoke) {
07970 peer = iaxs[fr->callno]->peerpoke;
07971 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
07972 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07973 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07974 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
07975 ast_device_state_changed("IAX2/%s", peer->name);
07976 }
07977 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07978 if (iaxs[fr->callno]->pingtime > peer->maxms) {
07979 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07980 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
07981 ast_device_state_changed("IAX2/%s", peer->name);
07982 }
07983 }
07984 peer->lastms = iaxs[fr->callno]->pingtime;
07985 if (peer->smoothing && (peer->lastms > -1))
07986 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07987 else if (peer->smoothing && peer->lastms < 0)
07988 peer->historicms = (0 + peer->historicms) / 2;
07989 else
07990 peer->historicms = iaxs[fr->callno]->pingtime;
07991
07992
07993 if (peer->pokeexpire > -1) {
07994 if (!ast_sched_del(sched, peer->pokeexpire)) {
07995 peer_unref(peer);
07996 peer->pokeexpire = -1;
07997 }
07998 }
07999
08000 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
08001 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08002 else
08003 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
08004 if (peer->pokeexpire == -1)
08005 peer_unref(peer);
08006
08007 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08008
08009 iax2_destroy(fr->callno);
08010 peer->callno = 0;
08011 if (option_debug)
08012 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
08013 }
08014 break;
08015 case IAX_COMMAND_LAGRQ:
08016 case IAX_COMMAND_LAGRP:
08017 f.src = "LAGRQ";
08018 f.mallocd = 0;
08019 f.offset = 0;
08020 f.samples = 0;
08021 iax_frame_wrap(fr, &f);
08022 if(f.subclass == IAX_COMMAND_LAGRQ) {
08023
08024 fr->af.subclass = IAX_COMMAND_LAGRP;
08025 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
08026 } else {
08027
08028 unsigned int ts;
08029
08030 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
08031 iaxs[fr->callno]->lag = ts - fr->ts;
08032 if (option_debug && iaxdebug)
08033 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
08034 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
08035 }
08036 break;
08037 case IAX_COMMAND_AUTHREQ:
08038 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08039 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>");
08040 break;
08041 }
08042 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
08043 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
08044 .subclass = AST_CONTROL_HANGUP,
08045 };
08046 ast_log(LOG_WARNING,
08047 "I don't know how to authenticate %s to %s\n",
08048 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
08049 iax2_queue_frame(fr->callno, &hangup_fr);
08050 }
08051 if (!iaxs[fr->callno]) {
08052 ast_mutex_unlock(&iaxsl[fr->callno]);
08053 return 1;
08054 }
08055 break;
08056 case IAX_COMMAND_AUTHREP:
08057
08058 if (delayreject)
08059 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08060
08061 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
08062 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>");
08063 break;
08064 }
08065 if (authenticate_verify(iaxs[fr->callno], &ies)) {
08066 if (authdebug)
08067 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);
08068 memset(&ied0, 0, sizeof(ied0));
08069 auth_fail(fr->callno, IAX_COMMAND_REJECT);
08070 break;
08071 }
08072 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08073
08074 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
08075 } else
08076 exists = 0;
08077 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08078 if (authdebug)
08079 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);
08080 memset(&ied0, 0, sizeof(ied0));
08081 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08082 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08083 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08084 if (!iaxs[fr->callno]) {
08085 ast_mutex_unlock(&iaxsl[fr->callno]);
08086 return 1;
08087 }
08088 } else {
08089
08090 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08091 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08092 using_prefs = "reqonly";
08093 } else {
08094 using_prefs = "disabled";
08095 }
08096 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08097 memset(&pref, 0, sizeof(pref));
08098 strcpy(caller_pref_buf, "disabled");
08099 strcpy(host_pref_buf, "disabled");
08100 } else {
08101 using_prefs = "mine";
08102 if (ies.codec_prefs)
08103 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08104 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08105 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08106 pref = iaxs[fr->callno]->rprefs;
08107 using_prefs = "caller";
08108 } else {
08109 pref = iaxs[fr->callno]->prefs;
08110 }
08111 } else
08112 pref = iaxs[fr->callno]->prefs;
08113
08114 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08115 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08116 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08117 }
08118 if (!format) {
08119 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08120 if (option_debug)
08121 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);
08122 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08123 }
08124 if (!format) {
08125 if (authdebug) {
08126 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08127 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);
08128 else
08129 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);
08130 }
08131 memset(&ied0, 0, sizeof(ied0));
08132 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08133 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08134 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08135 if (!iaxs[fr->callno]) {
08136 ast_mutex_unlock(&iaxsl[fr->callno]);
08137 return 1;
08138 }
08139 } else {
08140
08141 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08142 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08143 format = 0;
08144 } else {
08145 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08146 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08147 memset(&pref, 0, sizeof(pref));
08148 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
08149 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08150 strcpy(caller_pref_buf,"disabled");
08151 strcpy(host_pref_buf,"disabled");
08152 } else {
08153 using_prefs = "mine";
08154 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08155
08156 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08157 pref = iaxs[fr->callno]->prefs;
08158 } else {
08159 pref = iaxs[fr->callno]->rprefs;
08160 using_prefs = "caller";
08161 }
08162 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08163 } else
08164 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08165 }
08166 }
08167 if (!format) {
08168 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08169 if (authdebug) {
08170 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08171 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);
08172 else
08173 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);
08174 }
08175 memset(&ied0, 0, sizeof(ied0));
08176 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08177 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08178 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08179 if (!iaxs[fr->callno]) {
08180 ast_mutex_unlock(&iaxsl[fr->callno]);
08181 return 1;
08182 }
08183 }
08184 }
08185 }
08186 if (format) {
08187
08188 memset(&ied1, 0, sizeof(ied1));
08189 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08190 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08191 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08192 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08193 if (option_verbose > 2)
08194 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
08195 "%srequested format = %s,\n"
08196 "%srequested prefs = %s,\n"
08197 "%sactual format = %s,\n"
08198 "%shost prefs = %s,\n"
08199 "%spriority = %s\n",
08200 ast_inet_ntoa(sin.sin_addr),
08201 VERBOSE_PREFIX_4,
08202 ast_getformatname(iaxs[fr->callno]->peerformat),
08203 VERBOSE_PREFIX_4,
08204 caller_pref_buf,
08205 VERBOSE_PREFIX_4,
08206 ast_getformatname(format),
08207 VERBOSE_PREFIX_4,
08208 host_pref_buf,
08209 VERBOSE_PREFIX_4,
08210 using_prefs);
08211
08212 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08213 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
08214 iax2_destroy(fr->callno);
08215 } else {
08216 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08217
08218 if (option_verbose > 2)
08219 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08220 }
08221 }
08222 }
08223 break;
08224 case IAX_COMMAND_DIAL:
08225 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
08226 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08227 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
08228 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
08229 if (authdebug)
08230 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);
08231 memset(&ied0, 0, sizeof(ied0));
08232 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08233 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08234 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08235 if (!iaxs[fr->callno]) {
08236 ast_mutex_unlock(&iaxsl[fr->callno]);
08237 return 1;
08238 }
08239 } else {
08240 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08241 if (option_verbose > 2)
08242 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
08243 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08244 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
08245 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
08246 iax2_destroy(fr->callno);
08247 }
08248 }
08249 break;
08250 case IAX_COMMAND_INVAL:
08251 iaxs[fr->callno]->error = ENOTCONN;
08252 if (option_debug)
08253 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
08254 iax2_destroy(fr->callno);
08255 if (option_debug)
08256 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
08257 break;
08258 case IAX_COMMAND_VNAK:
08259 if (option_debug)
08260 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
08261
08262 vnak_retransmit(fr->callno, fr->iseqno);
08263 break;
08264 case IAX_COMMAND_REGREQ:
08265 case IAX_COMMAND_REGREL:
08266
08267 if (delayreject)
08268 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08269 if (register_verify(fr->callno, &sin, &ies)) {
08270 if (!iaxs[fr->callno]) {
08271 ast_mutex_unlock(&iaxsl[fr->callno]);
08272 return 1;
08273 }
08274
08275 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
08276 break;
08277 }
08278 if (!iaxs[fr->callno]) {
08279 ast_mutex_unlock(&iaxsl[fr->callno]);
08280 return 1;
08281 }
08282 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
08283 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
08284
08285 if (f.subclass == IAX_COMMAND_REGREL)
08286 memset(&sin, 0, sizeof(sin));
08287 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
08288 ast_log(LOG_WARNING, "Registry error\n");
08289 if (!iaxs[fr->callno]) {
08290 ast_mutex_unlock(&iaxsl[fr->callno]);
08291 return 1;
08292 }
08293 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08294 ast_mutex_unlock(&iaxsl[fr->callno]);
08295 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08296 ast_mutex_lock(&iaxsl[fr->callno]);
08297 if (!iaxs[fr->callno]) {
08298 ast_mutex_unlock(&iaxsl[fr->callno]);
08299 return 1;
08300 }
08301 }
08302 break;
08303 }
08304 registry_authrequest(fr->callno);
08305 if (!iaxs[fr->callno]) {
08306 ast_mutex_unlock(&iaxsl[fr->callno]);
08307 return 1;
08308 }
08309 break;
08310 case IAX_COMMAND_REGACK:
08311 if (iax2_ack_registry(&ies, &sin, fr->callno))
08312 ast_log(LOG_WARNING, "Registration failure\n");
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_REGREJ:
08318 if (iaxs[fr->callno]->reg) {
08319 if (authdebug) {
08320 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));
08321 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>");
08322 }
08323 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
08324 }
08325
08326 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08327 iax2_destroy(fr->callno);
08328 break;
08329 case IAX_COMMAND_REGAUTH:
08330
08331 if (registry_rerequest(&ies, fr->callno, &sin)) {
08332 memset(&ied0, 0, sizeof(ied0));
08333 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
08334 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08335 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08336 if (!iaxs[fr->callno]) {
08337 ast_mutex_unlock(&iaxsl[fr->callno]);
08338 return 1;
08339 }
08340 }
08341 break;
08342 case IAX_COMMAND_TXREJ:
08343 iaxs[fr->callno]->transferring = 0;
08344 if (option_verbose > 2)
08345 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08346 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
08347 if (iaxs[fr->callno]->bridgecallno) {
08348 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
08349 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
08350 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
08351 }
08352 }
08353 break;
08354 case IAX_COMMAND_TXREADY:
08355 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
08356 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
08357 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
08358 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
08359 else
08360 iaxs[fr->callno]->transferring = TRANSFER_READY;
08361 if (option_verbose > 2)
08362 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
08363 if (iaxs[fr->callno]->bridgecallno) {
08364 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
08365 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
08366
08367 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
08368 if (option_verbose > 2)
08369 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08370 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08371
08372 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
08373 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
08374
08375 memset(&ied0, 0, sizeof(ied0));
08376 memset(&ied1, 0, sizeof(ied1));
08377 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08378 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08379 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
08380 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
08381 } else {
08382 if (option_verbose > 2)
08383 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
08384 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
08385
08386 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
08387 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
08388 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
08389 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08390
08391
08392 stop_stuff(fr->callno);
08393 stop_stuff(iaxs[fr->callno]->bridgecallno);
08394
08395 memset(&ied0, 0, sizeof(ied0));
08396 memset(&ied1, 0, sizeof(ied1));
08397 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
08398 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
08399 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
08400 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
08401 }
08402
08403 }
08404 }
08405 }
08406 break;
08407 case IAX_COMMAND_TXREQ:
08408 try_transfer(iaxs[fr->callno], &ies);
08409 break;
08410 case IAX_COMMAND_TXCNT:
08411 if (iaxs[fr->callno]->transferring)
08412 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
08413 break;
08414 case IAX_COMMAND_TXREL:
08415
08416 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08417 complete_transfer(fr->callno, &ies);
08418 stop_stuff(fr->callno);
08419 break;
08420 case IAX_COMMAND_TXMEDIA:
08421 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
08422 AST_LIST_LOCK(&iaxq.queue);
08423 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
08424
08425 if ((fr->callno == cur->callno) && (cur->transfer)) {
08426 cur->retries = -1;
08427 }
08428 }
08429 AST_LIST_UNLOCK(&iaxq.queue);
08430
08431 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
08432 }
08433 break;
08434 case IAX_COMMAND_DPREP:
08435 complete_dpreply(iaxs[fr->callno], &ies);
08436 break;
08437 case IAX_COMMAND_UNSUPPORT:
08438 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
08439 break;
08440 case IAX_COMMAND_FWDOWNL:
08441
08442 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
08443 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
08444 break;
08445 }
08446 memset(&ied0, 0, sizeof(ied0));
08447 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
08448 if (res < 0)
08449 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08450 else if (res > 0)
08451 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08452 else
08453 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
08454 if (!iaxs[fr->callno]) {
08455 ast_mutex_unlock(&iaxsl[fr->callno]);
08456 return 1;
08457 }
08458 break;
08459 default:
08460 if (option_debug)
08461 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
08462 memset(&ied0, 0, sizeof(ied0));
08463 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
08464 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
08465 }
08466
08467 if ((f.subclass != IAX_COMMAND_ACK) &&
08468 (f.subclass != IAX_COMMAND_TXCNT) &&
08469 (f.subclass != IAX_COMMAND_TXACC) &&
08470 (f.subclass != IAX_COMMAND_INVAL) &&
08471 (f.subclass != IAX_COMMAND_VNAK)) {
08472 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08473 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08474 }
08475 ast_mutex_unlock(&iaxsl[fr->callno]);
08476 return 1;
08477 }
08478
08479 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
08480 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08481 } else if (minivid) {
08482 f.frametype = AST_FRAME_VIDEO;
08483 if (iaxs[fr->callno]->videoformat > 0)
08484 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
08485 else {
08486 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
08487 iax2_vnak(fr->callno);
08488 ast_mutex_unlock(&iaxsl[fr->callno]);
08489 return 1;
08490 }
08491 f.datalen = res - sizeof(*vh);
08492 if (f.datalen)
08493 f.data = thread->buf + sizeof(*vh);
08494 else
08495 f.data = NULL;
08496 #ifdef IAXTESTS
08497 if (test_resync) {
08498 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
08499 } else
08500 #endif
08501 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
08502 } else {
08503
08504 f.frametype = AST_FRAME_VOICE;
08505 if (iaxs[fr->callno]->voiceformat > 0)
08506 f.subclass = iaxs[fr->callno]->voiceformat;
08507 else {
08508 if (option_debug)
08509 ast_log(LOG_DEBUG, "Received mini frame before first full voice frame\n");
08510 iax2_vnak(fr->callno);
08511 ast_mutex_unlock(&iaxsl[fr->callno]);
08512 return 1;
08513 }
08514 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
08515 if (f.datalen < 0) {
08516 ast_log(LOG_WARNING, "Datalen < 0?\n");
08517 ast_mutex_unlock(&iaxsl[fr->callno]);
08518 return 1;
08519 }
08520 if (f.datalen)
08521 f.data = thread->buf + sizeof(*mh);
08522 else
08523 f.data = NULL;
08524 #ifdef IAXTESTS
08525 if (test_resync) {
08526 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
08527 } else
08528 #endif
08529 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
08530
08531 }
08532
08533 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08534 ast_mutex_unlock(&iaxsl[fr->callno]);
08535 return 1;
08536 }
08537
08538 f.src = "IAX2";
08539 f.mallocd = 0;
08540 f.offset = 0;
08541 f.len = 0;
08542 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
08543 f.samples = ast_codec_get_samples(&f);
08544
08545 if (f.subclass == AST_FORMAT_SLINEAR)
08546 ast_frame_byteswap_be(&f);
08547 } else
08548 f.samples = 0;
08549 iax_frame_wrap(fr, &f);
08550
08551
08552 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08553
08554 fr->outoforder = 0;
08555 } else {
08556 if (option_debug && iaxdebug && iaxs[fr->callno])
08557 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);
08558 fr->outoforder = -1;
08559 }
08560 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
08561 duped_fr = iaxfrdup2(fr);
08562 if (duped_fr) {
08563 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
08564 }
08565 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
08566 iaxs[fr->callno]->last = fr->ts;
08567 #if 1
08568 if (option_debug && iaxdebug)
08569 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08570 #endif
08571 }
08572
08573
08574 ast_mutex_unlock(&iaxsl[fr->callno]);
08575 return 1;
08576 }
08577
08578
08579 static void iax2_process_thread_cleanup(void *data)
08580 {
08581 struct iax2_thread *thread = data;
08582 ast_mutex_destroy(&thread->lock);
08583 ast_cond_destroy(&thread->cond);
08584 free(thread);
08585 ast_atomic_dec_and_test(&iaxactivethreadcount);
08586 }
08587
08588 static void *iax2_process_thread(void *data)
08589 {
08590 struct iax2_thread *thread = data;
08591 struct timeval tv;
08592 struct timespec ts;
08593 int put_into_idle = 0;
08594
08595 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
08596 pthread_cleanup_push(iax2_process_thread_cleanup, data);
08597 for(;;) {
08598
08599 ast_mutex_lock(&thread->lock);
08600
08601
08602 thread->ready_for_signal = 1;
08603
08604
08605 if (put_into_idle)
08606 insert_idle_thread(thread);
08607
08608 if (thread->type == IAX_TYPE_DYNAMIC) {
08609 struct iax2_thread *t = NULL;
08610
08611 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08612 ts.tv_sec = tv.tv_sec;
08613 ts.tv_nsec = tv.tv_usec * 1000;
08614 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
08615
08616
08617 if (!put_into_idle) {
08618 ast_mutex_unlock(&thread->lock);
08619 break;
08620 }
08621 AST_LIST_LOCK(&dynamic_list);
08622
08623 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
08624 iaxdynamicthreadcount--;
08625 AST_LIST_UNLOCK(&dynamic_list);
08626 if (t) {
08627
08628
08629
08630 ast_mutex_unlock(&thread->lock);
08631 break;
08632 }
08633
08634
08635
08636 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
08637 ts.tv_sec = tv.tv_sec;
08638 ts.tv_nsec = tv.tv_usec * 1000;
08639 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
08640 {
08641 ast_mutex_unlock(&thread->lock);
08642 break;
08643 }
08644 }
08645 } else {
08646 ast_cond_wait(&thread->cond, &thread->lock);
08647 }
08648
08649
08650 put_into_idle = 1;
08651
08652 ast_mutex_unlock(&thread->lock);
08653
08654 if (thread->iostate == IAX_IOSTATE_IDLE)
08655 continue;
08656
08657
08658 AST_LIST_LOCK(&active_list);
08659 AST_LIST_INSERT_HEAD(&active_list, thread, list);
08660 AST_LIST_UNLOCK(&active_list);
08661
08662
08663 switch(thread->iostate) {
08664 case IAX_IOSTATE_READY:
08665 thread->actions++;
08666 thread->iostate = IAX_IOSTATE_PROCESSING;
08667 socket_process(thread);
08668 handle_deferred_full_frames(thread);
08669 break;
08670 case IAX_IOSTATE_SCHEDREADY:
08671 thread->actions++;
08672 thread->iostate = IAX_IOSTATE_PROCESSING;
08673 #ifdef SCHED_MULTITHREADED
08674 thread->schedfunc(thread->scheddata);
08675 #endif
08676 break;
08677 }
08678 time(&thread->checktime);
08679 thread->iostate = IAX_IOSTATE_IDLE;
08680 #ifdef DEBUG_SCHED_MULTITHREAD
08681 thread->curfunc[0]='\0';
08682 #endif
08683
08684
08685 AST_LIST_LOCK(&active_list);
08686 AST_LIST_REMOVE(&active_list, thread, list);
08687 AST_LIST_UNLOCK(&active_list);
08688
08689
08690 handle_deferred_full_frames(thread);
08691 }
08692
08693
08694
08695
08696
08697 AST_LIST_LOCK(&idle_list);
08698 AST_LIST_REMOVE(&idle_list, thread, list);
08699 AST_LIST_UNLOCK(&idle_list);
08700
08701 AST_LIST_LOCK(&dynamic_list);
08702 AST_LIST_REMOVE(&dynamic_list, thread, list);
08703 AST_LIST_UNLOCK(&dynamic_list);
08704
08705
08706
08707
08708 pthread_cleanup_pop(1);
08709
08710 return NULL;
08711 }
08712
08713 static int iax2_do_register(struct iax2_registry *reg)
08714 {
08715 struct iax_ie_data ied;
08716 if (option_debug && iaxdebug)
08717 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
08718
08719 if (reg->dnsmgr &&
08720 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
08721
08722 ast_dnsmgr_refresh(reg->dnsmgr);
08723 }
08724
08725
08726
08727
08728
08729 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
08730 ast_mutex_lock(&iaxsl[reg->callno]);
08731 iax2_destroy(reg->callno);
08732 ast_mutex_unlock(&iaxsl[reg->callno]);
08733 reg->callno = 0;
08734 }
08735 if (!reg->addr.sin_addr.s_addr) {
08736 if (option_debug && iaxdebug)
08737 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
08738
08739 AST_SCHED_DEL(sched, reg->expire);
08740 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08741 return -1;
08742 }
08743
08744 if (!reg->callno) {
08745 if (option_debug)
08746 ast_log(LOG_DEBUG, "Allocate call number\n");
08747 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
08748 if (reg->callno < 1) {
08749 ast_log(LOG_WARNING, "Unable to create call for registration\n");
08750 return -1;
08751 } else if (option_debug)
08752 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
08753 iaxs[reg->callno]->reg = reg;
08754 ast_mutex_unlock(&iaxsl[reg->callno]);
08755 }
08756
08757 AST_SCHED_DEL(sched, reg->expire);
08758
08759 reg->expire = iax2_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08760
08761 memset(&ied, 0, sizeof(ied));
08762 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08763 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08764 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08765 reg->regstate = REG_STATE_REGSENT;
08766 return 0;
08767 }
08768
08769 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
08770 {
08771 if (pos != 3)
08772 return NULL;
08773 return iax_prov_complete_template(line, word, pos, state);
08774 }
08775
08776 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
08777 {
08778
08779
08780 struct iax_ie_data provdata;
08781 struct iax_ie_data ied;
08782 unsigned int sig;
08783 struct sockaddr_in sin;
08784 int callno;
08785 struct create_addr_info cai;
08786
08787 memset(&cai, 0, sizeof(cai));
08788
08789 if (option_debug)
08790 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
08791
08792 if (iax_provision_build(&provdata, &sig, template, force)) {
08793 if (option_debug)
08794 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
08795 return 0;
08796 }
08797
08798 if (end) {
08799 memcpy(&sin, end, sizeof(sin));
08800 cai.sockfd = sockfd;
08801 } else if (create_addr(dest, NULL, &sin, &cai))
08802 return -1;
08803
08804
08805 memset(&ied, 0, sizeof(ied));
08806 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
08807
08808 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
08809 if (!callno)
08810 return -1;
08811
08812 if (iaxs[callno]) {
08813
08814 AST_SCHED_DEL(sched, iaxs[callno]->autoid);
08815 iaxs[callno]->autoid = iax2_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
08816 ast_set_flag(iaxs[callno], IAX_PROVISION);
08817
08818 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
08819 }
08820 ast_mutex_unlock(&iaxsl[callno]);
08821
08822 return 1;
08823 }
08824
08825 static char *papp = "IAX2Provision";
08826 static char *psyn = "Provision a calling IAXy with a given template";
08827 static char *pdescrip =
08828 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
08829 "the calling entity is in fact an IAXy) with the given template or\n"
08830 "default if one is not specified. Returns -1 on error or 0 on success.\n";
08831
08832
08833
08834
08835 static int iax2_prov_app(struct ast_channel *chan, void *data)
08836 {
08837 int res;
08838 char *sdata;
08839 char *opts;
08840 int force =0;
08841 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
08842 if (ast_strlen_zero(data))
08843 data = "default";
08844 sdata = ast_strdupa(data);
08845 opts = strchr(sdata, '|');
08846 if (opts)
08847 *opts='\0';
08848
08849 if (chan->tech != &iax2_tech) {
08850 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
08851 return -1;
08852 }
08853 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
08854 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
08855 return -1;
08856 }
08857 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
08858 if (option_verbose > 2)
08859 ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n",
08860 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
08861 sdata, res);
08862 return res;
08863 }
08864
08865
08866 static int iax2_prov_cmd(int fd, int argc, char *argv[])
08867 {
08868 int force = 0;
08869 int res;
08870 if (argc < 4)
08871 return RESULT_SHOWUSAGE;
08872 if ((argc > 4)) {
08873 if (!strcasecmp(argv[4], "forced"))
08874 force = 1;
08875 else
08876 return RESULT_SHOWUSAGE;
08877 }
08878 res = iax2_provision(NULL, -1, argv[2], argv[3], force);
08879 if (res < 0)
08880 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
08881 else if (res < 1)
08882 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
08883 else
08884 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
08885 return RESULT_SUCCESS;
08886 }
08887
08888 static void __iax2_poke_noanswer(const void *data)
08889 {
08890 struct iax2_peer *peer = (struct iax2_peer *)data;
08891 int callno;
08892
08893 if (peer->lastms > -1) {
08894 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
08895 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
08896 ast_device_state_changed("IAX2/%s", peer->name);
08897 }
08898 if ((callno = peer->callno) > 0) {
08899 ast_mutex_lock(&iaxsl[callno]);
08900 iax2_destroy(callno);
08901 ast_mutex_unlock(&iaxsl[callno]);
08902 }
08903 peer->callno = 0;
08904 peer->lastms = -1;
08905
08906 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
08907 if (peer->pokeexpire == -1)
08908 peer_unref(peer);
08909 }
08910
08911 static int iax2_poke_noanswer(const void *data)
08912 {
08913 struct iax2_peer *peer = (struct iax2_peer *)data;
08914 peer->pokeexpire = -1;
08915 #ifdef SCHED_MULTITHREADED
08916 if (schedule_action(__iax2_poke_noanswer, data))
08917 #endif
08918 __iax2_poke_noanswer(data);
08919 peer_unref(peer);
08920 return 0;
08921 }
08922
08923 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
08924 {
08925 struct iax2_peer *peer = obj;
08926
08927 iax2_poke_peer(peer, 0);
08928
08929 return 0;
08930 }
08931
08932 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
08933 {
08934 int callno;
08935 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
08936
08937
08938 peer->lastms = 0;
08939 peer->historicms = 0;
08940 peer->pokeexpire = -1;
08941 peer->callno = 0;
08942 return 0;
08943 }
08944
08945
08946 if ((callno = peer->callno) > 0) {
08947 ast_log(LOG_NOTICE, "Still have a callno...\n");
08948 ast_mutex_lock(&iaxsl[callno]);
08949 iax2_destroy(callno);
08950 ast_mutex_unlock(&iaxsl[callno]);
08951 }
08952 if (heldcall)
08953 ast_mutex_unlock(&iaxsl[heldcall]);
08954 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
08955 if (heldcall)
08956 ast_mutex_lock(&iaxsl[heldcall]);
08957 if (peer->callno < 1) {
08958 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08959 return -1;
08960 }
08961
08962
08963 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08964 iaxs[peer->callno]->peerpoke = peer;
08965
08966
08967 if (peer->pokeexpire > -1) {
08968 if (!ast_sched_del(sched, peer->pokeexpire)) {
08969 peer->pokeexpire = -1;
08970 peer_unref(peer);
08971 }
08972 }
08973
08974
08975
08976 if (peer->lastms < 0) {
08977 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
08978 } else
08979 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
08980
08981 if (peer->pokeexpire == -1)
08982 peer_unref(peer);
08983
08984
08985 ast_mutex_lock(&iaxsl[callno]);
08986 if (iaxs[callno]) {
08987 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08988 }
08989 ast_mutex_unlock(&iaxsl[callno]);
08990
08991 return 0;
08992 }
08993
08994 static void free_context(struct iax2_context *con)
08995 {
08996 struct iax2_context *conl;
08997 while(con) {
08998 conl = con;
08999 con = con->next;
09000 free(conl);
09001 }
09002 }
09003
09004 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
09005 {
09006 int callno;
09007 int res;
09008 int fmt, native;
09009 struct sockaddr_in sin;
09010 struct ast_channel *c;
09011 struct parsed_dial_string pds;
09012 struct create_addr_info cai;
09013 char *tmpstr;
09014
09015 memset(&pds, 0, sizeof(pds));
09016 tmpstr = ast_strdupa(data);
09017 parse_dial_string(tmpstr, &pds);
09018
09019 if (ast_strlen_zero(pds.peer)) {
09020 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
09021 return NULL;
09022 }
09023
09024 memset(&cai, 0, sizeof(cai));
09025 cai.capability = iax2_capability;
09026
09027 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09028
09029
09030 if (create_addr(pds.peer, NULL, &sin, &cai)) {
09031 *cause = AST_CAUSE_UNREGISTERED;
09032 return NULL;
09033 }
09034
09035 if (pds.port)
09036 sin.sin_port = htons(atoi(pds.port));
09037
09038 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
09039 if (callno < 1) {
09040 ast_log(LOG_WARNING, "Unable to create call\n");
09041 *cause = AST_CAUSE_CONGESTION;
09042 return NULL;
09043 }
09044
09045
09046 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09047 if (ast_test_flag(&cai, IAX_TRUNK)) {
09048 int new_callno;
09049 if ((new_callno = make_trunk(callno, 1)) != -1)
09050 callno = new_callno;
09051 }
09052 iaxs[callno]->maxtime = cai.maxtime;
09053 if (cai.found)
09054 ast_string_field_set(iaxs[callno], host, pds.peer);
09055
09056 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
09057
09058 ast_mutex_unlock(&iaxsl[callno]);
09059
09060 if (c) {
09061
09062 if (c->nativeformats & format)
09063 c->nativeformats &= format;
09064 else {
09065 native = c->nativeformats;
09066 fmt = format;
09067 res = ast_translator_best_choice(&fmt, &native);
09068 if (res < 0) {
09069 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
09070 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
09071 ast_hangup(c);
09072 return NULL;
09073 }
09074 c->nativeformats = native;
09075 }
09076 c->readformat = ast_best_codec(c->nativeformats);
09077 c->writeformat = c->readformat;
09078 }
09079
09080 return c;
09081 }
09082
09083 static void *sched_thread(void *ignore)
09084 {
09085 int count;
09086 int res;
09087 struct timeval tv;
09088 struct timespec ts;
09089
09090 for (;;) {
09091 res = ast_sched_wait(sched);
09092 if ((res > 1000) || (res < 0))
09093 res = 1000;
09094 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
09095 ts.tv_sec = tv.tv_sec;
09096 ts.tv_nsec = tv.tv_usec * 1000;
09097
09098 pthread_testcancel();
09099 ast_mutex_lock(&sched_lock);
09100 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
09101 ast_mutex_unlock(&sched_lock);
09102 pthread_testcancel();
09103
09104 count = ast_sched_runq(sched);
09105 if (option_debug && count >= 20)
09106 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
09107 }
09108 return NULL;
09109 }
09110
09111 static void *network_thread(void *ignore)
09112 {
09113
09114
09115 int res, count, wakeup;
09116 struct iax_frame *f;
09117
09118 if (timingfd > -1)
09119 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
09120
09121 for(;;) {
09122 pthread_testcancel();
09123
09124
09125
09126 AST_LIST_LOCK(&iaxq.queue);
09127 count = 0;
09128 wakeup = -1;
09129 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
09130 if (f->sentyet)
09131 continue;
09132
09133
09134 if (ast_mutex_trylock(&iaxsl[f->callno])) {
09135 wakeup = 1;
09136 continue;
09137 }
09138
09139 f->sentyet++;
09140
09141 if (iaxs[f->callno]) {
09142 send_packet(f);
09143 count++;
09144 }
09145
09146 ast_mutex_unlock(&iaxsl[f->callno]);
09147
09148 if (f->retries < 0) {
09149
09150 AST_LIST_REMOVE_CURRENT(&iaxq.queue, list);
09151 iaxq.count--;
09152
09153 iax_frame_free(f);
09154 } else {
09155
09156 f->retries++;
09157 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
09158 }
09159 }
09160 AST_LIST_TRAVERSE_SAFE_END
09161 AST_LIST_UNLOCK(&iaxq.queue);
09162
09163 pthread_testcancel();
09164
09165 if (option_debug && count >= 20)
09166 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
09167
09168
09169 res = ast_io_wait(io, wakeup);
09170 if (res >= 0) {
09171 if (option_debug && res >= 20)
09172 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
09173 }
09174 }
09175 return NULL;
09176 }
09177
09178 static int start_network_thread(void)
09179 {
09180 pthread_attr_t attr;
09181 int threadcount = 0;
09182 int x;
09183 for (x = 0; x < iaxthreadcount; x++) {
09184 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
09185 if (thread) {
09186 thread->type = IAX_TYPE_POOL;
09187 thread->threadnum = ++threadcount;
09188 ast_mutex_init(&thread->lock);
09189 ast_cond_init(&thread->cond, NULL);
09190 pthread_attr_init(&attr);
09191 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
09192 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
09193 ast_log(LOG_WARNING, "Failed to create new thread!\n");
09194 free(thread);
09195 thread = NULL;
09196 }
09197 AST_LIST_LOCK(&idle_list);
09198 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
09199 AST_LIST_UNLOCK(&idle_list);
09200 }
09201 }
09202 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
09203 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
09204 if (option_verbose > 1)
09205 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
09206 return 0;
09207 }
09208
09209 static struct iax2_context *build_context(char *context)
09210 {
09211 struct iax2_context *con;
09212
09213 if ((con = ast_calloc(1, sizeof(*con))))
09214 ast_copy_string(con->context, context, sizeof(con->context));
09215
09216 return con;
09217 }
09218
09219 static int get_auth_methods(char *value)
09220 {
09221 int methods = 0;
09222 if (strstr(value, "rsa"))
09223 methods |= IAX_AUTH_RSA;
09224 if (strstr(value, "md5"))
09225 methods |= IAX_AUTH_MD5;
09226 if (strstr(value, "plaintext"))
09227 methods |= IAX_AUTH_PLAINTEXT;
09228 return methods;
09229 }
09230
09231
09232
09233
09234
09235 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
09236 {
09237 int sd;
09238 int res;
09239
09240 sd = socket(AF_INET, SOCK_DGRAM, 0);
09241 if (sd < 0) {
09242 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
09243 return -1;
09244 }
09245
09246 res = bind(sd, sa, salen);
09247 if (res < 0) {
09248 if (option_debug)
09249 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
09250 close(sd);
09251 return 1;
09252 }
09253
09254 close(sd);
09255 return 0;
09256 }
09257
09258
09259
09260
09261 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
09262 {
09263 struct sockaddr_in sin;
09264 int nonlocal = 1;
09265 int port = IAX_DEFAULT_PORTNO;
09266 int sockfd = defaultsockfd;
09267 char *tmp;
09268 char *addr;
09269 char *portstr;
09270
09271 if (!(tmp = ast_strdupa(srcaddr)))
09272 return -1;
09273
09274 addr = strsep(&tmp, ":");
09275 portstr = tmp;
09276
09277 if (portstr) {
09278 port = atoi(portstr);
09279 if (port < 1)
09280 port = IAX_DEFAULT_PORTNO;
09281 }
09282
09283 if (!ast_get_ip(&sin, addr)) {
09284 struct ast_netsock *sock;
09285 int res;
09286
09287 sin.sin_port = 0;
09288 sin.sin_family = AF_INET;
09289 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
09290 if (res == 0) {
09291
09292 sin.sin_port = htons(port);
09293 if (!(sock = ast_netsock_find(netsock, &sin)))
09294 sock = ast_netsock_find(outsock, &sin);
09295 if (sock) {
09296 sockfd = ast_netsock_sockfd(sock);
09297 nonlocal = 0;
09298 } else {
09299 unsigned int orig_saddr = sin.sin_addr.s_addr;
09300
09301 sin.sin_addr.s_addr = INADDR_ANY;
09302 if (ast_netsock_find(netsock, &sin)) {
09303 sin.sin_addr.s_addr = orig_saddr;
09304 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
09305 if (sock) {
09306 sockfd = ast_netsock_sockfd(sock);
09307 ast_netsock_unref(sock);
09308 nonlocal = 0;
09309 } else {
09310 nonlocal = 2;
09311 }
09312 }
09313 }
09314 }
09315 }
09316
09317 peer->sockfd = sockfd;
09318
09319 if (nonlocal == 1) {
09320 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
09321 srcaddr, peer->name);
09322 return -1;
09323 } else if (nonlocal == 2) {
09324 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
09325 srcaddr, peer->name);
09326 return -1;
09327 } else {
09328 if (option_debug)
09329 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
09330 return 0;
09331 }
09332 }
09333
09334 static void peer_destructor(void *obj)
09335 {
09336 struct iax2_peer *peer = obj;
09337
09338 ast_free_ha(peer->ha);
09339
09340 if (peer->callno > 0) {
09341 ast_mutex_lock(&iaxsl[peer->callno]);
09342 iax2_destroy(peer->callno);
09343 ast_mutex_unlock(&iaxsl[peer->callno]);
09344 }
09345
09346 register_peer_exten(peer, 0);
09347
09348 if (peer->dnsmgr)
09349 ast_dnsmgr_release(peer->dnsmgr);
09350
09351 ast_string_field_free_memory(peer);
09352 }
09353
09354
09355 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09356 {
09357 struct iax2_peer *peer = NULL;
09358 struct ast_ha *oldha = NULL;
09359 int maskfound=0;
09360 int found=0;
09361 int firstpass=1;
09362 struct iax2_peer tmp_peer = {
09363 .name = name,
09364 };
09365
09366 if (!temponly) {
09367 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
09368 if (peer && !ast_test_flag(peer, IAX_DELME))
09369 firstpass = 0;
09370 }
09371
09372 if (peer) {
09373 found++;
09374 if (firstpass) {
09375 oldha = peer->ha;
09376 peer->ha = NULL;
09377 }
09378 unlink_peer(peer);
09379 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
09380 peer->expire = -1;
09381 peer->pokeexpire = -1;
09382 peer->sockfd = defaultsockfd;
09383 if (ast_string_field_init(peer, 32))
09384 peer = peer_unref(peer);
09385 }
09386
09387 if (peer) {
09388 if (firstpass) {
09389 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
09390 peer->encmethods = iax2_encryption;
09391 peer->adsi = adsi;
09392 ast_string_field_set(peer,secret,"");
09393 if (!found) {
09394 ast_string_field_set(peer, name, name);
09395 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09396 peer->expiry = min_reg_expire;
09397 }
09398 peer->prefs = prefs;
09399 peer->capability = iax2_capability;
09400 peer->smoothing = 0;
09401 peer->pokefreqok = DEFAULT_FREQ_OK;
09402 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
09403 ast_string_field_set(peer,context,"");
09404 ast_string_field_set(peer,peercontext,"");
09405 ast_clear_flag(peer, IAX_HASCALLERID);
09406 ast_string_field_set(peer, cid_name, "");
09407 ast_string_field_set(peer, cid_num, "");
09408 }
09409
09410 if (!v) {
09411 v = alt;
09412 alt = NULL;
09413 }
09414 while(v) {
09415 if (!strcasecmp(v->name, "secret")) {
09416 ast_string_field_set(peer, secret, v->value);
09417 } else if (!strcasecmp(v->name, "mailbox")) {
09418 ast_string_field_set(peer, mailbox, v->value);
09419 } else if (!strcasecmp(v->name, "mohinterpret")) {
09420 ast_string_field_set(peer, mohinterpret, v->value);
09421 } else if (!strcasecmp(v->name, "mohsuggest")) {
09422 ast_string_field_set(peer, mohsuggest, v->value);
09423 } else if (!strcasecmp(v->name, "dbsecret")) {
09424 ast_string_field_set(peer, dbsecret, v->value);
09425 } else if (!strcasecmp(v->name, "trunk")) {
09426 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
09427 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
09428 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
09429 ast_clear_flag(peer, IAX_TRUNK);
09430 }
09431 } else if (!strcasecmp(v->name, "auth")) {
09432 peer->authmethods = get_auth_methods(v->value);
09433 } else if (!strcasecmp(v->name, "encryption")) {
09434 peer->encmethods = get_encrypt_methods(v->value);
09435 } else if (!strcasecmp(v->name, "notransfer")) {
09436 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09437 ast_clear_flag(peer, IAX_TRANSFERMEDIA);
09438 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER);
09439 } else if (!strcasecmp(v->name, "transfer")) {
09440 if (!strcasecmp(v->value, "mediaonly")) {
09441 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
09442 } else if (ast_true(v->value)) {
09443 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09444 } else
09445 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09446 } else if (!strcasecmp(v->name, "jitterbuffer")) {
09447 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
09448 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09449 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
09450 } else if (!strcasecmp(v->name, "host")) {
09451 if (!strcasecmp(v->value, "dynamic")) {
09452
09453 ast_set_flag(peer, IAX_DYNAMIC);
09454 if (!found) {
09455
09456
09457 memset(&peer->addr.sin_addr, 0, 4);
09458 if (peer->addr.sin_port) {
09459
09460 peer->defaddr.sin_port = peer->addr.sin_port;
09461 peer->addr.sin_port = 0;
09462 }
09463 }
09464 } else {
09465
09466 AST_SCHED_DEL(sched, peer->expire);
09467 ast_clear_flag(peer, IAX_DYNAMIC);
09468 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
09469 return peer_unref(peer);
09470 if (!peer->addr.sin_port)
09471 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
09472 }
09473 if (!maskfound)
09474 inet_aton("255.255.255.255", &peer->mask);
09475 } else if (!strcasecmp(v->name, "defaultip")) {
09476 if (ast_get_ip(&peer->defaddr, v->value))
09477 return peer_unref(peer);
09478 } else if (!strcasecmp(v->name, "sourceaddress")) {
09479 peer_set_srcaddr(peer, v->value);
09480 } else if (!strcasecmp(v->name, "permit") ||
09481 !strcasecmp(v->name, "deny")) {
09482 peer->ha = ast_append_ha(v->name, v->value, peer->ha);
09483 } else if (!strcasecmp(v->name, "mask")) {
09484 maskfound++;
09485 inet_aton(v->value, &peer->mask);
09486 } else if (!strcasecmp(v->name, "context")) {
09487 ast_string_field_set(peer, context, v->value);
09488 } else if (!strcasecmp(v->name, "regexten")) {
09489 ast_string_field_set(peer, regexten, v->value);
09490 } else if (!strcasecmp(v->name, "peercontext")) {
09491 ast_string_field_set(peer, peercontext, v->value);
09492 } else if (!strcasecmp(v->name, "port")) {
09493 if (ast_test_flag(peer, IAX_DYNAMIC))
09494 peer->defaddr.sin_port = htons(atoi(v->value));
09495 else
09496 peer->addr.sin_port = htons(atoi(v->value));
09497 } else if (!strcasecmp(v->name, "username")) {
09498 ast_string_field_set(peer, username, v->value);
09499 } else if (!strcasecmp(v->name, "allow")) {
09500 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
09501 } else if (!strcasecmp(v->name, "disallow")) {
09502 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
09503 } else if (!strcasecmp(v->name, "callerid")) {
09504 if (!ast_strlen_zero(v->value)) {
09505 char name2[80];
09506 char num2[80];
09507 ast_callerid_split(v->value, name2, 80, num2, 80);
09508 ast_string_field_set(peer, cid_name, name2);
09509 ast_string_field_set(peer, cid_num, num2);
09510 ast_set_flag(peer, IAX_HASCALLERID);
09511 } else {
09512 ast_clear_flag(peer, IAX_HASCALLERID);
09513 ast_string_field_set(peer, cid_name, "");
09514 ast_string_field_set(peer, cid_num, "");
09515 }
09516 } else if (!strcasecmp(v->name, "fullname")) {
09517 if (!ast_strlen_zero(v->value)) {
09518 ast_string_field_set(peer, cid_name, v->value);
09519 ast_set_flag(peer, IAX_HASCALLERID);
09520 } else {
09521 ast_string_field_set(peer, cid_name, "");
09522 if (ast_strlen_zero(peer->cid_num))
09523 ast_clear_flag(peer, IAX_HASCALLERID);
09524 }
09525 } else if (!strcasecmp(v->name, "cid_number")) {
09526 if (!ast_strlen_zero(v->value)) {
09527 ast_string_field_set(peer, cid_num, v->value);
09528 ast_set_flag(peer, IAX_HASCALLERID);
09529 } else {
09530 ast_string_field_set(peer, cid_num, "");
09531 if (ast_strlen_zero(peer->cid_name))
09532 ast_clear_flag(peer, IAX_HASCALLERID);
09533 }
09534 } else if (!strcasecmp(v->name, "sendani")) {
09535 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
09536 } else if (!strcasecmp(v->name, "inkeys")) {
09537 ast_string_field_set(peer, inkeys, v->value);
09538 } else if (!strcasecmp(v->name, "outkey")) {
09539 ast_string_field_set(peer, outkey, v->value);
09540 } else if (!strcasecmp(v->name, "qualify")) {
09541 if (!strcasecmp(v->value, "no")) {
09542 peer->maxms = 0;
09543 } else if (!strcasecmp(v->value, "yes")) {
09544 peer->maxms = DEFAULT_MAXMS;
09545 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
09546 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);
09547 peer->maxms = 0;
09548 }
09549 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
09550 peer->smoothing = ast_true(v->value);
09551 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
09552 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
09553 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);
09554 }
09555 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
09556 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
09557 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);
09558 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
09559 } else if (!strcasecmp(v->name, "timezone")) {
09560 ast_string_field_set(peer, zonetag, v->value);
09561 } else if (!strcasecmp(v->name, "adsi")) {
09562 peer->adsi = ast_true(v->value);
09563 }
09564
09565 v = v->next;
09566 if (!v) {
09567 v = alt;
09568 alt = NULL;
09569 }
09570 }
09571 if (!peer->authmethods)
09572 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09573 ast_clear_flag(peer, IAX_DELME);
09574
09575 peer->addr.sin_family = AF_INET;
09576 }
09577 if (oldha)
09578 ast_free_ha(oldha);
09579 return peer;
09580 }
09581
09582 static void user_destructor(void *obj)
09583 {
09584 struct iax2_user *user = obj;
09585
09586 ast_free_ha(user->ha);
09587 free_context(user->contexts);
09588 if(user->vars) {
09589 ast_variables_destroy(user->vars);
09590 user->vars = NULL;
09591 }
09592 ast_string_field_free_memory(user);
09593 }
09594
09595
09596 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
09597 {
09598 struct iax2_user *user = NULL;
09599 struct iax2_context *con, *conl = NULL;
09600 struct ast_ha *oldha = NULL;
09601 struct iax2_context *oldcon = NULL;
09602 int format;
09603 int firstpass=1;
09604 int oldcurauthreq = 0;
09605 char *varname = NULL, *varval = NULL;
09606 struct ast_variable *tmpvar = NULL;
09607 struct iax2_user tmp_user = {
09608 .name = name,
09609 };
09610
09611 if (!temponly) {
09612 user = ao2_find(users, &tmp_user, OBJ_POINTER);
09613 if (user && !ast_test_flag(user, IAX_DELME))
09614 firstpass = 0;
09615 }
09616
09617 if (user) {
09618 if (firstpass) {
09619 oldcurauthreq = user->curauthreq;
09620 oldha = user->ha;
09621 oldcon = user->contexts;
09622 user->ha = NULL;
09623 user->contexts = NULL;
09624 }
09625
09626 ao2_unlink(users, user);
09627 } else {
09628 user = ao2_alloc(sizeof(*user), user_destructor);
09629 }
09630
09631 if (user) {
09632 if (firstpass) {
09633 ast_string_field_free_memory(user);
09634 memset(user, 0, sizeof(struct iax2_user));
09635 if (ast_string_field_init(user, 32)) {
09636 user = user_unref(user);
09637 goto cleanup;
09638 }
09639 user->maxauthreq = maxauthreq;
09640 user->curauthreq = oldcurauthreq;
09641 user->prefs = prefs;
09642 user->capability = iax2_capability;
09643 user->encmethods = iax2_encryption;
09644 user->adsi = adsi;
09645 ast_string_field_set(user, name, name);
09646 ast_string_field_set(user, language, language);
09647 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
09648 ast_clear_flag(user, IAX_HASCALLERID);
09649 ast_string_field_set(user, cid_name, "");
09650 ast_string_field_set(user, cid_num, "");
09651 }
09652 if (!v) {
09653 v = alt;
09654 alt = NULL;
09655 }
09656 while(v) {
09657 if (!strcasecmp(v->name, "context")) {
09658 con = build_context(v->value);
09659 if (con) {
09660 if (conl)
09661 conl->next = con;
09662 else
09663 user->contexts = con;
09664 conl = con;
09665 }
09666 } else if (!strcasecmp(v->name, "permit") ||
09667 !strcasecmp(v->name, "deny")) {
09668 user->ha = ast_append_ha(v->name, v->value, user->ha);
09669 } else if (!strcasecmp(v->name, "setvar")) {
09670 varname = ast_strdupa(v->value);
09671 if (varname && (varval = strchr(varname,'='))) {
09672 *varval = '\0';
09673 varval++;
09674 if((tmpvar = ast_variable_new(varname, varval))) {
09675 tmpvar->next = user->vars;
09676 user->vars = tmpvar;
09677 }
09678 }
09679 } else if (!strcasecmp(v->name, "allow")) {
09680 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
09681 } else if (!strcasecmp(v->name, "disallow")) {
09682 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
09683 } else if (!strcasecmp(v->name, "trunk")) {
09684 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
09685 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
09686 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
09687 ast_clear_flag(user, IAX_TRUNK);
09688 }
09689 } else if (!strcasecmp(v->name, "auth")) {
09690 user->authmethods = get_auth_methods(v->value);
09691 } else if (!strcasecmp(v->name, "encryption")) {
09692 user->encmethods = get_encrypt_methods(v->value);
09693 } else if (!strcasecmp(v->name, "notransfer")) {
09694 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09695 ast_clear_flag(user, IAX_TRANSFERMEDIA);
09696 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER);
09697 } else if (!strcasecmp(v->name, "transfer")) {
09698 if (!strcasecmp(v->value, "mediaonly")) {
09699 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
09700 } else if (ast_true(v->value)) {
09701 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09702 } else
09703 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09704 } else if (!strcasecmp(v->name, "codecpriority")) {
09705 if(!strcasecmp(v->value, "caller"))
09706 ast_set_flag(user, IAX_CODEC_USER_FIRST);
09707 else if(!strcasecmp(v->value, "disabled"))
09708 ast_set_flag(user, IAX_CODEC_NOPREFS);
09709 else if(!strcasecmp(v->value, "reqonly")) {
09710 ast_set_flag(user, IAX_CODEC_NOCAP);
09711 ast_set_flag(user, IAX_CODEC_NOPREFS);
09712 }
09713 } else if (!strcasecmp(v->name, "jitterbuffer")) {
09714 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
09715 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
09716 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
09717 } else if (!strcasecmp(v->name, "dbsecret")) {
09718 ast_string_field_set(user, dbsecret, v->value);
09719 } else if (!strcasecmp(v->name, "secret")) {
09720 if (!ast_strlen_zero(user->secret)) {
09721 char *old = ast_strdupa(user->secret);
09722
09723 ast_string_field_build(user, secret, "%s;%s", old, v->value);
09724 } else
09725 ast_string_field_set(user, secret, v->value);
09726 } else if (!strcasecmp(v->name, "callerid")) {
09727 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
09728 char name2[80];
09729 char num2[80];
09730 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
09731 ast_string_field_set(user, cid_name, name2);
09732 ast_string_field_set(user, cid_num, num2);
09733 ast_set_flag(user, IAX_HASCALLERID);
09734 } else {
09735 ast_clear_flag(user, IAX_HASCALLERID);
09736 ast_string_field_set(user, cid_name, "");
09737 ast_string_field_set(user, cid_num, "");
09738 }
09739 } else if (!strcasecmp(v->name, "fullname")) {
09740 if (!ast_strlen_zero(v->value)) {
09741 ast_string_field_set(user, cid_name, v->value);
09742 ast_set_flag(user, IAX_HASCALLERID);
09743 } else {
09744 ast_string_field_set(user, cid_name, "");
09745 if (ast_strlen_zero(user->cid_num))
09746 ast_clear_flag(user, IAX_HASCALLERID);
09747 }
09748 } else if (!strcasecmp(v->name, "cid_number")) {
09749 if (!ast_strlen_zero(v->value)) {
09750 ast_string_field_set(user, cid_num, v->value);
09751 ast_set_flag(user, IAX_HASCALLERID);
09752 } else {
09753 ast_string_field_set(user, cid_num, "");
09754 if (ast_strlen_zero(user->cid_name))
09755 ast_clear_flag(user, IAX_HASCALLERID);
09756 }
09757 } else if (!strcasecmp(v->name, "accountcode")) {
09758 ast_string_field_set(user, accountcode, v->value);
09759 } else if (!strcasecmp(v->name, "mohinterpret")) {
09760 ast_string_field_set(user, mohinterpret, v->value);
09761 } else if (!strcasecmp(v->name, "mohsuggest")) {
09762 ast_string_field_set(user, mohsuggest, v->value);
09763 } else if (!strcasecmp(v->name, "language")) {
09764 ast_string_field_set(user, language, v->value);
09765 } else if (!strcasecmp(v->name, "amaflags")) {
09766 format = ast_cdr_amaflags2int(v->value);
09767 if (format < 0) {
09768 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09769 } else {
09770 user->amaflags = format;
09771 }
09772 } else if (!strcasecmp(v->name, "inkeys")) {
09773 ast_string_field_set(user, inkeys, v->value);
09774 } else if (!strcasecmp(v->name, "maxauthreq")) {
09775 user->maxauthreq = atoi(v->value);
09776 if (user->maxauthreq < 0)
09777 user->maxauthreq = 0;
09778 } else if (!strcasecmp(v->name, "adsi")) {
09779 user->adsi = ast_true(v->value);
09780 }
09781
09782 v = v->next;
09783 if (!v) {
09784 v = alt;
09785 alt = NULL;
09786 }
09787 }
09788 if (!user->authmethods) {
09789 if (!ast_strlen_zero(user->secret)) {
09790 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09791 if (!ast_strlen_zero(user->inkeys))
09792 user->authmethods |= IAX_AUTH_RSA;
09793 } else if (!ast_strlen_zero(user->inkeys)) {
09794 user->authmethods = IAX_AUTH_RSA;
09795 } else {
09796 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
09797 }
09798 }
09799 ast_clear_flag(user, IAX_DELME);
09800 }
09801 cleanup:
09802 if (oldha)
09803 ast_free_ha(oldha);
09804 if (oldcon)
09805 free_context(oldcon);
09806 return user;
09807 }
09808
09809 static int peer_delme_cb(void *obj, void *arg, int flags)
09810 {
09811 struct iax2_peer *peer = obj;
09812
09813 ast_set_flag(peer, IAX_DELME);
09814
09815 return 0;
09816 }
09817
09818 static int user_delme_cb(void *obj, void *arg, int flags)
09819 {
09820 struct iax2_user *user = obj;
09821
09822 ast_set_flag(user, IAX_DELME);
09823
09824 return 0;
09825 }
09826
09827 static void delete_users(void)
09828 {
09829 struct iax2_registry *reg;
09830
09831 ao2_callback(users, 0, user_delme_cb, NULL);
09832
09833 AST_LIST_LOCK(®istrations);
09834 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
09835 ast_sched_del(sched, reg->expire);
09836 if (reg->callno) {
09837 ast_mutex_lock(&iaxsl[reg->callno]);
09838 if (iaxs[reg->callno]) {
09839 iaxs[reg->callno]->reg = NULL;
09840 iax2_destroy(reg->callno);
09841 }
09842 ast_mutex_unlock(&iaxsl[reg->callno]);
09843 }
09844 if (reg->dnsmgr)
09845 ast_dnsmgr_release(reg->dnsmgr);
09846 free(reg);
09847 }
09848 AST_LIST_UNLOCK(®istrations);
09849
09850 ao2_callback(peers, 0, peer_delme_cb, NULL);
09851 }
09852
09853 static void prune_users(void)
09854 {
09855 struct iax2_user *user;
09856 struct ao2_iterator i;
09857
09858 i = ao2_iterator_init(users, 0);
09859 while ((user = ao2_iterator_next(&i))) {
09860 if (ast_test_flag(user, IAX_DELME))
09861 ao2_unlink(users, user);
09862 user_unref(user);
09863 }
09864 }
09865
09866
09867 static void prune_peers(void)
09868 {
09869 struct iax2_peer *peer;
09870 struct ao2_iterator i;
09871
09872 i = ao2_iterator_init(peers, 0);
09873 while ((peer = ao2_iterator_next(&i))) {
09874 if (ast_test_flag(peer, IAX_DELME))
09875 unlink_peer(peer);
09876 peer_unref(peer);
09877 }
09878 }
09879
09880 static void set_timing(void)
09881 {
09882 #ifdef HAVE_ZAPTEL
09883 int bs = trunkfreq * 8;
09884 if (timingfd > -1) {
09885 if (
09886 #ifdef ZT_TIMERACK
09887 ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
09888 #endif
09889 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
09890 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
09891 }
09892 #endif
09893 }
09894
09895 static void set_config_destroy(void)
09896 {
09897 strcpy(accountcode, "");
09898 strcpy(language, "");
09899 strcpy(mohinterpret, "default");
09900 strcpy(mohsuggest, "");
09901 amaflags = 0;
09902 delayreject = 0;
09903 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
09904 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
09905 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
09906 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
09907 delete_users();
09908 }
09909
09910
09911 static int set_config(char *config_file, int reload)
09912 {
09913 struct ast_config *cfg, *ucfg;
09914 int capability=iax2_capability;
09915 struct ast_variable *v;
09916 char *cat;
09917 const char *utype;
09918 const char *tosval;
09919 int format;
09920 int portno = IAX_DEFAULT_PORTNO;
09921 int x;
09922 struct iax2_user *user;
09923 struct iax2_peer *peer;
09924 struct ast_netsock *ns;
09925 #if 0
09926 static unsigned short int last_port=0;
09927 #endif
09928
09929 cfg = ast_config_load(config_file);
09930
09931 if (!cfg) {
09932 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
09933 return -1;
09934 }
09935
09936 if (reload) {
09937 set_config_destroy();
09938 }
09939
09940
09941 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
09942
09943
09944 memset(&globalflags, 0, sizeof(globalflags));
09945 ast_set_flag(&globalflags, IAX_RTUPDATE);
09946
09947 #ifdef SO_NO_CHECK
09948 nochecksums = 0;
09949 #endif
09950
09951 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09952 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
09953
09954 maxauthreq = 3;
09955
09956 v = ast_variable_browse(cfg, "general");
09957
09958
09959 tosval = ast_variable_retrieve(cfg, "general", "tos");
09960 if (tosval) {
09961 if (ast_str2tos(tosval, &tos))
09962 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09963 }
09964 while(v) {
09965 if (!strcasecmp(v->name, "bindport")){
09966 if (reload)
09967 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09968 else
09969 portno = atoi(v->value);
09970 } else if (!strcasecmp(v->name, "pingtime"))
09971 ping_time = atoi(v->value);
09972 else if (!strcasecmp(v->name, "iaxthreadcount")) {
09973 if (reload) {
09974 if (atoi(v->value) != iaxthreadcount)
09975 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09976 } else {
09977 iaxthreadcount = atoi(v->value);
09978 if (iaxthreadcount < 1) {
09979 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09980 iaxthreadcount = 1;
09981 } else if (iaxthreadcount > 256) {
09982 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09983 iaxthreadcount = 256;
09984 }
09985 }
09986 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09987 if (reload) {
09988 AST_LIST_LOCK(&dynamic_list);
09989 iaxmaxthreadcount = atoi(v->value);
09990 AST_LIST_UNLOCK(&dynamic_list);
09991 } else {
09992 iaxmaxthreadcount = atoi(v->value);
09993 if (iaxmaxthreadcount < 0) {
09994 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09995 iaxmaxthreadcount = 0;
09996 } else if (iaxmaxthreadcount > 256) {
09997 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09998 iaxmaxthreadcount = 256;
09999 }
10000 }
10001 } else if (!strcasecmp(v->name, "nochecksums")) {
10002 #ifdef SO_NO_CHECK
10003 if (ast_true(v->value))
10004 nochecksums = 1;
10005 else
10006 nochecksums = 0;
10007 #else
10008 if (ast_true(v->value))
10009 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
10010 #endif
10011 }
10012 else if (!strcasecmp(v->name, "maxjitterbuffer"))
10013 maxjitterbuffer = atoi(v->value);
10014 else if (!strcasecmp(v->name, "resyncthreshold"))
10015 resyncthreshold = atoi(v->value);
10016 else if (!strcasecmp(v->name, "maxjitterinterps"))
10017 maxjitterinterps = atoi(v->value);
10018 else if (!strcasecmp(v->name, "lagrqtime"))
10019 lagrq_time = atoi(v->value);
10020 else if (!strcasecmp(v->name, "maxregexpire"))
10021 max_reg_expire = atoi(v->value);
10022 else if (!strcasecmp(v->name, "minregexpire"))
10023 min_reg_expire = atoi(v->value);
10024 else if (!strcasecmp(v->name, "bindaddr")) {
10025 if (reload) {
10026 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
10027 } else {
10028 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
10029 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
10030 } else {
10031 if (option_verbose > 1) {
10032 if (strchr(v->value, ':'))
10033 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
10034 else
10035 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
10036 }
10037 if (defaultsockfd < 0)
10038 defaultsockfd = ast_netsock_sockfd(ns);
10039 ast_netsock_unref(ns);
10040 }
10041 }
10042 } else if (!strcasecmp(v->name, "authdebug"))
10043 authdebug = ast_true(v->value);
10044 else if (!strcasecmp(v->name, "encryption"))
10045 iax2_encryption = get_encrypt_methods(v->value);
10046 else if (!strcasecmp(v->name, "notransfer")) {
10047 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
10048 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
10049 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);
10050 } else if (!strcasecmp(v->name, "transfer")) {
10051 if (!strcasecmp(v->value, "mediaonly")) {
10052 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
10053 } else if (ast_true(v->value)) {
10054 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10055 } else
10056 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10057 } else if (!strcasecmp(v->name, "codecpriority")) {
10058 if(!strcasecmp(v->value, "caller"))
10059 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
10060 else if(!strcasecmp(v->value, "disabled"))
10061 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10062 else if(!strcasecmp(v->value, "reqonly")) {
10063 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
10064 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
10065 }
10066 } else if (!strcasecmp(v->name, "jitterbuffer"))
10067 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
10068 else if (!strcasecmp(v->name, "forcejitterbuffer"))
10069 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
10070 else if (!strcasecmp(v->name, "delayreject"))
10071 delayreject = ast_true(v->value);
10072 else if (!strcasecmp(v->name, "allowfwdownload"))
10073 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
10074 else if (!strcasecmp(v->name, "rtcachefriends"))
10075 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
10076 else if (!strcasecmp(v->name, "rtignoreregexpire"))
10077 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
10078 else if (!strcasecmp(v->name, "rtupdate"))
10079 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
10080 else if (!strcasecmp(v->name, "trunktimestamps"))
10081 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
10082 else if (!strcasecmp(v->name, "rtautoclear")) {
10083 int i = atoi(v->value);
10084 if(i > 0)
10085 global_rtautoclear = i;
10086 else
10087 i = 0;
10088 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
10089 } else if (!strcasecmp(v->name, "trunkfreq")) {
10090 trunkfreq = atoi(v->value);
10091 if (trunkfreq < 10)
10092 trunkfreq = 10;
10093 } else if (!strcasecmp(v->name, "autokill")) {
10094 if (sscanf(v->value, "%d", &x) == 1) {
10095 if (x >= 0)
10096 autokill = x;
10097 else
10098 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
10099 } else if (ast_true(v->value)) {
10100 autokill = DEFAULT_MAXMS;
10101 } else {
10102 autokill = 0;
10103 }
10104 } else if (!strcasecmp(v->name, "bandwidth")) {
10105 if (!strcasecmp(v->value, "low")) {
10106 capability = IAX_CAPABILITY_LOWBANDWIDTH;
10107 } else if (!strcasecmp(v->value, "medium")) {
10108 capability = IAX_CAPABILITY_MEDBANDWIDTH;
10109 } else if (!strcasecmp(v->value, "high")) {
10110 capability = IAX_CAPABILITY_FULLBANDWIDTH;
10111 } else
10112 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
10113 } else if (!strcasecmp(v->name, "allow")) {
10114 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
10115 } else if (!strcasecmp(v->name, "disallow")) {
10116 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
10117 } else if (!strcasecmp(v->name, "register")) {
10118 iax2_register(v->value, v->lineno);
10119 } else if (!strcasecmp(v->name, "iaxcompat")) {
10120 iaxcompat = ast_true(v->value);
10121 } else if (!strcasecmp(v->name, "regcontext")) {
10122 ast_copy_string(regcontext, v->value, sizeof(regcontext));
10123
10124 if (!ast_context_find(regcontext))
10125 ast_context_create(NULL, regcontext, "IAX2");
10126 } else if (!strcasecmp(v->name, "tos")) {
10127 if (ast_str2tos(v->value, &tos))
10128 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
10129 } else if (!strcasecmp(v->name, "accountcode")) {
10130 ast_copy_string(accountcode, v->value, sizeof(accountcode));
10131 } else if (!strcasecmp(v->name, "mohinterpret")) {
10132 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
10133 } else if (!strcasecmp(v->name, "mohsuggest")) {
10134 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
10135 } else if (!strcasecmp(v->name, "amaflags")) {
10136 format = ast_cdr_amaflags2int(v->value);
10137 if (format < 0) {
10138 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
10139 } else {
10140 amaflags = format;
10141 }
10142 } else if (!strcasecmp(v->name, "language")) {
10143 ast_copy_string(language, v->value, sizeof(language));
10144 } else if (!strcasecmp(v->name, "maxauthreq")) {
10145 maxauthreq = atoi(v->value);
10146 if (maxauthreq < 0)
10147 maxauthreq = 0;
10148 } else if (!strcasecmp(v->name, "adsi")) {
10149 adsi = ast_true(v->value);
10150 }
10151
10152 v = v->next;
10153 }
10154
10155 if (defaultsockfd < 0) {
10156 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
10157 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
10158 } else {
10159 if (option_verbose > 1)
10160 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
10161 defaultsockfd = ast_netsock_sockfd(ns);
10162 ast_netsock_unref(ns);
10163 }
10164 }
10165 if (reload) {
10166 ast_netsock_release(outsock);
10167 outsock = ast_netsock_list_alloc();
10168 if (!outsock) {
10169 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10170 return -1;
10171 }
10172 ast_netsock_init(outsock);
10173 }
10174
10175 if (min_reg_expire > max_reg_expire) {
10176 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
10177 min_reg_expire, max_reg_expire, max_reg_expire);
10178 min_reg_expire = max_reg_expire;
10179 }
10180 iax2_capability = capability;
10181
10182 ucfg = ast_config_load("users.conf");
10183 if (ucfg) {
10184 struct ast_variable *gen;
10185 int genhasiax;
10186 int genregisteriax;
10187 const char *hasiax, *registeriax;
10188
10189 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
10190 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
10191 gen = ast_variable_browse(ucfg, "general");
10192 cat = ast_category_browse(ucfg, NULL);
10193 while (cat) {
10194 if (strcasecmp(cat, "general")) {
10195 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
10196 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
10197 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
10198
10199 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
10200 if (user) {
10201 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10202 user = user_unref(user);
10203 }
10204 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
10205 if (peer) {
10206 if (ast_test_flag(peer, IAX_DYNAMIC))
10207 reg_source_db(peer);
10208 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10209 peer = peer_unref(peer);
10210 }
10211 }
10212 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
10213 char tmp[256];
10214 const char *host = ast_variable_retrieve(ucfg, cat, "host");
10215 const char *username = ast_variable_retrieve(ucfg, cat, "username");
10216 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
10217 if (!host)
10218 host = ast_variable_retrieve(ucfg, "general", "host");
10219 if (!username)
10220 username = ast_variable_retrieve(ucfg, "general", "username");
10221 if (!secret)
10222 secret = ast_variable_retrieve(ucfg, "general", "secret");
10223 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
10224 if (!ast_strlen_zero(secret))
10225 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
10226 else
10227 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
10228 iax2_register(tmp, 0);
10229 }
10230 }
10231 }
10232 cat = ast_category_browse(ucfg, cat);
10233 }
10234 ast_config_destroy(ucfg);
10235 }
10236
10237 cat = ast_category_browse(cfg, NULL);
10238 while(cat) {
10239 if (strcasecmp(cat, "general")) {
10240 utype = ast_variable_retrieve(cfg, cat, "type");
10241 if (utype) {
10242 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
10243 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
10244 if (user) {
10245 __ao2_link(users, user, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10246 user = user_unref(user);
10247 }
10248 }
10249 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
10250 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
10251 if (peer) {
10252 if (ast_test_flag(peer, IAX_DYNAMIC))
10253 reg_source_db(peer);
10254 __ao2_link(peers, peer, (MAX_PEER_BUCKETS == 1) ? 1 : 0);
10255 peer = peer_unref(peer);
10256 }
10257 } else if (strcasecmp(utype, "user")) {
10258 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
10259 }
10260 } else
10261 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
10262 }
10263 cat = ast_category_browse(cfg, cat);
10264 }
10265 ast_config_destroy(cfg);
10266 set_timing();
10267 return 1;
10268 }
10269
10270 static void poke_all_peers(void)
10271 {
10272 struct ao2_iterator i;
10273 struct iax2_peer *peer;
10274
10275 i = ao2_iterator_init(peers, 0);
10276 while ((peer = ao2_iterator_next(&i))) {
10277 iax2_poke_peer(peer, 0);
10278 peer_unref(peer);
10279 }
10280 }
10281 static int reload_config(void)
10282 {
10283 char *config = "iax.conf";
10284 struct iax2_registry *reg;
10285
10286 if (set_config(config, 1) > 0) {
10287 prune_peers();
10288 prune_users();
10289 AST_LIST_LOCK(®istrations);
10290 AST_LIST_TRAVERSE(®istrations, reg, entry)
10291 iax2_do_register(reg);
10292 AST_LIST_UNLOCK(®istrations);
10293
10294 poke_all_peers();
10295 }
10296 reload_firmware(0);
10297 iax_provision_reload();
10298
10299 return 0;
10300 }
10301
10302 static int iax2_reload(int fd, int argc, char *argv[])
10303 {
10304 return reload_config();
10305 }
10306
10307 static int reload(void)
10308 {
10309 return reload_config();
10310 }
10311
10312 static int cache_get_callno_locked(const char *data)
10313 {
10314 struct sockaddr_in sin;
10315 int x;
10316 int callno;
10317 struct iax_ie_data ied;
10318 struct create_addr_info cai;
10319 struct parsed_dial_string pds;
10320 char *tmpstr;
10321
10322 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
10323
10324
10325 if (!ast_mutex_trylock(&iaxsl[x])) {
10326 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
10327 return x;
10328 ast_mutex_unlock(&iaxsl[x]);
10329 }
10330 }
10331
10332
10333
10334 memset(&cai, 0, sizeof(cai));
10335 memset(&ied, 0, sizeof(ied));
10336 memset(&pds, 0, sizeof(pds));
10337
10338 tmpstr = ast_strdupa(data);
10339 parse_dial_string(tmpstr, &pds);
10340
10341 if (ast_strlen_zero(pds.peer)) {
10342 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
10343 return -1;
10344 }
10345
10346
10347 if (create_addr(pds.peer, NULL, &sin, &cai))
10348 return -1;
10349
10350 if (option_debug)
10351 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
10352 pds.peer, pds.username, pds.password, pds.context);
10353
10354 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10355 if (callno < 1) {
10356 ast_log(LOG_WARNING, "Unable to create call\n");
10357 return -1;
10358 }
10359
10360 ast_string_field_set(iaxs[callno], dproot, data);
10361 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
10362
10363 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
10364 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
10365
10366
10367
10368 if (pds.exten)
10369 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
10370 if (pds.username)
10371 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
10372 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
10373 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
10374
10375 if (pds.password)
10376 ast_string_field_set(iaxs[callno], secret, pds.password);
10377 if (pds.key)
10378 ast_string_field_set(iaxs[callno], outkey, pds.key);
10379
10380 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
10381
10382 return callno;
10383 }
10384
10385 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
10386 {
10387 struct iax2_dpcache *dp, *prev = NULL, *next;
10388 struct timeval tv;
10389 int x;
10390 int com[2];
10391 int timeout;
10392 int old=0;
10393 int outfd;
10394 int abort;
10395 int callno;
10396 struct ast_channel *c;
10397 struct ast_frame *f;
10398 gettimeofday(&tv, NULL);
10399 dp = dpcache;
10400 while(dp) {
10401 next = dp->next;
10402
10403 if (ast_tvcmp(tv, dp->expiry) > 0) {
10404
10405 if (prev)
10406 prev->next = dp->next;
10407 else
10408 dpcache = dp->next;
10409 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
10410
10411 free(dp);
10412 } else {
10413 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);
10414 }
10415 dp = next;
10416 continue;
10417 }
10418
10419 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
10420 break;
10421 prev = dp;
10422 dp = next;
10423 }
10424 if (!dp) {
10425
10426
10427 callno = cache_get_callno_locked(data);
10428 if (callno < 0) {
10429 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
10430 return NULL;
10431 }
10432 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
10433 ast_mutex_unlock(&iaxsl[callno]);
10434 return NULL;
10435 }
10436 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
10437 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
10438 gettimeofday(&dp->expiry, NULL);
10439 dp->orig = dp->expiry;
10440
10441 dp->expiry.tv_sec += iaxdefaultdpcache;
10442 dp->next = dpcache;
10443 dp->flags = CACHE_FLAG_PENDING;
10444 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10445 dp->waiters[x] = -1;
10446 dpcache = dp;
10447 dp->peer = iaxs[callno]->dpentries;
10448 iaxs[callno]->dpentries = dp;
10449
10450 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
10451 iax2_dprequest(dp, callno);
10452 ast_mutex_unlock(&iaxsl[callno]);
10453 }
10454
10455 if (dp->flags & CACHE_FLAG_PENDING) {
10456
10457
10458 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
10459
10460 if (dp->waiters[x] < 0)
10461 break;
10462 }
10463 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
10464 ast_log(LOG_WARNING, "No more waiter positions available\n");
10465 return NULL;
10466 }
10467 if (pipe(com)) {
10468 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
10469 return NULL;
10470 }
10471 dp->waiters[x] = com[1];
10472
10473 timeout = iaxdefaulttimeout * 1000;
10474
10475 ast_mutex_unlock(&dpcache_lock);
10476
10477 if (chan)
10478 old = ast_channel_defer_dtmf(chan);
10479 abort = 0;
10480 while(timeout) {
10481 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
10482 if (outfd > -1) {
10483 break;
10484 }
10485 if (c) {
10486 f = ast_read(c);
10487 if (f)
10488 ast_frfree(f);
10489 else {
10490
10491 break;
10492 abort = 1;
10493 }
10494 }
10495 }
10496 if (!timeout) {
10497 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
10498 }
10499 ast_mutex_lock(&dpcache_lock);
10500 dp->waiters[x] = -1;
10501 close(com[1]);
10502 close(com[0]);
10503 if (abort) {
10504
10505
10506 if (!old && chan)
10507 ast_channel_undefer_dtmf(chan);
10508 return NULL;
10509 }
10510 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
10511
10512 if (dp->flags & CACHE_FLAG_PENDING) {
10513
10514
10515 dp->flags &= ~CACHE_FLAG_PENDING;
10516 dp->flags |= CACHE_FLAG_TIMEOUT;
10517
10518
10519 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
10520 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
10521 if (dp->waiters[x] > -1)
10522 write(dp->waiters[x], "asdf", 4);
10523 }
10524 }
10525
10526 if (!old && chan)
10527 ast_channel_undefer_dtmf(chan);
10528 }
10529 return dp;
10530 }
10531
10532
10533 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10534 {
10535 struct iax2_dpcache *dp;
10536 int res = 0;
10537 #if 0
10538 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10539 #endif
10540 if ((priority != 1) && (priority != 2))
10541 return 0;
10542 ast_mutex_lock(&dpcache_lock);
10543 dp = find_cache(chan, data, context, exten, priority);
10544 if (dp) {
10545 if (dp->flags & CACHE_FLAG_EXISTS)
10546 res= 1;
10547 }
10548 ast_mutex_unlock(&dpcache_lock);
10549 if (!dp) {
10550 ast_log(LOG_WARNING, "Unable to make DP cache\n");
10551 }
10552 return res;
10553 }
10554
10555
10556 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10557 {
10558 int res = 0;
10559 struct iax2_dpcache *dp;
10560 #if 0
10561 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10562 #endif
10563 if ((priority != 1) && (priority != 2))
10564 return 0;
10565 ast_mutex_lock(&dpcache_lock);
10566 dp = find_cache(chan, data, context, exten, priority);
10567 if (dp) {
10568 if (dp->flags & CACHE_FLAG_CANEXIST)
10569 res= 1;
10570 }
10571 ast_mutex_unlock(&dpcache_lock);
10572 if (!dp) {
10573 ast_log(LOG_WARNING, "Unable to make DP cache\n");
10574 }
10575 return res;
10576 }
10577
10578
10579 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10580 {
10581 int res = 0;
10582 struct iax2_dpcache *dp;
10583 #if 0
10584 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
10585 #endif
10586 if ((priority != 1) && (priority != 2))
10587 return 0;
10588 ast_mutex_lock(&dpcache_lock);
10589 dp = find_cache(chan, data, context, exten, priority);
10590 if (dp) {
10591 if (dp->flags & CACHE_FLAG_MATCHMORE)
10592 res= 1;
10593 }
10594 ast_mutex_unlock(&dpcache_lock);
10595 if (!dp) {
10596 ast_log(LOG_WARNING, "Unable to make DP cache\n");
10597 }
10598 return res;
10599 }
10600
10601
10602 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
10603 {
10604 char odata[256];
10605 char req[256];
10606 char *ncontext;
10607 struct iax2_dpcache *dp;
10608 struct ast_app *dial;
10609 #if 0
10610 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);
10611 #endif
10612 if (priority == 2) {
10613
10614 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
10615 if (dialstatus) {
10616 dial = pbx_findapp(dialstatus);
10617 if (dial)
10618 pbx_exec(chan, dial, "");
10619 }
10620 return -1;
10621 } else if (priority != 1)
10622 return -1;
10623 ast_mutex_lock(&dpcache_lock);
10624 dp = find_cache(chan, data, context, exten, priority);
10625 if (dp) {
10626 if (dp->flags & CACHE_FLAG_EXISTS) {
10627 ast_copy_string(odata, data, sizeof(odata));
10628 ncontext = strchr(odata, '/');
10629 if (ncontext) {
10630 *ncontext = '\0';
10631 ncontext++;
10632 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
10633 } else {
10634 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
10635 }
10636 if (option_verbose > 2)
10637 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
10638 } else {
10639 ast_mutex_unlock(&dpcache_lock);
10640 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
10641 return -1;
10642 }
10643 }
10644 ast_mutex_unlock(&dpcache_lock);
10645 dial = pbx_findapp("Dial");
10646 if (dial) {
10647 return pbx_exec(chan, dial, req);
10648 } else {
10649 ast_log(LOG_WARNING, "No dial application registered\n");
10650 }
10651 return -1;
10652 }
10653
10654 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
10655 {
10656 struct iax2_peer *peer;
10657 char *peername, *colname;
10658
10659 peername = ast_strdupa(data);
10660
10661
10662 if (!strcmp(peername,"CURRENTCHANNEL")) {
10663 unsigned short callno;
10664 if (chan->tech != &iax2_tech)
10665 return -1;
10666 callno = PTR_TO_CALLNO(chan->tech_pvt);
10667 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
10668 return 0;
10669 }
10670
10671 if ((colname = strchr(peername, ':')))
10672 *colname++ = '\0';
10673 else if ((colname = strchr(peername, '|')))
10674 *colname++ = '\0';
10675 else
10676 colname = "ip";
10677
10678 if (!(peer = find_peer(peername, 1)))
10679 return -1;
10680
10681 if (!strcasecmp(colname, "ip")) {
10682 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
10683 } else if (!strcasecmp(colname, "status")) {
10684 peer_status(peer, buf, len);
10685 } else if (!strcasecmp(colname, "mailbox")) {
10686 ast_copy_string(buf, peer->mailbox, len);
10687 } else if (!strcasecmp(colname, "context")) {
10688 ast_copy_string(buf, peer->context, len);
10689 } else if (!strcasecmp(colname, "expire")) {
10690 snprintf(buf, len, "%d", peer->expire);
10691 } else if (!strcasecmp(colname, "dynamic")) {
10692 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
10693 } else if (!strcasecmp(colname, "callerid_name")) {
10694 ast_copy_string(buf, peer->cid_name, len);
10695 } else if (!strcasecmp(colname, "callerid_num")) {
10696 ast_copy_string(buf, peer->cid_num, len);
10697 } else if (!strcasecmp(colname, "codecs")) {
10698 ast_getformatname_multiple(buf, len -1, peer->capability);
10699 } else if (!strncasecmp(colname, "codec[", 6)) {
10700 char *codecnum, *ptr;
10701 int index = 0, codec = 0;
10702
10703 codecnum = strchr(colname, '[');
10704 *codecnum = '\0';
10705 codecnum++;
10706 if ((ptr = strchr(codecnum, ']'))) {
10707 *ptr = '\0';
10708 }
10709 index = atoi(codecnum);
10710 if((codec = ast_codec_pref_index(&peer->prefs, index))) {
10711 ast_copy_string(buf, ast_getformatname(codec), len);
10712 }
10713 }
10714
10715 peer_unref(peer);
10716
10717 return 0;
10718 }
10719
10720 struct ast_custom_function iaxpeer_function = {
10721 .name = "IAXPEER",
10722 .synopsis = "Gets IAX peer information",
10723 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
10724 .read = function_iaxpeer,
10725 .desc = "If peername specified, valid items are:\n"
10726 "- ip (default) The IP address.\n"
10727 "- status The peer's status (if qualify=yes)\n"
10728 "- mailbox The configured mailbox.\n"
10729 "- context The configured context.\n"
10730 "- expire The epoch time of the next expire.\n"
10731 "- dynamic Is it dynamic? (yes/no).\n"
10732 "- callerid_name The configured Caller ID name.\n"
10733 "- callerid_num The configured Caller ID number.\n"
10734 "- codecs The configured codecs.\n"
10735 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
10736 "\n"
10737 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
10738 "\n"
10739 };
10740
10741
10742
10743 static int iax2_devicestate(void *data)
10744 {
10745 struct parsed_dial_string pds;
10746 char *tmp = ast_strdupa(data);
10747 struct iax2_peer *p;
10748 int res = AST_DEVICE_INVALID;
10749
10750 memset(&pds, 0, sizeof(pds));
10751 parse_dial_string(tmp, &pds);
10752
10753 if (ast_strlen_zero(pds.peer)) {
10754 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10755 return res;
10756 }
10757
10758 if (option_debug > 2)
10759 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
10760
10761
10762 if (!(p = find_peer(pds.peer, 1)))
10763 return res;
10764
10765 res = AST_DEVICE_UNAVAILABLE;
10766 if (option_debug > 2)
10767 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
10768 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
10769
10770 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
10771 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
10772
10773
10774 if (p->historicms == 0 || p->historicms <= p->maxms)
10775
10776 res = AST_DEVICE_UNKNOWN;
10777 }
10778
10779 peer_unref(p);
10780
10781 return res;
10782 }
10783
10784 static struct ast_switch iax2_switch =
10785 {
10786 name: "IAX2",
10787 description: "IAX Remote Dialplan Switch",
10788 exists: iax2_exists,
10789 canmatch: iax2_canmatch,
10790 exec: iax2_exec,
10791 matchmore: iax2_matchmore,
10792 };
10793
10794 static char show_stats_usage[] =
10795 "Usage: iax2 show stats\n"
10796 " Display statistics on IAX channel driver.\n";
10797
10798 static char show_cache_usage[] =
10799 "Usage: iax2 show cache\n"
10800 " Display currently cached IAX Dialplan results.\n";
10801
10802 static char show_peer_usage[] =
10803 "Usage: iax2 show peer <name>\n"
10804 " Display details on specific IAX peer\n";
10805
10806 static char prune_realtime_usage[] =
10807 "Usage: iax2 prune realtime [<peername>|all]\n"
10808 " Prunes object(s) from the cache\n";
10809
10810 static char iax2_reload_usage[] =
10811 "Usage: iax2 reload\n"
10812 " Reloads IAX configuration from iax.conf\n";
10813
10814 static char show_prov_usage[] =
10815 "Usage: iax2 provision <host> <template> [forced]\n"
10816 " Provisions the given peer or IP address using a template\n"
10817 " matching either 'template' or '*' if the template is not\n"
10818 " found. If 'forced' is specified, even empty provisioning\n"
10819 " fields will be provisioned as empty fields.\n";
10820
10821 static char show_users_usage[] =
10822 "Usage: iax2 show users [like <pattern>]\n"
10823 " Lists all known IAX2 users.\n"
10824 " Optional regular expression pattern is used to filter the user list.\n";
10825
10826 static char show_channels_usage[] =
10827 "Usage: iax2 show channels\n"
10828 " Lists all currently active IAX channels.\n";
10829
10830 static char show_netstats_usage[] =
10831 "Usage: iax2 show netstats\n"
10832 " Lists network status for all currently active IAX channels.\n";
10833
10834 static char show_threads_usage[] =
10835 "Usage: iax2 show threads\n"
10836 " Lists status of IAX helper threads\n";
10837
10838 static char show_peers_usage[] =
10839 "Usage: iax2 show peers [registered] [like <pattern>]\n"
10840 " Lists all known IAX2 peers.\n"
10841 " Optional 'registered' argument lists only peers with known addresses.\n"
10842 " Optional regular expression pattern is used to filter the peer list.\n";
10843
10844 static char show_firmware_usage[] =
10845 "Usage: iax2 show firmware\n"
10846 " Lists all known IAX firmware images.\n";
10847
10848 static char show_reg_usage[] =
10849 "Usage: iax2 show registry\n"
10850 " Lists all registration requests and status.\n";
10851
10852 static char debug_usage[] =
10853 "Usage: iax2 set debug\n"
10854 " Enables dumping of IAX packets for debugging purposes\n";
10855
10856 static char no_debug_usage[] =
10857 "Usage: iax2 set debug off\n"
10858 " Disables dumping of IAX packets for debugging purposes\n";
10859
10860 static char debug_trunk_usage[] =
10861 "Usage: iax2 set debug trunk\n"
10862 " Requests current status of IAX trunking\n";
10863
10864 static char no_debug_trunk_usage[] =
10865 "Usage: iax2 set debug trunk off\n"
10866 " Requests current status of IAX trunking\n";
10867
10868 static char debug_jb_usage[] =
10869 "Usage: iax2 set debug jb\n"
10870 " Enables jitterbuffer debugging information\n";
10871
10872 static char no_debug_jb_usage[] =
10873 "Usage: iax2 set debug jb off\n"
10874 " Disables jitterbuffer debugging information\n";
10875
10876 static char iax2_test_losspct_usage[] =
10877 "Usage: iax2 test losspct <percentage>\n"
10878 " For testing, throws away <percentage> percent of incoming packets\n";
10879
10880 #ifdef IAXTESTS
10881 static char iax2_test_late_usage[] =
10882 "Usage: iax2 test late <ms>\n"
10883 " For testing, count the next frame as <ms> ms late\n";
10884
10885 static char iax2_test_resync_usage[] =
10886 "Usage: iax2 test resync <ms>\n"
10887 " For testing, adjust all future frames by <ms> ms\n";
10888
10889 static char iax2_test_jitter_usage[] =
10890 "Usage: iax2 test jitter <ms> <pct>\n"
10891 " For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
10892 #endif
10893
10894 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
10895 { "iax2", "trunk", "debug", NULL },
10896 iax2_do_trunk_debug, NULL,
10897 NULL };
10898
10899 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
10900 { "iax2", "jb", "debug", NULL },
10901 iax2_do_jb_debug, NULL,
10902 NULL };
10903
10904 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
10905 { "iax2", "no", "debug", NULL },
10906 iax2_no_debug, NULL,
10907 NULL };
10908
10909 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
10910 { "iax2", "no", "trunk", "debug", NULL },
10911 iax2_no_trunk_debug, NULL,
10912 NULL };
10913
10914 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
10915 { "iax2", "no", "jb", "debug", NULL },
10916 iax2_no_jb_debug, NULL,
10917 NULL };
10918
10919 static struct ast_cli_entry cli_iax2[] = {
10920 { { "iax2", "show", "cache", NULL },
10921 iax2_show_cache, "Display IAX cached dialplan",
10922 show_cache_usage, NULL, },
10923
10924 { { "iax2", "show", "channels", NULL },
10925 iax2_show_channels, "List active IAX channels",
10926 show_channels_usage, NULL, },
10927
10928 { { "iax2", "show", "firmware", NULL },
10929 iax2_show_firmware, "List available IAX firmwares",
10930 show_firmware_usage, NULL, },
10931
10932 { { "iax2", "show", "netstats", NULL },
10933 iax2_show_netstats, "List active IAX channel netstats",
10934 show_netstats_usage, NULL, },
10935
10936 { { "iax2", "show", "peers", NULL },
10937 iax2_show_peers, "List defined IAX peers",
10938 show_peers_usage, NULL, },
10939
10940 { { "iax2", "show", "registry", NULL },
10941 iax2_show_registry, "Display IAX registration status",
10942 show_reg_usage, NULL, },
10943
10944 { { "iax2", "show", "stats", NULL },
10945 iax2_show_stats, "Display IAX statistics",
10946 show_stats_usage, NULL, },
10947
10948 { { "iax2", "show", "threads", NULL },
10949 iax2_show_threads, "Display IAX helper thread info",
10950 show_threads_usage, NULL, },
10951
10952 { { "iax2", "show", "users", NULL },
10953 iax2_show_users, "List defined IAX users",
10954 show_users_usage, NULL, },
10955
10956 { { "iax2", "prune", "realtime", NULL },
10957 iax2_prune_realtime, "Prune a cached realtime lookup",
10958 prune_realtime_usage, complete_iax2_show_peer },
10959
10960 { { "iax2", "reload", NULL },
10961 iax2_reload, "Reload IAX configuration",
10962 iax2_reload_usage },
10963
10964 { { "iax2", "show", "peer", NULL },
10965 iax2_show_peer, "Show details on specific IAX peer",
10966 show_peer_usage, complete_iax2_show_peer },
10967
10968 { { "iax2", "set", "debug", NULL },
10969 iax2_do_debug, "Enable IAX debugging",
10970 debug_usage },
10971
10972 { { "iax2", "set", "debug", "trunk", NULL },
10973 iax2_do_trunk_debug, "Enable IAX trunk debugging",
10974 debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10975
10976 { { "iax2", "set", "debug", "jb", NULL },
10977 iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10978 debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10979
10980 { { "iax2", "set", "debug", "off", NULL },
10981 iax2_no_debug, "Disable IAX debugging",
10982 no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10983
10984 { { "iax2", "set", "debug", "trunk", "off", NULL },
10985 iax2_no_trunk_debug, "Disable IAX trunk debugging",
10986 no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10987
10988 { { "iax2", "set", "debug", "jb", "off", NULL },
10989 iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10990 no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10991
10992 { { "iax2", "test", "losspct", NULL },
10993 iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10994 iax2_test_losspct_usage },
10995
10996 { { "iax2", "provision", NULL },
10997 iax2_prov_cmd, "Provision an IAX device",
10998 show_prov_usage, iax2_prov_complete_template_3rd },
10999
11000 #ifdef IAXTESTS
11001 { { "iax2", "test", "late", NULL },
11002 iax2_test_late, "Test the receipt of a late frame",
11003 iax2_test_late_usage },
11004
11005 { { "iax2", "test", "resync", NULL },
11006 iax2_test_resync, "Test a resync in received timestamps",
11007 iax2_test_resync_usage },
11008
11009 { { "iax2", "test", "jitter", NULL },
11010 iax2_test_jitter, "Simulates jitter for testing",
11011 iax2_test_jitter_usage },
11012 #endif
11013 };
11014
11015 static int __unload_module(void)
11016 {
11017 struct iax2_thread *thread = NULL;
11018 int x;
11019
11020
11021
11022
11023
11024 if (netthreadid != AST_PTHREADT_NULL) {
11025 AST_LIST_LOCK(&iaxq.queue);
11026 ast_mutex_lock(&sched_lock);
11027 pthread_cancel(netthreadid);
11028 ast_cond_signal(&sched_cond);
11029 ast_mutex_unlock(&sched_lock);
11030 AST_LIST_UNLOCK(&iaxq.queue);
11031 pthread_join(netthreadid, NULL);
11032 }
11033 if (schedthreadid != AST_PTHREADT_NULL) {
11034 ast_mutex_lock(&sched_lock);
11035 pthread_cancel(schedthreadid);
11036 ast_cond_signal(&sched_cond);
11037 ast_mutex_unlock(&sched_lock);
11038 pthread_join(schedthreadid, NULL);
11039 }
11040
11041
11042 AST_LIST_LOCK(&idle_list);
11043 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
11044 AST_LIST_REMOVE_CURRENT(&idle_list, list);
11045 pthread_cancel(thread->threadid);
11046 }
11047 AST_LIST_TRAVERSE_SAFE_END
11048 AST_LIST_UNLOCK(&idle_list);
11049
11050 AST_LIST_LOCK(&active_list);
11051 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
11052 AST_LIST_REMOVE_CURRENT(&active_list, list);
11053 pthread_cancel(thread->threadid);
11054 }
11055 AST_LIST_TRAVERSE_SAFE_END
11056 AST_LIST_UNLOCK(&active_list);
11057
11058 AST_LIST_LOCK(&dynamic_list);
11059 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
11060 AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
11061 pthread_cancel(thread->threadid);
11062 }
11063 AST_LIST_TRAVERSE_SAFE_END
11064 AST_LIST_UNLOCK(&dynamic_list);
11065
11066 AST_LIST_HEAD_DESTROY(&iaxq.queue);
11067
11068
11069 while(0 < iaxactivethreadcount)
11070 usleep(10000);
11071
11072 ast_netsock_release(netsock);
11073 ast_netsock_release(outsock);
11074 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11075 if (iaxs[x]) {
11076 iax2_destroy(x);
11077 }
11078 }
11079 ast_manager_unregister( "IAXpeers" );
11080 ast_manager_unregister( "IAXnetstats" );
11081 ast_unregister_application(papp);
11082 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11083 ast_unregister_switch(&iax2_switch);
11084 ast_channel_unregister(&iax2_tech);
11085 delete_users();
11086 iax_provision_unload();
11087 sched_context_destroy(sched);
11088 reload_firmware(1);
11089
11090 ast_mutex_destroy(&waresl.lock);
11091
11092 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11093 ast_mutex_destroy(&iaxsl[x]);
11094 }
11095
11096 ao2_ref(peers, -1);
11097 ao2_ref(users, -1);
11098 ao2_ref(iax_peercallno_pvts, -1);
11099
11100 return 0;
11101 }
11102
11103 static int unload_module(void)
11104 {
11105 ast_custom_function_unregister(&iaxpeer_function);
11106 return __unload_module();
11107 }
11108
11109 static int peer_set_sock_cb(void *obj, void *arg, int flags)
11110 {
11111 struct iax2_peer *peer = obj;
11112
11113 if (peer->sockfd < 0)
11114 peer->sockfd = defaultsockfd;
11115
11116 return 0;
11117 }
11118
11119 static int pvt_hash_cb(const void *obj, const int flags)
11120 {
11121 const struct chan_iax2_pvt *pvt = obj;
11122
11123 return pvt->peercallno;
11124 }
11125
11126 static int pvt_cmp_cb(void *obj, void *arg, int flags)
11127 {
11128 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
11129
11130
11131
11132
11133 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
11134 pvt2->frames_received) ? CMP_MATCH : 0;
11135 }
11136
11137
11138 static int load_module(void)
11139 {
11140 char *config = "iax.conf";
11141 int res = 0;
11142 int x;
11143 struct iax2_registry *reg = NULL;
11144
11145 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
11146 if (!peers)
11147 return AST_MODULE_LOAD_FAILURE;
11148 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
11149 if (!users) {
11150 ao2_ref(peers, -1);
11151 return AST_MODULE_LOAD_FAILURE;
11152 }
11153 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
11154 if (!iax_peercallno_pvts) {
11155 ao2_ref(peers, -1);
11156 ao2_ref(users, -1);
11157 return AST_MODULE_LOAD_FAILURE;
11158 }
11159
11160 ast_custom_function_register(&iaxpeer_function);
11161
11162 iax_set_output(iax_debug_output);
11163 iax_set_error(iax_error_output);
11164 jb_setoutput(jb_error_output, jb_warning_output, NULL);
11165
11166 #ifdef HAVE_ZAPTEL
11167 #ifdef ZT_TIMERACK
11168 timingfd = open("/dev/zap/timer", O_RDWR);
11169 if (timingfd < 0)
11170 #endif
11171 timingfd = open("/dev/zap/pseudo", O_RDWR);
11172 if (timingfd < 0)
11173 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
11174 #endif
11175
11176 memset(iaxs, 0, sizeof(iaxs));
11177
11178 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
11179 ast_mutex_init(&iaxsl[x]);
11180 }
11181
11182 ast_cond_init(&sched_cond, NULL);
11183
11184 io = io_context_create();
11185 sched = sched_context_create();
11186
11187 if (!io || !sched) {
11188 ast_log(LOG_ERROR, "Out of memory\n");
11189 return -1;
11190 }
11191
11192 netsock = ast_netsock_list_alloc();
11193 if (!netsock) {
11194 ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
11195 return -1;
11196 }
11197 ast_netsock_init(netsock);
11198
11199 outsock = ast_netsock_list_alloc();
11200 if (!outsock) {
11201 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11202 return -1;
11203 }
11204 ast_netsock_init(outsock);
11205
11206 ast_mutex_init(&waresl.lock);
11207
11208 AST_LIST_HEAD_INIT(&iaxq.queue);
11209
11210 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
11211
11212 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
11213
11214 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
11215 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
11216
11217 if(set_config(config, 0) == -1)
11218 return AST_MODULE_LOAD_DECLINE;
11219
11220 if (ast_channel_register(&iax2_tech)) {
11221 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
11222 __unload_module();
11223 return -1;
11224 }
11225
11226 if (ast_register_switch(&iax2_switch))
11227 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
11228
11229 res = start_network_thread();
11230 if (!res) {
11231 if (option_verbose > 1)
11232 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
11233 } else {
11234 ast_log(LOG_ERROR, "Unable to start network thread\n");
11235 ast_netsock_release(netsock);
11236 ast_netsock_release(outsock);
11237 }
11238
11239 AST_LIST_LOCK(®istrations);
11240 AST_LIST_TRAVERSE(®istrations, reg, entry)
11241 iax2_do_register(reg);
11242 AST_LIST_UNLOCK(®istrations);
11243
11244 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
11245 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
11246
11247 reload_firmware(0);
11248 iax_provision_reload();
11249 return res;
11250 }
11251
11252 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
11253 .load = load_module,
11254 .unload = unload_module,
11255 .reload = reload,
11256 );