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