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