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 if (netthreadid != AST_PTHREADT_NULL)
02411 pthread_kill(netthreadid, SIGURG);
02412 signal_condition(&sched_lock, &sched_cond);
02413 return 0;
02414 }
02415
02416
02417
02418 static int iax2_digit_begin(struct ast_channel *c, char digit)
02419 {
02420 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
02421 }
02422
02423 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
02424 {
02425 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
02426 }
02427
02428 static int iax2_sendtext(struct ast_channel *c, const char *text)
02429 {
02430
02431 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
02432 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
02433 }
02434
02435 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
02436 {
02437 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data, img->datalen, -1);
02438 }
02439
02440 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
02441 {
02442 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
02443 }
02444
02445 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
02446 {
02447 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
02448 ast_mutex_lock(&iaxsl[callno]);
02449 if (iaxs[callno])
02450 iaxs[callno]->owner = newchan;
02451 else
02452 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
02453 ast_mutex_unlock(&iaxsl[callno]);
02454 return 0;
02455 }
02456
02457 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
02458 {
02459 struct ast_variable *var;
02460 struct ast_variable *tmp;
02461 struct iax2_peer *peer=NULL;
02462 time_t regseconds = 0, nowtime;
02463 int dynamic=0;
02464
02465 if (peername)
02466 var = ast_load_realtime("iaxpeers", "name", peername, NULL);
02467 else {
02468 char porta[25];
02469 sprintf(porta, "%d", ntohs(sin->sin_port));
02470 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, NULL);
02471 if (var) {
02472
02473 for (tmp = var; tmp; tmp = tmp->next) {
02474 if (!strcasecmp(tmp->name, "name"))
02475 peername = tmp->value;
02476 }
02477 }
02478 }
02479 if (!var)
02480 return NULL;
02481
02482 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
02483
02484 if (!peer) {
02485 ast_variables_destroy(var);
02486 return NULL;
02487 }
02488
02489 for (tmp = var; tmp; tmp = tmp->next) {
02490
02491 if (!strcasecmp(tmp->name, "type")) {
02492 if (strcasecmp(tmp->value, "friend") &&
02493 strcasecmp(tmp->value, "peer")) {
02494
02495 destroy_peer(peer);
02496 peer = NULL;
02497 break;
02498 }
02499 } else if (!strcasecmp(tmp->name, "regseconds")) {
02500 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
02501 } else if (!strcasecmp(tmp->name, "ipaddr")) {
02502 inet_aton(tmp->value, &(peer->addr.sin_addr));
02503 } else if (!strcasecmp(tmp->name, "port")) {
02504 peer->addr.sin_port = htons(atoi(tmp->value));
02505 } else if (!strcasecmp(tmp->name, "host")) {
02506 if (!strcasecmp(tmp->value, "dynamic"))
02507 dynamic = 1;
02508 }
02509 }
02510
02511 ast_variables_destroy(var);
02512
02513 if (!peer)
02514 return NULL;
02515
02516 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02517 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
02518 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
02519 if (peer->expire > -1)
02520 ast_sched_del(sched, peer->expire);
02521 peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void*)peer->name);
02522 }
02523 AST_LIST_LOCK(&peers);
02524 AST_LIST_INSERT_HEAD(&peers, peer, entry);
02525 AST_LIST_UNLOCK(&peers);
02526 if (ast_test_flag(peer, IAX_DYNAMIC))
02527 reg_source_db(peer);
02528 } else {
02529 ast_set_flag(peer, IAX_TEMPONLY);
02530 }
02531
02532 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
02533 time(&nowtime);
02534 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
02535 memset(&peer->addr, 0, sizeof(peer->addr));
02536 realtime_update_peer(peer->name, &peer->addr, 0);
02537 if (option_debug)
02538 ast_log(LOG_DEBUG, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
02539 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02540 }
02541 else {
02542 if (option_debug)
02543 ast_log(LOG_DEBUG, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
02544 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
02545 }
02546 }
02547
02548 return peer;
02549 }
02550
02551 static struct iax2_user *realtime_user(const char *username)
02552 {
02553 struct ast_variable *var;
02554 struct ast_variable *tmp;
02555 struct iax2_user *user=NULL;
02556
02557 var = ast_load_realtime("iaxusers", "name", username, NULL);
02558 if (!var)
02559 return NULL;
02560
02561 tmp = var;
02562 while(tmp) {
02563
02564 if (!strcasecmp(tmp->name, "type")) {
02565 if (strcasecmp(tmp->value, "friend") &&
02566 strcasecmp(tmp->value, "user")) {
02567 return NULL;
02568 }
02569 }
02570 tmp = tmp->next;
02571 }
02572
02573 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
02574
02575 ast_variables_destroy(var);
02576
02577 if (!user)
02578 return NULL;
02579
02580 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
02581 ast_set_flag(user, IAX_RTCACHEFRIENDS);
02582 AST_LIST_LOCK(&users);
02583 AST_LIST_INSERT_HEAD(&users, user, entry);
02584 AST_LIST_UNLOCK(&users);
02585 } else {
02586 ast_set_flag(user, IAX_TEMPONLY);
02587 }
02588
02589 return user;
02590 }
02591
02592 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
02593 {
02594 char port[10];
02595 char regseconds[20];
02596
02597 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
02598 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
02599 ast_update_realtime("iaxpeers", "name", peername,
02600 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
02601 "regseconds", regseconds, NULL);
02602 }
02603
02604 struct create_addr_info {
02605 int capability;
02606 unsigned int flags;
02607 int maxtime;
02608 int encmethods;
02609 int found;
02610 int sockfd;
02611 int adsi;
02612 char username[80];
02613 char secret[80];
02614 char outkey[80];
02615 char timezone[80];
02616 char prefs[32];
02617 char context[AST_MAX_CONTEXT];
02618 char peercontext[AST_MAX_CONTEXT];
02619 char mohinterpret[MAX_MUSICCLASS];
02620 char mohsuggest[MAX_MUSICCLASS];
02621 };
02622
02623 static int create_addr(const char *peername, struct sockaddr_in *sin, struct create_addr_info *cai)
02624 {
02625 struct ast_hostent ahp;
02626 struct hostent *hp;
02627 struct iax2_peer *peer;
02628
02629 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
02630 cai->sockfd = defaultsockfd;
02631 cai->maxtime = 0;
02632 sin->sin_family = AF_INET;
02633
02634 if (!(peer = find_peer(peername, 1))) {
02635 cai->found = 0;
02636
02637 hp = ast_gethostbyname(peername, &ahp);
02638 if (hp) {
02639 memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
02640 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
02641
02642 ast_codec_pref_convert(&prefs, cai->prefs, sizeof(cai->prefs), 1);
02643 return 0;
02644 } else {
02645 ast_log(LOG_WARNING, "No such host: %s\n", peername);
02646 return -1;
02647 }
02648 }
02649
02650 cai->found = 1;
02651
02652
02653 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
02654 if (ast_test_flag(peer, IAX_TEMPONLY))
02655 destroy_peer(peer);
02656 return -1;
02657 }
02658
02659
02660 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) {
02661 if (ast_test_flag(peer, IAX_TEMPONLY))
02662 destroy_peer(peer);
02663 return -1;
02664 }
02665
02666 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
02667 cai->maxtime = peer->maxms;
02668 cai->capability = peer->capability;
02669 cai->encmethods = peer->encmethods;
02670 cai->sockfd = peer->sockfd;
02671 cai->adsi = peer->adsi;
02672 ast_codec_pref_convert(&peer->prefs, cai->prefs, sizeof(cai->prefs), 1);
02673 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
02674 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
02675 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
02676 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
02677 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
02678 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
02679 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
02680 if (ast_strlen_zero(peer->dbsecret)) {
02681 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
02682 } else {
02683 char *family;
02684 char *key = NULL;
02685
02686 family = ast_strdupa(peer->dbsecret);
02687 key = strchr(family, '/');
02688 if (key)
02689 *key++ = '\0';
02690 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
02691 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
02692 if (ast_test_flag(peer, IAX_TEMPONLY))
02693 destroy_peer(peer);
02694 return -1;
02695 }
02696 }
02697
02698 if (peer->addr.sin_addr.s_addr) {
02699 sin->sin_addr = peer->addr.sin_addr;
02700 sin->sin_port = peer->addr.sin_port;
02701 } else {
02702 sin->sin_addr = peer->defaddr.sin_addr;
02703 sin->sin_port = peer->defaddr.sin_port;
02704 }
02705
02706 if (ast_test_flag(peer, IAX_TEMPONLY))
02707 destroy_peer(peer);
02708
02709 return 0;
02710 }
02711
02712 static void __auto_congest(void *nothing)
02713 {
02714 int callno = PTR_TO_CALLNO(nothing);
02715 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
02716 ast_mutex_lock(&iaxsl[callno]);
02717 if (iaxs[callno]) {
02718 iaxs[callno]->initid = -1;
02719 iax2_queue_frame(callno, &f);
02720 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
02721 }
02722 ast_mutex_unlock(&iaxsl[callno]);
02723 }
02724
02725 static int auto_congest(void *data)
02726 {
02727 #ifdef SCHED_MULTITHREADED
02728 if (schedule_action(__auto_congest, data))
02729 #endif
02730 __auto_congest(data);
02731 return 0;
02732 }
02733
02734 static unsigned int iax2_datetime(const char *tz)
02735 {
02736 time_t t;
02737 struct tm tm;
02738 unsigned int tmp;
02739 time(&t);
02740 localtime_r(&t, &tm);
02741 if (!ast_strlen_zero(tz))
02742 ast_localtime(&t, &tm, tz);
02743 tmp = (tm.tm_sec >> 1) & 0x1f;
02744 tmp |= (tm.tm_min & 0x3f) << 5;
02745 tmp |= (tm.tm_hour & 0x1f) << 11;
02746 tmp |= (tm.tm_mday & 0x1f) << 16;
02747 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
02748 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
02749 return tmp;
02750 }
02751
02752 struct parsed_dial_string {
02753 char *username;
02754 char *password;
02755 char *key;
02756 char *peer;
02757 char *port;
02758 char *exten;
02759 char *context;
02760 char *options;
02761 };
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
02782 {
02783 if (ast_strlen_zero(data))
02784 return;
02785
02786 pds->peer = strsep(&data, "/");
02787 pds->exten = strsep(&data, "/");
02788 pds->options = data;
02789
02790 if (pds->exten) {
02791 data = pds->exten;
02792 pds->exten = strsep(&data, "@");
02793 pds->context = data;
02794 }
02795
02796 if (strchr(pds->peer, '@')) {
02797 data = pds->peer;
02798 pds->username = strsep(&data, "@");
02799 pds->peer = data;
02800 }
02801
02802 if (pds->username) {
02803 data = pds->username;
02804 pds->username = strsep(&data, ":");
02805 pds->password = data;
02806 }
02807
02808 data = pds->peer;
02809 pds->peer = strsep(&data, ":");
02810 pds->port = data;
02811
02812
02813
02814
02815 if (pds->password && (pds->password[0] == '[')) {
02816 pds->key = ast_strip_quoted(pds->password, "[", "]");
02817 pds->password = NULL;
02818 }
02819 }
02820
02821 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
02822 {
02823 struct sockaddr_in sin;
02824 char *l=NULL, *n=NULL, *tmpstr;
02825 struct iax_ie_data ied;
02826 char *defaultrdest = "s";
02827 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
02828 struct parsed_dial_string pds;
02829 struct create_addr_info cai;
02830 struct ast_var_t *var;
02831
02832 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
02833 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
02834 return -1;
02835 }
02836
02837 memset(&cai, 0, sizeof(cai));
02838 cai.encmethods = iax2_encryption;
02839
02840 memset(&pds, 0, sizeof(pds));
02841 tmpstr = ast_strdupa(dest);
02842 parse_dial_string(tmpstr, &pds);
02843
02844 if (!pds.exten)
02845 pds.exten = defaultrdest;
02846
02847 if (create_addr(pds.peer, &sin, &cai)) {
02848 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
02849 return -1;
02850 }
02851
02852 if (!pds.username && !ast_strlen_zero(cai.username))
02853 pds.username = cai.username;
02854 if (!pds.password && !ast_strlen_zero(cai.secret))
02855 pds.password = cai.secret;
02856 if (!pds.key && !ast_strlen_zero(cai.outkey))
02857 pds.key = cai.outkey;
02858 if (!pds.context && !ast_strlen_zero(cai.peercontext))
02859 pds.context = cai.peercontext;
02860
02861
02862 ast_copy_string(c->context, cai.context, sizeof(c->context));
02863
02864 if (pds.port)
02865 sin.sin_port = htons(atoi(pds.port));
02866
02867 l = c->cid.cid_num;
02868 n = c->cid.cid_name;
02869
02870
02871 memset(&ied, 0, sizeof(ied));
02872
02873
02874 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
02875 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
02876 if (pds.options && strchr(pds.options, 'a')) {
02877
02878 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
02879 }
02880
02881 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
02882
02883 if (l) {
02884 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
02885 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
02886 } else {
02887 if (n)
02888 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
02889 else
02890 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
02891 }
02892
02893 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
02894 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
02895
02896 if (n)
02897 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
02898 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
02899 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
02900
02901 if (!ast_strlen_zero(c->language))
02902 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
02903 if (!ast_strlen_zero(c->cid.cid_dnid))
02904 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
02905 if (!ast_strlen_zero(c->cid.cid_rdnis))
02906 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
02907
02908 if (pds.context)
02909 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
02910
02911 if (pds.username)
02912 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
02913
02914 if (cai.encmethods)
02915 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
02916
02917 ast_mutex_lock(&iaxsl[callno]);
02918
02919 if (!ast_strlen_zero(c->context))
02920 ast_string_field_set(iaxs[callno], context, c->context);
02921
02922 if (pds.username)
02923 ast_string_field_set(iaxs[callno], username, pds.username);
02924
02925 iaxs[callno]->encmethods = cai.encmethods;
02926
02927 iaxs[callno]->adsi = cai.adsi;
02928
02929 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
02930 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
02931
02932 if (pds.key)
02933 ast_string_field_set(iaxs[callno], outkey, pds.key);
02934 if (pds.password)
02935 ast_string_field_set(iaxs[callno], secret, pds.password);
02936
02937 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
02938 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
02939 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
02940 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
02941
02942 if (iaxs[callno]->maxtime) {
02943
02944 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
02945 iaxs[callno]->initid = ast_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
02946 } else if (autokill) {
02947 iaxs[callno]->pingtime = autokill / 2;
02948 iaxs[callno]->initid = ast_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
02949 }
02950
02951
02952 AST_LIST_TRAVERSE(&c->varshead, var, entries) {
02953 if (!strncmp(ast_var_name(var), "~IAX2~", strlen("~IAX2~"))) {
02954 char tmp[256];
02955 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var) + strlen("~IAX2~"), ast_var_value(var));
02956 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
02957 }
02958 }
02959
02960
02961 iaxs[callno]->sockfd = cai.sockfd;
02962
02963
02964 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
02965
02966 ast_mutex_unlock(&iaxsl[callno]);
02967 ast_setstate(c, AST_STATE_RINGING);
02968
02969 return 0;
02970 }
02971
02972 static int iax2_hangup(struct ast_channel *c)
02973 {
02974 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
02975 int alreadygone;
02976 struct iax_ie_data ied;
02977 memset(&ied, 0, sizeof(ied));
02978 ast_mutex_lock(&iaxsl[callno]);
02979 if (callno && iaxs[callno]) {
02980 ast_log(LOG_DEBUG, "We're hanging up %s with cause %i now...\n", c->name, c->hangupcause);
02981 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
02982
02983 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
02984 if (!iaxs[callno]->error && !alreadygone)
02985 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
02986
02987 iax2_predestroy(callno);
02988
02989 if (alreadygone) {
02990 ast_log(LOG_DEBUG, "Really destroying %s now...\n", c->name);
02991 iax2_destroy(callno);
02992 }
02993 }
02994 ast_mutex_unlock(&iaxsl[callno]);
02995 if (option_verbose > 2)
02996 ast_verbose(VERBOSE_PREFIX_3 "Hungup '%s'\n", c->name);
02997 return 0;
02998 }
02999
03000 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03001 {
03002 struct ast_option_header *h;
03003 int res;
03004
03005 switch (option) {
03006 case AST_OPTION_TXGAIN:
03007 case AST_OPTION_RXGAIN:
03008
03009 errno = ENOSYS;
03010 return -1;
03011 default:
03012 if (!(h = ast_malloc(datalen + sizeof(*h))))
03013 return -1;
03014
03015 h->flag = AST_OPTION_FLAG_REQUEST;
03016 h->option = htons(option);
03017 memcpy(h->data, data, datalen);
03018 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03019 AST_CONTROL_OPTION, 0, (unsigned char *) h,
03020 datalen + sizeof(*h), -1);
03021 free(h);
03022 return res;
03023 }
03024 }
03025
03026 static struct ast_frame *iax2_read(struct ast_channel *c)
03027 {
03028 ast_log(LOG_NOTICE, "I should never be called!\n");
03029 return &ast_null_frame;
03030 }
03031
03032 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
03033 {
03034 int res;
03035 struct iax_ie_data ied0;
03036 struct iax_ie_data ied1;
03037 unsigned int transferid = (unsigned int)ast_random();
03038 memset(&ied0, 0, sizeof(ied0));
03039 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
03040 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
03041 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
03042
03043 memset(&ied1, 0, sizeof(ied1));
03044 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
03045 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
03046 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
03047
03048 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
03049 if (res)
03050 return -1;
03051 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
03052 if (res)
03053 return -1;
03054 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03055 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
03056 return 0;
03057 }
03058
03059 static void lock_both(unsigned short callno0, unsigned short callno1)
03060 {
03061 ast_mutex_lock(&iaxsl[callno0]);
03062 while (ast_mutex_trylock(&iaxsl[callno1])) {
03063 ast_mutex_unlock(&iaxsl[callno0]);
03064 usleep(10);
03065 ast_mutex_lock(&iaxsl[callno0]);
03066 }
03067 }
03068
03069 static void unlock_both(unsigned short callno0, unsigned short callno1)
03070 {
03071 ast_mutex_unlock(&iaxsl[callno1]);
03072 ast_mutex_unlock(&iaxsl[callno0]);
03073 }
03074
03075 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)
03076 {
03077 struct ast_channel *cs[3];
03078 struct ast_channel *who, *other;
03079 int to = -1;
03080 int res = -1;
03081 int transferstarted=0;
03082 struct ast_frame *f;
03083 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
03084 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
03085 struct timeval waittimer = {0, 0}, tv;
03086
03087 lock_both(callno0, callno1);
03088
03089 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
03090 iaxs[callno0]->bridgecallno = callno1;
03091 iaxs[callno1]->bridgecallno = callno0;
03092 }
03093 unlock_both(callno0, callno1);
03094
03095
03096 cs[0] = c0;
03097 cs[1] = c1;
03098 for (;;) {
03099
03100 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
03101 if (option_verbose > 2)
03102 ast_verbose(VERBOSE_PREFIX_3 "Can't masquerade, we're different...\n");
03103
03104 if (c0->tech == &iax2_tech) {
03105 ast_mutex_lock(&iaxsl[callno0]);
03106 iaxs[callno0]->bridgecallno = 0;
03107 ast_mutex_unlock(&iaxsl[callno0]);
03108 }
03109 if (c1->tech == &iax2_tech) {
03110 ast_mutex_lock(&iaxsl[callno1]);
03111 iaxs[callno1]->bridgecallno = 0;
03112 ast_mutex_unlock(&iaxsl[callno1]);
03113 }
03114 return AST_BRIDGE_FAILED_NOWARN;
03115 }
03116 if (c0->nativeformats != c1->nativeformats) {
03117 if (option_verbose > 2) {
03118 char buf0[255];
03119 char buf1[255];
03120 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
03121 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
03122 ast_verbose(VERBOSE_PREFIX_3 "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
03123 }
03124
03125 lock_both(callno0, callno1);
03126 iaxs[callno0]->bridgecallno = 0;
03127 iaxs[callno1]->bridgecallno = 0;
03128 unlock_both(callno0, callno1);
03129 return AST_BRIDGE_FAILED_NOWARN;
03130 }
03131
03132 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
03133
03134 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
03135 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
03136 ast_log(LOG_WARNING, "Unable to start the transfer\n");
03137 transferstarted = 1;
03138 }
03139 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
03140
03141 gettimeofday(&tv, NULL);
03142 if (ast_tvzero(waittimer)) {
03143 waittimer = tv;
03144 } else if (tv.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
03145 c0->_softhangup |= AST_SOFTHANGUP_DEV;
03146 c1->_softhangup |= AST_SOFTHANGUP_DEV;
03147 *fo = NULL;
03148 *rc = c0;
03149 res = AST_BRIDGE_COMPLETE;
03150 break;
03151 }
03152 }
03153 to = 1000;
03154 who = ast_waitfor_n(cs, 2, &to);
03155 if (timeoutms > -1) {
03156 timeoutms -= (1000 - to);
03157 if (timeoutms < 0)
03158 timeoutms = 0;
03159 }
03160 if (!who) {
03161 if (!timeoutms) {
03162 res = AST_BRIDGE_RETRY;
03163 break;
03164 }
03165 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
03166 res = AST_BRIDGE_FAILED;
03167 break;
03168 }
03169 continue;
03170 }
03171 f = ast_read(who);
03172 if (!f) {
03173 *fo = NULL;
03174 *rc = who;
03175 res = AST_BRIDGE_COMPLETE;
03176 break;
03177 }
03178 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) {
03179 *fo = f;
03180 *rc = who;
03181 res = AST_BRIDGE_COMPLETE;
03182 break;
03183 }
03184 other = (who == c0) ? c1 : c0;
03185 if ((f->frametype == AST_FRAME_VOICE) ||
03186 (f->frametype == AST_FRAME_TEXT) ||
03187 (f->frametype == AST_FRAME_VIDEO) ||
03188 (f->frametype == AST_FRAME_IMAGE) ||
03189 (f->frametype == AST_FRAME_DTMF)) {
03190
03191
03192
03193 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
03194 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
03195 *rc = who;
03196 *fo = f;
03197 res = AST_BRIDGE_COMPLETE;
03198
03199 break;
03200 }
03201
03202 ast_write(other, f);
03203 }
03204 ast_frfree(f);
03205
03206 cs[2] = cs[0];
03207 cs[0] = cs[1];
03208 cs[1] = cs[2];
03209 }
03210 lock_both(callno0, callno1);
03211 if(iaxs[callno0])
03212 iaxs[callno0]->bridgecallno = 0;
03213 if(iaxs[callno1])
03214 iaxs[callno1]->bridgecallno = 0;
03215 unlock_both(callno0, callno1);
03216 return res;
03217 }
03218
03219 static int iax2_answer(struct ast_channel *c)
03220 {
03221 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03222 if (option_debug)
03223 ast_log(LOG_DEBUG, "Answering IAX2 call\n");
03224 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
03225 }
03226
03227 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
03228 {
03229 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03230 struct chan_iax2_pvt *pvt;
03231 int res = 0;
03232
03233 if (option_debug && iaxdebug)
03234 ast_log(LOG_DEBUG, "Indicating condition %d\n", condition);
03235
03236 ast_mutex_lock(&iaxsl[callno]);
03237 pvt = iaxs[callno];
03238 if (!strcasecmp(pvt->mohinterpret, "passthrough")) {
03239 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03240 ast_mutex_unlock(&iaxsl[callno]);
03241 return res;
03242 }
03243
03244 switch (condition) {
03245 case AST_CONTROL_HOLD:
03246 ast_moh_start(c, data, pvt->mohinterpret);
03247 break;
03248 case AST_CONTROL_UNHOLD:
03249 ast_moh_stop(c);
03250 break;
03251 default:
03252 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
03253 }
03254
03255 ast_mutex_unlock(&iaxsl[callno]);
03256
03257 return res;
03258 }
03259
03260 static int iax2_transfer(struct ast_channel *c, const char *dest)
03261 {
03262 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03263 struct iax_ie_data ied;
03264 char tmp[256], *context;
03265 ast_copy_string(tmp, dest, sizeof(tmp));
03266 context = strchr(tmp, '@');
03267 if (context) {
03268 *context = '\0';
03269 context++;
03270 }
03271 memset(&ied, 0, sizeof(ied));
03272 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
03273 if (context)
03274 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
03275 if (option_debug)
03276 ast_log(LOG_DEBUG, "Transferring '%s' to '%s'\n", c->name, dest);
03277 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
03278 }
03279
03280 static int iax2_getpeertrunk(struct sockaddr_in sin)
03281 {
03282 struct iax2_peer *peer = NULL;
03283 int res = 0;
03284
03285 AST_LIST_LOCK(&peers);
03286 AST_LIST_TRAVERSE(&peers, peer, entry) {
03287 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
03288 (peer->addr.sin_port == sin.sin_port)) {
03289 res = ast_test_flag(peer, IAX_TRUNK);
03290 break;
03291 }
03292 }
03293 AST_LIST_UNLOCK(&peers);
03294
03295 return res;
03296 }
03297
03298
03299 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
03300 {
03301 struct ast_channel *tmp;
03302 struct chan_iax2_pvt *i;
03303 struct ast_variable *v = NULL;
03304
03305 if (!(i = iaxs[callno])) {
03306 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
03307 return NULL;
03308 }
03309
03310
03311 ast_mutex_unlock(&iaxsl[callno]);
03312 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);
03313 ast_mutex_lock(&iaxsl[callno]);
03314 if (!tmp)
03315 return NULL;
03316 tmp->tech = &iax2_tech;
03317
03318 tmp->nativeformats = capability;
03319 tmp->readformat = ast_best_codec(capability);
03320 tmp->writeformat = ast_best_codec(capability);
03321 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
03322
03323
03324
03325 tmp->cid.cid_num = ast_strdup(i->cid_num);
03326 tmp->cid.cid_name = ast_strdup(i->cid_name);
03327 if (!ast_strlen_zero(i->ani))
03328 tmp->cid.cid_ani = ast_strdup(i->ani);
03329 else
03330 tmp->cid.cid_ani = ast_strdup(i->cid_num);
03331 tmp->cid.cid_dnid = ast_strdup(i->dnid);
03332 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
03333 tmp->cid.cid_pres = i->calling_pres;
03334 tmp->cid.cid_ton = i->calling_ton;
03335 tmp->cid.cid_tns = i->calling_tns;
03336 if (!ast_strlen_zero(i->language))
03337 ast_string_field_set(tmp, language, i->language);
03338 if (!ast_strlen_zero(i->accountcode))
03339 ast_string_field_set(tmp, accountcode, i->accountcode);
03340 if (i->amaflags)
03341 tmp->amaflags = i->amaflags;
03342 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
03343 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
03344 if (i->adsi)
03345 tmp->adsicpe = i->peeradsicpe;
03346 else
03347 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
03348 i->owner = tmp;
03349 i->capability = capability;
03350 if (state != AST_STATE_DOWN) {
03351 if (ast_pbx_start(tmp)) {
03352 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
03353 ast_hangup(tmp);
03354 i->owner = NULL;
03355 return NULL;
03356 }
03357 }
03358
03359 for (v = i->vars ; v ; v = v->next)
03360 pbx_builtin_setvar_helper(tmp, v->name, v->value);
03361
03362 ast_module_ref(ast_module_info->self);
03363
03364 return tmp;
03365 }
03366
03367 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *tv)
03368 {
03369 unsigned long int mssincetx;
03370 long int ms, pred;
03371
03372 tpeer->trunkact = *tv;
03373 mssincetx = ast_tvdiff_ms(*tv, tpeer->lasttxtime);
03374 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
03375
03376 tpeer->txtrunktime = *tv;
03377 tpeer->lastsent = 999999;
03378 }
03379
03380 tpeer->lasttxtime = *tv;
03381
03382
03383 ms = ast_tvdiff_ms(*tv, tpeer->txtrunktime);
03384
03385 pred = tpeer->lastsent + sampms;
03386 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
03387 ms = pred;
03388
03389
03390 if (ms == tpeer->lastsent)
03391 ms = tpeer->lastsent + 1;
03392 tpeer->lastsent = ms;
03393 return ms;
03394 }
03395
03396 static unsigned int fix_peerts(struct timeval *tv, int callno, unsigned int ts)
03397 {
03398 long ms;
03399 if (ast_tvzero(iaxs[callno]->rxcore)) {
03400
03401 gettimeofday(&iaxs[callno]->rxcore, NULL);
03402
03403 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
03404 }
03405
03406 ms = ast_tvdiff_ms(*tv, iaxs[callno]->rxcore);
03407
03408 return ms + ts;
03409 }
03410
03411 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
03412 {
03413 int ms;
03414 int voice = 0;
03415 int genuine = 0;
03416 int adjust;
03417 struct timeval *delivery = NULL;
03418
03419
03420
03421
03422
03423
03424
03425
03426 if (f) {
03427 if (f->frametype == AST_FRAME_VOICE) {
03428 voice = 1;
03429 delivery = &f->delivery;
03430 } else if (f->frametype == AST_FRAME_IAX) {
03431 genuine = 1;
03432 } else if (f->frametype == AST_FRAME_CNG) {
03433 p->notsilenttx = 0;
03434 }
03435 }
03436 if (ast_tvzero(p->offset)) {
03437 gettimeofday(&p->offset, NULL);
03438
03439 p->offset.tv_usec -= p->offset.tv_usec % 20000;
03440 }
03441
03442 if (ts)
03443 return ts;
03444
03445 if (delivery && !ast_tvzero(*delivery)) {
03446 ms = ast_tvdiff_ms(*delivery, p->offset);
03447 if (option_debug > 2 && iaxdebug)
03448 ast_log(LOG_DEBUG, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
03449 } else {
03450 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
03451 if (ms < 0)
03452 ms = 0;
03453 if (voice) {
03454
03455 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474 adjust = (ms - p->nextpred);
03475 if (adjust < 0)
03476 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
03477 else if (adjust > 0)
03478 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
03479
03480 if (!p->nextpred) {
03481 p->nextpred = ms;
03482 if (p->nextpred <= p->lastsent)
03483 p->nextpred = p->lastsent + 3;
03484 }
03485 ms = p->nextpred;
03486 } else {
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
03497 ast_log(LOG_DEBUG, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
03498 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
03499
03500 if (f->samples >= 8)
03501 {
03502 int diff = ms % (f->samples / 8);
03503 if (diff)
03504 ms += f->samples/8 - diff;
03505 }
03506
03507 p->nextpred = ms;
03508 p->notsilenttx = 1;
03509 }
03510 } else {
03511
03512
03513 if (genuine) {
03514
03515 if (ms <= p->lastsent)
03516 ms = p->lastsent + 3;
03517 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
03518
03519 ms = p->lastsent + 3;
03520 }
03521 }
03522 }
03523 p->lastsent = ms;
03524 if (voice)
03525 p->nextpred = p->nextpred + f->samples / 8;
03526 return ms;
03527 }
03528
03529 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
03530 {
03531
03532
03533 int ms;
03534 #ifdef IAXTESTS
03535 int jit;
03536 #endif
03537
03538 if (ast_tvzero(p->rxcore)) {
03539 p->rxcore = ast_tvnow();
03540 if (option_debug && iaxdebug)
03541 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
03542 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
03543 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
03544 #if 1
03545 if (option_debug && iaxdebug)
03546 ast_log(LOG_DEBUG, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
03547 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
03548 #endif
03549 }
03550
03551 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
03552 #ifdef IAXTESTS
03553 if (test_jit) {
03554 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
03555 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
03556 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
03557 jit = -jit;
03558 ms += jit;
03559 }
03560 }
03561 if (test_late) {
03562 ms += test_late;
03563 test_late = 0;
03564 }
03565 #endif
03566 return ms;
03567 }
03568
03569 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
03570 {
03571 struct iax2_trunk_peer *tpeer;
03572
03573
03574 ast_mutex_lock(&tpeerlock);
03575 for (tpeer = tpeers; tpeer; tpeer = tpeer->next) {
03576
03577 if (!inaddrcmp(&tpeer->addr, sin)) {
03578 ast_mutex_lock(&tpeer->lock);
03579 break;
03580 }
03581 }
03582 if (!tpeer) {
03583 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
03584 ast_mutex_init(&tpeer->lock);
03585 tpeer->lastsent = 9999;
03586 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
03587 tpeer->trunkact = ast_tvnow();
03588 ast_mutex_lock(&tpeer->lock);
03589 tpeer->next = tpeers;
03590 tpeer->sockfd = fd;
03591 tpeers = tpeer;
03592 #ifdef SO_NO_CHECK
03593 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
03594 #endif
03595 ast_log(LOG_DEBUG, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
03596 }
03597 }
03598 ast_mutex_unlock(&tpeerlock);
03599 return tpeer;
03600 }
03601
03602 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
03603 {
03604 struct ast_frame *f;
03605 struct iax2_trunk_peer *tpeer;
03606 void *tmp, *ptr;
03607 struct ast_iax2_meta_trunk_entry *met;
03608 struct ast_iax2_meta_trunk_mini *mtm;
03609
03610 f = &fr->af;
03611 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
03612 if (tpeer) {
03613 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
03614
03615 if (tpeer->trunkdataalloc < MAX_TRUNKDATA) {
03616 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
03617 ast_mutex_unlock(&tpeer->lock);
03618 return -1;
03619 }
03620
03621 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
03622 tpeer->trunkdata = tmp;
03623 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);
03624 } else {
03625 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));
03626 ast_mutex_unlock(&tpeer->lock);
03627 return -1;
03628 }
03629 }
03630
03631
03632 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
03633 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
03634 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
03635 mtm->len = htons(f->datalen);
03636 mtm->mini.callno = htons(pvt->callno);
03637 mtm->mini.ts = htons(0xffff & fr->ts);
03638 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
03639 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
03640 } else {
03641 met = (struct ast_iax2_meta_trunk_entry *)ptr;
03642
03643 met->callno = htons(pvt->callno);
03644 met->len = htons(f->datalen);
03645
03646 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
03647 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
03648 }
03649
03650 memcpy(ptr, f->data, f->datalen);
03651 tpeer->trunkdatalen += f->datalen;
03652
03653 tpeer->calls++;
03654 ast_mutex_unlock(&tpeer->lock);
03655 }
03656 return 0;
03657 }
03658
03659 static void build_enc_keys(const unsigned char *digest, aes_encrypt_ctx *ecx, aes_decrypt_ctx *dcx)
03660 {
03661 aes_encrypt_key128(digest, ecx);
03662 aes_decrypt_key128(digest, dcx);
03663 }
03664
03665 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, aes_decrypt_ctx *dcx)
03666 {
03667 #if 0
03668
03669 int x;
03670 if (len % 16)
03671 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03672 for (x=0;x<len;x++)
03673 dst[x] = src[x] ^ 0xff;
03674 #else
03675 unsigned char lastblock[16] = { 0 };
03676 int x;
03677 while(len > 0) {
03678 aes_decrypt(src, dst, dcx);
03679 for (x=0;x<16;x++)
03680 dst[x] ^= lastblock[x];
03681 memcpy(lastblock, src, sizeof(lastblock));
03682 dst += 16;
03683 src += 16;
03684 len -= 16;
03685 }
03686 #endif
03687 }
03688
03689 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, aes_encrypt_ctx *ecx)
03690 {
03691 #if 0
03692
03693 int x;
03694 if (len % 16)
03695 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
03696 for (x=0;x<len;x++)
03697 dst[x] = src[x] ^ 0xff;
03698 #else
03699 unsigned char curblock[16] = { 0 };
03700 int x;
03701 while(len > 0) {
03702 for (x=0;x<16;x++)
03703 curblock[x] ^= src[x];
03704 aes_encrypt(curblock, dst, ecx);
03705 memcpy(curblock, dst, sizeof(curblock));
03706 dst += 16;
03707 src += 16;
03708 len -= 16;
03709 }
03710 #endif
03711 }
03712
03713 static int decode_frame(aes_decrypt_ctx *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03714 {
03715 int padding;
03716 unsigned char *workspace;
03717
03718 workspace = alloca(*datalen);
03719 memset(f, 0, sizeof(*f));
03720 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03721 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03722 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
03723 return -1;
03724
03725 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
03726
03727 padding = 16 + (workspace[15] & 0xf);
03728 if (option_debug && iaxdebug)
03729 ast_log(LOG_DEBUG, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
03730 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
03731 return -1;
03732
03733 *datalen -= padding;
03734 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03735 f->frametype = fh->type;
03736 if (f->frametype == AST_FRAME_VIDEO) {
03737 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
03738 } else {
03739 f->subclass = uncompress_subclass(fh->csub);
03740 }
03741 } else {
03742 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03743 if (option_debug && iaxdebug)
03744 ast_log(LOG_DEBUG, "Decoding mini with length %d\n", *datalen);
03745 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
03746 return -1;
03747
03748 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
03749 padding = 16 + (workspace[15] & 0x0f);
03750 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
03751 return -1;
03752 *datalen -= padding;
03753 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03754 }
03755 return 0;
03756 }
03757
03758 static int encrypt_frame(aes_encrypt_ctx *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
03759 {
03760 int padding;
03761 unsigned char *workspace;
03762 workspace = alloca(*datalen + 32);
03763 if (!workspace)
03764 return -1;
03765 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
03766 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
03767 if (option_debug && iaxdebug)
03768 ast_log(LOG_DEBUG, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
03769 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
03770 padding = 16 + (padding & 0xf);
03771 memcpy(workspace, poo, padding);
03772 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
03773 workspace[15] &= 0xf0;
03774 workspace[15] |= (padding & 0xf);
03775 if (option_debug && iaxdebug)
03776 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]);
03777 *datalen += padding;
03778 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
03779 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
03780 memcpy(poo, workspace + *datalen - 32, 32);
03781 } else {
03782 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
03783 if (option_debug && iaxdebug)
03784 ast_log(LOG_DEBUG, "Encoding mini frame with length %d\n", *datalen);
03785 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
03786 padding = 16 + (padding & 0xf);
03787 memcpy(workspace, poo, padding);
03788 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
03789 workspace[15] &= 0xf0;
03790 workspace[15] |= (padding & 0x0f);
03791 *datalen += padding;
03792 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
03793 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
03794 memcpy(poo, workspace + *datalen - 32, 32);
03795 }
03796 return 0;
03797 }
03798
03799 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
03800 {
03801 int res=-1;
03802 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
03803
03804 struct MD5Context md5;
03805 unsigned char digest[16];
03806 char *tmppw, *stringp;
03807
03808 tmppw = ast_strdupa(iaxs[callno]->secret);
03809 stringp = tmppw;
03810 while ((tmppw = strsep(&stringp, ";"))) {
03811 MD5Init(&md5);
03812 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
03813 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
03814 MD5Final(digest, &md5);
03815 build_enc_keys(digest, &iaxs[callno]->ecx, &iaxs[callno]->dcx);
03816 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03817 if (!res) {
03818 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
03819 break;
03820 }
03821 }
03822 } else
03823 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
03824 return res;
03825 }
03826
03827 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
03828 {
03829
03830
03831
03832 struct ast_iax2_full_hdr *fh;
03833 struct ast_iax2_mini_hdr *mh;
03834 struct ast_iax2_video_hdr *vh;
03835 struct {
03836 struct iax_frame fr2;
03837 unsigned char buffer[4096];
03838 } frb;
03839 struct iax_frame *fr;
03840 int res;
03841 int sendmini=0;
03842 unsigned int lastsent;
03843 unsigned int fts;
03844
03845 if (!pvt) {
03846 ast_log(LOG_WARNING, "No private structure for packet?\n");
03847 return -1;
03848 }
03849
03850 lastsent = pvt->lastsent;
03851
03852
03853 fts = calc_timestamp(pvt, ts, f);
03854
03855
03856
03857
03858 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
03859 return 0;
03860
03861
03862 if ((ast_test_flag(pvt, IAX_TRUNK) ||
03863 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
03864 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
03865 &&
03866 (f->frametype == AST_FRAME_VOICE)
03867 &&
03868 (f->subclass == pvt->svoiceformat)
03869 ) {
03870
03871 now = 1;
03872
03873 sendmini = 1;
03874 }
03875 if (((fts & 0xFFFF8000L) == (lastsent & 0xFFFF8000L)) &&
03876 (f->frametype == AST_FRAME_VIDEO) &&
03877 ((f->subclass & ~0x1) == pvt->svideoformat)) {
03878 now = 1;
03879 sendmini = 1;
03880 }
03881
03882 if (now) {
03883 fr = &frb.fr2;
03884 } else
03885 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));
03886 if (!fr) {
03887 ast_log(LOG_WARNING, "Out of memory\n");
03888 return -1;
03889 }
03890
03891 iax_frame_wrap(fr, f);
03892
03893 fr->ts = fts;
03894 fr->callno = pvt->callno;
03895 fr->transfer = transfer;
03896 fr->final = final;
03897 if (!sendmini) {
03898
03899 if (seqno > -1)
03900 fr->oseqno = seqno;
03901 else
03902 fr->oseqno = pvt->oseqno++;
03903 fr->iseqno = pvt->iseqno;
03904 fh = (struct ast_iax2_full_hdr *)(fr->af.data - sizeof(struct ast_iax2_full_hdr));
03905 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
03906 fh->ts = htonl(fr->ts);
03907 fh->oseqno = fr->oseqno;
03908 if (transfer) {
03909 fh->iseqno = 0;
03910 } else
03911 fh->iseqno = fr->iseqno;
03912
03913 if (!transfer)
03914 pvt->aseqno = fr->iseqno;
03915 fh->type = fr->af.frametype & 0xFF;
03916 if (fr->af.frametype == AST_FRAME_VIDEO)
03917 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
03918 else
03919 fh->csub = compress_subclass(fr->af.subclass);
03920 if (transfer) {
03921 fr->dcallno = pvt->transfercallno;
03922 } else
03923 fr->dcallno = pvt->peercallno;
03924 fh->dcallno = htons(fr->dcallno);
03925 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
03926 fr->data = fh;
03927 fr->retries = 0;
03928
03929 fr->retrytime = pvt->pingtime * 2;
03930 if (fr->retrytime < MIN_RETRY_TIME)
03931 fr->retrytime = MIN_RETRY_TIME;
03932 if (fr->retrytime > MAX_RETRY_TIME)
03933 fr->retrytime = MAX_RETRY_TIME;
03934
03935 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
03936 fr->retries = -1;
03937 else if (f->frametype == AST_FRAME_VOICE)
03938 pvt->svoiceformat = f->subclass;
03939 else if (f->frametype == AST_FRAME_VIDEO)
03940 pvt->svideoformat = f->subclass & ~0x1;
03941 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
03942 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
03943 if (iaxdebug) {
03944 if (fr->transfer)
03945 iax_showframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
03946 else
03947 iax_showframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
03948 }
03949 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
03950 } else
03951 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
03952 }
03953
03954 if (now) {
03955 res = send_packet(fr);
03956 } else
03957 res = iax2_transmit(fr);
03958 } else {
03959 if (ast_test_flag(pvt, IAX_TRUNK)) {
03960 iax2_trunk_queue(pvt, fr);
03961 res = 0;
03962 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
03963
03964 fr->oseqno = -1;
03965 fr->iseqno = -1;
03966 vh = (struct ast_iax2_video_hdr *)(fr->af.data - sizeof(struct ast_iax2_video_hdr));
03967 vh->zeros = 0;
03968 vh->callno = htons(0x8000 | fr->callno);
03969 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
03970 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
03971 fr->data = vh;
03972 fr->retries = -1;
03973 res = send_packet(fr);
03974 } else {
03975
03976 fr->oseqno = -1;
03977 fr->iseqno = -1;
03978
03979 mh = (struct ast_iax2_mini_hdr *)(fr->af.data - sizeof(struct ast_iax2_mini_hdr));
03980 mh->callno = htons(fr->callno);
03981 mh->ts = htons(fr->ts & 0xFFFF);
03982 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
03983 fr->data = mh;
03984 fr->retries = -1;
03985 if (pvt->transferring == TRANSFER_MEDIAPASS)
03986 fr->transfer = 1;
03987 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
03988 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
03989 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
03990 } else
03991 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
03992 }
03993 res = send_packet(fr);
03994 }
03995 }
03996 return res;
03997 }
03998
03999 static int iax2_show_users(int fd, int argc, char *argv[])
04000 {
04001 regex_t regexbuf;
04002 int havepattern = 0;
04003
04004 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
04005 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
04006
04007 struct iax2_user *user = NULL;
04008 char auth[90];
04009 char *pstr = "";
04010
04011 switch (argc) {
04012 case 5:
04013 if (!strcasecmp(argv[3], "like")) {
04014 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04015 return RESULT_SHOWUSAGE;
04016 havepattern = 1;
04017 } else
04018 return RESULT_SHOWUSAGE;
04019 case 3:
04020 break;
04021 default:
04022 return RESULT_SHOWUSAGE;
04023 }
04024
04025 ast_cli(fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
04026 AST_LIST_LOCK(&users);
04027 AST_LIST_TRAVERSE(&users, user, entry) {
04028 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
04029 continue;
04030
04031 if (!ast_strlen_zero(user->secret)) {
04032 ast_copy_string(auth,user->secret,sizeof(auth));
04033 } else if (!ast_strlen_zero(user->inkeys)) {
04034 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
04035 } else
04036 ast_copy_string(auth, "-no secret-", sizeof(auth));
04037
04038 if(ast_test_flag(user,IAX_CODEC_NOCAP))
04039 pstr = "REQ Only";
04040 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
04041 pstr = "Disabled";
04042 else
04043 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
04044
04045 ast_cli(fd, FORMAT2, user->name, auth, user->authmethods,
04046 user->contexts ? user->contexts->context : context,
04047 user->ha ? "Yes" : "No", pstr);
04048
04049 }
04050 AST_LIST_UNLOCK(&users);
04051
04052 if (havepattern)
04053 regfree(®exbuf);
04054
04055 return RESULT_SUCCESS;
04056 #undef FORMAT
04057 #undef FORMAT2
04058 }
04059
04060 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
04061 {
04062 regex_t regexbuf;
04063 int havepattern = 0;
04064 int total_peers = 0;
04065 int online_peers = 0;
04066 int offline_peers = 0;
04067 int unmonitored_peers = 0;
04068
04069 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
04070 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
04071
04072 struct iax2_peer *peer = NULL;
04073 char name[256];
04074 int registeredonly=0;
04075 char *term = manager ? "\r\n" : "\n";
04076
04077 switch (argc) {
04078 case 6:
04079 if (!strcasecmp(argv[3], "registered"))
04080 registeredonly = 1;
04081 else
04082 return RESULT_SHOWUSAGE;
04083 if (!strcasecmp(argv[4], "like")) {
04084 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
04085 return RESULT_SHOWUSAGE;
04086 havepattern = 1;
04087 } else
04088 return RESULT_SHOWUSAGE;
04089 break;
04090 case 5:
04091 if (!strcasecmp(argv[3], "like")) {
04092 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
04093 return RESULT_SHOWUSAGE;
04094 havepattern = 1;
04095 } else
04096 return RESULT_SHOWUSAGE;
04097 break;
04098 case 4:
04099 if (!strcasecmp(argv[3], "registered"))
04100 registeredonly = 1;
04101 else
04102 return RESULT_SHOWUSAGE;
04103 break;
04104 case 3:
04105 break;
04106 default:
04107 return RESULT_SHOWUSAGE;
04108 }
04109
04110
04111 if (s)
04112 astman_append(s, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
04113 else
04114 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
04115
04116 AST_LIST_LOCK(&peers);
04117 AST_LIST_TRAVERSE(&peers, peer, entry) {
04118 char nm[20];
04119 char status[20];
04120 char srch[2000];
04121 int retstatus;
04122
04123 if (registeredonly && !peer->addr.sin_addr.s_addr)
04124 continue;
04125 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
04126 continue;
04127
04128 if (!ast_strlen_zero(peer->username))
04129 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
04130 else
04131 ast_copy_string(name, peer->name, sizeof(name));
04132
04133 retstatus = peer_status(peer, status, sizeof(status));
04134 if (retstatus > 0)
04135 online_peers++;
04136 else if (!retstatus)
04137 offline_peers++;
04138 else
04139 unmonitored_peers++;
04140
04141 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
04142
04143 snprintf(srch, sizeof(srch), FORMAT, name,
04144 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04145 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04146 nm,
04147 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04148 peer->encmethods ? "(E)" : " ", status, term);
04149
04150 if (s)
04151 astman_append(s, FORMAT, name,
04152 peer->addr.sin_addr.s_addr ? ast_inet_ntoa( peer->addr.sin_addr) : "(Unspecified)",
04153 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04154 nm,
04155 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04156 peer->encmethods ? "(E)" : " ", status, term);
04157 else
04158 ast_cli(fd, FORMAT, name,
04159 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
04160 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
04161 nm,
04162 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
04163 peer->encmethods ? "(E)" : " ", status, term);
04164 total_peers++;
04165 }
04166 AST_LIST_UNLOCK(&peers);
04167
04168 if (s)
04169 astman_append(s,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04170 else
04171 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
04172
04173 if (havepattern)
04174 regfree(®exbuf);
04175
04176 return RESULT_SUCCESS;
04177 #undef FORMAT
04178 #undef FORMAT2
04179 }
04180
04181 static int iax2_show_threads(int fd, int argc, char *argv[])
04182 {
04183 struct iax2_thread *thread = NULL;
04184 time_t t;
04185 int threadcount = 0, dynamiccount = 0;
04186 char type;
04187
04188 if (argc != 3)
04189 return RESULT_SHOWUSAGE;
04190
04191 ast_cli(fd, "IAX2 Thread Information\n");
04192 time(&t);
04193 ast_cli(fd, "Idle Threads:\n");
04194 AST_LIST_LOCK(&idle_list);
04195 AST_LIST_TRAVERSE(&idle_list, thread, list) {
04196 #ifdef DEBUG_SCHED_MULTITHREAD
04197 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04198 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04199 #else
04200 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04201 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04202 #endif
04203 threadcount++;
04204 }
04205 AST_LIST_UNLOCK(&idle_list);
04206 ast_cli(fd, "Active Threads:\n");
04207 AST_LIST_LOCK(&active_list);
04208 AST_LIST_TRAVERSE(&active_list, thread, list) {
04209 if (thread->type == IAX_TYPE_DYNAMIC)
04210 type = 'D';
04211 else
04212 type = 'P';
04213 #ifdef DEBUG_SCHED_MULTITHREAD
04214 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d, func ='%s'\n",
04215 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04216 #else
04217 ast_cli(fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
04218 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04219 #endif
04220 threadcount++;
04221 }
04222 AST_LIST_UNLOCK(&active_list);
04223 ast_cli(fd, "Dynamic Threads:\n");
04224 AST_LIST_LOCK(&dynamic_list);
04225 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
04226 #ifdef DEBUG_SCHED_MULTITHREAD
04227 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d, func ='%s'\n",
04228 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
04229 #else
04230 ast_cli(fd, "Thread %d: state=%d, update=%d, actions=%d\n",
04231 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
04232 #endif
04233 dynamiccount++;
04234 }
04235 AST_LIST_UNLOCK(&dynamic_list);
04236 ast_cli(fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
04237 return RESULT_SUCCESS;
04238 }
04239
04240 static int iax2_show_peers(int fd, int argc, char *argv[])
04241 {
04242 return __iax2_show_peers(0, fd, NULL, argc, argv);
04243 }
04244 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
04245 {
04246 ast_cli_netstats(s, -1, 0);
04247 astman_append(s, "\r\n");
04248 return RESULT_SUCCESS;
04249 }
04250
04251 static int iax2_show_firmware(int fd, int argc, char *argv[])
04252 {
04253 #define FORMAT2 "%-15.15s %-15.15s %-15.15s\n"
04254 #if !defined(__FreeBSD__)
04255 #define FORMAT "%-15.15s %-15d %-15d\n"
04256 #else
04257 #define FORMAT "%-15.15s %-15d %-15d\n"
04258 #endif
04259 struct iax_firmware *cur;
04260 if ((argc != 3) && (argc != 4))
04261 return RESULT_SHOWUSAGE;
04262 ast_mutex_lock(&waresl.lock);
04263
04264 ast_cli(fd, FORMAT2, "Device", "Version", "Size");
04265 for (cur = waresl.wares;cur;cur = cur->next) {
04266 if ((argc == 3) || (!strcasecmp(argv[3], (char *)cur->fwh->devname)))
04267 ast_cli(fd, FORMAT, cur->fwh->devname, ntohs(cur->fwh->version),
04268 (int)ntohl(cur->fwh->datalen));
04269 }
04270 ast_mutex_unlock(&waresl.lock);
04271 return RESULT_SUCCESS;
04272 #undef FORMAT
04273 #undef FORMAT2
04274 }
04275
04276
04277 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
04278 {
04279 char *a[] = { "iax2", "show", "users" };
04280 int ret;
04281 const char *id = astman_get_header(m,"ActionID");
04282
04283 if (!ast_strlen_zero(id))
04284 astman_append(s, "ActionID: %s\r\n",id);
04285 ret = __iax2_show_peers(1, -1, s, 3, a );
04286 astman_append(s, "\r\n\r\n" );
04287 return ret;
04288 }
04289
04290 static char *regstate2str(int regstate)
04291 {
04292 switch(regstate) {
04293 case REG_STATE_UNREGISTERED:
04294 return "Unregistered";
04295 case REG_STATE_REGSENT:
04296 return "Request Sent";
04297 case REG_STATE_AUTHSENT:
04298 return "Auth. Sent";
04299 case REG_STATE_REGISTERED:
04300 return "Registered";
04301 case REG_STATE_REJECTED:
04302 return "Rejected";
04303 case REG_STATE_TIMEOUT:
04304 return "Timeout";
04305 case REG_STATE_NOAUTH:
04306 return "No Authentication";
04307 default:
04308 return "Unknown";
04309 }
04310 }
04311
04312 static int iax2_show_registry(int fd, int argc, char *argv[])
04313 {
04314 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
04315 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
04316 struct iax2_registry *reg = NULL;
04317
04318 char host[80];
04319 char perceived[80];
04320 if (argc != 3)
04321 return RESULT_SHOWUSAGE;
04322 ast_cli(fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
04323 AST_LIST_LOCK(®istrations);
04324 AST_LIST_TRAVERSE(®istrations, reg, entry) {
04325 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
04326 if (reg->us.sin_addr.s_addr)
04327 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
04328 else
04329 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
04330 ast_cli(fd, FORMAT, host,
04331 (reg->dnsmgr) ? "Y" : "N",
04332 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
04333 }
04334 AST_LIST_UNLOCK(®istrations);
04335 return RESULT_SUCCESS;
04336 #undef FORMAT
04337 #undef FORMAT2
04338 }
04339
04340 static int iax2_show_channels(int fd, int argc, char *argv[])
04341 {
04342 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
04343 #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"
04344 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
04345 int x;
04346 int numchans = 0;
04347
04348 if (argc != 3)
04349 return RESULT_SHOWUSAGE;
04350 ast_cli(fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
04351 for (x=0;x<IAX_MAX_CALLS;x++) {
04352 ast_mutex_lock(&iaxsl[x]);
04353 if (iaxs[x]) {
04354 int lag, jitter, localdelay;
04355 jb_info jbinfo;
04356
04357 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04358 jb_getinfo(iaxs[x]->jb, &jbinfo);
04359 jitter = jbinfo.jitter;
04360 localdelay = jbinfo.current - jbinfo.min;
04361 } else {
04362 jitter = -1;
04363 localdelay = 0;
04364 }
04365 lag = iaxs[x]->remote_rr.delay;
04366 ast_cli(fd, FORMAT,
04367 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04368 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
04369 S_OR(iaxs[x]->username, "(None)"),
04370 iaxs[x]->callno, iaxs[x]->peercallno,
04371 iaxs[x]->oseqno, iaxs[x]->iseqno,
04372 lag,
04373 jitter,
04374 localdelay,
04375 ast_getformatname(iaxs[x]->voiceformat) );
04376 numchans++;
04377 }
04378 ast_mutex_unlock(&iaxsl[x]);
04379 }
04380 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04381 return RESULT_SUCCESS;
04382 #undef FORMAT
04383 #undef FORMAT2
04384 #undef FORMATB
04385 }
04386
04387 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
04388 {
04389 int x;
04390 int numchans = 0;
04391 for (x=0;x<IAX_MAX_CALLS;x++) {
04392 ast_mutex_lock(&iaxsl[x]);
04393 if (iaxs[x]) {
04394 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
04395 char *fmt;
04396 jb_info jbinfo;
04397
04398 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
04399 jb_getinfo(iaxs[x]->jb, &jbinfo);
04400 localjitter = jbinfo.jitter;
04401 localdelay = jbinfo.current - jbinfo.min;
04402 locallost = jbinfo.frames_lost;
04403 locallosspct = jbinfo.losspct/1000;
04404 localdropped = jbinfo.frames_dropped;
04405 localooo = jbinfo.frames_ooo;
04406 } else {
04407 localjitter = -1;
04408 localdelay = 0;
04409 locallost = -1;
04410 locallosspct = -1;
04411 localdropped = 0;
04412 localooo = -1;
04413 }
04414 if (limit_fmt)
04415 fmt = "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n";
04416 else
04417 fmt = "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n";
04418 if (s)
04419
04420 astman_append(s, fmt,
04421 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04422 iaxs[x]->pingtime,
04423 localjitter,
04424 localdelay,
04425 locallost,
04426 locallosspct,
04427 localdropped,
04428 localooo,
04429 iaxs[x]->frames_received/1000,
04430 iaxs[x]->remote_rr.jitter,
04431 iaxs[x]->remote_rr.delay,
04432 iaxs[x]->remote_rr.losscnt,
04433 iaxs[x]->remote_rr.losspct,
04434 iaxs[x]->remote_rr.dropped,
04435 iaxs[x]->remote_rr.ooo,
04436 iaxs[x]->remote_rr.packets/1000);
04437 else
04438 ast_cli(fd, fmt,
04439 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
04440 iaxs[x]->pingtime,
04441 localjitter,
04442 localdelay,
04443 locallost,
04444 locallosspct,
04445 localdropped,
04446 localooo,
04447 iaxs[x]->frames_received/1000,
04448 iaxs[x]->remote_rr.jitter,
04449 iaxs[x]->remote_rr.delay,
04450 iaxs[x]->remote_rr.losscnt,
04451 iaxs[x]->remote_rr.losspct,
04452 iaxs[x]->remote_rr.dropped,
04453 iaxs[x]->remote_rr.ooo,
04454 iaxs[x]->remote_rr.packets/1000
04455 );
04456 numchans++;
04457 }
04458 ast_mutex_unlock(&iaxsl[x]);
04459 }
04460 return numchans;
04461 }
04462
04463 static int iax2_show_netstats(int fd, int argc, char *argv[])
04464 {
04465 int numchans = 0;
04466 if (argc != 3)
04467 return RESULT_SHOWUSAGE;
04468 ast_cli(fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
04469 ast_cli(fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
04470 numchans = ast_cli_netstats(NULL, fd, 1);
04471 ast_cli(fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
04472 return RESULT_SUCCESS;
04473 }
04474
04475 static int iax2_do_debug(int fd, int argc, char *argv[])
04476 {
04477 if (argc < 2 || argc > 3)
04478 return RESULT_SHOWUSAGE;
04479 iaxdebug = 1;
04480 ast_cli(fd, "IAX2 Debugging Enabled\n");
04481 return RESULT_SUCCESS;
04482 }
04483
04484 static int iax2_do_trunk_debug(int fd, int argc, char *argv[])
04485 {
04486 if (argc < 3 || argc > 4)
04487 return RESULT_SHOWUSAGE;
04488 iaxtrunkdebug = 1;
04489 ast_cli(fd, "IAX2 Trunk Debug Requested\n");
04490 return RESULT_SUCCESS;
04491 }
04492
04493 static int iax2_do_jb_debug(int fd, int argc, char *argv[])
04494 {
04495 if (argc < 3 || argc > 4)
04496 return RESULT_SHOWUSAGE;
04497 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
04498 ast_cli(fd, "IAX2 Jitterbuffer Debugging Enabled\n");
04499 return RESULT_SUCCESS;
04500 }
04501
04502 static int iax2_no_debug(int fd, int argc, char *argv[])
04503 {
04504 if (argc < 3 || argc > 4)
04505 return RESULT_SHOWUSAGE;
04506 iaxdebug = 0;
04507 ast_cli(fd, "IAX2 Debugging Disabled\n");
04508 return RESULT_SUCCESS;
04509 }
04510
04511 static int iax2_no_trunk_debug(int fd, int argc, char *argv[])
04512 {
04513 if (argc < 4 || argc > 5)
04514 return RESULT_SHOWUSAGE;
04515 iaxtrunkdebug = 0;
04516 ast_cli(fd, "IAX2 Trunk Debugging Disabled\n");
04517 return RESULT_SUCCESS;
04518 }
04519
04520 static int iax2_no_jb_debug(int fd, int argc, char *argv[])
04521 {
04522 if (argc < 4 || argc > 5)
04523 return RESULT_SHOWUSAGE;
04524 jb_setoutput(jb_error_output, jb_warning_output, NULL);
04525 jb_debug_output("\n");
04526 ast_cli(fd, "IAX2 Jitterbuffer Debugging Disabled\n");
04527 return RESULT_SUCCESS;
04528 }
04529
04530 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
04531 {
04532 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04533 int res = -1;
04534 ast_mutex_lock(&iaxsl[callno]);
04535 if (iaxs[callno]) {
04536
04537 if (!iaxs[callno]->error) {
04538 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
04539 res = 0;
04540
04541 else if (f->frametype == AST_FRAME_NULL)
04542 res = 0;
04543 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
04544 res = 0;
04545 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
04546 res = 0;
04547 else
04548
04549 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
04550 } else {
04551 ast_log(LOG_DEBUG, "Write error: %s\n", strerror(errno));
04552 }
04553 }
04554
04555 ast_mutex_unlock(&iaxsl[callno]);
04556 return res;
04557 }
04558
04559 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
04560 int now, int transfer, int final)
04561 {
04562 struct ast_frame f = { 0, };
04563
04564 f.frametype = type;
04565 f.subclass = command;
04566 f.datalen = datalen;
04567 f.src = __FUNCTION__;
04568 f.data = (void *) data;
04569
04570 return iax2_send(i, &f, ts, seqno, now, transfer, final);
04571 }
04572
04573 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04574 {
04575 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
04576 }
04577
04578 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
04579 {
04580 int res;
04581 ast_mutex_lock(&iaxsl[callno]);
04582 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
04583 ast_mutex_unlock(&iaxsl[callno]);
04584 return res;
04585 }
04586
04587 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)
04588 {
04589
04590 iax2_predestroy(i->callno);
04591 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
04592 }
04593
04594 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)
04595 {
04596 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
04597 }
04598
04599 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
04600 {
04601 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
04602 }
04603
04604 static int apply_context(struct iax2_context *con, const char *context)
04605 {
04606 while(con) {
04607 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
04608 return -1;
04609 con = con->next;
04610 }
04611 return 0;
04612 }
04613
04614
04615 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
04616 {
04617
04618 int res = -1;
04619 int version = 2;
04620 struct iax2_user *user = NULL, *best = NULL;
04621 int bestscore = 0;
04622 int gotcapability = 0;
04623 struct ast_variable *v = NULL, *tmpvar = NULL;
04624
04625 if (!iaxs[callno])
04626 return res;
04627 if (ies->called_number)
04628 ast_string_field_set(iaxs[callno], exten, ies->called_number);
04629 if (ies->calling_number) {
04630 ast_shrink_phone_number(ies->calling_number);
04631 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
04632 }
04633 if (ies->calling_name)
04634 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
04635 if (ies->calling_ani)
04636 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
04637 if (ies->dnid)
04638 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
04639 if (ies->rdnis)
04640 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
04641 if (ies->called_context)
04642 ast_string_field_set(iaxs[callno], context, ies->called_context);
04643 if (ies->language)
04644 ast_string_field_set(iaxs[callno], language, ies->language);
04645 if (ies->username)
04646 ast_string_field_set(iaxs[callno], username, ies->username);
04647 if (ies->calling_ton > -1)
04648 iaxs[callno]->calling_ton = ies->calling_ton;
04649 if (ies->calling_tns > -1)
04650 iaxs[callno]->calling_tns = ies->calling_tns;
04651 if (ies->calling_pres > -1)
04652 iaxs[callno]->calling_pres = ies->calling_pres;
04653 if (ies->format)
04654 iaxs[callno]->peerformat = ies->format;
04655 if (ies->adsicpe)
04656 iaxs[callno]->peeradsicpe = ies->adsicpe;
04657 if (ies->capability) {
04658 gotcapability = 1;
04659 iaxs[callno]->peercapability = ies->capability;
04660 }
04661 if (ies->version)
04662 version = ies->version;
04663
04664
04665 if(ies->codec_prefs) {
04666 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
04667 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
04668 }
04669
04670 if (!gotcapability)
04671 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
04672 if (version > IAX_PROTO_VERSION) {
04673 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
04674 ast_inet_ntoa(sin->sin_addr), version);
04675 return res;
04676 }
04677
04678 AST_LIST_LOCK(&users);
04679 AST_LIST_TRAVERSE(&users, user, entry) {
04680 if ((ast_strlen_zero(iaxs[callno]->username) ||
04681 !strcmp(iaxs[callno]->username, user->name))
04682 && ast_apply_ha(user->ha, sin)
04683 && (ast_strlen_zero(iaxs[callno]->context) ||
04684 apply_context(user->contexts, iaxs[callno]->context))) {
04685 if (!ast_strlen_zero(iaxs[callno]->username)) {
04686
04687 best = user;
04688 break;
04689 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->inkeys)) {
04690
04691 if (user->ha) {
04692
04693 if (bestscore < 4) {
04694 bestscore = 4;
04695 best = user;
04696 }
04697 } else {
04698
04699 if (bestscore < 3) {
04700 bestscore = 3;
04701 best = user;
04702 }
04703 }
04704 } else {
04705 if (user->ha) {
04706
04707 if (bestscore < 2) {
04708 bestscore = 2;
04709 best = user;
04710 }
04711 } else {
04712
04713 if (bestscore < 1) {
04714 bestscore = 1;
04715 best = user;
04716 }
04717 }
04718 }
04719 }
04720 }
04721 AST_LIST_UNLOCK(&users);
04722 user = best;
04723 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
04724 user = realtime_user(iaxs[callno]->username);
04725 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
04726 !apply_context(user->contexts, iaxs[callno]->context)) {
04727 destroy_user(user);
04728 user = NULL;
04729 }
04730 }
04731 if (user) {
04732
04733
04734 for (v = user->vars ; v ; v = v->next) {
04735 if((tmpvar = ast_variable_new(v->name, v->value))) {
04736 tmpvar->next = iaxs[callno]->vars;
04737 iaxs[callno]->vars = tmpvar;
04738 }
04739 }
04740
04741 if (user->maxauthreq > 0)
04742 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
04743 iaxs[callno]->prefs = user->prefs;
04744 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
04745 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
04746 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
04747 iaxs[callno]->encmethods = user->encmethods;
04748
04749 if (ast_strlen_zero(iaxs[callno]->username))
04750 ast_string_field_set(iaxs[callno], username, user->name);
04751
04752 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
04753 iaxs[callno]->capability = user->capability;
04754
04755 if (ast_strlen_zero(iaxs[callno]->context)) {
04756 if (user->contexts)
04757 ast_string_field_set(iaxs[callno], context, user->contexts->context);
04758 else
04759 ast_string_field_set(iaxs[callno], context, context);
04760 }
04761
04762 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
04763
04764 iaxs[callno]->authmethods = user->authmethods;
04765 iaxs[callno]->adsi = user->adsi;
04766
04767 if (!ast_strlen_zero(iaxs[callno]->cid_num) || !ast_strlen_zero(iaxs[callno]->cid_name)) {
04768 if (ast_test_flag(user, IAX_HASCALLERID)) {
04769 iaxs[callno]->calling_tns = 0;
04770 iaxs[callno]->calling_ton = 0;
04771 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
04772 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
04773 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
04774 }
04775 if (ast_strlen_zero(iaxs[callno]->ani))
04776 ast_string_field_set(iaxs[callno], ani, user->cid_num);
04777 } else {
04778 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
04779 }
04780 if (!ast_strlen_zero(user->accountcode))
04781 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
04782 if (!ast_strlen_zero(user->mohinterpret))
04783 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
04784 if (!ast_strlen_zero(user->mohsuggest))
04785 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
04786 if (user->amaflags)
04787 iaxs[callno]->amaflags = user->amaflags;
04788 if (!ast_strlen_zero(user->language))
04789 ast_string_field_set(iaxs[callno], language, user->language);
04790 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
04791
04792 if (!ast_strlen_zero(user->dbsecret)) {
04793 char *family, *key=NULL;
04794 char buf[80];
04795 family = ast_strdupa(user->dbsecret);
04796 key = strchr(family, '/');
04797 if (key) {
04798 *key = '\0';
04799 key++;
04800 }
04801 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
04802 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
04803 else
04804 ast_string_field_set(iaxs[callno], secret, buf);
04805 } else
04806 ast_string_field_set(iaxs[callno], secret, user->secret);
04807 if (ast_test_flag(user, IAX_TEMPONLY))
04808 destroy_user(user);
04809 res = 0;
04810 }
04811 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
04812 return res;
04813 }
04814
04815 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
04816 {
04817 struct ast_iax2_full_hdr fh;
04818 fh.scallno = htons(src | IAX_FLAG_FULL);
04819 fh.dcallno = htons(dst);
04820 fh.ts = 0;
04821 fh.oseqno = 0;
04822 fh.iseqno = 0;
04823 fh.type = AST_FRAME_IAX;
04824 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
04825 if (iaxdebug)
04826 iax_showframe(NULL, &fh, 0, sin, 0);
04827 #if 0
04828 if (option_debug)
04829 #endif
04830 ast_log(LOG_DEBUG, "Raw Hangup %s:%d, src=%d, dst=%d\n",
04831 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
04832 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
04833 }
04834
04835 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
04836 {
04837
04838 p->encmethods &= enc;
04839 if (p->encmethods) {
04840 if (p->encmethods & IAX_ENCRYPT_AES128)
04841 p->encmethods = IAX_ENCRYPT_AES128;
04842 else
04843 p->encmethods = 0;
04844 }
04845 }
04846
04847 static int authenticate_request(struct chan_iax2_pvt *p)
04848 {
04849 struct iax2_user *user = NULL;
04850 struct iax_ie_data ied;
04851 int res = -1, authreq_restrict = 0;
04852 char challenge[10];
04853
04854 memset(&ied, 0, sizeof(ied));
04855
04856
04857 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04858 AST_LIST_LOCK(&users);
04859 AST_LIST_TRAVERSE(&users, user, entry) {
04860 if (!strcmp(user->name, p->username)) {
04861 if (user->curauthreq == user->maxauthreq)
04862 authreq_restrict = 1;
04863 else
04864 user->curauthreq++;
04865 break;
04866 }
04867 }
04868 AST_LIST_UNLOCK(&users);
04869 }
04870
04871
04872 if (authreq_restrict) {
04873 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
04874 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
04875 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
04876 return 0;
04877 }
04878
04879 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
04880 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
04881 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
04882 ast_string_field_set(p, challenge, challenge);
04883
04884 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
04885 }
04886 if (p->encmethods)
04887 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
04888
04889 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
04890
04891 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
04892
04893 if (p->encmethods)
04894 ast_set_flag(p, IAX_ENCRYPTED);
04895
04896 return res;
04897 }
04898
04899 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
04900 {
04901 char requeststr[256];
04902 char md5secret[256] = "";
04903 char secret[256] = "";
04904 char rsasecret[256] = "";
04905 int res = -1;
04906 int x;
04907 struct iax2_user *user = NULL;
04908
04909 AST_LIST_LOCK(&users);
04910 AST_LIST_TRAVERSE(&users, user, entry) {
04911 if (!strcmp(user->name, p->username))
04912 break;
04913 }
04914 if (user) {
04915 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
04916 user->curauthreq--;
04917 ast_clear_flag(p, IAX_MAXAUTHREQ);
04918 }
04919 ast_string_field_set(p, host, user->name);
04920 }
04921 AST_LIST_UNLOCK(&users);
04922
04923 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
04924 return res;
04925 if (ies->password)
04926 ast_copy_string(secret, ies->password, sizeof(secret));
04927 if (ies->md5_result)
04928 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
04929 if (ies->rsa_result)
04930 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
04931 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
04932 struct ast_key *key;
04933 char *keyn;
04934 char tmpkey[256];
04935 char *stringp=NULL;
04936 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
04937 stringp=tmpkey;
04938 keyn = strsep(&stringp, ":");
04939 while(keyn) {
04940 key = ast_key_get(keyn, AST_KEY_PUBLIC);
04941 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
04942 res = 0;
04943 break;
04944 } else if (!key)
04945 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
04946 keyn = strsep(&stringp, ":");
04947 }
04948 } else if (p->authmethods & IAX_AUTH_MD5) {
04949 struct MD5Context md5;
04950 unsigned char digest[16];
04951 char *tmppw, *stringp;
04952
04953 tmppw = ast_strdupa(p->secret);
04954 stringp = tmppw;
04955 while((tmppw = strsep(&stringp, ";"))) {
04956 MD5Init(&md5);
04957 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
04958 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04959 MD5Final(digest, &md5);
04960
04961 for (x=0;x<16;x++)
04962 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
04963 if (!strcasecmp(requeststr, md5secret)) {
04964 res = 0;
04965 break;
04966 }
04967 }
04968 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
04969 if (!strcmp(secret, p->secret))
04970 res = 0;
04971 }
04972 return res;
04973 }
04974
04975
04976 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
04977 {
04978 char requeststr[256] = "";
04979 char peer[256] = "";
04980 char md5secret[256] = "";
04981 char rsasecret[256] = "";
04982 char secret[256] = "";
04983 struct iax2_peer *p;
04984 struct ast_key *key;
04985 char *keyn;
04986 int x;
04987 int expire = 0;
04988
04989 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED);
04990
04991 if (ies->username)
04992 ast_copy_string(peer, ies->username, sizeof(peer));
04993 if (ies->password)
04994 ast_copy_string(secret, ies->password, sizeof(secret));
04995 if (ies->md5_result)
04996 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
04997 if (ies->rsa_result)
04998 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
04999 if (ies->refresh)
05000 expire = ies->refresh;
05001
05002 if (ast_strlen_zero(peer)) {
05003 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
05004 return -1;
05005 }
05006
05007
05008 p = find_peer(peer, 1);
05009
05010 if (!p) {
05011 if (authdebug)
05012 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05013 return -1;
05014 }
05015
05016 if (!ast_test_flag(p, IAX_DYNAMIC)) {
05017 if (authdebug)
05018 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
05019 if (ast_test_flag(p, IAX_TEMPONLY))
05020 destroy_peer(p);
05021 return -1;
05022 }
05023
05024 if (!ast_apply_ha(p->ha, sin)) {
05025 if (authdebug)
05026 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05027 if (ast_test_flag(p, IAX_TEMPONLY))
05028 destroy_peer(p);
05029 return -1;
05030 }
05031 if (!inaddrcmp(&p->addr, sin))
05032 ast_set_flag(&iaxs[callno]->state, IAX_STATE_UNCHANGED);
05033 ast_string_field_set(iaxs[callno], secret, p->secret);
05034 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
05035
05036 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05037 if (!ast_strlen_zero(p->inkeys)) {
05038 char tmpkeys[256];
05039 char *stringp=NULL;
05040 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
05041 stringp=tmpkeys;
05042 keyn = strsep(&stringp, ":");
05043 while(keyn) {
05044 key = ast_key_get(keyn, AST_KEY_PUBLIC);
05045 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
05046 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05047 break;
05048 } else if (!key)
05049 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
05050 keyn = strsep(&stringp, ":");
05051 }
05052 if (!keyn) {
05053 if (authdebug)
05054 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
05055 if (ast_test_flag(p, IAX_TEMPONLY))
05056 destroy_peer(p);
05057 return -1;
05058 }
05059 } else {
05060 if (authdebug)
05061 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
05062 if (ast_test_flag(p, IAX_TEMPONLY))
05063 destroy_peer(p);
05064 return -1;
05065 }
05066 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
05067 struct MD5Context md5;
05068 unsigned char digest[16];
05069 char *tmppw, *stringp;
05070
05071 tmppw = ast_strdupa(p->secret);
05072 stringp = tmppw;
05073 while((tmppw = strsep(&stringp, ";"))) {
05074 MD5Init(&md5);
05075 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
05076 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
05077 MD5Final(digest, &md5);
05078 for (x=0;x<16;x++)
05079 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
05080 if (!strcasecmp(requeststr, md5secret))
05081 break;
05082 }
05083 if (tmppw) {
05084 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05085 } else {
05086 if (authdebug)
05087 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
05088 if (ast_test_flag(p, IAX_TEMPONLY))
05089 destroy_peer(p);
05090 return -1;
05091 }
05092 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
05093
05094 if (strcmp(secret, p->secret)) {
05095 if (authdebug)
05096 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
05097 if (ast_test_flag(p, IAX_TEMPONLY))
05098 destroy_peer(p);
05099 return -1;
05100 } else
05101 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
05102 } else if (!ast_strlen_zero(md5secret) || !ast_strlen_zero(secret)) {
05103 if (authdebug)
05104 ast_log(LOG_NOTICE, "Inappropriate authentication received\n");
05105 if (ast_test_flag(p, IAX_TEMPONLY))
05106 destroy_peer(p);
05107 return -1;
05108 }
05109 ast_string_field_set(iaxs[callno], peer, peer);
05110
05111 if (expire && (expire < iaxs[callno]->expiry))
05112 iaxs[callno]->expiry = expire;
05113
05114 ast_device_state_changed("IAX2/%s", p->name);
05115
05116 if (ast_test_flag(p, IAX_TEMPONLY))
05117 destroy_peer(p);
05118 return 0;
05119
05120 }
05121
05122 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)
05123 {
05124 int res = -1;
05125 int x;
05126 if (!ast_strlen_zero(keyn)) {
05127 if (!(authmethods & IAX_AUTH_RSA)) {
05128 if (ast_strlen_zero(secret))
05129 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));
05130 } else if (ast_strlen_zero(challenge)) {
05131 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
05132 } else {
05133 char sig[256];
05134 struct ast_key *key;
05135 key = ast_key_get(keyn, AST_KEY_PRIVATE);
05136 if (!key) {
05137 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
05138 } else {
05139 if (ast_sign(key, (char*)challenge, sig)) {
05140 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
05141 res = -1;
05142 } else {
05143 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
05144 res = 0;
05145 }
05146 }
05147 }
05148 }
05149
05150 if (res && !ast_strlen_zero(secret)) {
05151 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
05152 struct MD5Context md5;
05153 unsigned char digest[16];
05154 char digres[128];
05155 MD5Init(&md5);
05156 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
05157 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
05158 MD5Final(digest, &md5);
05159
05160 for (x=0;x<16;x++)
05161 sprintf(digres + (x << 1), "%2.2x", digest[x]);
05162 if (ecx && dcx)
05163 build_enc_keys(digest, ecx, dcx);
05164 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
05165 res = 0;
05166 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
05167 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
05168 res = 0;
05169 } else
05170 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
05171 }
05172 return res;
05173 }
05174
05175 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
05176 {
05177 struct iax2_peer *peer = NULL;
05178
05179 int res = -1;
05180 int authmethods = 0;
05181 struct iax_ie_data ied;
05182
05183 memset(&ied, 0, sizeof(ied));
05184
05185 if (ies->username)
05186 ast_string_field_set(p, username, ies->username);
05187 if (ies->challenge)
05188 ast_string_field_set(p, challenge, ies->challenge);
05189 if (ies->authmethods)
05190 authmethods = ies->authmethods;
05191 if (authmethods & IAX_AUTH_MD5)
05192 merge_encryption(p, ies->encmethods);
05193 else
05194 p->encmethods = 0;
05195
05196
05197 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
05198
05199 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05200 } else {
05201 AST_LIST_LOCK(&peers);
05202 AST_LIST_TRAVERSE(&peers, peer, entry) {
05203 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
05204
05205 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
05206
05207 && (!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)))
05208
05209 ) {
05210 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05211 if (!res)
05212 break;
05213 }
05214 }
05215 AST_LIST_UNLOCK(&peers);
05216 if (!peer) {
05217
05218
05219 if ((peer = realtime_peer(p->peer, NULL))) {
05220 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
05221 if (ast_test_flag(peer, IAX_TEMPONLY))
05222 destroy_peer(peer);
05223 }
05224 }
05225 }
05226 if (ies->encmethods)
05227 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
05228 if (!res)
05229 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
05230 return res;
05231 }
05232
05233 static int iax2_do_register(struct iax2_registry *reg);
05234
05235 static void __iax2_do_register_s(void *data)
05236 {
05237 struct iax2_registry *reg = data;
05238 reg->expire = -1;
05239 iax2_do_register(reg);
05240 }
05241
05242 static int iax2_do_register_s(void *data)
05243 {
05244 #ifdef SCHED_MULTITHREADED
05245 if (schedule_action(__iax2_do_register_s, data))
05246 #endif
05247 __iax2_do_register_s(data);
05248 return 0;
05249 }
05250
05251 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05252 {
05253 int newcall = 0;
05254 char newip[256];
05255 struct iax_ie_data ied;
05256 struct sockaddr_in new;
05257
05258
05259 memset(&ied, 0, sizeof(ied));
05260 if (ies->apparent_addr)
05261 bcopy(ies->apparent_addr, &new, sizeof(new));
05262 if (ies->callno)
05263 newcall = ies->callno;
05264 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
05265 ast_log(LOG_WARNING, "Invalid transfer request\n");
05266 return -1;
05267 }
05268 pvt->transfercallno = newcall;
05269 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
05270 inet_aton(newip, &pvt->transfer.sin_addr);
05271 pvt->transfer.sin_family = AF_INET;
05272 pvt->transferring = TRANSFER_BEGIN;
05273 pvt->transferid = ies->transferid;
05274 if (ies->transferid)
05275 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
05276 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
05277 return 0;
05278 }
05279
05280 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
05281 {
05282 char exten[256] = "";
05283 int status = CACHE_FLAG_UNKNOWN;
05284 int expiry = iaxdefaultdpcache;
05285 int x;
05286 int matchmore = 0;
05287 struct iax2_dpcache *dp, *prev;
05288
05289 if (ies->called_number)
05290 ast_copy_string(exten, ies->called_number, sizeof(exten));
05291
05292 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
05293 status = CACHE_FLAG_EXISTS;
05294 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
05295 status = CACHE_FLAG_CANEXIST;
05296 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
05297 status = CACHE_FLAG_NONEXISTENT;
05298
05299 if (ies->dpstatus & IAX_DPSTATUS_IGNOREPAT) {
05300
05301 }
05302 if (ies->refresh)
05303 expiry = ies->refresh;
05304 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
05305 matchmore = CACHE_FLAG_MATCHMORE;
05306 ast_mutex_lock(&dpcache_lock);
05307 prev = NULL;
05308 dp = pvt->dpentries;
05309 while(dp) {
05310 if (!strcmp(dp->exten, exten)) {
05311
05312 if (prev)
05313 prev->peer = dp->peer;
05314 else
05315 pvt->dpentries = dp->peer;
05316 dp->peer = NULL;
05317 dp->callno = 0;
05318 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
05319 if (dp->flags & CACHE_FLAG_PENDING) {
05320 dp->flags &= ~CACHE_FLAG_PENDING;
05321 dp->flags |= status;
05322 dp->flags |= matchmore;
05323 }
05324
05325 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
05326 if (dp->waiters[x] > -1)
05327 write(dp->waiters[x], "asdf", 4);
05328 }
05329 prev = dp;
05330 dp = dp->peer;
05331 }
05332 ast_mutex_unlock(&dpcache_lock);
05333 return 0;
05334 }
05335
05336 static int complete_transfer(int callno, struct iax_ies *ies)
05337 {
05338 int peercallno = 0;
05339 struct chan_iax2_pvt *pvt = iaxs[callno];
05340 struct iax_frame *cur;
05341 jb_frame frame;
05342
05343 if (ies->callno)
05344 peercallno = ies->callno;
05345
05346 if (peercallno < 1) {
05347 ast_log(LOG_WARNING, "Invalid transfer request\n");
05348 return -1;
05349 }
05350 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
05351 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
05352
05353 pvt->oseqno = 0;
05354 pvt->rseqno = 0;
05355 pvt->iseqno = 0;
05356 pvt->aseqno = 0;
05357 pvt->peercallno = peercallno;
05358 pvt->transferring = TRANSFER_NONE;
05359 pvt->svoiceformat = -1;
05360 pvt->voiceformat = 0;
05361 pvt->svideoformat = -1;
05362 pvt->videoformat = 0;
05363 pvt->transfercallno = -1;
05364 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
05365 memset(&pvt->offset, 0, sizeof(pvt->offset));
05366
05367 while(jb_getall(pvt->jb,&frame) == JB_OK)
05368 iax2_frame_free(frame.data);
05369 jb_reset(pvt->jb);
05370 pvt->lag = 0;
05371 pvt->last = 0;
05372 pvt->lastsent = 0;
05373 pvt->nextpred = 0;
05374 pvt->pingtime = DEFAULT_RETRY_TIME;
05375 AST_LIST_LOCK(&iaxq.queue);
05376 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
05377
05378
05379
05380 if (callno == cur->callno)
05381 cur->retries = -1;
05382 }
05383 AST_LIST_UNLOCK(&iaxq.queue);
05384 return 0;
05385 }
05386
05387
05388 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
05389 {
05390 struct iax2_registry *reg;
05391
05392 char peer[256] = "";
05393 char msgstatus[60];
05394 int refresh = 60;
05395 char ourip[256] = "<Unspecified>";
05396 struct sockaddr_in oldus;
05397 struct sockaddr_in us;
05398 int oldmsgs;
05399
05400 memset(&us, 0, sizeof(us));
05401 if (ies->apparent_addr)
05402 bcopy(ies->apparent_addr, &us, sizeof(us));
05403 if (ies->username)
05404 ast_copy_string(peer, ies->username, sizeof(peer));
05405 if (ies->refresh)
05406 refresh = ies->refresh;
05407 if (ies->calling_number) {
05408
05409 }
05410 reg = iaxs[callno]->reg;
05411 if (!reg) {
05412 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
05413 return -1;
05414 }
05415 memcpy(&oldus, ®->us, sizeof(oldus));
05416 oldmsgs = reg->messages;
05417 if (inaddrcmp(®->addr, sin)) {
05418 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05419 return -1;
05420 }
05421 memcpy(®->us, &us, sizeof(reg->us));
05422 if (ies->msgcount >= 0)
05423 reg->messages = ies->msgcount & 0xffff;
05424
05425
05426
05427 reg->refresh = refresh;
05428 if (reg->expire > -1)
05429 ast_sched_del(sched, reg->expire);
05430 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
05431 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
05432 if (option_verbose > 2) {
05433 if (reg->messages > 255)
05434 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
05435 else if (reg->messages > 1)
05436 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
05437 else if (reg->messages > 0)
05438 snprintf(msgstatus, sizeof(msgstatus), " with 1 new message waiting\n");
05439 else
05440 snprintf(msgstatus, sizeof(msgstatus), " with no messages waiting\n");
05441 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05442 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
05443 }
05444 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelDriver: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
05445 }
05446 reg->regstate = REG_STATE_REGISTERED;
05447 return 0;
05448 }
05449
05450 static int iax2_register(char *value, int lineno)
05451 {
05452 struct iax2_registry *reg;
05453 char copy[256];
05454 char *username, *hostname, *secret;
05455 char *porta;
05456 char *stringp=NULL;
05457
05458 if (!value)
05459 return -1;
05460 ast_copy_string(copy, value, sizeof(copy));
05461 stringp=copy;
05462 username = strsep(&stringp, "@");
05463 hostname = strsep(&stringp, "@");
05464 if (!hostname) {
05465 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
05466 return -1;
05467 }
05468 stringp=username;
05469 username = strsep(&stringp, ":");
05470 secret = strsep(&stringp, ":");
05471 stringp=hostname;
05472 hostname = strsep(&stringp, ":");
05473 porta = strsep(&stringp, ":");
05474
05475 if (porta && !atoi(porta)) {
05476 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
05477 return -1;
05478 }
05479 if (!(reg = ast_calloc(1, sizeof(*reg))))
05480 return -1;
05481 if (ast_dnsmgr_lookup(hostname, ®->addr.sin_addr, ®->dnsmgr) < 0) {
05482 free(reg);
05483 return -1;
05484 }
05485 ast_copy_string(reg->username, username, sizeof(reg->username));
05486 if (secret)
05487 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
05488 reg->expire = -1;
05489 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
05490 reg->addr.sin_family = AF_INET;
05491 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
05492 AST_LIST_LOCK(®istrations);
05493 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
05494 AST_LIST_UNLOCK(®istrations);
05495
05496 return 0;
05497 }
05498
05499 static void register_peer_exten(struct iax2_peer *peer, int onoff)
05500 {
05501 char multi[256];
05502 char *stringp, *ext;
05503 if (!ast_strlen_zero(regcontext)) {
05504 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
05505 stringp = multi;
05506 while((ext = strsep(&stringp, "&"))) {
05507 if (onoff) {
05508 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
05509 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
05510 "Noop", ast_strdup(peer->name), ast_free, "IAX2");
05511 } else
05512 ast_context_remove_extension(regcontext, ext, 1, NULL);
05513 }
05514 }
05515 }
05516 static void prune_peers(void);
05517
05518 static void __expire_registry(void *data)
05519 {
05520 char *name = data;
05521 struct iax2_peer *p = NULL;
05522
05523
05524 AST_LIST_LOCK(&peers);
05525 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, p, entry) {
05526 if (!strcasecmp(p->name, name)) {
05527 p->expire = -1;
05528 break;
05529 }
05530 }
05531 AST_LIST_TRAVERSE_SAFE_END
05532 AST_LIST_UNLOCK(&peers);
05533
05534
05535 if (!p)
05536 return;
05537
05538 ast_log(LOG_DEBUG, "Expiring registration for peer '%s'\n", p->name);
05539 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
05540 realtime_update_peer(p->name, &p->addr, 0);
05541 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", p->name);
05542
05543 memset(&p->addr, 0, sizeof(p->addr));
05544
05545 p->expiry = min_reg_expire;
05546 if (!ast_test_flag(p, IAX_TEMPONLY))
05547 ast_db_del("IAX/Registry", p->name);
05548 register_peer_exten(p, 0);
05549 ast_device_state_changed("IAX2/%s", p->name);
05550 if (iax2_regfunk)
05551 iax2_regfunk(p->name, 0);
05552
05553 if (ast_test_flag(p, IAX_RTAUTOCLEAR)) {
05554 ast_set_flag(p, IAX_DELME);
05555 prune_peers();
05556 }
05557 }
05558
05559 static int expire_registry(void *data)
05560 {
05561 #ifdef SCHED_MULTITHREADED
05562 if (schedule_action(__expire_registry, data))
05563 #endif
05564 __expire_registry(data);
05565 return 0;
05566 }
05567
05568 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
05569
05570 static void reg_source_db(struct iax2_peer *p)
05571 {
05572 char data[80];
05573 struct in_addr in;
05574 char *c, *d;
05575 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
05576 c = strchr(data, ':');
05577 if (c) {
05578 *c = '\0';
05579 c++;
05580 if (inet_aton(data, &in)) {
05581 d = strchr(c, ':');
05582 if (d) {
05583 *d = '\0';
05584 d++;
05585 if (option_verbose > 2)
05586 ast_verbose(VERBOSE_PREFIX_3 "Seeding '%s' at %s:%d for %d\n", p->name,
05587 ast_inet_ntoa(in), atoi(c), atoi(d));
05588 iax2_poke_peer(p, 0);
05589 p->expiry = atoi(d);
05590 memset(&p->addr, 0, sizeof(p->addr));
05591 p->addr.sin_family = AF_INET;
05592 p->addr.sin_addr = in;
05593 p->addr.sin_port = htons(atoi(c));
05594 if (p->expire > -1)
05595 ast_sched_del(sched, p->expire);
05596 ast_device_state_changed("IAX2/%s", p->name);
05597 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
05598 if (iax2_regfunk)
05599 iax2_regfunk(p->name, 1);
05600 register_peer_exten(p, 1);
05601 }
05602
05603 }
05604 }
05605 }
05606 }
05607
05608 static int update_registry(const char *name, struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
05609 {
05610
05611 struct iax_ie_data ied;
05612 struct iax2_peer *p;
05613 int msgcount;
05614 char data[80];
05615 int version;
05616
05617 memset(&ied, 0, sizeof(ied));
05618
05619
05620 if (!(p = find_peer(name, 1))) {
05621 ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05622 return -1;
05623 }
05624
05625 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
05626 if (sin->sin_addr.s_addr) {
05627 time_t nowtime;
05628 time(&nowtime);
05629 realtime_update_peer(name, sin, nowtime);
05630 } else {
05631 realtime_update_peer(name, sin, 0);
05632 }
05633 }
05634 if (inaddrcmp(&p->addr, sin)) {
05635 if (iax2_regfunk)
05636 iax2_regfunk(p->name, 1);
05637
05638 memcpy(&p->addr, sin, sizeof(p->addr));
05639 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
05640 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
05641 ast_db_put("IAX/Registry", p->name, data);
05642 if (option_verbose > 2)
05643 ast_verbose(VERBOSE_PREFIX_3 "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
05644 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
05645 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
05646 register_peer_exten(p, 1);
05647 ast_device_state_changed("IAX2/%s", p->name);
05648 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
05649 if (option_verbose > 2)
05650 ast_verbose(VERBOSE_PREFIX_3 "Unregistered IAX2 '%s' (%s)\n", p->name,
05651 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
05652 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
05653 register_peer_exten(p, 0);
05654 ast_db_del("IAX/Registry", p->name);
05655 ast_device_state_changed("IAX2/%s", p->name);
05656 }
05657
05658
05659 iax2_poke_peer(p, callno);
05660 }
05661
05662
05663 if (!iaxs[callno])
05664 return 0;
05665
05666
05667 p->sockfd = fd;
05668
05669 if (p->expire > -1)
05670 ast_sched_del(sched, p->expire);
05671
05672 if (!refresh)
05673 refresh = min_reg_expire;
05674 if (refresh > max_reg_expire) {
05675 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05676 p->name, max_reg_expire, refresh);
05677 p->expiry = max_reg_expire;
05678 } else if (refresh < min_reg_expire) {
05679 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
05680 p->name, min_reg_expire, refresh);
05681 p->expiry = min_reg_expire;
05682 } else {
05683 p->expiry = refresh;
05684 }
05685 if (p->expiry && sin->sin_addr.s_addr)
05686 p->expire = ast_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, (void *)p->name);
05687 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
05688 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
05689 if (sin->sin_addr.s_addr) {
05690 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
05691 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
05692 if (!ast_strlen_zero(p->mailbox)) {
05693 int new, old;
05694 ast_app_inboxcount(p->mailbox, &new, &old);
05695 if (new > 255)
05696 new = 255;
05697 if (old > 255)
05698 old = 255;
05699 msgcount = (old << 8) | new;
05700 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
05701 }
05702 if (ast_test_flag(p, IAX_HASCALLERID)) {
05703 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
05704 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
05705 }
05706 }
05707 version = iax_check_version(devtype);
05708 if (version)
05709 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
05710 if (ast_test_flag(p, IAX_TEMPONLY))
05711 destroy_peer(p);
05712 return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
05713 }
05714
05715 static int registry_authrequest(const char *name, int callno)
05716 {
05717 struct iax_ie_data ied;
05718 struct iax2_peer *p;
05719 char challenge[10];
05720
05721 p = find_peer(name, 1);
05722 if (p) {
05723 memset(&ied, 0, sizeof(ied));
05724 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
05725 if (p->authmethods & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
05726
05727 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
05728 ast_string_field_set(iaxs[callno], challenge, challenge);
05729
05730 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
05731 }
05732 iax_ie_append_str(&ied, IAX_IE_USERNAME, name);
05733 if (ast_test_flag(p, IAX_TEMPONLY))
05734 destroy_peer(p);
05735 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);;
05736 }
05737 ast_log(LOG_WARNING, "No such peer '%s'\n", name);
05738 return 0;
05739 }
05740
05741 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
05742 {
05743 struct iax2_registry *reg;
05744
05745 struct iax_ie_data ied;
05746 char peer[256] = "";
05747 char challenge[256] = "";
05748 int res;
05749 int authmethods = 0;
05750 if (ies->authmethods)
05751 authmethods = ies->authmethods;
05752 if (ies->username)
05753 ast_copy_string(peer, ies->username, sizeof(peer));
05754 if (ies->challenge)
05755 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
05756 memset(&ied, 0, sizeof(ied));
05757 reg = iaxs[callno]->reg;
05758 if (reg) {
05759 if (inaddrcmp(®->addr, sin)) {
05760 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
05761 return -1;
05762 }
05763 if (ast_strlen_zero(reg->secret)) {
05764 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
05765 reg->regstate = REG_STATE_NOAUTH;
05766 return -1;
05767 }
05768 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
05769 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
05770 if (reg->secret[0] == '[') {
05771 char tmpkey[256];
05772 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
05773 tmpkey[strlen(tmpkey) - 1] = '\0';
05774 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL, NULL);
05775 } else
05776 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL, NULL);
05777 if (!res) {
05778 reg->regstate = REG_STATE_AUTHSENT;
05779 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
05780 } else
05781 return -1;
05782 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
05783 } else
05784 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
05785 return -1;
05786 }
05787
05788 static void stop_stuff(int callno)
05789 {
05790 iax2_destroy_helper(iaxs[callno]);
05791 }
05792
05793 static void __auth_reject(void *nothing)
05794 {
05795
05796 int callno = (int)(long)(nothing);
05797 struct iax_ie_data ied;
05798 ast_mutex_lock(&iaxsl[callno]);
05799 if (iaxs[callno]) {
05800 memset(&ied, 0, sizeof(ied));
05801 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
05802 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
05803 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
05804 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
05805 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
05806 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
05807 }
05808 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
05809 }
05810 ast_mutex_unlock(&iaxsl[callno]);
05811 }
05812
05813 static int auth_reject(void *data)
05814 {
05815 int callno = (int)(long)(data);
05816 ast_mutex_lock(&iaxsl[callno]);
05817 if (iaxs[callno])
05818 iaxs[callno]->authid = -1;
05819 ast_mutex_unlock(&iaxsl[callno]);
05820 #ifdef SCHED_MULTITHREADED
05821 if (schedule_action(__auth_reject, data))
05822 #endif
05823 __auth_reject(data);
05824 return 0;
05825 }
05826
05827 static int auth_fail(int callno, int failcode)
05828 {
05829
05830
05831 ast_mutex_lock(&iaxsl[callno]);
05832 if (iaxs[callno]) {
05833 iaxs[callno]->authfail = failcode;
05834 if (delayreject) {
05835 if (iaxs[callno]->authid > -1)
05836 ast_sched_del(sched, iaxs[callno]->authid);
05837 iaxs[callno]->authid = ast_sched_add(sched, 1000, auth_reject, (void *)(long)callno);
05838 } else
05839 auth_reject((void *)(long)callno);
05840 }
05841 ast_mutex_unlock(&iaxsl[callno]);
05842 return 0;
05843 }
05844
05845 static void __auto_hangup(void *nothing)
05846 {
05847
05848 int callno = (int)(long)(nothing);
05849 struct iax_ie_data ied;
05850 ast_mutex_lock(&iaxsl[callno]);
05851 if (iaxs[callno]) {
05852 memset(&ied, 0, sizeof(ied));
05853 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
05854 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
05855 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
05856 }
05857 ast_mutex_unlock(&iaxsl[callno]);
05858 }
05859
05860 static int auto_hangup(void *data)
05861 {
05862 int callno = (int)(long)(data);
05863 ast_mutex_lock(&iaxsl[callno]);
05864 if (iaxs[callno]) {
05865 iaxs[callno]->autoid = -1;
05866 }
05867 ast_mutex_unlock(&iaxsl[callno]);
05868 #ifdef SCHED_MULTITHREADED
05869 if (schedule_action(__auto_hangup, data))
05870 #endif
05871 __auto_hangup(data);
05872 return 0;
05873 }
05874
05875 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
05876 {
05877 struct iax_ie_data ied;
05878
05879 if (iaxs[callno]->autoid > -1)
05880 ast_sched_del(sched, iaxs[callno]->autoid);
05881 iaxs[callno]->autoid = ast_sched_add(sched, 30000, auto_hangup, (void *)(long)callno);
05882 memset(&ied, 0, sizeof(ied));
05883 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
05884 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
05885 dp->flags |= CACHE_FLAG_TRANSMITTED;
05886 }
05887
05888 static int iax2_vnak(int callno)
05889 {
05890 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
05891 }
05892
05893 static void vnak_retransmit(int callno, int last)
05894 {
05895 struct iax_frame *f;
05896
05897 AST_LIST_LOCK(&iaxq.queue);
05898 AST_LIST_TRAVERSE(&iaxq.queue, f, list) {
05899
05900 if ((f->callno == callno) && iaxs[f->callno] &&
05901 (f->oseqno >= last)) {
05902 send_packet(f);
05903 }
05904 }
05905 AST_LIST_UNLOCK(&iaxq.queue);
05906 }
05907
05908 static void __iax2_poke_peer_s(void *data)
05909 {
05910 struct iax2_peer *peer = data;
05911 iax2_poke_peer(peer, 0);
05912 }
05913
05914 static int iax2_poke_peer_s(void *data)
05915 {
05916 struct iax2_peer *peer = data;
05917 peer->pokeexpire = -1;
05918 #ifdef SCHED_MULTITHREADED
05919 if (schedule_action(__iax2_poke_peer_s, data))
05920 #endif
05921 __iax2_poke_peer_s(data);
05922 return 0;
05923 }
05924
05925 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
05926 {
05927 int res = 0;
05928 struct iax_frame *fr;
05929 struct ast_iax2_meta_hdr *meta;
05930 struct ast_iax2_meta_trunk_hdr *mth;
05931 int calls = 0;
05932
05933
05934 fr = (struct iax_frame *)tpeer->trunkdata;
05935
05936 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
05937 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
05938 if (tpeer->trunkdatalen) {
05939
05940 meta->zeros = 0;
05941 meta->metacmd = IAX_META_TRUNK;
05942 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
05943 meta->cmddata = IAX_META_TRUNK_MINI;
05944 else
05945 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
05946 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
05947
05948 fr->direction = DIRECTION_OUTGRESS;
05949 fr->retrans = -1;
05950 fr->transfer = 0;
05951
05952 fr->data = fr->afdata;
05953 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
05954 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
05955 calls = tpeer->calls;
05956 #if 0
05957 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));
05958 #endif
05959
05960 tpeer->trunkdatalen = 0;
05961 tpeer->calls = 0;
05962 }
05963 if (res < 0)
05964 return res;
05965 return calls;
05966 }
05967
05968 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
05969 {
05970
05971 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
05972 return 1;
05973 return 0;
05974 }
05975
05976 static int timing_read(int *id, int fd, short events, void *cbdata)
05977 {
05978 char buf[1024];
05979 int res;
05980 struct iax2_trunk_peer *tpeer, *prev = NULL, *drop=NULL;
05981 int processed = 0;
05982 int totalcalls = 0;
05983 #ifdef ZT_TIMERACK
05984 int x = 1;
05985 #endif
05986 struct timeval now;
05987 if (iaxtrunkdebug)
05988 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", MAX_TRUNKDATA);
05989 gettimeofday(&now, NULL);
05990 if (events & AST_IO_PRI) {
05991 #ifdef ZT_TIMERACK
05992
05993 if (ioctl(fd, ZT_TIMERACK, &x))
05994 ast_log(LOG_WARNING, "Unable to acknowledge zap timer\n");
05995 res = 0;
05996 #endif
05997 } else {
05998
05999 res = read(fd, buf, sizeof(buf));
06000 if (res < 1) {
06001 ast_log(LOG_WARNING, "Unable to read from timing fd\n");
06002 return 1;
06003 }
06004 }
06005
06006 ast_mutex_lock(&tpeerlock);
06007 tpeer = tpeers;
06008 while(tpeer) {
06009 processed++;
06010 res = 0;
06011 ast_mutex_lock(&tpeer->lock);
06012
06013
06014 if (!drop && iax2_trunk_expired(tpeer, &now)) {
06015
06016
06017 if (prev)
06018 prev->next = tpeer->next;
06019 else
06020 tpeers = tpeer->next;
06021 drop = tpeer;
06022 } else {
06023 res = send_trunk(tpeer, &now);
06024 if (iaxtrunkdebug)
06025 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);
06026 }
06027 totalcalls += res;
06028 res = 0;
06029 ast_mutex_unlock(&tpeer->lock);
06030 prev = tpeer;
06031 tpeer = tpeer->next;
06032 }
06033 ast_mutex_unlock(&tpeerlock);
06034 if (drop) {
06035 ast_mutex_lock(&drop->lock);
06036
06037
06038 ast_log(LOG_DEBUG, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
06039 free(drop->trunkdata);
06040 ast_mutex_unlock(&drop->lock);
06041 ast_mutex_destroy(&drop->lock);
06042 free(drop);
06043
06044 }
06045 if (iaxtrunkdebug)
06046 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
06047 iaxtrunkdebug =0;
06048 return 1;
06049 }
06050
06051 struct dpreq_data {
06052 int callno;
06053 char context[AST_MAX_EXTENSION];
06054 char callednum[AST_MAX_EXTENSION];
06055 char *callerid;
06056 };
06057
06058 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
06059 {
06060 unsigned short dpstatus = 0;
06061 struct iax_ie_data ied1;
06062 int mm;
06063
06064 memset(&ied1, 0, sizeof(ied1));
06065 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
06066
06067 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
06068 dpstatus = IAX_DPSTATUS_EXISTS;
06069 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
06070 dpstatus = IAX_DPSTATUS_CANEXIST;
06071 } else {
06072 dpstatus = IAX_DPSTATUS_NONEXISTENT;
06073 }
06074 if (ast_ignore_pattern(context, callednum))
06075 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
06076 if (mm)
06077 dpstatus |= IAX_DPSTATUS_MATCHMORE;
06078 if (!skiplock)
06079 ast_mutex_lock(&iaxsl[callno]);
06080 if (iaxs[callno]) {
06081 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
06082 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
06083 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
06084 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
06085 }
06086 if (!skiplock)
06087 ast_mutex_unlock(&iaxsl[callno]);
06088 }
06089
06090 static void *dp_lookup_thread(void *data)
06091 {
06092
06093 struct dpreq_data *dpr = data;
06094 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
06095 if (dpr->callerid)
06096 free(dpr->callerid);
06097 free(dpr);
06098 return NULL;
06099 }
06100
06101 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
06102 {
06103 pthread_t newthread;
06104 struct dpreq_data *dpr;
06105 pthread_attr_t attr;
06106
06107 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
06108 return;
06109
06110 pthread_attr_init(&attr);
06111 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06112
06113 dpr->callno = callno;
06114 ast_copy_string(dpr->context, context, sizeof(dpr->context));
06115 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
06116 if (callerid)
06117 dpr->callerid = ast_strdup(callerid);
06118 if (ast_pthread_create(&newthread, &attr, dp_lookup_thread, dpr)) {
06119 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
06120 }
06121
06122 pthread_attr_destroy(&attr);
06123 }
06124
06125 struct iax_dual {
06126 struct ast_channel *chan1;
06127 struct ast_channel *chan2;
06128 };
06129
06130 static void *iax_park_thread(void *stuff)
06131 {
06132 struct ast_channel *chan1, *chan2;
06133 struct iax_dual *d;
06134 struct ast_frame *f;
06135 int ext;
06136 int res;
06137 d = stuff;
06138 chan1 = d->chan1;
06139 chan2 = d->chan2;
06140 free(d);
06141 f = ast_read(chan1);
06142 if (f)
06143 ast_frfree(f);
06144 res = ast_park_call(chan1, chan2, 0, &ext);
06145 ast_hangup(chan2);
06146 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
06147 return NULL;
06148 }
06149
06150 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
06151 {
06152 struct iax_dual *d;
06153 struct ast_channel *chan1m, *chan2m;
06154 pthread_t th;
06155 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
06156 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
06157 if (chan2m && chan1m) {
06158
06159 chan1m->readformat = chan1->readformat;
06160 chan1m->writeformat = chan1->writeformat;
06161 ast_channel_masquerade(chan1m, chan1);
06162
06163 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
06164 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
06165 chan1m->priority = chan1->priority;
06166
06167
06168
06169
06170 chan2m->readformat = chan2->readformat;
06171 chan2m->writeformat = chan2->writeformat;
06172 ast_channel_masquerade(chan2m, chan2);
06173
06174 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
06175 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
06176 chan2m->priority = chan2->priority;
06177 if (ast_do_masquerade(chan2m)) {
06178 ast_log(LOG_WARNING, "Masquerade failed :(\n");
06179 ast_hangup(chan2m);
06180 return -1;
06181 }
06182 } else {
06183 if (chan1m)
06184 ast_hangup(chan1m);
06185 if (chan2m)
06186 ast_hangup(chan2m);
06187 return -1;
06188 }
06189 if ((d = ast_calloc(1, sizeof(*d)))) {
06190 pthread_attr_t attr;
06191
06192 pthread_attr_init(&attr);
06193 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
06194
06195 d->chan1 = chan1m;
06196 d->chan2 = chan2m;
06197 if (!ast_pthread_create_background(&th, &attr, iax_park_thread, d)) {
06198 pthread_attr_destroy(&attr);
06199 return 0;
06200 }
06201 pthread_attr_destroy(&attr);
06202 free(d);
06203 }
06204 return -1;
06205 }
06206
06207
06208 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
06209
06210 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
06211 {
06212 unsigned int ourver;
06213 char rsi[80];
06214 snprintf(rsi, sizeof(rsi), "si-%s", si);
06215 if (iax_provision_version(&ourver, rsi, 1))
06216 return 0;
06217 if (option_debug)
06218 ast_log(LOG_DEBUG, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
06219 if (ourver != ver)
06220 iax2_provision(sin, sockfd, NULL, rsi, 1);
06221 return 0;
06222 }
06223
06224 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
06225 {
06226 jb_info stats;
06227 jb_getinfo(pvt->jb, &stats);
06228
06229 memset(iep, 0, sizeof(*iep));
06230
06231 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
06232 if(stats.frames_in == 0) stats.frames_in = 1;
06233 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
06234 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
06235 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
06236 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
06237 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
06238 }
06239
06240 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
06241 {
06242 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
06243 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
06244 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
06245 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
06246 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
06247 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
06248 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
06249 }
06250
06251 static int socket_read(int *id, int fd, short events, void *cbdata)
06252 {
06253 struct iax2_thread *thread;
06254 socklen_t len;
06255 time_t t;
06256 static time_t last_errtime=0;
06257
06258 thread = find_idle_thread();
06259 if (thread) {
06260 len = sizeof(thread->iosin);
06261 thread->iofd = fd;
06262 thread->iores = recvfrom(fd, thread->buf, sizeof(thread->buf), 0,(struct sockaddr *) &thread->iosin, &len);
06263 if (thread->iores < 0) {
06264 if (errno != ECONNREFUSED && errno != EAGAIN)
06265 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
06266 handle_error();
06267 insert_idle_thread(thread);
06268 return 1;
06269 }
06270 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
06271 insert_idle_thread(thread);
06272 return 1;
06273 }
06274
06275 thread->iostate = IAX_IOSTATE_READY;
06276 #ifdef DEBUG_SCHED_MULTITHREAD
06277 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
06278 #endif
06279 signal_condition(&thread->lock, &thread->cond);
06280 } else {
06281 time(&t);
06282 if (t != last_errtime)
06283 ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n");
06284 last_errtime = t;
06285 usleep(1);
06286 }
06287 return 1;
06288 }
06289
06290 static int acf_iaxvar_read(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
06291 {
06292 const char *value;
06293 char tmp[256];
06294 snprintf(tmp, sizeof(tmp), "~IAX2~%s", data);
06295 value = pbx_builtin_getvar_helper(chan, tmp);
06296 ast_copy_string(buf, value ? value : "", len);
06297 return 0;
06298 }
06299
06300 static int acf_iaxvar_write(struct ast_channel *chan, char *cmd, char *varname, const char *value)
06301 {
06302 char tmp[256];
06303
06304 snprintf(tmp, sizeof(tmp), "__~IAX2~%s", varname);
06305 pbx_builtin_setvar_helper(chan, tmp, value);
06306 return 0;
06307 }
06308
06309 static struct ast_custom_function iaxvar_function = {
06310 .name = "IAXVAR",
06311 .synopsis = "Sets or retrieves a remote variable",
06312 .syntax = "IAXVAR(<varname>)",
06313 .read = acf_iaxvar_read,
06314 .write = acf_iaxvar_write,
06315 };
06316
06317 static int socket_process(struct iax2_thread *thread)
06318 {
06319 struct sockaddr_in sin;
06320 int res;
06321 int updatehistory=1;
06322 int new = NEW_PREVENT;
06323 void *ptr;
06324 int dcallno = 0;
06325 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
06326 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
06327 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
06328 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
06329 struct ast_iax2_meta_trunk_hdr *mth;
06330 struct ast_iax2_meta_trunk_entry *mte;
06331 struct ast_iax2_meta_trunk_mini *mtm;
06332 struct iax_frame *fr;
06333 struct iax_frame *cur;
06334 struct ast_frame f = { 0, };
06335 struct ast_channel *c;
06336 struct iax2_dpcache *dp;
06337 struct iax2_peer *peer;
06338 struct iax2_trunk_peer *tpeer;
06339 struct timeval rxtrunktime;
06340 struct iax_ies ies;
06341 struct iax_ie_data ied0, ied1;
06342 int format;
06343 int fd;
06344 int exists;
06345 int minivid = 0;
06346 unsigned int ts;
06347 char empty[32]="";
06348 struct iax_frame *duped_fr;
06349 char host_pref_buf[128];
06350 char caller_pref_buf[128];
06351 struct ast_codec_pref pref;
06352 char *using_prefs = "mine";
06353
06354
06355 fr = alloca(sizeof(*fr) + 4096);
06356 fr->callno = 0;
06357
06358
06359 res = thread->iores;
06360 fd = thread->iofd;
06361 memcpy(&sin, &thread->iosin, sizeof(sin));
06362
06363 if (res < sizeof(*mh)) {
06364 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*mh));
06365 return 1;
06366 }
06367 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
06368 if (res < sizeof(*vh)) {
06369 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));
06370 return 1;
06371 }
06372
06373
06374 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd);
06375 minivid = 1;
06376 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) {
06377 unsigned char metatype;
06378
06379 if (res < sizeof(*meta)) {
06380 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));
06381 return 1;
06382 }
06383
06384
06385 switch(meta->metacmd) {
06386 case IAX_META_TRUNK:
06387 if (res < (sizeof(*meta) + sizeof(*mth))) {
06388 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %zd min)\n", res,
06389 sizeof(*meta) + sizeof(*mth));
06390 return 1;
06391 }
06392 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
06393 ts = ntohl(mth->ts);
06394 metatype = meta->cmddata;
06395 res -= (sizeof(*meta) + sizeof(*mth));
06396 ptr = mth->data;
06397 tpeer = find_tpeer(&sin, fd);
06398 if (!tpeer) {
06399 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));
06400 return 1;
06401 }
06402 tpeer->trunkact = ast_tvnow();
06403 if (!ts || ast_tvzero(tpeer->rxtrunktime))
06404 tpeer->rxtrunktime = tpeer->trunkact;
06405 rxtrunktime = tpeer->rxtrunktime;
06406 ast_mutex_unlock(&tpeer->lock);
06407 while(res >= sizeof(*mte)) {
06408
06409 unsigned short callno, trunked_ts, len;
06410
06411 if (metatype == IAX_META_TRUNK_MINI) {
06412 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06413 ptr += sizeof(*mtm);
06414 res -= sizeof(*mtm);
06415 len = ntohs(mtm->len);
06416 callno = ntohs(mtm->mini.callno);
06417 trunked_ts = ntohs(mtm->mini.ts);
06418 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
06419 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
06420 ptr += sizeof(*mte);
06421 res -= sizeof(*mte);
06422 len = ntohs(mte->len);
06423 callno = ntohs(mte->callno);
06424 trunked_ts = 0;
06425 } else {
06426 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
06427 break;
06428 }
06429
06430 if (len > res)
06431 break;
06432 fr->callno = find_callno(callno & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd);
06433 if (fr->callno) {
06434 ast_mutex_lock(&iaxsl[fr->callno]);
06435
06436
06437
06438 memset(&f, 0, sizeof(f));
06439 f.frametype = AST_FRAME_VOICE;
06440 if (iaxs[fr->callno]) {
06441 if (iaxs[fr->callno]->voiceformat > 0) {
06442 f.subclass = iaxs[fr->callno]->voiceformat;
06443 f.datalen = len;
06444 if (f.datalen >= 0) {
06445 if (f.datalen)
06446 f.data = ptr;
06447 if(trunked_ts) {
06448 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
06449 } else
06450 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
06451
06452 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06453
06454 f.src = "IAX2";
06455 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
06456 f.samples = ast_codec_get_samples(&f);
06457 iax_frame_wrap(fr, &f);
06458 duped_fr = iaxfrdup2(fr);
06459 if (duped_fr) {
06460 schedule_delivery(duped_fr, updatehistory, 1, &fr->ts);
06461 }
06462
06463 if (fr && fr->callno && iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
06464 iaxs[fr->callno]->last = fr->ts;
06465 #if 1
06466 if (option_debug && iaxdebug)
06467 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06468 #endif
06469 }
06470 }
06471 } else {
06472 ast_log(LOG_WARNING, "Datalen < 0?\n");
06473 }
06474 } else {
06475 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n ");
06476 iax2_vnak(fr->callno);
06477 }
06478 }
06479 ast_mutex_unlock(&iaxsl[fr->callno]);
06480 }
06481 ptr += len;
06482 res -= len;
06483 }
06484
06485 }
06486 return 1;
06487 }
06488
06489 #ifdef DEBUG_SUPPORT
06490 if (iaxdebug && (res >= sizeof(*fh)))
06491 iax_showframe(NULL, fh, 1, &sin, res - sizeof(*fh));
06492 #endif
06493 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06494 if (res < sizeof(*fh)) {
06495 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));
06496 return 1;
06497 }
06498
06499
06500 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
06501
06502 f.frametype = fh->type;
06503 if (f.frametype == AST_FRAME_VIDEO) {
06504 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06505 } else {
06506 f.subclass = uncompress_subclass(fh->csub);
06507 }
06508 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
06509 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
06510 (f.subclass == IAX_COMMAND_REGREL)))
06511 new = NEW_ALLOW;
06512 } else {
06513
06514 f.frametype = AST_FRAME_NULL;
06515 f.subclass = 0;
06516 }
06517
06518 if (!fr->callno)
06519 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, 1, fd);
06520
06521 if (fr->callno > 0)
06522 ast_mutex_lock(&iaxsl[fr->callno]);
06523
06524 if (!fr->callno || !iaxs[fr->callno]) {
06525
06526
06527 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06528
06529 if (((f.subclass != IAX_COMMAND_INVAL) &&
06530 (f.subclass != IAX_COMMAND_TXCNT) &&
06531 (f.subclass != IAX_COMMAND_TXACC) &&
06532 (f.subclass != IAX_COMMAND_FWDOWNL))||
06533 (f.frametype != AST_FRAME_IAX))
06534 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
06535 fd);
06536 }
06537 if (fr->callno > 0)
06538 ast_mutex_unlock(&iaxsl[fr->callno]);
06539 return 1;
06540 }
06541 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
06542 if (decrypt_frame(fr->callno, fh, &f, &res)) {
06543 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
06544 ast_mutex_unlock(&iaxsl[fr->callno]);
06545 return 1;
06546 }
06547 #ifdef DEBUG_SUPPORT
06548 else if (iaxdebug)
06549 iax_showframe(NULL, fh, 3, &sin, res - sizeof(*fh));
06550 #endif
06551 }
06552
06553
06554 iaxs[fr->callno]->frames_received++;
06555
06556 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
06557 f.subclass != IAX_COMMAND_TXCNT &&
06558 f.subclass != IAX_COMMAND_TXACC)
06559 iaxs[fr->callno]->peercallno = (unsigned short)(ntohs(mh->callno) & ~IAX_FLAG_FULL);
06560 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
06561 if (option_debug && iaxdebug)
06562 ast_log(LOG_DEBUG, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
06563
06564 fr->oseqno = fh->oseqno;
06565 fr->iseqno = fh->iseqno;
06566 fr->ts = ntohl(fh->ts);
06567 #ifdef IAXTESTS
06568 if (test_resync) {
06569 if (option_debug)
06570 ast_log(LOG_DEBUG, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
06571 fr->ts += test_resync;
06572 }
06573 #endif
06574 #if 0
06575 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
06576 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
06577 (f.subclass == IAX_COMMAND_NEW ||
06578 f.subclass == IAX_COMMAND_AUTHREQ ||
06579 f.subclass == IAX_COMMAND_ACCEPT ||
06580 f.subclass == IAX_COMMAND_REJECT)) ) )
06581 #endif
06582 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
06583 updatehistory = 0;
06584 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
06585 (iaxs[fr->callno]->iseqno ||
06586 ((f.subclass != IAX_COMMAND_TXCNT) &&
06587 (f.subclass != IAX_COMMAND_TXREADY) &&
06588 (f.subclass != IAX_COMMAND_TXREL) &&
06589 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
06590 (f.subclass != IAX_COMMAND_TXACC)) ||
06591 (f.frametype != AST_FRAME_IAX))) {
06592 if (
06593 ((f.subclass != IAX_COMMAND_ACK) &&
06594 (f.subclass != IAX_COMMAND_INVAL) &&
06595 (f.subclass != IAX_COMMAND_TXCNT) &&
06596 (f.subclass != IAX_COMMAND_TXREADY) &&
06597 (f.subclass != IAX_COMMAND_TXREL) &&
06598 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
06599 (f.subclass != IAX_COMMAND_TXACC) &&
06600 (f.subclass != IAX_COMMAND_VNAK)) ||
06601 (f.frametype != AST_FRAME_IAX)) {
06602
06603 if (option_debug)
06604 ast_log(LOG_DEBUG, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
06605 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
06606 if (iaxs[fr->callno]->iseqno > fr->oseqno) {
06607
06608 if ((f.frametype != AST_FRAME_IAX) ||
06609 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
06610 if (option_debug)
06611 ast_log(LOG_DEBUG, "Acking anyway\n");
06612
06613
06614 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06615 }
06616 } else {
06617
06618 iax2_vnak(fr->callno);
06619 }
06620 ast_mutex_unlock(&iaxsl[fr->callno]);
06621 return 1;
06622 }
06623 } else {
06624
06625 if (((f.subclass != IAX_COMMAND_ACK) &&
06626 (f.subclass != IAX_COMMAND_INVAL) &&
06627 (f.subclass != IAX_COMMAND_TXCNT) &&
06628 (f.subclass != IAX_COMMAND_TXACC) &&
06629 (f.subclass != IAX_COMMAND_VNAK)) ||
06630 (f.frametype != AST_FRAME_IAX))
06631 iaxs[fr->callno]->iseqno++;
06632 }
06633
06634 if (res < sizeof(*fh)) {
06635 ast_log(LOG_WARNING, "midget packet received (%d of %zd min)\n", res, sizeof(*fh));
06636 ast_mutex_unlock(&iaxsl[fr->callno]);
06637 return 1;
06638 }
06639
06640 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
06641 if (res < sizeof(thread->buf))
06642 thread->buf[res++] = '\0';
06643 else
06644 thread->buf[res - 1] = '\0';
06645 }
06646 f.datalen = res - sizeof(*fh);
06647
06648
06649
06650 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
06651 ((f.subclass != IAX_COMMAND_INVAL) ||
06652 (f.frametype != AST_FRAME_IAX))) {
06653 unsigned char x;
06654
06655
06656
06657 for (x=iaxs[fr->callno]->rseqno; x != iaxs[fr->callno]->oseqno; x++)
06658 if (fr->iseqno == x)
06659 break;
06660 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
06661
06662
06663 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
06664
06665 if (option_debug && iaxdebug)
06666 ast_log(LOG_DEBUG, "Cancelling transmission of packet %d\n", x);
06667 AST_LIST_LOCK(&iaxq.queue);
06668 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
06669
06670 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
06671 cur->retries = -1;
06672
06673 if (cur->final) {
06674 if (iaxdebug && option_debug)
06675 ast_log(LOG_DEBUG, "Really destroying %d, having been acked on final message\n", fr->callno);
06676 iax2_destroy(fr->callno);
06677 }
06678 }
06679 }
06680 AST_LIST_UNLOCK(&iaxq.queue);
06681 }
06682
06683 if (iaxs[fr->callno])
06684 iaxs[fr->callno]->rseqno = fr->iseqno;
06685 else {
06686
06687 ast_mutex_unlock(&iaxsl[fr->callno]);
06688 return 1;
06689 }
06690 } else
06691 ast_log(LOG_DEBUG, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
06692 }
06693 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
06694 ((f.frametype != AST_FRAME_IAX) ||
06695 ((f.subclass != IAX_COMMAND_TXACC) &&
06696 (f.subclass != IAX_COMMAND_TXCNT)))) {
06697
06698 ast_mutex_unlock(&iaxsl[fr->callno]);
06699 return 1;
06700 }
06701
06702 if (f.datalen) {
06703 if (f.frametype == AST_FRAME_IAX) {
06704 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
06705 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
06706 ast_mutex_unlock(&iaxsl[fr->callno]);
06707 return 1;
06708 }
06709 f.data = NULL;
06710 } else
06711 f.data = thread->buf + sizeof(*fh);
06712 } else {
06713 if (f.frametype == AST_FRAME_IAX)
06714 f.data = NULL;
06715 else
06716 f.data = empty;
06717 memset(&ies, 0, sizeof(ies));
06718 }
06719 if (f.frametype == AST_FRAME_VOICE) {
06720 if (f.subclass != iaxs[fr->callno]->voiceformat) {
06721 iaxs[fr->callno]->voiceformat = f.subclass;
06722 ast_log(LOG_DEBUG, "Ooh, voice format changed to %d\n", f.subclass);
06723 if (iaxs[fr->callno]->owner) {
06724 int orignative;
06725 retryowner:
06726 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
06727 ast_mutex_unlock(&iaxsl[fr->callno]);
06728 usleep(1);
06729 ast_mutex_lock(&iaxsl[fr->callno]);
06730 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
06731 }
06732 if (iaxs[fr->callno]) {
06733 if (iaxs[fr->callno]->owner) {
06734 orignative = iaxs[fr->callno]->owner->nativeformats;
06735 iaxs[fr->callno]->owner->nativeformats = f.subclass;
06736 if (iaxs[fr->callno]->owner->readformat)
06737 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
06738 iaxs[fr->callno]->owner->nativeformats = orignative;
06739 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
06740 }
06741 } else {
06742 ast_log(LOG_DEBUG, "Neat, somebody took away the channel at a magical time but i found it!\n");
06743
06744 if (ies.vars)
06745 ast_variables_destroy(ies.vars);
06746 ast_mutex_unlock(&iaxsl[fr->callno]);
06747 return 1;
06748 }
06749 }
06750 }
06751 }
06752 if (f.frametype == AST_FRAME_VIDEO) {
06753 if (f.subclass != iaxs[fr->callno]->videoformat) {
06754 ast_log(LOG_DEBUG, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
06755 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
06756 }
06757 }
06758 if (f.frametype == AST_FRAME_IAX) {
06759 if (iaxs[fr->callno]->initid > -1) {
06760
06761 ast_sched_del(sched, iaxs[fr->callno]->initid);
06762 iaxs[fr->callno]->initid = -1;
06763 }
06764
06765 if (option_debug && iaxdebug)
06766 ast_log(LOG_DEBUG, "IAX subclass %d received\n", f.subclass);
06767
06768
06769 if (iaxs[fr->callno]->last < fr->ts &&
06770 f.subclass != IAX_COMMAND_ACK &&
06771 f.subclass != IAX_COMMAND_PONG &&
06772 f.subclass != IAX_COMMAND_LAGRP) {
06773 iaxs[fr->callno]->last = fr->ts;
06774 if (option_debug && iaxdebug)
06775 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
06776 }
06777
06778 switch(f.subclass) {
06779 case IAX_COMMAND_ACK:
06780
06781 break;
06782 case IAX_COMMAND_QUELCH:
06783 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06784
06785 if (iaxs[fr->callno]->owner) {
06786 manager_event(EVENT_FLAG_CALL, "Hold",
06787 "Channel: %s\r\n"
06788 "Uniqueid: %s\r\n",
06789 iaxs[fr->callno]->owner->name,
06790 iaxs[fr->callno]->owner->uniqueid);
06791 }
06792
06793 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
06794 if (ies.musiconhold) {
06795 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
06796 const char *mohsuggest = iaxs[fr->callno]->mohsuggest;
06797 ast_queue_control_data(iaxs[fr->callno]->owner, AST_CONTROL_HOLD,
06798 S_OR(mohsuggest, NULL),
06799 !ast_strlen_zero(mohsuggest) ? strlen(mohsuggest) + 1 : 0);
06800 }
06801 }
06802 }
06803 break;
06804 case IAX_COMMAND_UNQUELCH:
06805 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
06806
06807 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
06808 manager_event(EVENT_FLAG_CALL, "Unhold",
06809 "Channel: %s\r\n"
06810 "Uniqueid: %s\r\n",
06811 iaxs[fr->callno]->owner->name,
06812 iaxs[fr->callno]->owner->uniqueid);
06813 }
06814
06815 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
06816 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner))
06817 ast_queue_control(iaxs[fr->callno]->owner, AST_CONTROL_UNHOLD);
06818 }
06819 break;
06820 case IAX_COMMAND_TXACC:
06821 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
06822
06823 AST_LIST_LOCK(&iaxq.queue);
06824 AST_LIST_TRAVERSE(&iaxq.queue, cur, list) {
06825
06826 if ((fr->callno == cur->callno) && (cur->transfer))
06827 cur->retries = -1;
06828 }
06829 AST_LIST_UNLOCK(&iaxq.queue);
06830 memset(&ied1, 0, sizeof(ied1));
06831 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
06832 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
06833 iaxs[fr->callno]->transferring = TRANSFER_READY;
06834 }
06835 break;
06836 case IAX_COMMAND_NEW:
06837
06838 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
06839 break;
06840 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
06841 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
06842
06843 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
06844 fr->callno = make_trunk(fr->callno, 1);
06845 }
06846
06847 if (delayreject)
06848 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
06849 if (check_access(fr->callno, &sin, &ies)) {
06850
06851 auth_fail(fr->callno, IAX_COMMAND_REJECT);
06852 if (authdebug)
06853 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);
06854 break;
06855 }
06856
06857 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
06858 ast_mutex_unlock(&iaxsl[fr->callno]);
06859 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
06860 ast_mutex_lock(&iaxsl[fr->callno]);
06861 } else
06862 exists = 0;
06863 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
06864 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
06865 memset(&ied0, 0, sizeof(ied0));
06866 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
06867 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
06868 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06869 if (authdebug)
06870 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);
06871 } else {
06872
06873
06874 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
06875 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
06876 using_prefs = "reqonly";
06877 } else {
06878 using_prefs = "disabled";
06879 }
06880 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
06881 memset(&pref, 0, sizeof(pref));
06882 strcpy(caller_pref_buf, "disabled");
06883 strcpy(host_pref_buf, "disabled");
06884 } else {
06885 using_prefs = "mine";
06886
06887 if (ies.codec_prefs)
06888 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
06889 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
06890
06891 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
06892 pref = iaxs[fr->callno]->rprefs;
06893 using_prefs = "caller";
06894 } else {
06895 pref = iaxs[fr->callno]->prefs;
06896 }
06897 } else
06898 pref = iaxs[fr->callno]->prefs;
06899
06900 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
06901 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
06902 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
06903 }
06904 if (!format) {
06905 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
06906 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
06907 if (!format) {
06908 memset(&ied0, 0, sizeof(ied0));
06909 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
06910 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
06911 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06912 if (authdebug) {
06913 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
06914 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);
06915 else
06916 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);
06917 }
06918 } else {
06919
06920 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
06921 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
06922 format = 0;
06923 } else {
06924 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
06925 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
06926 memset(&pref, 0, sizeof(pref));
06927 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
06928 strcpy(caller_pref_buf,"disabled");
06929 strcpy(host_pref_buf,"disabled");
06930 } else {
06931 using_prefs = "mine";
06932 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
06933
06934 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
06935 pref = iaxs[fr->callno]->prefs;
06936 } else {
06937 pref = iaxs[fr->callno]->rprefs;
06938 using_prefs = "caller";
06939 }
06940 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
06941
06942 } else
06943 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
06944 }
06945 }
06946
06947 if (!format) {
06948 memset(&ied0, 0, sizeof(ied0));
06949 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
06950 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
06951 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
06952 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
06953 if (authdebug)
06954 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);
06955 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
06956 break;
06957 }
06958 }
06959 }
06960 if (format) {
06961
06962 memset(&ied1, 0, sizeof(ied1));
06963 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
06964 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
06965 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
06966 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
06967 if (option_verbose > 2)
06968 ast_verbose(VERBOSE_PREFIX_3 "Accepting UNAUTHENTICATED call from %s:\n"
06969 "%srequested format = %s,\n"
06970 "%srequested prefs = %s,\n"
06971 "%sactual format = %s,\n"
06972 "%shost prefs = %s,\n"
06973 "%spriority = %s\n",
06974 ast_inet_ntoa(sin.sin_addr),
06975 VERBOSE_PREFIX_4,
06976 ast_getformatname(iaxs[fr->callno]->peerformat),
06977 VERBOSE_PREFIX_4,
06978 caller_pref_buf,
06979 VERBOSE_PREFIX_4,
06980 ast_getformatname(format),
06981 VERBOSE_PREFIX_4,
06982 host_pref_buf,
06983 VERBOSE_PREFIX_4,
06984 using_prefs);
06985
06986 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
06987 iax2_destroy(fr->callno);
06988 else if (ies.vars) {
06989 struct ast_variable *var, *prev = NULL;
06990 char tmp[256];
06991 for (var = ies.vars; var; var = var->next) {
06992 if (prev)
06993 free(prev);
06994 prev = var;
06995 snprintf(tmp, sizeof(tmp), "__~IAX2~%s", var->name);
06996 pbx_builtin_setvar_helper(c, tmp, var->value);
06997 }
06998 ies.vars = NULL;
06999 }
07000 } else {
07001 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07002
07003 if (option_verbose > 2)
07004 ast_verbose(VERBOSE_PREFIX_3 "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07005 }
07006 }
07007 }
07008 break;
07009 }
07010 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
07011 merge_encryption(iaxs[fr->callno],ies.encmethods);
07012 else
07013 iaxs[fr->callno]->encmethods = 0;
07014 if (!authenticate_request(iaxs[fr->callno]))
07015 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
07016 break;
07017 case IAX_COMMAND_DPREQ:
07018
07019 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
07020 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
07021 if (iaxcompat) {
07022
07023 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
07024 } else {
07025
07026 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
07027 }
07028 }
07029 break;
07030 case IAX_COMMAND_HANGUP:
07031 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07032 ast_log(LOG_DEBUG, "Immediately destroying %d, having received hangup\n", fr->callno);
07033
07034 if (ies.causecode && iaxs[fr->callno]->owner)
07035 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07036
07037 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07038 iax2_destroy(fr->callno);
07039 break;
07040 case IAX_COMMAND_REJECT:
07041
07042 if (ies.causecode && iaxs[fr->callno]->owner)
07043 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
07044
07045 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07046 if (iaxs[fr->callno]->owner && authdebug)
07047 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
07048 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
07049 ies.cause ? ies.cause : "<Unknown>");
07050 ast_log(LOG_DEBUG, "Immediately destroying %d, having received reject\n",
07051 fr->callno);
07052 }
07053
07054 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
07055 fr->ts, NULL, 0, fr->iseqno);
07056 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
07057 iaxs[fr->callno]->error = EPERM;
07058 iax2_destroy(fr->callno);
07059 break;
07060 case IAX_COMMAND_TRANSFER:
07061 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner) && ies.called_number) {
07062
07063 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07064 pbx_builtin_setvar_helper(ast_bridged_channel(iaxs[fr->callno]->owner), "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
07065 if (!strcmp(ies.called_number, ast_parking_ext())) {
07066 if (iax_park(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->owner)) {
07067 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07068 } else if (ast_bridged_channel(iaxs[fr->callno]->owner))
07069 ast_log(LOG_DEBUG, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
07070 } else {
07071 if (ast_async_goto(ast_bridged_channel(iaxs[fr->callno]->owner), iaxs[fr->callno]->context, ies.called_number, 1))
07072 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name,
07073 ies.called_number, iaxs[fr->callno]->context);
07074 else
07075 ast_log(LOG_DEBUG, "Async goto of '%s' to '%s@%s' started\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name,
07076 ies.called_number, iaxs[fr->callno]->context);
07077 }
07078 } else
07079 ast_log(LOG_DEBUG, "Async goto not applicable on call %d\n", fr->callno);
07080 break;
07081 case IAX_COMMAND_ACCEPT:
07082
07083 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
07084 break;
07085 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
07086
07087 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07088 iax2_destroy(fr->callno);
07089 break;
07090 }
07091 if (ies.format) {
07092 iaxs[fr->callno]->peerformat = ies.format;
07093 } else {
07094 if (iaxs[fr->callno]->owner)
07095 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
07096 else
07097 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
07098 }
07099 if (option_verbose > 2)
07100 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));
07101 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
07102 memset(&ied0, 0, sizeof(ied0));
07103 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07104 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07105 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07106 if (authdebug)
07107 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);
07108 } else {
07109 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07110 if (iaxs[fr->callno]->owner) {
07111
07112 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
07113 if (option_verbose > 2)
07114 ast_verbose(VERBOSE_PREFIX_3 "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
07115 retryowner2:
07116 if (ast_mutex_trylock(&iaxs[fr->callno]->owner->lock)) {
07117 ast_mutex_unlock(&iaxsl[fr->callno]);
07118 usleep(1);
07119 ast_mutex_lock(&iaxsl[fr->callno]);
07120 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
07121 }
07122
07123 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
07124
07125 if (iaxs[fr->callno]->owner->writeformat)
07126 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
07127 if (iaxs[fr->callno]->owner->readformat)
07128 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
07129 ast_mutex_unlock(&iaxs[fr->callno]->owner->lock);
07130 }
07131 }
07132 }
07133 if (iaxs[fr->callno]) {
07134 ast_mutex_lock(&dpcache_lock);
07135 dp = iaxs[fr->callno]->dpentries;
07136 while(dp) {
07137 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) {
07138 iax2_dprequest(dp, fr->callno);
07139 }
07140 dp = dp->peer;
07141 }
07142 ast_mutex_unlock(&dpcache_lock);
07143 }
07144 break;
07145 case IAX_COMMAND_POKE:
07146
07147 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
07148 break;
07149 case IAX_COMMAND_PING:
07150 {
07151 struct iax_ie_data pingied;
07152 construct_rr(iaxs[fr->callno], &pingied);
07153
07154 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
07155 }
07156 break;
07157 case IAX_COMMAND_PONG:
07158
07159 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
07160
07161 save_rr(fr, &ies);
07162
07163 if (iaxs[fr->callno]->peerpoke) {
07164 peer = iaxs[fr->callno]->peerpoke;
07165 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
07166 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
07167 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
07168 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
07169 ast_device_state_changed("IAX2/%s", peer->name);
07170 }
07171 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
07172 if (iaxs[fr->callno]->pingtime > peer->maxms) {
07173 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
07174 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
07175 ast_device_state_changed("IAX2/%s", peer->name);
07176 }
07177 }
07178 peer->lastms = iaxs[fr->callno]->pingtime;
07179 if (peer->smoothing && (peer->lastms > -1))
07180 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
07181 else if (peer->smoothing && peer->lastms < 0)
07182 peer->historicms = (0 + peer->historicms) / 2;
07183 else
07184 peer->historicms = iaxs[fr->callno]->pingtime;
07185
07186
07187 if (peer->pokeexpire > -1)
07188 ast_sched_del(sched, peer->pokeexpire);
07189
07190 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
07191 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07192 else
07193 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer);
07194
07195 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07196
07197 iax2_destroy(fr->callno);
07198 peer->callno = 0;
07199 if (option_debug)
07200 ast_log(LOG_DEBUG, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
07201 }
07202 break;
07203 case IAX_COMMAND_LAGRQ:
07204 case IAX_COMMAND_LAGRP:
07205 f.src = "LAGRQ";
07206 f.mallocd = 0;
07207 f.offset = 0;
07208 f.samples = 0;
07209 iax_frame_wrap(fr, &f);
07210 if(f.subclass == IAX_COMMAND_LAGRQ) {
07211
07212 fr->af.subclass = IAX_COMMAND_LAGRP;
07213 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
07214 } else {
07215
07216 unsigned int ts;
07217
07218 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
07219 iaxs[fr->callno]->lag = ts - fr->ts;
07220 if (option_debug && iaxdebug)
07221 ast_log(LOG_DEBUG, "Peer %s lag measured as %dms\n",
07222 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
07223 }
07224 break;
07225 case IAX_COMMAND_AUTHREQ:
07226 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07227 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>");
07228 break;
07229 }
07230 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
07231 ast_log(LOG_WARNING,
07232 "I don't know how to authenticate %s to %s\n",
07233 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
07234 }
07235 break;
07236 case IAX_COMMAND_AUTHREP:
07237
07238 if (delayreject)
07239 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07240
07241 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
07242 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>");
07243 break;
07244 }
07245 if (authenticate_verify(iaxs[fr->callno], &ies)) {
07246 if (authdebug)
07247 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);
07248 memset(&ied0, 0, sizeof(ied0));
07249 auth_fail(fr->callno, IAX_COMMAND_REJECT);
07250 break;
07251 }
07252 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
07253
07254 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
07255 } else
07256 exists = 0;
07257 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
07258 if (authdebug)
07259 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);
07260 memset(&ied0, 0, sizeof(ied0));
07261 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07262 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07263 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07264 } else {
07265
07266 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07267 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07268 using_prefs = "reqonly";
07269 } else {
07270 using_prefs = "disabled";
07271 }
07272 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
07273 memset(&pref, 0, sizeof(pref));
07274 strcpy(caller_pref_buf, "disabled");
07275 strcpy(host_pref_buf, "disabled");
07276 } else {
07277 using_prefs = "mine";
07278 if (ies.codec_prefs)
07279 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
07280 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07281 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07282 pref = iaxs[fr->callno]->rprefs;
07283 using_prefs = "caller";
07284 } else {
07285 pref = iaxs[fr->callno]->prefs;
07286 }
07287 } else
07288 pref = iaxs[fr->callno]->prefs;
07289
07290 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
07291 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
07292 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
07293 }
07294 if (!format) {
07295 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07296 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);
07297 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
07298 }
07299 if (!format) {
07300 if (authdebug) {
07301 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07302 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);
07303 else
07304 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);
07305 }
07306 memset(&ied0, 0, sizeof(ied0));
07307 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07308 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07309 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07310 } else {
07311
07312 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
07313 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
07314 format = 0;
07315 } else {
07316 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
07317 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
07318 memset(&pref, 0, sizeof(pref));
07319 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
07320 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07321 strcpy(caller_pref_buf,"disabled");
07322 strcpy(host_pref_buf,"disabled");
07323 } else {
07324 using_prefs = "mine";
07325 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
07326
07327 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
07328 pref = iaxs[fr->callno]->prefs;
07329 } else {
07330 pref = iaxs[fr->callno]->rprefs;
07331 using_prefs = "caller";
07332 }
07333 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
07334 } else
07335 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07336 }
07337 }
07338 if (!format) {
07339 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
07340 if (authdebug) {
07341 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
07342 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);
07343 else
07344 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);
07345 }
07346 memset(&ied0, 0, sizeof(ied0));
07347 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
07348 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
07349 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07350 }
07351 }
07352 }
07353 if (format) {
07354
07355 memset(&ied1, 0, sizeof(ied1));
07356 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
07357 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
07358 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
07359 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07360 if (option_verbose > 2)
07361 ast_verbose(VERBOSE_PREFIX_3 "Accepting AUTHENTICATED call from %s:\n"
07362 "%srequested format = %s,\n"
07363 "%srequested prefs = %s,\n"
07364 "%sactual format = %s,\n"
07365 "%shost prefs = %s,\n"
07366 "%spriority = %s\n",
07367 ast_inet_ntoa(sin.sin_addr),
07368 VERBOSE_PREFIX_4,
07369 ast_getformatname(iaxs[fr->callno]->peerformat),
07370 VERBOSE_PREFIX_4,
07371 caller_pref_buf,
07372 VERBOSE_PREFIX_4,
07373 ast_getformatname(format),
07374 VERBOSE_PREFIX_4,
07375 host_pref_buf,
07376 VERBOSE_PREFIX_4,
07377 using_prefs);
07378
07379 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07380 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
07381 iax2_destroy(fr->callno);
07382 } else {
07383 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07384
07385 if (option_verbose > 2)
07386 ast_verbose(VERBOSE_PREFIX_3 "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
07387 }
07388 }
07389 }
07390 break;
07391 case IAX_COMMAND_DIAL:
07392 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
07393 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
07394 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
07395 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
07396 if (authdebug)
07397 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);
07398 memset(&ied0, 0, sizeof(ied0));
07399 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
07400 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
07401 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07402 } else {
07403 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07404 if (option_verbose > 2)
07405 ast_verbose(VERBOSE_PREFIX_3 "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
07406 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
07407 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
07408 if(!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
07409 iax2_destroy(fr->callno);
07410 }
07411 }
07412 break;
07413 case IAX_COMMAND_INVAL:
07414 iaxs[fr->callno]->error = ENOTCONN;
07415 ast_log(LOG_DEBUG, "Immediately destroying %d, having received INVAL\n", fr->callno);
07416 iax2_destroy(fr->callno);
07417 if (option_debug)
07418 ast_log(LOG_DEBUG, "Destroying call %d\n", fr->callno);
07419 break;
07420 case IAX_COMMAND_VNAK:
07421 ast_log(LOG_DEBUG, "Received VNAK: resending outstanding frames\n");
07422
07423 vnak_retransmit(fr->callno, fr->iseqno);
07424 break;
07425 case IAX_COMMAND_REGREQ:
07426 case IAX_COMMAND_REGREL:
07427
07428 if (delayreject)
07429 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07430 if (register_verify(fr->callno, &sin, &ies)) {
07431
07432 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
07433 break;
07434 }
07435 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
07436 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED | IAX_STATE_UNCHANGED)) {
07437 if (f.subclass == IAX_COMMAND_REGREL)
07438 memset(&sin, 0, sizeof(sin));
07439 if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh))
07440 ast_log(LOG_WARNING, "Registry error\n");
07441 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
07442 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
07443 break;
07444 }
07445 registry_authrequest(iaxs[fr->callno]->peer, fr->callno);
07446 break;
07447 case IAX_COMMAND_REGACK:
07448 if (iax2_ack_registry(&ies, &sin, fr->callno))
07449 ast_log(LOG_WARNING, "Registration failure\n");
07450
07451 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07452 iax2_destroy(fr->callno);
07453 break;
07454 case IAX_COMMAND_REGREJ:
07455 if (iaxs[fr->callno]->reg) {
07456 if (authdebug) {
07457 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));
07458 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>");
07459 }
07460 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
07461 }
07462
07463 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07464 iax2_destroy(fr->callno);
07465 break;
07466 case IAX_COMMAND_REGAUTH:
07467
07468 if (registry_rerequest(&ies, fr->callno, &sin)) {
07469 memset(&ied0, 0, sizeof(ied0));
07470 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
07471 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07472 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07473 }
07474 break;
07475 case IAX_COMMAND_TXREJ:
07476 iaxs[fr->callno]->transferring = 0;
07477 if (option_verbose > 2)
07478 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07479 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
07480 if (iaxs[fr->callno]->bridgecallno) {
07481 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
07482 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
07483 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
07484 }
07485 }
07486 break;
07487 case IAX_COMMAND_TXREADY:
07488 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
07489 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
07490 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
07491 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
07492 else
07493 iaxs[fr->callno]->transferring = TRANSFER_READY;
07494 if (option_verbose > 2)
07495 ast_verbose(VERBOSE_PREFIX_3 "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
07496 if (iaxs[fr->callno]->bridgecallno) {
07497 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
07498 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
07499
07500 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
07501 if (option_verbose > 2)
07502 ast_verbose(VERBOSE_PREFIX_3 "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07503 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07504
07505 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
07506 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
07507
07508 memset(&ied0, 0, sizeof(ied0));
07509 memset(&ied1, 0, sizeof(ied1));
07510 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
07511 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
07512 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
07513 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
07514 } else {
07515 if (option_verbose > 2)
07516 ast_verbose(VERBOSE_PREFIX_3 "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
07517 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
07518
07519 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
07520 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
07521 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
07522 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
07523
07524
07525 stop_stuff(fr->callno);
07526 stop_stuff(iaxs[fr->callno]->bridgecallno);
07527
07528 memset(&ied0, 0, sizeof(ied0));
07529 memset(&ied1, 0, sizeof(ied1));
07530 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
07531 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
07532 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
07533 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
07534 }
07535
07536 }
07537 }
07538 }
07539 break;
07540 case IAX_COMMAND_TXREQ:
07541 try_transfer(iaxs[fr->callno], &ies);
07542 break;
07543 case IAX_COMMAND_TXCNT:
07544 if (iaxs[fr->callno]->transferring)
07545 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
07546 break;
07547 case IAX_COMMAND_TXREL:
07548
07549 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07550 complete_transfer(fr->callno, &ies);
07551 stop_stuff(fr->callno);
07552 break;
07553 case IAX_COMMAND_TXMEDIA:
07554 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
07555
07556 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
07557 }
07558 break;
07559 case IAX_COMMAND_DPREP:
07560 complete_dpreply(iaxs[fr->callno], &ies);
07561 break;
07562 case IAX_COMMAND_UNSUPPORT:
07563 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
07564 break;
07565 case IAX_COMMAND_FWDOWNL:
07566
07567 memset(&ied0, 0, sizeof(ied0));
07568 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
07569 if (res < 0)
07570 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
07571 else if (res > 0)
07572 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07573 else
07574 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
07575 break;
07576 default:
07577 ast_log(LOG_DEBUG, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
07578 memset(&ied0, 0, sizeof(ied0));
07579 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
07580 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
07581 }
07582
07583 if (ies.vars)
07584 ast_variables_destroy(ies.vars);
07585
07586
07587 if ((f.subclass != IAX_COMMAND_ACK) &&
07588 (f.subclass != IAX_COMMAND_TXCNT) &&
07589 (f.subclass != IAX_COMMAND_TXACC) &&
07590 (f.subclass != IAX_COMMAND_INVAL) &&
07591 (f.subclass != IAX_COMMAND_VNAK)) {
07592 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07593 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07594 }
07595 ast_mutex_unlock(&iaxsl[fr->callno]);
07596 return 1;
07597 }
07598
07599 if (iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
07600 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
07601 } else if (minivid) {
07602 f.frametype = AST_FRAME_VIDEO;
07603 if (iaxs[fr->callno]->videoformat > 0)
07604 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
07605 else {
07606 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n ");
07607 iax2_vnak(fr->callno);
07608 ast_mutex_unlock(&iaxsl[fr->callno]);
07609 return 1;
07610 }
07611 f.datalen = res - sizeof(*vh);
07612 if (f.datalen)
07613 f.data = thread->buf + sizeof(*vh);
07614 else
07615 f.data = NULL;
07616 #ifdef IAXTESTS
07617 if (test_resync) {
07618 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
07619 } else
07620 #endif
07621 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
07622 } else {
07623
07624 f.frametype = AST_FRAME_VOICE;
07625 if (iaxs[fr->callno]->voiceformat > 0)
07626 f.subclass = iaxs[fr->callno]->voiceformat;
07627 else {
07628 ast_log(LOG_WARNING, "Received mini frame before first full voice frame\n ");
07629 iax2_vnak(fr->callno);
07630 ast_mutex_unlock(&iaxsl[fr->callno]);
07631 return 1;
07632 }
07633 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
07634 if (f.datalen < 0) {
07635 ast_log(LOG_WARNING, "Datalen < 0?\n");
07636 ast_mutex_unlock(&iaxsl[fr->callno]);
07637 return 1;
07638 }
07639 if (f.datalen)
07640 f.data = thread->buf + sizeof(*mh);
07641 else
07642 f.data = NULL;
07643 #ifdef IAXTESTS
07644 if (test_resync) {
07645 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
07646 } else
07647 #endif
07648 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
07649
07650 }
07651
07652 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
07653 ast_mutex_unlock(&iaxsl[fr->callno]);
07654 return 1;
07655 }
07656
07657 f.src = "IAX2";
07658 f.mallocd = 0;
07659 f.offset = 0;
07660 f.len = 0;
07661 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
07662 f.samples = ast_codec_get_samples(&f);
07663
07664 if (f.subclass == AST_FORMAT_SLINEAR)
07665 ast_frame_byteswap_be(&f);
07666 } else
07667 f.samples = 0;
07668 iax_frame_wrap(fr, &f);
07669
07670
07671 if (iaxs[fr->callno]->last < fr->ts) {
07672
07673 fr->outoforder = 0;
07674 } else {
07675 if (option_debug && iaxdebug)
07676 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);
07677 fr->outoforder = -1;
07678 }
07679 duped_fr = iaxfrdup2(fr);
07680 if (duped_fr) {
07681 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
07682 }
07683 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
07684 iaxs[fr->callno]->last = fr->ts;
07685 #if 1
07686 if (option_debug && iaxdebug)
07687 ast_log(LOG_DEBUG, "For call=%d, set last=%d\n", fr->callno, fr->ts);
07688 #endif
07689 }
07690
07691
07692 ast_mutex_unlock(&iaxsl[fr->callno]);
07693 return 1;
07694 }
07695
07696
07697 static void iax2_process_thread_cleanup(void *data)
07698 {
07699 struct iax2_thread *thread = data;
07700 ast_mutex_destroy(&thread->lock);
07701 ast_cond_destroy(&thread->cond);
07702 free(thread);
07703 ast_atomic_dec_and_test(&iaxactivethreadcount);
07704 }
07705
07706 static void *iax2_process_thread(void *data)
07707 {
07708 struct iax2_thread *thread = data;
07709 struct timeval tv;
07710 struct timespec ts;
07711 int put_into_idle = 0;
07712
07713 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
07714 pthread_cleanup_push(iax2_process_thread_cleanup, data);
07715 for(;;) {
07716
07717 ast_mutex_lock(&thread->lock);
07718
07719
07720 if (put_into_idle)
07721 insert_idle_thread(thread);
07722
07723 if (thread->type == IAX_TYPE_DYNAMIC) {
07724
07725 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
07726 ts.tv_sec = tv.tv_sec;
07727 ts.tv_nsec = tv.tv_usec * 1000;
07728 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
07729 ast_mutex_unlock(&thread->lock);
07730 AST_LIST_LOCK(&dynamic_list);
07731 AST_LIST_REMOVE(&dynamic_list, thread, list);
07732 iaxdynamicthreadcount--;
07733 AST_LIST_UNLOCK(&dynamic_list);
07734 break;
07735 }
07736 } else {
07737 ast_cond_wait(&thread->cond, &thread->lock);
07738 }
07739 ast_mutex_unlock(&thread->lock);
07740
07741
07742 AST_LIST_LOCK(&active_list);
07743 AST_LIST_INSERT_HEAD(&active_list, thread, list);
07744 AST_LIST_UNLOCK(&active_list);
07745
07746
07747 switch(thread->iostate) {
07748 case IAX_IOSTATE_READY:
07749 thread->actions++;
07750 thread->iostate = IAX_IOSTATE_PROCESSING;
07751 socket_process(thread);
07752 break;
07753 case IAX_IOSTATE_SCHEDREADY:
07754 thread->actions++;
07755 thread->iostate = IAX_IOSTATE_PROCESSING;
07756 #ifdef SCHED_MULTITHREADED
07757 thread->schedfunc(thread->scheddata);
07758 #endif
07759 break;
07760 }
07761 time(&thread->checktime);
07762 thread->iostate = IAX_IOSTATE_IDLE;
07763 #ifdef DEBUG_SCHED_MULTITHREAD
07764 thread->curfunc[0]='\0';
07765 #endif
07766
07767
07768 AST_LIST_LOCK(&active_list);
07769 AST_LIST_REMOVE(&active_list, thread, list);
07770 AST_LIST_UNLOCK(&active_list);
07771
07772
07773 put_into_idle = 1;
07774 }
07775
07776
07777
07778
07779 pthread_cleanup_pop(1);
07780
07781 return NULL;
07782 }
07783
07784 static int iax2_do_register(struct iax2_registry *reg)
07785 {
07786 struct iax_ie_data ied;
07787 if (option_debug && iaxdebug)
07788 ast_log(LOG_DEBUG, "Sending registration request for '%s'\n", reg->username);
07789
07790 if (reg->dnsmgr &&
07791 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
07792
07793 ast_dnsmgr_refresh(reg->dnsmgr);
07794 }
07795
07796
07797
07798
07799
07800 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
07801 ast_mutex_lock(&iaxsl[reg->callno]);
07802 iax2_destroy(reg->callno);
07803 ast_mutex_unlock(&iaxsl[reg->callno]);
07804 reg->callno = 0;
07805 }
07806 if (!reg->addr.sin_addr.s_addr) {
07807 if (option_debug && iaxdebug)
07808 ast_log(LOG_DEBUG, "Unable to send registration request for '%s' without IP address\n", reg->username);
07809
07810 if (reg->expire > -1)
07811 ast_sched_del(sched, reg->expire);
07812 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07813 return -1;
07814 }
07815
07816 if (!reg->callno) {
07817 if (option_debug)
07818 ast_log(LOG_DEBUG, "Allocate call number\n");
07819 reg->callno = find_callno(0, 0, ®->addr, NEW_FORCE, 1, defaultsockfd);
07820 if (reg->callno < 1) {
07821 ast_log(LOG_WARNING, "Unable to create call for registration\n");
07822 return -1;
07823 } else if (option_debug)
07824 ast_log(LOG_DEBUG, "Registration created on call %d\n", reg->callno);
07825 iaxs[reg->callno]->reg = reg;
07826 }
07827
07828 if (reg->expire > -1)
07829 ast_sched_del(sched, reg->expire);
07830
07831 reg->expire = ast_sched_add(sched, (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
07832
07833 memset(&ied, 0, sizeof(ied));
07834 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07835 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07836 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07837 reg->regstate = REG_STATE_REGSENT;
07838 return 0;
07839 }
07840
07841 static char *iax2_prov_complete_template_3rd(const char *line, const char *word, int pos, int state)
07842 {
07843 if (pos != 3)
07844 return NULL;
07845 return iax_prov_complete_template(line, word, pos, state);
07846 }
07847
07848 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
07849 {
07850
07851
07852 struct iax_ie_data provdata;
07853 struct iax_ie_data ied;
07854 unsigned int sig;
07855 struct sockaddr_in sin;
07856 int callno;
07857 struct create_addr_info cai;
07858
07859 memset(&cai, 0, sizeof(cai));
07860
07861 if (option_debug)
07862 ast_log(LOG_DEBUG, "Provisioning '%s' from template '%s'\n", dest, template);
07863
07864 if (iax_provision_build(&provdata, &sig, template, force)) {
07865 ast_log(LOG_DEBUG, "No provisioning found for template '%s'\n", template);
07866 return 0;
07867 }
07868
07869 if (end) {
07870 memcpy(&sin, end, sizeof(sin));
07871 cai.sockfd = sockfd;
07872 } else if (create_addr(dest, &sin, &cai))
07873 return -1;
07874
07875
07876 memset(&ied, 0, sizeof(ied));
07877 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
07878
07879 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
07880 if (!callno)
07881 return -1;
07882
07883 ast_mutex_lock(&iaxsl[callno]);
07884 if (iaxs[callno]) {
07885
07886 if (iaxs[callno]->autoid > -1)
07887 ast_sched_del(sched, iaxs[callno]->autoid);
07888 iaxs[callno]->autoid = ast_sched_add(sched, 15000, auto_hangup, (void *)(long)callno);
07889 ast_set_flag(iaxs[callno], IAX_PROVISION);
07890
07891 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
07892 }
07893 ast_mutex_unlock(&iaxsl[callno]);
07894
07895 return 1;
07896 }
07897
07898 static char *papp = "IAX2Provision";
07899 static char *psyn = "Provision a calling IAXy with a given template";
07900 static char *pdescrip =
07901 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
07902 "the calling entity is in fact an IAXy) with the given template or\n"
07903 "default if one is not specified. Returns -1 on error or 0 on success.\n";
07904
07905
07906
07907
07908 static int iax2_prov_app(struct ast_channel *chan, void *data)
07909 {
07910 int res;
07911 char *sdata;
07912 char *opts;
07913 int force =0;
07914 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
07915 if (ast_strlen_zero(data))
07916 data = "default";
07917 sdata = ast_strdupa(data);
07918 opts = strchr(sdata, '|');
07919 if (opts)
07920 *opts='\0';
07921
07922 if (chan->tech != &iax2_tech) {
07923 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
07924 return -1;
07925 }
07926 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
07927 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
07928 return -1;
07929 }
07930 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
07931 if (option_verbose > 2)
07932 ast_verbose(VERBOSE_PREFIX_3 "Provisioned IAXY at '%s' with '%s'= %d\n",
07933 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
07934 sdata, res);
07935 return res;
07936 }
07937
07938
07939 static int iax2_prov_cmd(int fd, int argc, char *argv[])
07940 {
07941 int force = 0;
07942 int res;
07943 if (argc < 4)
07944 return RESULT_SHOWUSAGE;
07945 if ((argc > 4)) {
07946 if (!strcasecmp(argv[4], "forced"))
07947 force = 1;
07948 else
07949 return RESULT_SHOWUSAGE;
07950 }
07951 res = iax2_provision(NULL, -1, argv[2], argv[3], force);
07952 if (res < 0)
07953 ast_cli(fd, "Unable to find peer/address '%s'\n", argv[2]);
07954 else if (res < 1)
07955 ast_cli(fd, "No template (including wildcard) matching '%s'\n", argv[3]);
07956 else
07957 ast_cli(fd, "Provisioning '%s' with template '%s'%s\n", argv[2], argv[3], force ? ", forced" : "");
07958 return RESULT_SUCCESS;
07959 }
07960
07961 static void __iax2_poke_noanswer(void *data)
07962 {
07963 struct iax2_peer *peer = data;
07964 if (peer->lastms > -1) {
07965 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
07966 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
07967 ast_device_state_changed("IAX2/%s", peer->name);
07968 }
07969 if (peer->callno > 0) {
07970 ast_mutex_lock(&iaxsl[peer->callno]);
07971 iax2_destroy(peer->callno);
07972 ast_mutex_unlock(&iaxsl[peer->callno]);
07973 }
07974 peer->callno = 0;
07975 peer->lastms = -1;
07976
07977 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer);
07978 }
07979
07980 static int iax2_poke_noanswer(void *data)
07981 {
07982 struct iax2_peer *peer = data;
07983 peer->pokeexpire = -1;
07984 #ifdef SCHED_MULTITHREADED
07985 if (schedule_action(__iax2_poke_noanswer, data))
07986 #endif
07987 __iax2_poke_noanswer(data);
07988 return 0;
07989 }
07990
07991 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
07992 {
07993 if (!peer->maxms || !peer->addr.sin_addr.s_addr) {
07994
07995
07996 peer->lastms = 0;
07997 peer->historicms = 0;
07998 peer->pokeexpire = -1;
07999 peer->callno = 0;
08000 return 0;
08001 }
08002 if (peer->callno > 0) {
08003 ast_log(LOG_NOTICE, "Still have a callno...\n");
08004 ast_mutex_lock(&iaxsl[peer->callno]);
08005 iax2_destroy(peer->callno);
08006 ast_mutex_unlock(&iaxsl[peer->callno]);
08007 }
08008 if (heldcall)
08009 ast_mutex_unlock(&iaxsl[heldcall]);
08010 peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, 0, peer->sockfd);
08011 if (heldcall)
08012 ast_mutex_lock(&iaxsl[heldcall]);
08013 if (peer->callno < 1) {
08014 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
08015 return -1;
08016 }
08017
08018
08019 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
08020 iaxs[peer->callno]->peerpoke = peer;
08021
08022
08023 if (peer->pokeexpire > -1)
08024 ast_sched_del(sched, peer->pokeexpire);
08025
08026
08027
08028 if (peer->lastms < 0) {
08029 peer->pokeexpire = ast_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer);
08030 } else
08031 peer->pokeexpire = ast_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer);
08032
08033
08034 send_command(iaxs[peer->callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
08035
08036 return 0;
08037 }
08038
08039 static void free_context(struct iax2_context *con)
08040 {
08041 struct iax2_context *conl;
08042 while(con) {
08043 conl = con;
08044 con = con->next;
08045 free(conl);
08046 }
08047 }
08048
08049 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
08050 {
08051 int callno;
08052 int res;
08053 int fmt, native;
08054 struct sockaddr_in sin;
08055 struct ast_channel *c;
08056 struct parsed_dial_string pds;
08057 struct create_addr_info cai;
08058 char *tmpstr;
08059
08060 memset(&pds, 0, sizeof(pds));
08061 tmpstr = ast_strdupa(data);
08062 parse_dial_string(tmpstr, &pds);
08063
08064 memset(&cai, 0, sizeof(cai));
08065 cai.capability = iax2_capability;
08066
08067 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08068
08069 if (!pds.peer) {
08070 ast_log(LOG_WARNING, "No peer given\n");
08071 return NULL;
08072 }
08073
08074
08075
08076 if (create_addr(pds.peer, &sin, &cai)) {
08077 *cause = AST_CAUSE_UNREGISTERED;
08078 return NULL;
08079 }
08080
08081 if (pds.port)
08082 sin.sin_port = htons(atoi(pds.port));
08083
08084 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
08085 if (callno < 1) {
08086 ast_log(LOG_WARNING, "Unable to create call\n");
08087 *cause = AST_CAUSE_CONGESTION;
08088 return NULL;
08089 }
08090
08091 ast_mutex_lock(&iaxsl[callno]);
08092
08093
08094 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08095 if (ast_test_flag(&cai, IAX_TRUNK))
08096 callno = make_trunk(callno, 1);
08097 iaxs[callno]->maxtime = cai.maxtime;
08098 if (cai.found)
08099 ast_string_field_set(iaxs[callno], host, pds.peer);
08100
08101 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
08102
08103 ast_mutex_unlock(&iaxsl[callno]);
08104
08105 if (c) {
08106
08107 if (c->nativeformats & format)
08108 c->nativeformats &= format;
08109 else {
08110 native = c->nativeformats;
08111 fmt = format;
08112 res = ast_translator_best_choice(&fmt, &native);
08113 if (res < 0) {
08114 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
08115 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
08116 ast_hangup(c);
08117 return NULL;
08118 }
08119 c->nativeformats = native;
08120 }
08121 c->readformat = ast_best_codec(c->nativeformats);
08122 c->writeformat = c->readformat;
08123 }
08124
08125 return c;
08126 }
08127
08128 static void *sched_thread(void *ignore)
08129 {
08130 int count;
08131 int res;
08132 struct timeval tv;
08133 struct timespec ts;
08134
08135 for (;;) {
08136 res = ast_sched_wait(sched);
08137 if ((res > 1000) || (res < 0))
08138 res = 1000;
08139 tv = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
08140 ts.tv_sec = tv.tv_sec;
08141 ts.tv_nsec = tv.tv_usec * 1000;
08142
08143 pthread_testcancel();
08144 ast_mutex_lock(&sched_lock);
08145 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
08146 ast_mutex_unlock(&sched_lock);
08147 pthread_testcancel();
08148
08149 count = ast_sched_runq(sched);
08150 if (count >= 20)
08151 ast_log(LOG_DEBUG, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
08152 }
08153 return NULL;
08154 }
08155
08156 static void *network_thread(void *ignore)
08157 {
08158
08159
08160 int res, count, wakeup;
08161 struct iax_frame *f;
08162
08163 if (timingfd > -1)
08164 ast_io_add(io, timingfd, timing_read, AST_IO_IN | AST_IO_PRI, NULL);
08165
08166 for(;;) {
08167 pthread_testcancel();
08168
08169
08170
08171 AST_LIST_LOCK(&iaxq.queue);
08172 count = 0;
08173 wakeup = -1;
08174 AST_LIST_TRAVERSE_SAFE_BEGIN(&iaxq.queue, f, list) {
08175 if (f->sentyet)
08176 continue;
08177
08178
08179 if (ast_mutex_trylock(&iaxsl[f->callno])) {
08180 wakeup = 1;
08181 continue;
08182 }
08183
08184 f->sentyet++;
08185
08186 if (iaxs[f->callno]) {
08187 send_packet(f);
08188 count++;
08189 }
08190
08191 ast_mutex_unlock(&iaxsl[f->callno]);
08192
08193 if (f->retries < 0) {
08194
08195 AST_LIST_REMOVE(&iaxq.queue, f, list);
08196 iaxq.count--;
08197
08198 iax_frame_free(f);
08199 } else {
08200
08201 f->retries++;
08202 f->retrans = ast_sched_add(sched, f->retrytime, attempt_transmit, f);
08203 signal_condition(&sched_lock, &sched_cond);
08204 }
08205 }
08206 AST_LIST_TRAVERSE_SAFE_END
08207 AST_LIST_UNLOCK(&iaxq.queue);
08208
08209 pthread_testcancel();
08210
08211 if (count >= 20)
08212 ast_log(LOG_DEBUG, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
08213
08214
08215 res = ast_io_wait(io, wakeup);
08216 if (res >= 0) {
08217 if (res >= 20)
08218 ast_log(LOG_DEBUG, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
08219 }
08220 }
08221 return NULL;
08222 }
08223
08224 static int start_network_thread(void)
08225 {
08226 pthread_attr_t attr;
08227 int threadcount = 0;
08228 int x;
08229 for (x = 0; x < iaxthreadcount; x++) {
08230 struct iax2_thread *thread = ast_calloc(1, sizeof(struct iax2_thread));
08231 if (thread) {
08232 thread->type = IAX_TYPE_POOL;
08233 thread->threadnum = ++threadcount;
08234 ast_mutex_init(&thread->lock);
08235 ast_cond_init(&thread->cond, NULL);
08236 pthread_attr_init(&attr);
08237 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
08238 if (ast_pthread_create(&thread->threadid, &attr, iax2_process_thread, thread)) {
08239 ast_log(LOG_WARNING, "Failed to create new thread!\n");
08240 free(thread);
08241 thread = NULL;
08242 }
08243 AST_LIST_LOCK(&idle_list);
08244 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
08245 AST_LIST_UNLOCK(&idle_list);
08246 }
08247 }
08248 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
08249 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
08250 if (option_verbose > 1)
08251 ast_verbose(VERBOSE_PREFIX_2 "%d helper threaads started\n", threadcount);
08252 return 0;
08253 }
08254
08255 static struct iax2_context *build_context(char *context)
08256 {
08257 struct iax2_context *con;
08258
08259 if ((con = ast_calloc(1, sizeof(*con))))
08260 ast_copy_string(con->context, context, sizeof(con->context));
08261
08262 return con;
08263 }
08264
08265 static int get_auth_methods(char *value)
08266 {
08267 int methods = 0;
08268 if (strstr(value, "rsa"))
08269 methods |= IAX_AUTH_RSA;
08270 if (strstr(value, "md5"))
08271 methods |= IAX_AUTH_MD5;
08272 if (strstr(value, "plaintext"))
08273 methods |= IAX_AUTH_PLAINTEXT;
08274 return methods;
08275 }
08276
08277
08278
08279
08280
08281 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
08282 {
08283 int sd;
08284 int res;
08285
08286 sd = socket(AF_INET, SOCK_DGRAM, 0);
08287 if (sd < 0) {
08288 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
08289 return -1;
08290 }
08291
08292 res = bind(sd, sa, salen);
08293 if (res < 0) {
08294 ast_log(LOG_DEBUG, "Can't bind: %s\n", strerror(errno));
08295 close(sd);
08296 return 1;
08297 }
08298
08299 close(sd);
08300 return 0;
08301 }
08302
08303
08304
08305
08306 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
08307 {
08308 struct sockaddr_in sin;
08309 int nonlocal = 1;
08310 int port = IAX_DEFAULT_PORTNO;
08311 int sockfd = defaultsockfd;
08312 char *tmp;
08313 char *addr;
08314 char *portstr;
08315
08316 if (!(tmp = ast_strdupa(srcaddr)))
08317 return -1;
08318
08319 addr = strsep(&tmp, ":");
08320 portstr = tmp;
08321
08322 if (portstr) {
08323 port = atoi(portstr);
08324 if (port < 1)
08325 port = IAX_DEFAULT_PORTNO;
08326 }
08327
08328 if (!ast_get_ip(&sin, addr)) {
08329 struct ast_netsock *sock;
08330 int res;
08331
08332 sin.sin_port = 0;
08333 sin.sin_family = AF_INET;
08334 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
08335 if (res == 0) {
08336
08337 sin.sin_port = htons(port);
08338 if (!(sock = ast_netsock_find(netsock, &sin)))
08339 sock = ast_netsock_find(outsock, &sin);
08340 if (sock) {
08341 sockfd = ast_netsock_sockfd(sock);
08342 nonlocal = 0;
08343 } else {
08344 unsigned int orig_saddr = sin.sin_addr.s_addr;
08345
08346 sin.sin_addr.s_addr = INADDR_ANY;
08347 if (ast_netsock_find(netsock, &sin)) {
08348 sin.sin_addr.s_addr = orig_saddr;
08349 sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
08350 if (sock) {
08351 sockfd = ast_netsock_sockfd(sock);
08352 ast_netsock_unref(sock);
08353 nonlocal = 0;
08354 } else {
08355 nonlocal = 2;
08356 }
08357 }
08358 }
08359 }
08360 }
08361
08362 peer->sockfd = sockfd;
08363
08364 if (nonlocal == 1) {
08365 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
08366 srcaddr, peer->name);
08367 return -1;
08368 } else if (nonlocal == 2) {
08369 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
08370 srcaddr, peer->name);
08371 return -1;
08372 } else {
08373 ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
08374 return 0;
08375 }
08376 }
08377
08378
08379
08380 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
08381 {
08382 struct iax2_peer *peer = NULL;
08383 struct ast_ha *oldha = NULL;
08384 int maskfound=0;
08385 int found=0;
08386 int firstpass=1;
08387
08388 AST_LIST_LOCK(&peers);
08389 if (!temponly) {
08390 AST_LIST_TRAVERSE(&peers, peer, entry) {
08391 if (!strcmp(peer->name, name)) {
08392 if (!ast_test_flag(peer, IAX_DELME))
08393 firstpass = 0;
08394 break;
08395 }
08396 }
08397 } else
08398 peer = NULL;
08399 if (peer) {
08400 found++;
08401 if (firstpass) {
08402 oldha = peer->ha;
08403 peer->ha = NULL;
08404 }
08405 AST_LIST_REMOVE(&peers, peer, entry);
08406 AST_LIST_UNLOCK(&peers);
08407 } else {
08408 AST_LIST_UNLOCK(&peers);
08409 if ((peer = ast_calloc(1, sizeof(*peer)))) {
08410 peer->expire = -1;
08411 peer->pokeexpire = -1;
08412 peer->sockfd = defaultsockfd;
08413 if (ast_string_field_init(peer, 32)) {
08414 free(peer);
08415 peer = NULL;
08416 }
08417 }
08418 }
08419 if (peer) {
08420 if (firstpass) {
08421 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
08422 peer->encmethods = iax2_encryption;
08423 peer->adsi = adsi;
08424 ast_string_field_set(peer,secret,"");
08425 if (!found) {
08426 ast_string_field_set(peer, name, name);
08427 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08428 peer->expiry = min_reg_expire;
08429 }
08430 peer->prefs = prefs;
08431 peer->capability = iax2_capability;
08432 peer->smoothing = 0;
08433 peer->pokefreqok = DEFAULT_FREQ_OK;
08434 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
08435 ast_string_field_set(peer,context,"");
08436 ast_string_field_set(peer,peercontext,"");
08437 ast_clear_flag(peer, IAX_HASCALLERID);
08438 ast_string_field_set(peer, cid_name, "");
08439 ast_string_field_set(peer, cid_num, "");
08440 }
08441
08442 if (!v) {
08443 v = alt;
08444 alt = NULL;
08445 }
08446 while(v) {
08447 if (!strcasecmp(v->name, "secret")) {
08448 ast_string_field_set(peer, secret, v->value);
08449 } else if (!strcasecmp(v->name, "mailbox")) {
08450 ast_string_field_set(peer, mailbox, v->value);
08451 } else if (!strcasecmp(v->name, "mohinterpret")) {
08452 ast_string_field_set(peer, mohinterpret, v->value);
08453 } else if (!strcasecmp(v->name, "mohsuggest")) {
08454 ast_string_field_set(peer, mohsuggest, v->value);
08455 } else if (!strcasecmp(v->name, "dbsecret")) {
08456 ast_string_field_set(peer, dbsecret, v->value);
08457 } else if (!strcasecmp(v->name, "trunk")) {
08458 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
08459 if (ast_test_flag(peer, IAX_TRUNK) && (timingfd < 0)) {
08460 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without zaptel timing\n", peer->name);
08461 ast_clear_flag(peer, IAX_TRUNK);
08462 }
08463 } else if (!strcasecmp(v->name, "auth")) {
08464 peer->authmethods = get_auth_methods(v->value);
08465 } else if (!strcasecmp(v->name, "encryption")) {
08466 peer->encmethods = get_encrypt_methods(v->value);
08467 } else if (!strcasecmp(v->name, "notransfer")) {
08468 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
08469 ast_clear_flag(peer, IAX_TRANSFERMEDIA);
08470 ast_set2_flag(peer, ast_true(v->value), IAX_NOTRANSFER);
08471 } else if (!strcasecmp(v->name, "transfer")) {
08472 if (!strcasecmp(v->value, "mediaonly")) {
08473 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
08474 } else if (ast_true(v->value)) {
08475 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
08476 } else
08477 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
08478 } else if (!strcasecmp(v->name, "jitterbuffer")) {
08479 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
08480 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08481 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
08482 } else if (!strcasecmp(v->name, "host")) {
08483 if (!strcasecmp(v->value, "dynamic")) {
08484
08485 ast_set_flag(peer, IAX_DYNAMIC);
08486 if (!found) {
08487
08488
08489 memset(&peer->addr.sin_addr, 0, 4);
08490 if (peer->addr.sin_port) {
08491
08492 peer->defaddr.sin_port = peer->addr.sin_port;
08493 peer->addr.sin_port = 0;
08494 }
08495 }
08496 } else {
08497
08498 if (peer->expire > -1)
08499 ast_sched_del(sched, peer->expire);
08500 peer->expire = -1;
08501 ast_clear_flag(peer, IAX_DYNAMIC);
08502 if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr)) {
08503 ast_string_field_free_pools(peer);
08504 free(peer);
08505 return NULL;
08506 }
08507 if (!peer->addr.sin_port)
08508 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
08509 }
08510 if (!maskfound)
08511 inet_aton("255.255.255.255", &peer->mask);
08512 } else if (!strcasecmp(v->name, "defaultip")) {
08513 if (ast_get_ip(&peer->defaddr, v->value)) {
08514 ast_string_field_free_pools(peer);
08515 free(peer);
08516 return NULL;
08517 }
08518 } else if (!strcasecmp(v->name, "sourceaddress")) {
08519 peer_set_srcaddr(peer, v->value);
08520 } else if (!strcasecmp(v->name, "permit") ||
08521 !strcasecmp(v->name, "deny")) {
08522 peer->ha = ast_append_ha(v->name, v->value, peer->ha);
08523 } else if (!strcasecmp(v->name, "mask")) {
08524 maskfound++;
08525 inet_aton(v->value, &peer->mask);
08526 } else if (!strcasecmp(v->name, "context")) {
08527 ast_string_field_set(peer, context, v->value);
08528 } else if (!strcasecmp(v->name, "regexten")) {
08529 ast_string_field_set(peer, regexten, v->value);
08530 } else if (!strcasecmp(v->name, "peercontext")) {
08531 ast_string_field_set(peer, peercontext, v->value);
08532 } else if (!strcasecmp(v->name, "port")) {
08533 if (ast_test_flag(peer, IAX_DYNAMIC))
08534 peer->defaddr.sin_port = htons(atoi(v->value));
08535 else
08536 peer->addr.sin_port = htons(atoi(v->value));
08537 } else if (!strcasecmp(v->name, "username")) {
08538 ast_string_field_set(peer, username, v->value);
08539 } else if (!strcasecmp(v->name, "allow")) {
08540 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
08541 } else if (!strcasecmp(v->name, "disallow")) {
08542 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
08543 } else if (!strcasecmp(v->name, "callerid")) {
08544 if (!ast_strlen_zero(v->value)) {
08545 char name2[80];
08546 char num2[80];
08547 ast_callerid_split(v->value, name2, 80, num2, 80);
08548 ast_string_field_set(peer, cid_name, name2);
08549 ast_string_field_set(peer, cid_num, num2);
08550 ast_set_flag(peer, IAX_HASCALLERID);
08551 } else {
08552 ast_clear_flag(peer, IAX_HASCALLERID);
08553 ast_string_field_set(peer, cid_name, "");
08554 ast_string_field_set(peer, cid_num, "");
08555 }
08556 } else if (!strcasecmp(v->name, "fullname")) {
08557 if (!ast_strlen_zero(v->value)) {
08558 ast_string_field_set(peer, cid_name, v->value);
08559 ast_set_flag(peer, IAX_HASCALLERID);
08560 } else {
08561 ast_string_field_set(peer, cid_name, "");
08562 if (ast_strlen_zero(peer->cid_num))
08563 ast_clear_flag(peer, IAX_HASCALLERID);
08564 }
08565 } else if (!strcasecmp(v->name, "cid_number")) {
08566 if (!ast_strlen_zero(v->value)) {
08567 ast_string_field_set(peer, cid_num, v->value);
08568 ast_set_flag(peer, IAX_HASCALLERID);
08569 } else {
08570 ast_string_field_set(peer, cid_num, "");
08571 if (ast_strlen_zero(peer->cid_name))
08572 ast_clear_flag(peer, IAX_HASCALLERID);
08573 }
08574 } else if (!strcasecmp(v->name, "sendani")) {
08575 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
08576 } else if (!strcasecmp(v->name, "inkeys")) {
08577 ast_string_field_set(peer, inkeys, v->value);
08578 } else if (!strcasecmp(v->name, "outkey")) {
08579 ast_string_field_set(peer, outkey, v->value);
08580 } else if (!strcasecmp(v->name, "qualify")) {
08581 if (!strcasecmp(v->value, "no")) {
08582 peer->maxms = 0;
08583 } else if (!strcasecmp(v->value, "yes")) {
08584 peer->maxms = DEFAULT_MAXMS;
08585 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
08586 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);
08587 peer->maxms = 0;
08588 }
08589 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
08590 peer->smoothing = ast_true(v->value);
08591 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
08592 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
08593 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);
08594 }
08595 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
08596 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
08597 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);
08598 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
08599 } else if (!strcasecmp(v->name, "timezone")) {
08600 ast_string_field_set(peer, zonetag, v->value);
08601 } else if (!strcasecmp(v->name, "adsi")) {
08602 peer->adsi = ast_true(v->value);
08603 }
08604
08605 v = v->next;
08606 if (!v) {
08607 v = alt;
08608 alt = NULL;
08609 }
08610 }
08611 if (!peer->authmethods)
08612 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08613 ast_clear_flag(peer, IAX_DELME);
08614
08615 peer->addr.sin_family = AF_INET;
08616 }
08617 if (oldha)
08618 ast_free_ha(oldha);
08619 return peer;
08620 }
08621
08622
08623 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
08624 {
08625 struct iax2_user *user = NULL;
08626 struct iax2_context *con, *conl = NULL;
08627 struct ast_ha *oldha = NULL;
08628 struct iax2_context *oldcon = NULL;
08629 int format;
08630 int firstpass=1;
08631 int oldcurauthreq = 0;
08632 char *varname = NULL, *varval = NULL;
08633 struct ast_variable *tmpvar = NULL;
08634
08635 AST_LIST_LOCK(&users);
08636 if (!temponly) {
08637 AST_LIST_TRAVERSE(&users, user, entry) {
08638 if (!strcmp(user->name, name)) {
08639 if (!ast_test_flag(user, IAX_DELME))
08640 firstpass = 0;
08641 break;
08642 }
08643 }
08644 } else
08645 user = NULL;
08646
08647 if (user) {
08648 if (firstpass) {
08649 oldcurauthreq = user->curauthreq;
08650 oldha = user->ha;
08651 oldcon = user->contexts;
08652 user->ha = NULL;
08653 user->contexts = NULL;
08654 }
08655
08656 AST_LIST_REMOVE(&users, user, entry);
08657 AST_LIST_UNLOCK(&users);
08658 } else {
08659 AST_LIST_UNLOCK(&users);
08660
08661 user = ast_calloc(sizeof(*user),1);
08662 }
08663
08664 if (user) {
08665 if (firstpass) {
08666 ast_string_field_free_pools(user);
08667 memset(user, 0, sizeof(struct iax2_user));
08668 if (ast_string_field_init(user, 32)) {
08669 free(user);
08670 user = NULL;
08671 }
08672 user->maxauthreq = maxauthreq;
08673 user->curauthreq = oldcurauthreq;
08674 user->prefs = prefs;
08675 user->capability = iax2_capability;
08676 user->encmethods = iax2_encryption;
08677 user->adsi = adsi;
08678 ast_string_field_set(user, name, name);
08679 ast_string_field_set(user, language, language);
08680 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
08681 ast_clear_flag(user, IAX_HASCALLERID);
08682 ast_string_field_set(user, cid_name, "");
08683 ast_string_field_set(user, cid_num, "");
08684 }
08685 if (!v) {
08686 v = alt;
08687 alt = NULL;
08688 }
08689 while(v) {
08690 if (!strcasecmp(v->name, "context")) {
08691 con = build_context(v->value);
08692 if (con) {
08693 if (conl)
08694 conl->next = con;
08695 else
08696 user->contexts = con;
08697 conl = con;
08698 }
08699 } else if (!strcasecmp(v->name, "permit") ||
08700 !strcasecmp(v->name, "deny")) {
08701 user->ha = ast_append_ha(v->name, v->value, user->ha);
08702 } else if (!strcasecmp(v->name, "setvar")) {
08703 varname = ast_strdupa(v->value);
08704 if (varname && (varval = strchr(varname,'='))) {
08705 *varval = '\0';
08706 varval++;
08707 if((tmpvar = ast_variable_new(varname, varval))) {
08708 tmpvar->next = user->vars;
08709 user->vars = tmpvar;
08710 }
08711 }
08712 } else if (!strcasecmp(v->name, "allow")) {
08713 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
08714 } else if (!strcasecmp(v->name, "disallow")) {
08715 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
08716 } else if (!strcasecmp(v->name, "trunk")) {
08717 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
08718 if (ast_test_flag(user, IAX_TRUNK) && (timingfd < 0)) {
08719 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without zaptel timing\n", user->name);
08720 ast_clear_flag(user, IAX_TRUNK);
08721 }
08722 } else if (!strcasecmp(v->name, "auth")) {
08723 user->authmethods = get_auth_methods(v->value);
08724 } else if (!strcasecmp(v->name, "encryption")) {
08725 user->encmethods = get_encrypt_methods(v->value);
08726 } else if (!strcasecmp(v->name, "notransfer")) {
08727 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
08728 ast_clear_flag(user, IAX_TRANSFERMEDIA);
08729 ast_set2_flag(user, ast_true(v->value), IAX_NOTRANSFER);
08730 } else if (!strcasecmp(v->name, "transfer")) {
08731 if (!strcasecmp(v->value, "mediaonly")) {
08732 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
08733 } else if (ast_true(v->value)) {
08734 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
08735 } else
08736 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
08737 } else if (!strcasecmp(v->name, "codecpriority")) {
08738 if(!strcasecmp(v->value, "caller"))
08739 ast_set_flag(user, IAX_CODEC_USER_FIRST);
08740 else if(!strcasecmp(v->value, "disabled"))
08741 ast_set_flag(user, IAX_CODEC_NOPREFS);
08742 else if(!strcasecmp(v->value, "reqonly")) {
08743 ast_set_flag(user, IAX_CODEC_NOCAP);
08744 ast_set_flag(user, IAX_CODEC_NOPREFS);
08745 }
08746 } else if (!strcasecmp(v->name, "jitterbuffer")) {
08747 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
08748 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
08749 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
08750 } else if (!strcasecmp(v->name, "dbsecret")) {
08751 ast_string_field_set(user, dbsecret, v->value);
08752 } else if (!strcasecmp(v->name, "secret")) {
08753 if (!ast_strlen_zero(user->secret)) {
08754 char *old = ast_strdupa(user->secret);
08755
08756 ast_string_field_build(user, secret, "%s;%s", old, v->value);
08757 } else
08758 ast_string_field_set(user, secret, v->value);
08759 } else if (!strcasecmp(v->name, "callerid")) {
08760 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
08761 char name2[80];
08762 char num2[80];
08763 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
08764 ast_string_field_set(user, cid_name, name2);
08765 ast_string_field_set(user, cid_num, num2);
08766 ast_set_flag(user, IAX_HASCALLERID);
08767 } else {
08768 ast_clear_flag(user, IAX_HASCALLERID);
08769 ast_string_field_set(user, cid_name, "");
08770 ast_string_field_set(user, cid_num, "");
08771 }
08772 } else if (!strcasecmp(v->name, "fullname")) {
08773 if (!ast_strlen_zero(v->value)) {
08774 ast_string_field_set(user, cid_name, v->value);
08775 ast_set_flag(user, IAX_HASCALLERID);
08776 } else {
08777 ast_string_field_set(user, cid_name, "");
08778 if (ast_strlen_zero(user->cid_num))
08779 ast_clear_flag(user, IAX_HASCALLERID);
08780 }
08781 } else if (!strcasecmp(v->name, "cid_number")) {
08782 if (!ast_strlen_zero(v->value)) {
08783 ast_string_field_set(user, cid_num, v->value);
08784 ast_set_flag(user, IAX_HASCALLERID);
08785 } else {
08786 ast_string_field_set(user, cid_num, "");
08787 if (ast_strlen_zero(user->cid_name))
08788 ast_clear_flag(user, IAX_HASCALLERID);
08789 }
08790 } else if (!strcasecmp(v->name, "accountcode")) {
08791 ast_string_field_set(user, accountcode, v->value);
08792 } else if (!strcasecmp(v->name, "mohinterpret")) {
08793 ast_string_field_set(user, mohinterpret, v->value);
08794 } else if (!strcasecmp(v->name, "mohsuggest")) {
08795 ast_string_field_set(user, mohsuggest, v->value);
08796 } else if (!strcasecmp(v->name, "language")) {
08797 ast_string_field_set(user, language, v->value);
08798 } else if (!strcasecmp(v->name, "amaflags")) {
08799 format = ast_cdr_amaflags2int(v->value);
08800 if (format < 0) {
08801 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
08802 } else {
08803 user->amaflags = format;
08804 }
08805 } else if (!strcasecmp(v->name, "inkeys")) {
08806 ast_string_field_set(user, inkeys, v->value);
08807 } else if (!strcasecmp(v->name, "maxauthreq")) {
08808 user->maxauthreq = atoi(v->value);
08809 if (user->maxauthreq < 0)
08810 user->maxauthreq = 0;
08811 } else if (!strcasecmp(v->name, "adsi")) {
08812 user->adsi = ast_true(v->value);
08813 }
08814
08815 v = v->next;
08816 if (!v) {
08817 v = alt;
08818 alt = NULL;
08819 }
08820 }
08821 if (!user->authmethods) {
08822 if (!ast_strlen_zero(user->secret)) {
08823 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08824 if (!ast_strlen_zero(user->inkeys))
08825 user->authmethods |= IAX_AUTH_RSA;
08826 } else if (!ast_strlen_zero(user->inkeys)) {
08827 user->authmethods = IAX_AUTH_RSA;
08828 } else {
08829 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
08830 }
08831 }
08832 ast_clear_flag(user, IAX_DELME);
08833 }
08834 if (oldha)
08835 ast_free_ha(oldha);
08836 if (oldcon)
08837 free_context(oldcon);
08838 return user;
08839 }
08840
08841 static void delete_users(void)
08842 {
08843 struct iax2_user *user;
08844 struct iax2_peer *peer;
08845 struct iax2_registry *reg;
08846
08847 AST_LIST_LOCK(&users);
08848 AST_LIST_TRAVERSE(&users, user, entry)
08849 ast_set_flag(user, IAX_DELME);
08850 AST_LIST_UNLOCK(&users);
08851
08852 AST_LIST_LOCK(®istrations);
08853 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
08854 if (reg->expire > -1)
08855 ast_sched_del(sched, reg->expire);
08856 if (reg->callno) {
08857 ast_mutex_lock(&iaxsl[reg->callno]);
08858 if (iaxs[reg->callno]) {
08859 iaxs[reg->callno]->reg = NULL;
08860 iax2_destroy(reg->callno);
08861 }
08862 ast_mutex_unlock(&iaxsl[reg->callno]);
08863 }
08864 if (reg->dnsmgr)
08865 ast_dnsmgr_release(reg->dnsmgr);
08866 free(reg);
08867 }
08868 AST_LIST_UNLOCK(®istrations);
08869
08870 AST_LIST_LOCK(&peers);
08871 AST_LIST_TRAVERSE(&peers, peer, entry)
08872 ast_set_flag(peer, IAX_DELME);
08873 AST_LIST_UNLOCK(&peers);
08874 }
08875
08876 static void destroy_user(struct iax2_user *user)
08877 {
08878 ast_free_ha(user->ha);
08879 free_context(user->contexts);
08880 if(user->vars) {
08881 ast_variables_destroy(user->vars);
08882 user->vars = NULL;
08883 }
08884 ast_string_field_free_pools(user);
08885 free(user);
08886 }
08887
08888 static void prune_users(void)
08889 {
08890 struct iax2_user *user = NULL;
08891
08892 AST_LIST_LOCK(&users);
08893 AST_LIST_TRAVERSE_SAFE_BEGIN(&users, user, entry) {
08894 if (ast_test_flag(user, IAX_DELME)) {
08895 destroy_user(user);
08896 AST_LIST_REMOVE_CURRENT(&users, entry);
08897 }
08898 }
08899 AST_LIST_TRAVERSE_SAFE_END
08900 AST_LIST_UNLOCK(&users);
08901
08902 }
08903
08904 static void destroy_peer(struct iax2_peer *peer)
08905 {
08906 ast_free_ha(peer->ha);
08907
08908
08909 if (peer->expire > -1)
08910 ast_sched_del(sched, peer->expire);
08911 if (peer->pokeexpire > -1)
08912 ast_sched_del(sched, peer->pokeexpire);
08913 if (peer->callno > 0) {
08914 ast_mutex_lock(&iaxsl[peer->callno]);
08915 iax2_destroy(peer->callno);
08916 ast_mutex_unlock(&iaxsl[peer->callno]);
08917 }
08918
08919 register_peer_exten(peer, 0);
08920
08921 if (peer->dnsmgr)
08922 ast_dnsmgr_release(peer->dnsmgr);
08923
08924 ast_string_field_free_pools(peer);
08925
08926 free(peer);
08927 }
08928
08929 static void prune_peers(void){
08930
08931 struct iax2_peer *peer = NULL;
08932
08933 AST_LIST_LOCK(&peers);
08934 AST_LIST_TRAVERSE_SAFE_BEGIN(&peers, peer, entry) {
08935 if (ast_test_flag(peer, IAX_DELME)) {
08936 destroy_peer(peer);
08937 AST_LIST_REMOVE_CURRENT(&peers, entry);
08938 }
08939 }
08940 AST_LIST_TRAVERSE_SAFE_END
08941 AST_LIST_UNLOCK(&peers);
08942 }
08943
08944 static void set_timing(void)
08945 {
08946 #ifdef HAVE_ZAPTEL
08947 int bs = trunkfreq * 8;
08948 if (timingfd > -1) {
08949 if (
08950 #ifdef ZT_TIMERACK
08951 ioctl(timingfd, ZT_TIMERCONFIG, &bs) &&
08952 #endif
08953 ioctl(timingfd, ZT_SET_BLOCKSIZE, &bs))
08954 ast_log(LOG_WARNING, "Unable to set blocksize on timing source\n");
08955 }
08956 #endif
08957 }
08958
08959
08960
08961 static int set_config(char *config_file, int reload)
08962 {
08963 struct ast_config *cfg, *ucfg;
08964 int capability=iax2_capability;
08965 struct ast_variable *v;
08966 char *cat;
08967 const char *utype;
08968 const char *tosval;
08969 int format;
08970 int portno = IAX_DEFAULT_PORTNO;
08971 int x;
08972 struct iax2_user *user;
08973 struct iax2_peer *peer;
08974 struct ast_netsock *ns;
08975 #if 0
08976 static unsigned short int last_port=0;
08977 #endif
08978
08979 cfg = ast_config_load(config_file);
08980
08981 if (!cfg) {
08982 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
08983 return -1;
08984 }
08985
08986
08987 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
08988
08989
08990 memset(&globalflags, 0, sizeof(globalflags));
08991 ast_set_flag(&globalflags, IAX_RTUPDATE);
08992
08993 #ifdef SO_NO_CHECK
08994 nochecksums = 0;
08995 #endif
08996
08997 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08998 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
08999
09000 maxauthreq = 3;
09001
09002 v = ast_variable_browse(cfg, "general");
09003
09004
09005 tosval = ast_variable_retrieve(cfg, "general", "tos");
09006 if (tosval) {
09007 if (ast_str2tos(tosval, &tos))
09008 ast_log(LOG_WARNING, "Invalid tos value, see doc/ip-tos.txt for more information.\n");
09009 }
09010 while(v) {
09011 if (!strcasecmp(v->name, "bindport")){
09012 if (reload)
09013 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
09014 else
09015 portno = atoi(v->value);
09016 } else if (!strcasecmp(v->name, "pingtime"))
09017 ping_time = atoi(v->value);
09018 else if (!strcasecmp(v->name, "iaxthreadcount")) {
09019 if (reload) {
09020 if (atoi(v->value) != iaxthreadcount)
09021 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
09022 } else {
09023 iaxthreadcount = atoi(v->value);
09024 if (iaxthreadcount < 1) {
09025 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
09026 iaxthreadcount = 1;
09027 } else if (iaxthreadcount > 256) {
09028 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
09029 iaxthreadcount = 256;
09030 }
09031 }
09032 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
09033 if (reload) {
09034 AST_LIST_LOCK(&dynamic_list);
09035 iaxmaxthreadcount = atoi(v->value);
09036 AST_LIST_UNLOCK(&dynamic_list);
09037 } else {
09038 iaxmaxthreadcount = atoi(v->value);
09039 if (iaxmaxthreadcount < 0) {
09040 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
09041 iaxmaxthreadcount = 0;
09042 } else if (iaxmaxthreadcount > 256) {
09043 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
09044 iaxmaxthreadcount = 256;
09045 }
09046 }
09047 } else if (!strcasecmp(v->name, "nochecksums")) {
09048 #ifdef SO_NO_CHECK
09049 if (ast_true(v->value))
09050 nochecksums = 1;
09051 else
09052 nochecksums = 0;
09053 #else
09054 if (ast_true(v->value))
09055 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
09056 #endif
09057 }
09058 else if (!strcasecmp(v->name, "maxjitterbuffer"))
09059 maxjitterbuffer = atoi(v->value);
09060 else if (!strcasecmp(v->name, "resyncthreshold"))
09061 resyncthreshold = atoi(v->value);
09062 else if (!strcasecmp(v->name, "maxjitterinterps"))
09063 maxjitterinterps = atoi(v->value);
09064 else if (!strcasecmp(v->name, "lagrqtime"))
09065 lagrq_time = atoi(v->value);
09066 else if (!strcasecmp(v->name, "maxregexpire"))
09067 max_reg_expire = atoi(v->value);
09068 else if (!strcasecmp(v->name, "minregexpire"))
09069 min_reg_expire = atoi(v->value);
09070 else if (!strcasecmp(v->name, "bindaddr")) {
09071 if (reload) {
09072 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
09073 } else {
09074 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, tos, socket_read, NULL))) {
09075 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
09076 } else {
09077 if (option_verbose > 1) {
09078 if (strchr(v->value, ':'))
09079 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s'\n", v->value);
09080 else
09081 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to '%s:%d'\n", v->value, portno);
09082 }
09083 if (defaultsockfd < 0)
09084 defaultsockfd = ast_netsock_sockfd(ns);
09085 ast_netsock_unref(ns);
09086 }
09087 }
09088 } else if (!strcasecmp(v->name, "authdebug"))
09089 authdebug = ast_true(v->value);
09090 else if (!strcasecmp(v->name, "encryption"))
09091 iax2_encryption = get_encrypt_methods(v->value);
09092 else if (!strcasecmp(v->name, "notransfer")) {
09093 ast_log(LOG_NOTICE, "The option 'notransfer' is deprecated in favor of 'transfer' which has options 'yes', 'no', and 'mediaonly'\n");
09094 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
09095 ast_set2_flag((&globalflags), ast_true(v->value), IAX_NOTRANSFER);
09096 } else if (!strcasecmp(v->name, "transfer")) {
09097 if (!strcasecmp(v->value, "mediaonly")) {
09098 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
09099 } else if (ast_true(v->value)) {
09100 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
09101 } else
09102 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
09103 } else if (!strcasecmp(v->name, "codecpriority")) {
09104 if(!strcasecmp(v->value, "caller"))
09105 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
09106 else if(!strcasecmp(v->value, "disabled"))
09107 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09108 else if(!strcasecmp(v->value, "reqonly")) {
09109 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
09110 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
09111 }
09112 } else if (!strcasecmp(v->name, "jitterbuffer"))
09113 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
09114 else if (!strcasecmp(v->name, "forcejitterbuffer"))
09115 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
09116 else if (!strcasecmp(v->name, "delayreject"))
09117 delayreject = ast_true(v->value);
09118 else if (!strcasecmp(v->name, "rtcachefriends"))
09119 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
09120 else if (!strcasecmp(v->name, "rtignoreregexpire"))
09121 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
09122 else if (!strcasecmp(v->name, "rtupdate"))
09123 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
09124 else if (!strcasecmp(v->name, "trunktimestamps"))
09125 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
09126 else if (!strcasecmp(v->name, "rtautoclear")) {
09127 int i = atoi(v->value);
09128 if(i > 0)
09129 global_rtautoclear = i;
09130 else
09131 i = 0;
09132 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
09133 } else if (!strcasecmp(v->name, "trunkfreq")) {
09134 trunkfreq = atoi(v->value);
09135 if (trunkfreq < 10)
09136 trunkfreq = 10;
09137 } else if (!strcasecmp(v->name, "autokill")) {
09138 if (sscanf(v->value, "%d", &x) == 1) {
09139 if (x >= 0)
09140 autokill = x;
09141 else
09142 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
09143 } else if (ast_true(v->value)) {
09144 autokill = DEFAULT_MAXMS;
09145 } else {
09146 autokill = 0;
09147 }
09148 } else if (!strcasecmp(v->name, "bandwidth")) {
09149 if (!strcasecmp(v->value, "low")) {
09150 capability = IAX_CAPABILITY_LOWBANDWIDTH;
09151 } else if (!strcasecmp(v->value, "medium")) {
09152 capability = IAX_CAPABILITY_MEDBANDWIDTH;
09153 } else if (!strcasecmp(v->value, "high")) {
09154 capability = IAX_CAPABILITY_FULLBANDWIDTH;
09155 } else
09156 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
09157 } else if (!strcasecmp(v->name, "allow")) {
09158 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
09159 } else if (!strcasecmp(v->name, "disallow")) {
09160 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
09161 } else if (!strcasecmp(v->name, "register")) {
09162 iax2_register(v->value, v->lineno);
09163 } else if (!strcasecmp(v->name, "iaxcompat")) {
09164 iaxcompat = ast_true(v->value);
09165 } else if (!strcasecmp(v->name, "regcontext")) {
09166 ast_copy_string(regcontext, v->value, sizeof(regcontext));
09167
09168 if (!ast_context_find(regcontext))
09169 ast_context_create(NULL, regcontext, "IAX2");
09170 } else if (!strcasecmp(v->name, "tos")) {
09171 if (ast_str2tos(v->value, &tos))
09172 ast_log(LOG_WARNING, "Invalid tos value at line %d, see doc/ip-tos.txt for more information.'\n", v->lineno);
09173 } else if (!strcasecmp(v->name, "accountcode")) {
09174 ast_copy_string(accountcode, v->value, sizeof(accountcode));
09175 } else if (!strcasecmp(v->name, "mohinterpret")) {
09176 ast_copy_string(mohinterpret, v->value, sizeof(user->mohinterpret));
09177 } else if (!strcasecmp(v->name, "mohsuggest")) {
09178 ast_copy_string(mohsuggest, v->value, sizeof(user->mohsuggest));
09179 } else if (!strcasecmp(v->name, "amaflags")) {
09180 format = ast_cdr_amaflags2int(v->value);
09181 if (format < 0) {
09182 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
09183 } else {
09184 amaflags = format;
09185 }
09186 } else if (!strcasecmp(v->name, "language")) {
09187 ast_copy_string(language, v->value, sizeof(language));
09188 } else if (!strcasecmp(v->name, "maxauthreq")) {
09189 maxauthreq = atoi(v->value);
09190 if (maxauthreq < 0)
09191 maxauthreq = 0;
09192 } else if (!strcasecmp(v->name, "adsi")) {
09193 adsi = ast_true(v->value);
09194 }
09195
09196 v = v->next;
09197 }
09198
09199 if (defaultsockfd < 0) {
09200 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, tos, socket_read, NULL))) {
09201 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
09202 } else {
09203 if (option_verbose > 1)
09204 ast_verbose(VERBOSE_PREFIX_2 "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
09205 defaultsockfd = ast_netsock_sockfd(ns);
09206 ast_netsock_unref(ns);
09207 }
09208 }
09209 if (reload) {
09210 ast_netsock_release(outsock);
09211 outsock = ast_netsock_list_alloc();
09212 if (!outsock) {
09213 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
09214 return -1;
09215 }
09216 ast_netsock_init(outsock);
09217 }
09218
09219 if (min_reg_expire > max_reg_expire) {
09220 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
09221 min_reg_expire, max_reg_expire, max_reg_expire);
09222 min_reg_expire = max_reg_expire;
09223 }
09224 iax2_capability = capability;
09225
09226 ucfg = ast_config_load("users.conf");
09227 if (ucfg) {
09228 struct ast_variable *gen;
09229 int genhasiax;
09230 int genregisteriax;
09231 const char *hasiax, *registeriax;
09232
09233 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
09234 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
09235 gen = ast_variable_browse(ucfg, "general");
09236 cat = ast_category_browse(ucfg, NULL);
09237 while (cat) {
09238 if (strcasecmp(cat, "general")) {
09239 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
09240 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
09241 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
09242
09243 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
09244 if (user) {
09245 AST_LIST_LOCK(&users);
09246 AST_LIST_INSERT_HEAD(&users, user, entry);
09247 AST_LIST_UNLOCK(&users);
09248 }
09249 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
09250 if (peer) {
09251 AST_LIST_LOCK(&peers);
09252 AST_LIST_INSERT_HEAD(&peers, peer, entry);
09253 AST_LIST_UNLOCK(&peers);
09254 if (ast_test_flag(peer, IAX_DYNAMIC))
09255 reg_source_db(peer);
09256 }
09257 }
09258 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
09259 char tmp[256];
09260 const char *host = ast_variable_retrieve(ucfg, cat, "host");
09261 const char *username = ast_variable_retrieve(ucfg, cat, "username");
09262 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
09263 if (!host)
09264 host = ast_variable_retrieve(ucfg, "general", "host");
09265 if (!username)
09266 username = ast_variable_retrieve(ucfg, "general", "username");
09267 if (!secret)
09268 secret = ast_variable_retrieve(ucfg, "general", "secret");
09269 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
09270 if (!ast_strlen_zero(secret))
09271 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
09272 else
09273 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
09274 iax2_register(tmp, 0);
09275 }
09276 }
09277 }
09278 cat = ast_category_browse(ucfg, cat);
09279 }
09280 ast_config_destroy(ucfg);
09281 }
09282
09283 cat = ast_category_browse(cfg, NULL);
09284 while(cat) {
09285 if (strcasecmp(cat, "general")) {
09286 utype = ast_variable_retrieve(cfg, cat, "type");
09287 if (utype) {
09288 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
09289 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
09290 if (user) {
09291 AST_LIST_LOCK(&users);
09292 AST_LIST_INSERT_HEAD(&users, user, entry);
09293 AST_LIST_UNLOCK(&users);
09294 }
09295 }
09296 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
09297 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
09298 if (peer) {
09299 AST_LIST_LOCK(&peers);
09300 AST_LIST_INSERT_HEAD(&peers, peer, entry);
09301 AST_LIST_UNLOCK(&peers);
09302 if (ast_test_flag(peer, IAX_DYNAMIC))
09303 reg_source_db(peer);
09304 }
09305 } else if (strcasecmp(utype, "user")) {
09306 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
09307 }
09308 } else
09309 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
09310 }
09311 cat = ast_category_browse(cfg, cat);
09312 }
09313 ast_config_destroy(cfg);
09314 set_timing();
09315 return capability;
09316 }
09317
09318 static int reload_config(void)
09319 {
09320 char *config = "iax.conf";
09321 struct iax2_registry *reg;
09322 struct iax2_peer *peer;
09323
09324 strcpy(accountcode, "");
09325 strcpy(language, "");
09326 strcpy(mohinterpret, "default");
09327 strcpy(mohsuggest, "");
09328 amaflags = 0;
09329 delayreject = 0;
09330 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
09331 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
09332 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
09333 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
09334 delete_users();
09335 set_config(config, 1);
09336 prune_peers();
09337 prune_users();
09338 AST_LIST_LOCK(®istrations);
09339 AST_LIST_TRAVERSE(®istrations, reg, entry)
09340 iax2_do_register(reg);
09341 AST_LIST_UNLOCK(®istrations);
09342
09343 AST_LIST_LOCK(&peers);
09344 AST_LIST_TRAVERSE(&peers, peer, entry)
09345 iax2_poke_peer(peer, 0);
09346 AST_LIST_UNLOCK(&peers);
09347 reload_firmware();
09348 iax_provision_reload();
09349
09350 return 0;
09351 }
09352
09353 static int iax2_reload(int fd, int argc, char *argv[])
09354 {
09355 return reload_config();
09356 }
09357
09358 static int reload(void)
09359 {
09360 return reload_config();
09361 }
09362
09363 static int cache_get_callno_locked(const char *data)
09364 {
09365 struct sockaddr_in sin;
09366 int x;
09367 int callno;
09368 struct iax_ie_data ied;
09369 struct create_addr_info cai;
09370 struct parsed_dial_string pds;
09371 char *tmpstr;
09372
09373 for (x=0; x<IAX_MAX_CALLS; x++) {
09374
09375
09376 if (!ast_mutex_trylock(&iaxsl[x])) {
09377 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
09378 return x;
09379 ast_mutex_unlock(&iaxsl[x]);
09380 }
09381 }
09382
09383
09384
09385 memset(&cai, 0, sizeof(cai));
09386 memset(&ied, 0, sizeof(ied));
09387 memset(&pds, 0, sizeof(pds));
09388
09389 tmpstr = ast_strdupa(data);
09390 parse_dial_string(tmpstr, &pds);
09391
09392
09393 if (create_addr(pds.peer, &sin, &cai))
09394 return -1;
09395
09396 ast_log(LOG_DEBUG, "peer: %s, username: %s, password: %s, context: %s\n",
09397 pds.peer, pds.username, pds.password, pds.context);
09398
09399 callno = find_callno(0, 0, &sin, NEW_FORCE, 1, cai.sockfd);
09400 if (callno < 1) {
09401 ast_log(LOG_WARNING, "Unable to create call\n");
09402 return -1;
09403 }
09404
09405 ast_mutex_lock(&iaxsl[callno]);
09406 ast_string_field_set(iaxs[callno], dproot, data);
09407 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
09408
09409 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
09410 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
09411
09412
09413
09414 if (pds.exten)
09415 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
09416 if (pds.username)
09417 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
09418 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
09419 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
09420
09421 if (pds.password)
09422 ast_string_field_set(iaxs[callno], secret, pds.password);
09423 if (pds.key)
09424 ast_string_field_set(iaxs[callno], outkey, pds.key);
09425
09426 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
09427
09428 return callno;
09429 }
09430
09431 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
09432 {
09433 struct iax2_dpcache *dp, *prev = NULL, *next;
09434 struct timeval tv;
09435 int x;
09436 int com[2];
09437 int timeout;
09438 int old=0;
09439 int outfd;
09440 int abort;
09441 int callno;
09442 struct ast_channel *c;
09443 struct ast_frame *f;
09444 gettimeofday(&tv, NULL);
09445 dp = dpcache;
09446 while(dp) {
09447 next = dp->next;
09448
09449 if (ast_tvcmp(tv, dp->expiry) > 0) {
09450
09451 if (prev)
09452 prev->next = dp->next;
09453 else
09454 dpcache = dp->next;
09455 if (!dp->peer && !(dp->flags & CACHE_FLAG_PENDING) && !dp->callno) {
09456
09457 free(dp);
09458 } else {
09459 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);
09460 }
09461 dp = next;
09462 continue;
09463 }
09464
09465 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
09466 break;
09467 prev = dp;
09468 dp = next;
09469 }
09470 if (!dp) {
09471
09472
09473 callno = cache_get_callno_locked(data);
09474 if (callno < 0) {
09475 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
09476 return NULL;
09477 }
09478 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
09479 ast_mutex_unlock(&iaxsl[callno]);
09480 return NULL;
09481 }
09482 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
09483 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
09484 gettimeofday(&dp->expiry, NULL);
09485 dp->orig = dp->expiry;
09486
09487 dp->expiry.tv_sec += iaxdefaultdpcache;
09488 dp->next = dpcache;
09489 dp->flags = CACHE_FLAG_PENDING;
09490 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09491 dp->waiters[x] = -1;
09492 dpcache = dp;
09493 dp->peer = iaxs[callno]->dpentries;
09494 iaxs[callno]->dpentries = dp;
09495
09496 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
09497 iax2_dprequest(dp, callno);
09498 ast_mutex_unlock(&iaxsl[callno]);
09499 }
09500
09501 if (dp->flags & CACHE_FLAG_PENDING) {
09502
09503
09504 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++) {
09505
09506 if (dp->waiters[x] < 0)
09507 break;
09508 }
09509 if (x >= sizeof(dp->waiters) / sizeof(dp->waiters[0])) {
09510 ast_log(LOG_WARNING, "No more waiter positions available\n");
09511 return NULL;
09512 }
09513 if (pipe(com)) {
09514 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
09515 return NULL;
09516 }
09517 dp->waiters[x] = com[1];
09518
09519 timeout = iaxdefaulttimeout * 1000;
09520
09521 ast_mutex_unlock(&dpcache_lock);
09522
09523 if (chan)
09524 old = ast_channel_defer_dtmf(chan);
09525 abort = 0;
09526 while(timeout) {
09527 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
09528 if (outfd > -1) {
09529 break;
09530 }
09531 if (c) {
09532 f = ast_read(c);
09533 if (f)
09534 ast_frfree(f);
09535 else {
09536
09537 break;
09538 abort = 1;
09539 }
09540 }
09541 }
09542 if (!timeout) {
09543 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
09544 }
09545 ast_mutex_lock(&dpcache_lock);
09546 dp->waiters[x] = -1;
09547 close(com[1]);
09548 close(com[0]);
09549 if (abort) {
09550
09551
09552 if (!old && chan)
09553 ast_channel_undefer_dtmf(chan);
09554 return NULL;
09555 }
09556 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
09557
09558 if (dp->flags & CACHE_FLAG_PENDING) {
09559
09560
09561 dp->flags &= ~CACHE_FLAG_PENDING;
09562 dp->flags |= CACHE_FLAG_TIMEOUT;
09563
09564
09565 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
09566 for (x=0;x<sizeof(dp->waiters) / sizeof(dp->waiters[0]); x++)
09567 if (dp->waiters[x] > -1)
09568 write(dp->waiters[x], "asdf", 4);
09569 }
09570 }
09571
09572 if (!old && chan)
09573 ast_channel_undefer_dtmf(chan);
09574 }
09575 return dp;
09576 }
09577
09578
09579 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09580 {
09581 struct iax2_dpcache *dp;
09582 int res = 0;
09583 #if 0
09584 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09585 #endif
09586 if ((priority != 1) && (priority != 2))
09587 return 0;
09588 ast_mutex_lock(&dpcache_lock);
09589 dp = find_cache(chan, data, context, exten, priority);
09590 if (dp) {
09591 if (dp->flags & CACHE_FLAG_EXISTS)
09592 res= 1;
09593 }
09594 ast_mutex_unlock(&dpcache_lock);
09595 if (!dp) {
09596 ast_log(LOG_WARNING, "Unable to make DP cache\n");
09597 }
09598 return res;
09599 }
09600
09601
09602 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09603 {
09604 int res = 0;
09605 struct iax2_dpcache *dp;
09606 #if 0
09607 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09608 #endif
09609 if ((priority != 1) && (priority != 2))
09610 return 0;
09611 ast_mutex_lock(&dpcache_lock);
09612 dp = find_cache(chan, data, context, exten, priority);
09613 if (dp) {
09614 if (dp->flags & CACHE_FLAG_CANEXIST)
09615 res= 1;
09616 }
09617 ast_mutex_unlock(&dpcache_lock);
09618 if (!dp) {
09619 ast_log(LOG_WARNING, "Unable to make DP cache\n");
09620 }
09621 return res;
09622 }
09623
09624
09625 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09626 {
09627 int res = 0;
09628 struct iax2_dpcache *dp;
09629 #if 0
09630 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
09631 #endif
09632 if ((priority != 1) && (priority != 2))
09633 return 0;
09634 ast_mutex_lock(&dpcache_lock);
09635 dp = find_cache(chan, data, context, exten, priority);
09636 if (dp) {
09637 if (dp->flags & CACHE_FLAG_MATCHMORE)
09638 res= 1;
09639 }
09640 ast_mutex_unlock(&dpcache_lock);
09641 if (!dp) {
09642 ast_log(LOG_WARNING, "Unable to make DP cache\n");
09643 }
09644 return res;
09645 }
09646
09647
09648 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
09649 {
09650 char odata[256];
09651 char req[256];
09652 char *ncontext;
09653 struct iax2_dpcache *dp;
09654 struct ast_app *dial;
09655 #if 0
09656 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);
09657 #endif
09658 if (priority == 2) {
09659
09660 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
09661 if (dialstatus) {
09662 dial = pbx_findapp(dialstatus);
09663 if (dial)
09664 pbx_exec(chan, dial, "");
09665 }
09666 return -1;
09667 } else if (priority != 1)
09668 return -1;
09669 ast_mutex_lock(&dpcache_lock);
09670 dp = find_cache(chan, data, context, exten, priority);
09671 if (dp) {
09672 if (dp->flags & CACHE_FLAG_EXISTS) {
09673 ast_copy_string(odata, data, sizeof(odata));
09674 ncontext = strchr(odata, '/');
09675 if (ncontext) {
09676 *ncontext = '\0';
09677 ncontext++;
09678 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
09679 } else {
09680 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
09681 }
09682 if (option_verbose > 2)
09683 ast_verbose(VERBOSE_PREFIX_3 "Executing Dial('%s')\n", req);
09684 } else {
09685 ast_mutex_unlock(&dpcache_lock);
09686 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
09687 return -1;
09688 }
09689 }
09690 ast_mutex_unlock(&dpcache_lock);
09691 dial = pbx_findapp("Dial");
09692 if (dial) {
09693 return pbx_exec(chan, dial, req);
09694 } else {
09695 ast_log(LOG_WARNING, "No dial application registered\n");
09696 }
09697 return -1;
09698 }
09699
09700 static int function_iaxpeer(struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len)
09701 {
09702 struct iax2_peer *peer;
09703 char *peername, *colname;
09704
09705 peername = ast_strdupa(data);
09706
09707
09708 if (!strcmp(peername,"CURRENTCHANNEL")) {
09709 unsigned short callno;
09710 if (chan->tech != &iax2_tech)
09711 return -1;
09712 callno = PTR_TO_CALLNO(chan->tech_pvt);
09713 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
09714 return 0;
09715 }
09716
09717 if ((colname = strchr(peername, ':')))
09718 *colname++ = '\0';
09719 else if ((colname = strchr(peername, '|')))
09720 *colname++ = '\0';
09721 else
09722 colname = "ip";
09723
09724 if (!(peer = find_peer(peername, 1)))
09725 return -1;
09726
09727 if (!strcasecmp(colname, "ip")) {
09728 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
09729 } else if (!strcasecmp(colname, "status")) {
09730 peer_status(peer, buf, len);
09731 } else if (!strcasecmp(colname, "mailbox")) {
09732 ast_copy_string(buf, peer->mailbox, len);
09733 } else if (!strcasecmp(colname, "context")) {
09734 ast_copy_string(buf, peer->context, len);
09735 } else if (!strcasecmp(colname, "expire")) {
09736 snprintf(buf, len, "%d", peer->expire);
09737 } else if (!strcasecmp(colname, "dynamic")) {
09738 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
09739 } else if (!strcasecmp(colname, "callerid_name")) {
09740 ast_copy_string(buf, peer->cid_name, len);
09741 } else if (!strcasecmp(colname, "callerid_num")) {
09742 ast_copy_string(buf, peer->cid_num, len);
09743 } else if (!strcasecmp(colname, "codecs")) {
09744 ast_getformatname_multiple(buf, len -1, peer->capability);
09745 } else if (!strncasecmp(colname, "codec[", 6)) {
09746 char *codecnum, *ptr;
09747 int index = 0, codec = 0;
09748
09749 codecnum = strchr(colname, '[');
09750 *codecnum = '\0';
09751 codecnum++;
09752 if ((ptr = strchr(codecnum, ']'))) {
09753 *ptr = '\0';
09754 }
09755 index = atoi(codecnum);
09756 if((codec = ast_codec_pref_index(&peer->prefs, index))) {
09757 ast_copy_string(buf, ast_getformatname(codec), len);
09758 }
09759 }
09760
09761 return 0;
09762 }
09763
09764 struct ast_custom_function iaxpeer_function = {
09765 .name = "IAXPEER",
09766 .synopsis = "Gets IAX peer information",
09767 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[|item])",
09768 .read = function_iaxpeer,
09769 .desc = "If peername specified, valid items are:\n"
09770 "- ip (default) The IP address.\n"
09771 "- status The peer's status (if qualify=yes)\n"
09772 "- mailbox The configured mailbox.\n"
09773 "- context The configured context.\n"
09774 "- expire The epoch time of the next expire.\n"
09775 "- dynamic Is it dynamic? (yes/no).\n"
09776 "- callerid_name The configured Caller ID name.\n"
09777 "- callerid_num The configured Caller ID number.\n"
09778 "- codecs The configured codecs.\n"
09779 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
09780 "\n"
09781 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
09782 "\n"
09783 };
09784
09785
09786
09787 static int iax2_devicestate(void *data)
09788 {
09789 struct parsed_dial_string pds;
09790 char *tmp = ast_strdupa(data);
09791 struct iax2_peer *p;
09792 int res = AST_DEVICE_INVALID;
09793
09794 memset(&pds, 0, sizeof(pds));
09795 parse_dial_string(tmp, &pds);
09796 if (ast_strlen_zero(pds.peer))
09797 return res;
09798
09799 if (option_debug > 2)
09800 ast_log(LOG_DEBUG, "Checking device state for device %s\n", pds.peer);
09801
09802
09803 if (!(p = find_peer(pds.peer, 1)))
09804 return res;
09805
09806 res = AST_DEVICE_UNAVAILABLE;
09807 if (option_debug > 2)
09808 ast_log(LOG_DEBUG, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
09809 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
09810
09811 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
09812 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
09813
09814
09815 if (p->historicms == 0 || p->historicms <= p->maxms)
09816
09817 res = AST_DEVICE_UNKNOWN;
09818 }
09819
09820 if (ast_test_flag(p, IAX_TEMPONLY))
09821 destroy_peer(p);
09822
09823 return res;
09824 }
09825
09826 static struct ast_switch iax2_switch =
09827 {
09828 name: "IAX2",
09829 description: "IAX Remote Dialplan Switch",
09830 exists: iax2_exists,
09831 canmatch: iax2_canmatch,
09832 exec: iax2_exec,
09833 matchmore: iax2_matchmore,
09834 };
09835
09836 static char show_stats_usage[] =
09837 "Usage: iax2 show stats\n"
09838 " Display statistics on IAX channel driver.\n";
09839
09840 static char show_cache_usage[] =
09841 "Usage: iax2 show cache\n"
09842 " Display currently cached IAX Dialplan results.\n";
09843
09844 static char show_peer_usage[] =
09845 "Usage: iax2 show peer <name>\n"
09846 " Display details on specific IAX peer\n";
09847
09848 static char prune_realtime_usage[] =
09849 "Usage: iax2 prune realtime [<peername>|all]\n"
09850 " Prunes object(s) from the cache\n";
09851
09852 static char iax2_reload_usage[] =
09853 "Usage: iax2 reload\n"
09854 " Reloads IAX configuration from iax.conf\n";
09855
09856 static char show_prov_usage[] =
09857 "Usage: iax2 provision <host> <template> [forced]\n"
09858 " Provisions the given peer or IP address using a template\n"
09859 " matching either 'template' or '*' if the template is not\n"
09860 " found. If 'forced' is specified, even empty provisioning\n"
09861 " fields will be provisioned as empty fields.\n";
09862
09863 static char show_users_usage[] =
09864 "Usage: iax2 show users [like <pattern>]\n"
09865 " Lists all known IAX2 users.\n"
09866 " Optional regular expression pattern is used to filter the user list.\n";
09867
09868 static char show_channels_usage[] =
09869 "Usage: iax2 show channels\n"
09870 " Lists all currently active IAX channels.\n";
09871
09872 static char show_netstats_usage[] =
09873 "Usage: iax2 show netstats\n"
09874 " Lists network status for all currently active IAX channels.\n";
09875
09876 static char show_threads_usage[] =
09877 "Usage: iax2 show threads\n"
09878 " Lists status of IAX helper threads\n";
09879
09880 static char show_peers_usage[] =
09881 "Usage: iax2 show peers [registered] [like <pattern>]\n"
09882 " Lists all known IAX2 peers.\n"
09883 " Optional 'registered' argument lists only peers with known addresses.\n"
09884 " Optional regular expression pattern is used to filter the peer list.\n";
09885
09886 static char show_firmware_usage[] =
09887 "Usage: iax2 show firmware\n"
09888 " Lists all known IAX firmware images.\n";
09889
09890 static char show_reg_usage[] =
09891 "Usage: iax2 show registry\n"
09892 " Lists all registration requests and status.\n";
09893
09894 static char debug_usage[] =
09895 "Usage: iax2 set debug\n"
09896 " Enables dumping of IAX packets for debugging purposes\n";
09897
09898 static char no_debug_usage[] =
09899 "Usage: iax2 set debug off\n"
09900 " Disables dumping of IAX packets for debugging purposes\n";
09901
09902 static char debug_trunk_usage[] =
09903 "Usage: iax2 set debug trunk\n"
09904 " Requests current status of IAX trunking\n";
09905
09906 static char no_debug_trunk_usage[] =
09907 "Usage: iax2 set debug trunk off\n"
09908 " Requests current status of IAX trunking\n";
09909
09910 static char debug_jb_usage[] =
09911 "Usage: iax2 set debug jb\n"
09912 " Enables jitterbuffer debugging information\n";
09913
09914 static char no_debug_jb_usage[] =
09915 "Usage: iax2 set debug jb off\n"
09916 " Disables jitterbuffer debugging information\n";
09917
09918 static char iax2_test_losspct_usage[] =
09919 "Usage: iax2 test losspct <percentage>\n"
09920 " For testing, throws away <percentage> percent of incoming packets\n";
09921
09922 #ifdef IAXTESTS
09923 static char iax2_test_late_usage[] =
09924 "Usage: iax2 test late <ms>\n"
09925 " For testing, count the next frame as <ms> ms late\n";
09926
09927 static char iax2_test_resync_usage[] =
09928 "Usage: iax2 test resync <ms>\n"
09929 " For testing, adjust all future frames by <ms> ms\n";
09930
09931 static char iax2_test_jitter_usage[] =
09932 "Usage: iax2 test jitter <ms> <pct>\n"
09933 " For testing, simulate maximum jitter of +/- <ms> on <pct> percentage of packets. If <pct> is not specified, adds jitter to all packets.\n";
09934 #endif
09935
09936 static struct ast_cli_entry cli_iax2_trunk_debug_deprecated = {
09937 { "iax2", "trunk", "debug", NULL },
09938 iax2_do_trunk_debug, NULL,
09939 NULL };
09940
09941 static struct ast_cli_entry cli_iax2_jb_debug_deprecated = {
09942 { "iax2", "jb", "debug", NULL },
09943 iax2_do_jb_debug, NULL,
09944 NULL };
09945
09946 static struct ast_cli_entry cli_iax2_no_debug_deprecated = {
09947 { "iax2", "no", "debug", NULL },
09948 iax2_no_debug, NULL,
09949 NULL };
09950
09951 static struct ast_cli_entry cli_iax2_no_trunk_debug_deprecated = {
09952 { "iax2", "no", "trunk", "debug", NULL },
09953 iax2_no_trunk_debug, NULL,
09954 NULL };
09955
09956 static struct ast_cli_entry cli_iax2_no_jb_debug_deprecated = {
09957 { "iax2", "no", "jb", "debug", NULL },
09958 iax2_no_jb_debug, NULL,
09959 NULL };
09960
09961 static struct ast_cli_entry cli_iax2[] = {
09962 { { "iax2", "show", "cache", NULL },
09963 iax2_show_cache, "Display IAX cached dialplan",
09964 show_cache_usage, NULL, },
09965
09966 { { "iax2", "show", "channels", NULL },
09967 iax2_show_channels, "List active IAX channels",
09968 show_channels_usage, NULL, },
09969
09970 { { "iax2", "show", "firmware", NULL },
09971 iax2_show_firmware, "List available IAX firmwares",
09972 show_firmware_usage, NULL, },
09973
09974 { { "iax2", "show", "netstats", NULL },
09975 iax2_show_netstats, "List active IAX channel netstats",
09976 show_netstats_usage, NULL, },
09977
09978 { { "iax2", "show", "peers", NULL },
09979 iax2_show_peers, "List defined IAX peers",
09980 show_peers_usage, NULL, },
09981
09982 { { "iax2", "show", "registry", NULL },
09983 iax2_show_registry, "Display IAX registration status",
09984 show_reg_usage, NULL, },
09985
09986 { { "iax2", "show", "stats", NULL },
09987 iax2_show_stats, "Display IAX statistics",
09988 show_stats_usage, NULL, },
09989
09990 { { "iax2", "show", "threads", NULL },
09991 iax2_show_threads, "Display IAX helper thread info",
09992 show_threads_usage, NULL, },
09993
09994 { { "iax2", "show", "users", NULL },
09995 iax2_show_users, "List defined IAX users",
09996 show_users_usage, NULL, },
09997
09998 { { "iax2", "prune", "realtime", NULL },
09999 iax2_prune_realtime, "Prune a cached realtime lookup",
10000 prune_realtime_usage, complete_iax2_show_peer },
10001
10002 { { "iax2", "reload", NULL },
10003 iax2_reload, "Reload IAX configuration",
10004 iax2_reload_usage },
10005
10006 { { "iax2", "show", "peer", NULL },
10007 iax2_show_peer, "Show details on specific IAX peer",
10008 show_peer_usage, complete_iax2_show_peer },
10009
10010 { { "iax2", "set", "debug", NULL },
10011 iax2_do_debug, "Enable IAX debugging",
10012 debug_usage },
10013
10014 { { "iax2", "set", "debug", "trunk", NULL },
10015 iax2_do_trunk_debug, "Enable IAX trunk debugging",
10016 debug_trunk_usage, NULL, &cli_iax2_trunk_debug_deprecated },
10017
10018 { { "iax2", "set", "debug", "jb", NULL },
10019 iax2_do_jb_debug, "Enable IAX jitterbuffer debugging",
10020 debug_jb_usage, NULL, &cli_iax2_jb_debug_deprecated },
10021
10022 { { "iax2", "set", "debug", "off", NULL },
10023 iax2_no_debug, "Disable IAX debugging",
10024 no_debug_usage, NULL, &cli_iax2_no_debug_deprecated },
10025
10026 { { "iax2", "set", "debug", "trunk", "off", NULL },
10027 iax2_no_trunk_debug, "Disable IAX trunk debugging",
10028 no_debug_trunk_usage, NULL, &cli_iax2_no_trunk_debug_deprecated },
10029
10030 { { "iax2", "set", "debug", "jb", "off", NULL },
10031 iax2_no_jb_debug, "Disable IAX jitterbuffer debugging",
10032 no_debug_jb_usage, NULL, &cli_iax2_no_jb_debug_deprecated },
10033
10034 { { "iax2", "test", "losspct", NULL },
10035 iax2_test_losspct, "Set IAX2 incoming frame loss percentage",
10036 iax2_test_losspct_usage },
10037
10038 { { "iax2", "provision", NULL },
10039 iax2_prov_cmd, "Provision an IAX device",
10040 show_prov_usage, iax2_prov_complete_template_3rd },
10041
10042 #ifdef IAXTESTS
10043 { { "iax2", "test", "late", NULL },
10044 iax2_test_late, "Test the receipt of a late frame",
10045 iax2_test_late_usage },
10046
10047 { { "iax2", "test", "resync", NULL },
10048 iax2_test_resync, "Test a resync in received timestamps",
10049 iax2_test_resync_usage },
10050
10051 { { "iax2", "test", "jitter", NULL },
10052 iax2_test_jitter, "Simulates jitter for testing",
10053 iax2_test_jitter_usage },
10054 #endif
10055 };
10056
10057 static int __unload_module(void)
10058 {
10059 struct iax2_thread *thread = NULL;
10060 int x;
10061
10062
10063
10064
10065
10066 if (netthreadid != AST_PTHREADT_NULL) {
10067 AST_LIST_LOCK(&iaxq.queue);
10068 ast_mutex_lock(&sched_lock);
10069 pthread_cancel(netthreadid);
10070 ast_cond_signal(&sched_cond);
10071 ast_mutex_unlock(&sched_lock);
10072 AST_LIST_UNLOCK(&iaxq.queue);
10073 pthread_join(netthreadid, NULL);
10074 }
10075 if (schedthreadid != AST_PTHREADT_NULL) {
10076 ast_mutex_lock(&sched_lock);
10077 pthread_cancel(schedthreadid);
10078 ast_cond_signal(&sched_cond);
10079 ast_mutex_unlock(&sched_lock);
10080 pthread_join(schedthreadid, NULL);
10081 }
10082
10083
10084 AST_LIST_LOCK(&idle_list);
10085 AST_LIST_TRAVERSE_SAFE_BEGIN(&idle_list, thread, list) {
10086 AST_LIST_REMOVE_CURRENT(&idle_list, list);
10087 pthread_cancel(thread->threadid);
10088 }
10089 AST_LIST_TRAVERSE_SAFE_END
10090 AST_LIST_UNLOCK(&idle_list);
10091
10092 AST_LIST_LOCK(&active_list);
10093 AST_LIST_TRAVERSE_SAFE_BEGIN(&active_list, thread, list) {
10094 AST_LIST_REMOVE_CURRENT(&active_list, list);
10095 pthread_cancel(thread->threadid);
10096 }
10097 AST_LIST_TRAVERSE_SAFE_END
10098 AST_LIST_UNLOCK(&active_list);
10099
10100 AST_LIST_LOCK(&dynamic_list);
10101 AST_LIST_TRAVERSE_SAFE_BEGIN(&dynamic_list, thread, list) {
10102 AST_LIST_REMOVE_CURRENT(&dynamic_list, list);
10103 pthread_cancel(thread->threadid);
10104 }
10105 AST_LIST_TRAVERSE_SAFE_END
10106 AST_LIST_UNLOCK(&dynamic_list);
10107
10108 AST_LIST_HEAD_DESTROY(&iaxq.queue);
10109
10110
10111 while(0 < iaxactivethreadcount)
10112 usleep(10000);
10113
10114 ast_netsock_release(netsock);
10115 ast_netsock_release(outsock);
10116 for (x=0;x<IAX_MAX_CALLS;x++)
10117 if (iaxs[x])
10118 iax2_destroy(x);
10119 ast_manager_unregister( "IAXpeers" );
10120 ast_manager_unregister( "IAXnetstats" );
10121 ast_unregister_application(papp);
10122 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10123 ast_unregister_switch(&iax2_switch);
10124 ast_channel_unregister(&iax2_tech);
10125 delete_users();
10126 iax_provision_unload();
10127 sched_context_destroy(sched);
10128
10129 ast_mutex_destroy(&waresl.lock);
10130
10131 for (x = 0; x < IAX_MAX_CALLS; x++)
10132 ast_mutex_destroy(&iaxsl[x]);
10133
10134 return 0;
10135 }
10136
10137 static int unload_module(void)
10138 {
10139 ast_custom_function_unregister(&iaxpeer_function);
10140 ast_custom_function_unregister(&iaxvar_function);
10141 return __unload_module();
10142 }
10143
10144
10145
10146 static int load_module(void)
10147 {
10148 char *config = "iax.conf";
10149 int res = 0;
10150 int x;
10151 struct iax2_registry *reg = NULL;
10152 struct iax2_peer *peer = NULL;
10153
10154 ast_custom_function_register(&iaxpeer_function);
10155 ast_custom_function_register(&iaxvar_function);
10156
10157 iax_set_output(iax_debug_output);
10158 iax_set_error(iax_error_output);
10159 jb_setoutput(jb_error_output, jb_warning_output, NULL);
10160
10161 #ifdef HAVE_ZAPTEL
10162 #ifdef ZT_TIMERACK
10163 timingfd = open("/dev/zap/timer", O_RDWR);
10164 if (timingfd < 0)
10165 #endif
10166 timingfd = open("/dev/zap/pseudo", O_RDWR);
10167 if (timingfd < 0)
10168 ast_log(LOG_WARNING, "Unable to open IAX timing interface: %s\n", strerror(errno));
10169 #endif
10170
10171 memset(iaxs, 0, sizeof(iaxs));
10172
10173 for (x=0;x<IAX_MAX_CALLS;x++)
10174 ast_mutex_init(&iaxsl[x]);
10175
10176 ast_cond_init(&sched_cond, NULL);
10177
10178 io = io_context_create();
10179 sched = sched_context_create();
10180
10181 if (!io || !sched) {
10182 ast_log(LOG_ERROR, "Out of memory\n");
10183 return -1;
10184 }
10185
10186 netsock = ast_netsock_list_alloc();
10187 if (!netsock) {
10188 ast_log(LOG_ERROR, "Could not allocate netsock list.\n");
10189 return -1;
10190 }
10191 ast_netsock_init(netsock);
10192
10193 outsock = ast_netsock_list_alloc();
10194 if (!outsock) {
10195 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
10196 return -1;
10197 }
10198 ast_netsock_init(outsock);
10199
10200 ast_mutex_init(&waresl.lock);
10201
10202 AST_LIST_HEAD_INIT(&iaxq.queue);
10203
10204 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
10205
10206 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
10207
10208 ast_manager_register( "IAXpeers", 0, manager_iax2_show_peers, "List IAX Peers" );
10209 ast_manager_register( "IAXnetstats", 0, manager_iax2_show_netstats, "Show IAX Netstats" );
10210
10211 if(set_config(config, 0) == -1)
10212 return AST_MODULE_LOAD_DECLINE;
10213
10214 if (ast_channel_register(&iax2_tech)) {
10215 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
10216 __unload_module();
10217 return -1;
10218 }
10219
10220 if (ast_register_switch(&iax2_switch))
10221 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
10222
10223 res = start_network_thread();
10224 if (!res) {
10225 if (option_verbose > 1)
10226 ast_verbose(VERBOSE_PREFIX_2 "IAX Ready and Listening\n");
10227 } else {
10228 ast_log(LOG_ERROR, "Unable to start network thread\n");
10229 ast_netsock_release(netsock);
10230 ast_netsock_release(outsock);
10231 }
10232
10233 AST_LIST_LOCK(®istrations);
10234 AST_LIST_TRAVERSE(®istrations, reg, entry)
10235 iax2_do_register(reg);
10236 AST_LIST_UNLOCK(®istrations);
10237
10238 AST_LIST_LOCK(&peers);
10239 AST_LIST_TRAVERSE(&peers, peer, entry) {
10240 if (peer->sockfd < 0)
10241 peer->sockfd = defaultsockfd;
10242 iax2_poke_peer(peer, 0);
10243 }
10244 AST_LIST_UNLOCK(&peers);
10245 reload_firmware();
10246 iax_provision_reload();
10247 return res;
10248 }
10249
10250 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
10251 .load = load_module,
10252 .unload = unload_module,
10253 .reload = reload,
10254 );