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