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