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