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