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