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