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