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
00030
00031
00032
00033
00034
00035
00036
00037 #include "asterisk.h"
00038
00039 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 199209 $")
00040
00041 #include <sys/mman.h>
00042 #include <dirent.h>
00043 #include <sys/socket.h>
00044 #include <netinet/in.h>
00045 #include <arpa/inet.h>
00046 #include <netinet/in_systm.h>
00047 #include <netinet/ip.h>
00048 #include <sys/time.h>
00049 #include <sys/signal.h>
00050 #include <signal.h>
00051 #include <strings.h>
00052 #include <netdb.h>
00053 #include <fcntl.h>
00054 #include <sys/stat.h>
00055 #include <regex.h>
00056
00057 #include "asterisk/paths.h"
00058
00059 #include "asterisk/lock.h"
00060 #include "asterisk/frame.h"
00061 #include "asterisk/channel.h"
00062 #include "asterisk/module.h"
00063 #include "asterisk/pbx.h"
00064 #include "asterisk/sched.h"
00065 #include "asterisk/io.h"
00066 #include "asterisk/config.h"
00067 #include "asterisk/cli.h"
00068 #include "asterisk/translate.h"
00069 #include "asterisk/md5.h"
00070 #include "asterisk/cdr.h"
00071 #include "asterisk/crypto.h"
00072 #include "asterisk/acl.h"
00073 #include "asterisk/manager.h"
00074 #include "asterisk/callerid.h"
00075 #include "asterisk/app.h"
00076 #include "asterisk/astdb.h"
00077 #include "asterisk/musiconhold.h"
00078 #include "asterisk/features.h"
00079 #include "asterisk/utils.h"
00080 #include "asterisk/causes.h"
00081 #include "asterisk/localtime.h"
00082 #include "asterisk/aes.h"
00083 #include "asterisk/dnsmgr.h"
00084 #include "asterisk/devicestate.h"
00085 #include "asterisk/netsock.h"
00086 #include "asterisk/stringfields.h"
00087 #include "asterisk/linkedlists.h"
00088 #include "asterisk/event.h"
00089 #include "asterisk/astobj2.h"
00090 #include "asterisk/timing.h"
00091
00092 #include "iax2.h"
00093 #include "iax2-parser.h"
00094 #include "iax2-provision.h"
00095 #include "jitterbuf.h"
00096
00097
00098
00099 #define SCHED_MULTITHREADED
00100
00101
00102
00103 #define DEBUG_SCHED_MULTITHREAD
00104
00105
00106 #ifdef SO_NO_CHECK
00107 static int nochecksums = 0;
00108 #endif
00109
00110 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00111 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00112
00113 #define DEFAULT_THREAD_COUNT 10
00114 #define DEFAULT_MAX_THREAD_COUNT 100
00115 #define DEFAULT_RETRY_TIME 1000
00116 #define MEMORY_SIZE 100
00117 #define DEFAULT_DROP 3
00118
00119 #define DEBUG_SUPPORT
00120
00121 #define MIN_REUSE_TIME 60
00122
00123
00124 #define GAMMA (0.01)
00125
00126 static struct ast_codec_pref prefs;
00127
00128 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00129
00130
00131
00132
00133 #define MAX_TRUNK_MTU 1240
00134
00135 static int global_max_trunk_mtu;
00136 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00137
00138 #define DEFAULT_CONTEXT "default"
00139
00140 static char default_parkinglot[AST_MAX_CONTEXT];
00141
00142 static char language[MAX_LANGUAGE] = "";
00143 static char regcontext[AST_MAX_CONTEXT] = "";
00144
00145 static int maxauthreq = 3;
00146 static int max_retries = 4;
00147 static int ping_time = 21;
00148 static int lagrq_time = 10;
00149 static int maxjitterbuffer=1000;
00150 static int resyncthreshold=1000;
00151 static int maxjitterinterps=10;
00152 static int jittertargetextra = 40;
00153
00154 #define MAX_TRUNKDATA 640 * 200
00155
00156 static int trunkfreq = 20;
00157 static int trunkmaxsize = MAX_TRUNKDATA;
00158
00159 static int authdebug = 1;
00160 static int autokill = 0;
00161 static int iaxcompat = 0;
00162 static int last_authmethod = 0;
00163
00164 static int iaxdefaultdpcache=10 * 60;
00165
00166 static int iaxdefaulttimeout = 5;
00167
00168 static struct {
00169 unsigned int tos;
00170 unsigned int cos;
00171 } qos = { 0, 0 };
00172
00173 static int min_reg_expire;
00174 static int max_reg_expire;
00175
00176 static int srvlookup = 0;
00177
00178 static struct ast_timer *timer;
00179
00180 static struct ast_netsock_list *netsock;
00181 static struct ast_netsock_list *outsock;
00182 static int defaultsockfd = -1;
00183
00184 int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00185
00186
00187 #define IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED)
00188
00189 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00190 ~AST_FORMAT_SLINEAR & \
00191 ~AST_FORMAT_SLINEAR16 & \
00192 ~AST_FORMAT_ULAW & \
00193 ~AST_FORMAT_ALAW & \
00194 ~AST_FORMAT_G722)
00195
00196 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00197 ~AST_FORMAT_G726 & \
00198 ~AST_FORMAT_G726_AAL2 & \
00199 ~AST_FORMAT_ADPCM)
00200
00201 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00202 ~AST_FORMAT_G723_1)
00203
00204
00205 #define DEFAULT_MAXMS 2000
00206 #define DEFAULT_FREQ_OK 60 * 1000
00207 #define DEFAULT_FREQ_NOTOK 10 * 1000
00208
00209
00210 #define IAX_CALLENCRYPTED(pvt) \
00211 (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED))
00212
00213 #define IAX_DEBUGDIGEST(msg, key) do { \
00214 int idx; \
00215 char digest[33] = ""; \
00216 \
00217 if (!iaxdebug) \
00218 break; \
00219 \
00220 for (idx = 0; idx < 16; idx++) \
00221 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00222 \
00223 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00224 } while(0)
00225
00226 static struct io_context *io;
00227 static struct sched_context *sched;
00228
00229 static int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00230
00231 static int iaxdebug = 0;
00232
00233 static int iaxtrunkdebug = 0;
00234
00235 static int test_losspct = 0;
00236 #ifdef IAXTESTS
00237 static int test_late = 0;
00238 static int test_resync = 0;
00239 static int test_jit = 0;
00240 static int test_jitpct = 0;
00241 #endif
00242
00243 static char accountcode[AST_MAX_ACCOUNT_CODE];
00244 static char mohinterpret[MAX_MUSICCLASS];
00245 static char mohsuggest[MAX_MUSICCLASS];
00246 static int amaflags = 0;
00247 static int adsi = 0;
00248 static int delayreject = 0;
00249 static int iax2_encryption = 0;
00250
00251 static struct ast_flags globalflags = { 0 };
00252
00253 static pthread_t netthreadid = AST_PTHREADT_NULL;
00254 static pthread_t schedthreadid = AST_PTHREADT_NULL;
00255 AST_MUTEX_DEFINE_STATIC(sched_lock);
00256 static ast_cond_t sched_cond;
00257
00258 enum iax2_state {
00259 IAX_STATE_STARTED = (1 << 0),
00260 IAX_STATE_AUTHENTICATED = (1 << 1),
00261 IAX_STATE_TBD = (1 << 2),
00262 };
00263
00264 struct iax2_context {
00265 char context[AST_MAX_CONTEXT];
00266 struct iax2_context *next;
00267 };
00268
00269 enum iax2_flags {
00270 IAX_HASCALLERID = (1 << 0),
00271 IAX_DELME = (1 << 1),
00272 IAX_TEMPONLY = (1 << 2),
00273 IAX_TRUNK = (1 << 3),
00274 IAX_NOTRANSFER = (1 << 4),
00275 IAX_USEJITTERBUF = (1 << 5),
00276 IAX_DYNAMIC = (1 << 6),
00277 IAX_SENDANI = (1 << 7),
00278
00279 IAX_ALREADYGONE = (1 << 9),
00280 IAX_PROVISION = (1 << 10),
00281 IAX_QUELCH = (1 << 11),
00282 IAX_ENCRYPTED = (1 << 12),
00283 IAX_KEYPOPULATED = (1 << 13),
00284 IAX_CODEC_USER_FIRST = (1 << 14),
00285 IAX_CODEC_NOPREFS = (1 << 15),
00286 IAX_CODEC_NOCAP = (1 << 16),
00287 IAX_RTCACHEFRIENDS = (1 << 17),
00288 IAX_RTUPDATE = (1 << 18),
00289 IAX_RTAUTOCLEAR = (1 << 19),
00290 IAX_FORCEJITTERBUF = (1 << 20),
00291 IAX_RTIGNOREREGEXPIRE = (1 << 21),
00292 IAX_TRUNKTIMESTAMPS = (1 << 22),
00293 IAX_TRANSFERMEDIA = (1 << 23),
00294 IAX_MAXAUTHREQ = (1 << 24),
00295 IAX_DELAYPBXSTART = (1 << 25),
00296
00297
00298 IAX_ALLOWFWDOWNLOAD = (1 << 26),
00299 };
00300
00301 static int global_rtautoclear = 120;
00302
00303 static int reload_config(void);
00304
00305 struct iax2_user {
00306 AST_DECLARE_STRING_FIELDS(
00307 AST_STRING_FIELD(name);
00308 AST_STRING_FIELD(secret);
00309 AST_STRING_FIELD(dbsecret);
00310 AST_STRING_FIELD(accountcode);
00311 AST_STRING_FIELD(mohinterpret);
00312 AST_STRING_FIELD(mohsuggest);
00313 AST_STRING_FIELD(inkeys);
00314 AST_STRING_FIELD(language);
00315 AST_STRING_FIELD(cid_num);
00316 AST_STRING_FIELD(cid_name);
00317 AST_STRING_FIELD(parkinglot);
00318 );
00319
00320 int authmethods;
00321 int encmethods;
00322 int amaflags;
00323 int adsi;
00324 unsigned int flags;
00325 int capability;
00326 int maxauthreq;
00327 int curauthreq;
00328 struct ast_codec_pref prefs;
00329 struct ast_ha *ha;
00330 struct iax2_context *contexts;
00331 struct ast_variable *vars;
00332 };
00333
00334 struct iax2_peer {
00335 AST_DECLARE_STRING_FIELDS(
00336 AST_STRING_FIELD(name);
00337 AST_STRING_FIELD(username);
00338 AST_STRING_FIELD(secret);
00339 AST_STRING_FIELD(dbsecret);
00340 AST_STRING_FIELD(outkey);
00341
00342 AST_STRING_FIELD(regexten);
00343 AST_STRING_FIELD(context);
00344 AST_STRING_FIELD(peercontext);
00345 AST_STRING_FIELD(mailbox);
00346 AST_STRING_FIELD(mohinterpret);
00347 AST_STRING_FIELD(mohsuggest);
00348 AST_STRING_FIELD(inkeys);
00349
00350 AST_STRING_FIELD(cid_num);
00351 AST_STRING_FIELD(cid_name);
00352 AST_STRING_FIELD(zonetag);
00353 AST_STRING_FIELD(parkinglot);
00354 );
00355 struct ast_codec_pref prefs;
00356 struct ast_dnsmgr_entry *dnsmgr;
00357 struct sockaddr_in addr;
00358 int formats;
00359 int sockfd;
00360 struct in_addr mask;
00361 int adsi;
00362 unsigned int flags;
00363
00364
00365 struct sockaddr_in defaddr;
00366 int authmethods;
00367 int encmethods;
00368
00369 int expire;
00370 int expiry;
00371 int capability;
00372
00373
00374 int callno;
00375 int pokeexpire;
00376 int lastms;
00377 int maxms;
00378
00379 int pokefreqok;
00380 int pokefreqnotok;
00381 int historicms;
00382 int smoothing;
00383
00384 struct ast_event_sub *mwi_event_sub;
00385
00386 struct ast_ha *ha;
00387 };
00388
00389 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00390
00391 struct iax2_trunk_peer {
00392 ast_mutex_t lock;
00393 int sockfd;
00394 struct sockaddr_in addr;
00395 struct timeval txtrunktime;
00396 struct timeval rxtrunktime;
00397 struct timeval lasttxtime;
00398 struct timeval trunkact;
00399 unsigned int lastsent;
00400
00401 unsigned char *trunkdata;
00402 unsigned int trunkdatalen;
00403 unsigned int trunkdataalloc;
00404 int trunkmaxmtu;
00405 int trunkerror;
00406 int calls;
00407 AST_LIST_ENTRY(iax2_trunk_peer) list;
00408 };
00409
00410 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00411
00412 struct iax_firmware {
00413 AST_LIST_ENTRY(iax_firmware) list;
00414 int fd;
00415 int mmaplen;
00416 int dead;
00417 struct ast_iax2_firmware_header *fwh;
00418 unsigned char *buf;
00419 };
00420
00421 enum iax_reg_state {
00422 REG_STATE_UNREGISTERED = 0,
00423 REG_STATE_REGSENT,
00424 REG_STATE_AUTHSENT,
00425 REG_STATE_REGISTERED,
00426 REG_STATE_REJECTED,
00427 REG_STATE_TIMEOUT,
00428 REG_STATE_NOAUTH
00429 };
00430
00431 enum iax_transfer_state {
00432 TRANSFER_NONE = 0,
00433 TRANSFER_BEGIN,
00434 TRANSFER_READY,
00435 TRANSFER_RELEASED,
00436 TRANSFER_PASSTHROUGH,
00437 TRANSFER_MBEGIN,
00438 TRANSFER_MREADY,
00439 TRANSFER_MRELEASED,
00440 TRANSFER_MPASSTHROUGH,
00441 TRANSFER_MEDIA,
00442 TRANSFER_MEDIAPASS
00443 };
00444
00445 struct iax2_registry {
00446 struct sockaddr_in addr;
00447 char username[80];
00448 char secret[80];
00449 int expire;
00450 int refresh;
00451 enum iax_reg_state regstate;
00452 int messages;
00453 int callno;
00454 struct sockaddr_in us;
00455 struct ast_dnsmgr_entry *dnsmgr;
00456 AST_LIST_ENTRY(iax2_registry) entry;
00457 };
00458
00459 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00460
00461
00462 #define MIN_RETRY_TIME 100
00463 #define MAX_RETRY_TIME 10000
00464
00465 #define MAX_JITTER_BUFFER 50
00466 #define MIN_JITTER_BUFFER 10
00467
00468 #define DEFAULT_TRUNKDATA 640 * 10
00469
00470 #define MAX_TIMESTAMP_SKEW 160
00471
00472
00473 #define TS_GAP_FOR_JB_RESYNC 5000
00474
00475 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00476 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00477 static int iaxdynamicthreadcount = 0;
00478 static int iaxdynamicthreadnum = 0;
00479 static int iaxactivethreadcount = 0;
00480
00481 struct iax_rr {
00482 int jitter;
00483 int losspct;
00484 int losscnt;
00485 int packets;
00486 int delay;
00487 int dropped;
00488 int ooo;
00489 };
00490
00491 struct iax2_pvt_ref;
00492
00493 struct chan_iax2_pvt {
00494
00495 int sockfd;
00496
00497 int voiceformat;
00498
00499 int videoformat;
00500
00501 int svoiceformat;
00502
00503 int svideoformat;
00504
00505 int capability;
00506
00507 unsigned int last;
00508
00509 unsigned int lastsent;
00510
00511 unsigned int lastvsent;
00512
00513 unsigned int nextpred;
00514
00515 unsigned int notsilenttx:1;
00516
00517 unsigned int pingtime;
00518
00519 int maxtime;
00520
00521 struct sockaddr_in addr;
00522
00523 struct ast_codec_pref prefs;
00524
00525 struct ast_codec_pref rprefs;
00526
00527 unsigned short callno;
00528
00529 unsigned short peercallno;
00530
00531
00532
00533 int chosenformat;
00534
00535 int peerformat;
00536
00537 int peercapability;
00538
00539 struct timeval offset;
00540
00541 struct timeval rxcore;
00542
00543 jitterbuf *jb;
00544
00545 int jbid;
00546
00547 int lag;
00548
00549 int error;
00550
00551 struct ast_channel *owner;
00552
00553 struct ast_flags state;
00554
00555 int expiry;
00556
00557 unsigned char oseqno;
00558
00559 unsigned char rseqno;
00560
00561 unsigned char iseqno;
00562
00563 unsigned char aseqno;
00564
00565 AST_DECLARE_STRING_FIELDS(
00566
00567 AST_STRING_FIELD(peer);
00568
00569 AST_STRING_FIELD(context);
00570
00571 AST_STRING_FIELD(cid_num);
00572 AST_STRING_FIELD(cid_name);
00573
00574 AST_STRING_FIELD(ani);
00575
00576 AST_STRING_FIELD(dnid);
00577
00578 AST_STRING_FIELD(rdnis);
00579
00580 AST_STRING_FIELD(exten);
00581
00582 AST_STRING_FIELD(username);
00583
00584 AST_STRING_FIELD(secret);
00585
00586 AST_STRING_FIELD(challenge);
00587
00588 AST_STRING_FIELD(inkeys);
00589
00590 AST_STRING_FIELD(outkey);
00591
00592 AST_STRING_FIELD(language);
00593
00594 AST_STRING_FIELD(host);
00595
00596 AST_STRING_FIELD(dproot);
00597 AST_STRING_FIELD(accountcode);
00598 AST_STRING_FIELD(mohinterpret);
00599 AST_STRING_FIELD(mohsuggest);
00600
00601 AST_STRING_FIELD(osptoken);
00602
00603 AST_STRING_FIELD(parkinglot);
00604 );
00605
00606 int authrej;
00607
00608 int authmethods;
00609
00610 int encmethods;
00611
00612 ast_aes_encrypt_key ecx;
00613
00614 ast_aes_decrypt_key mydcx;
00615
00616 ast_aes_decrypt_key dcx;
00617
00618
00619 int keyrotateid;
00620
00621 unsigned char semirand[32];
00622
00623 struct iax2_registry *reg;
00624
00625 struct iax2_peer *peerpoke;
00626
00627 unsigned int flags;
00628 int adsi;
00629
00630
00631 enum iax_transfer_state transferring;
00632
00633 int transferid;
00634
00635 struct sockaddr_in transfer;
00636
00637 unsigned short transfercallno;
00638
00639 ast_aes_encrypt_key tdcx;
00640
00641
00642 int peeradsicpe;
00643
00644
00645 unsigned short bridgecallno;
00646
00647 int pingid;
00648 int lagid;
00649 int autoid;
00650 int authid;
00651 int authfail;
00652 int initid;
00653 int calling_ton;
00654 int calling_tns;
00655 int calling_pres;
00656 int amaflags;
00657 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00658
00659 struct ast_variable *vars;
00660
00661 struct ast_variable *iaxvars;
00662
00663 struct iax_rr remote_rr;
00664
00665 int min;
00666
00667 int frames_dropped;
00668
00669 int frames_received;
00670 };
00671
00672
00673
00674
00675
00676
00677
00678
00679 static AST_LIST_HEAD_STATIC(frame_queue, iax_frame);
00680
00681
00682
00683
00684
00685
00686
00687
00688 #ifdef LOW_MEMORY
00689 #define MAX_PEER_BUCKETS 17
00690 #else
00691 #define MAX_PEER_BUCKETS 563
00692 #endif
00693 static struct ao2_container *peers;
00694
00695 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00696 static struct ao2_container *users;
00697
00698 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00699
00700 enum {
00701
00702 CACHE_FLAG_EXISTS = (1 << 0),
00703
00704 CACHE_FLAG_NONEXISTENT = (1 << 1),
00705
00706 CACHE_FLAG_CANEXIST = (1 << 2),
00707
00708 CACHE_FLAG_PENDING = (1 << 3),
00709
00710 CACHE_FLAG_TIMEOUT = (1 << 4),
00711
00712 CACHE_FLAG_TRANSMITTED = (1 << 5),
00713
00714 CACHE_FLAG_UNKNOWN = (1 << 6),
00715
00716 CACHE_FLAG_MATCHMORE = (1 << 7),
00717 };
00718
00719 struct iax2_dpcache {
00720 char peercontext[AST_MAX_CONTEXT];
00721 char exten[AST_MAX_EXTENSION];
00722 struct timeval orig;
00723 struct timeval expiry;
00724 int flags;
00725 unsigned short callno;
00726 int waiters[256];
00727 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00728 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00729 };
00730
00731 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00732
00733 static void reg_source_db(struct iax2_peer *p);
00734 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00735
00736 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00737 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state);
00738 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00739
00740 enum iax2_thread_iostate {
00741 IAX_IOSTATE_IDLE,
00742 IAX_IOSTATE_READY,
00743 IAX_IOSTATE_PROCESSING,
00744 IAX_IOSTATE_SCHEDREADY,
00745 };
00746
00747 enum iax2_thread_type {
00748 IAX_THREAD_TYPE_POOL,
00749 IAX_THREAD_TYPE_DYNAMIC,
00750 };
00751
00752 struct iax2_pkt_buf {
00753 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00754 size_t len;
00755 unsigned char buf[1];
00756 };
00757
00758 struct iax2_thread {
00759 AST_LIST_ENTRY(iax2_thread) list;
00760 enum iax2_thread_type type;
00761 enum iax2_thread_iostate iostate;
00762 #ifdef SCHED_MULTITHREADED
00763 void (*schedfunc)(const void *);
00764 const void *scheddata;
00765 #endif
00766 #ifdef DEBUG_SCHED_MULTITHREAD
00767 char curfunc[80];
00768 #endif
00769 int actions;
00770 pthread_t threadid;
00771 int threadnum;
00772 struct sockaddr_in iosin;
00773 unsigned char readbuf[4096];
00774 unsigned char *buf;
00775 ssize_t buf_len;
00776 size_t buf_size;
00777 int iofd;
00778 time_t checktime;
00779 ast_mutex_t lock;
00780 ast_cond_t cond;
00781 ast_mutex_t init_lock;
00782 ast_cond_t init_cond;
00783
00784
00785
00786
00787 struct {
00788 unsigned short callno;
00789 struct sockaddr_in sin;
00790 unsigned char type;
00791 unsigned char csub;
00792 } ffinfo;
00793
00794
00795
00796 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
00797 };
00798
00799
00800 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
00801 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
00802 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
00803
00804 static void *iax2_process_thread(void *data);
00805 static void iax2_destroy(int callno);
00806
00807 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
00808 {
00809 ast_mutex_lock(lock);
00810 ast_cond_signal(cond);
00811 ast_mutex_unlock(lock);
00812 }
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS];
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833 static struct ao2_container *iax_peercallno_pvts;
00834
00835
00836
00837
00838
00839
00840
00841
00842 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 static struct timeval lastused[ARRAY_LEN(iaxs)];
00864
00865
00866
00867
00868
00869
00870 static struct ao2_container *iax_transfercallno_pvts;
00871
00872
00873
00874 #define TRUNK_CALL_START ARRAY_LEN(iaxs) / 2
00875
00876
00877 static struct sockaddr_in debugaddr;
00878
00879 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
00880 {
00881 if (iaxdebug ||
00882 (sin && debugaddr.sin_addr.s_addr &&
00883 (!ntohs(debugaddr.sin_port) ||
00884 debugaddr.sin_port == sin->sin_port) &&
00885 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
00886 if (iaxdebug) {
00887 iax_showframe(f, fhi, rx, sin, datalen);
00888 } else {
00889 iaxdebug = 1;
00890 iax_showframe(f, fhi, rx, sin, datalen);
00891 iaxdebug = 0;
00892 }
00893 }
00894 }
00895
00896 static void iax_debug_output(const char *data)
00897 {
00898 if (iaxdebug)
00899 ast_verbose("%s", data);
00900 }
00901
00902 static void iax_error_output(const char *data)
00903 {
00904 ast_log(LOG_WARNING, "%s", data);
00905 }
00906
00907 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
00908 {
00909 va_list args;
00910 char buf[1024];
00911
00912 va_start(args, fmt);
00913 vsnprintf(buf, sizeof(buf), fmt, args);
00914 va_end(args);
00915
00916 ast_log(LOG_ERROR, "%s", buf);
00917 }
00918
00919 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
00920 {
00921 va_list args;
00922 char buf[1024];
00923
00924 va_start(args, fmt);
00925 vsnprintf(buf, sizeof(buf), fmt, args);
00926 va_end(args);
00927
00928 ast_log(LOG_WARNING, "%s", buf);
00929 }
00930
00931 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
00932 {
00933 va_list args;
00934 char buf[1024];
00935
00936 va_start(args, fmt);
00937 vsnprintf(buf, sizeof(buf), fmt, args);
00938 va_end(args);
00939
00940 ast_verbose("%s", buf);
00941 }
00942
00943 static int maxtrunkcall = TRUNK_CALL_START;
00944 static int maxnontrunkcall = 1;
00945
00946 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);
00947 static int expire_registry(const void *data);
00948 static int iax2_answer(struct ast_channel *c);
00949 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
00950 static int iax2_devicestate(void *data);
00951 static int iax2_digit_begin(struct ast_channel *c, char digit);
00952 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
00953 static int iax2_do_register(struct iax2_registry *reg);
00954 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
00955 static int iax2_hangup(struct ast_channel *c);
00956 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
00957 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
00958 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
00959 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
00960 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
00961 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
00962 static int iax2_sendtext(struct ast_channel *c, const char *text);
00963 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
00964 static int iax2_transfer(struct ast_channel *c, const char *dest);
00965 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
00966 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
00967 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00968 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00969 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
00970 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
00971 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
00972 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause);
00973 static struct ast_frame *iax2_read(struct ast_channel *c);
00974 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00975 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
00976 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime);
00977 static void *iax2_dup_variable_datastore(void *);
00978 static void prune_peers(void);
00979 static void prune_users(void);
00980 static void iax2_free_variable_datastore(void *);
00981
00982 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
00983 static int acf_channel_write(struct ast_channel *chan, const char *function, char *data, const char *value);
00984 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
00985 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
00986 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
00987 static void build_rand_pad(unsigned char *buf, ssize_t len);
00988
00989 static const struct ast_channel_tech iax2_tech = {
00990 .type = "IAX2",
00991 .description = tdesc,
00992 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
00993 .properties = AST_CHAN_TP_WANTSJITTER,
00994 .requester = iax2_request,
00995 .devicestate = iax2_devicestate,
00996 .send_digit_begin = iax2_digit_begin,
00997 .send_digit_end = iax2_digit_end,
00998 .send_text = iax2_sendtext,
00999 .send_image = iax2_sendimage,
01000 .send_html = iax2_sendhtml,
01001 .call = iax2_call,
01002 .hangup = iax2_hangup,
01003 .answer = iax2_answer,
01004 .read = iax2_read,
01005 .write = iax2_write,
01006 .write_video = iax2_write,
01007 .indicate = iax2_indicate,
01008 .setoption = iax2_setoption,
01009 .bridge = iax2_bridge,
01010 .transfer = iax2_transfer,
01011 .fixup = iax2_fixup,
01012 .func_channel_read = acf_channel_read,
01013 .func_channel_write = acf_channel_write,
01014 };
01015
01016 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01017 {
01018
01019
01020
01021 }
01022
01023
01024
01025 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01026 {
01027 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01028 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01029 pvt->owner ? pvt->owner->name : "",
01030 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01031 }
01032
01033
01034 static struct ast_datastore_info iax2_variable_datastore_info = {
01035 .type = "IAX2_VARIABLE",
01036 .duplicate = iax2_dup_variable_datastore,
01037 .destroy = iax2_free_variable_datastore,
01038 };
01039
01040 static void *iax2_dup_variable_datastore(void *old)
01041 {
01042 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01043 struct ast_var_t *oldvar, *newvar;
01044
01045 newlist = ast_calloc(sizeof(*newlist), 1);
01046 if (!newlist) {
01047 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01048 return NULL;
01049 }
01050
01051 AST_LIST_HEAD_INIT(newlist);
01052 AST_LIST_LOCK(oldlist);
01053 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01054 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01055 if (newvar)
01056 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01057 else
01058 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01059 }
01060 AST_LIST_UNLOCK(oldlist);
01061 return newlist;
01062 }
01063
01064 static void iax2_free_variable_datastore(void *old)
01065 {
01066 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01067 struct ast_var_t *oldvar;
01068
01069 AST_LIST_LOCK(oldlist);
01070 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01071 ast_free(oldvar);
01072 }
01073 AST_LIST_UNLOCK(oldlist);
01074 AST_LIST_HEAD_DESTROY(oldlist);
01075 ast_free(oldlist);
01076 }
01077
01078
01079
01080
01081
01082 static void insert_idle_thread(struct iax2_thread *thread)
01083 {
01084 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01085 AST_LIST_LOCK(&dynamic_list);
01086 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01087 AST_LIST_UNLOCK(&dynamic_list);
01088 } else {
01089 AST_LIST_LOCK(&idle_list);
01090 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01091 AST_LIST_UNLOCK(&idle_list);
01092 }
01093
01094 return;
01095 }
01096
01097 static struct iax2_thread *find_idle_thread(void)
01098 {
01099 struct iax2_thread *thread = NULL;
01100
01101
01102 AST_LIST_LOCK(&idle_list);
01103 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01104 AST_LIST_UNLOCK(&idle_list);
01105
01106
01107 if (thread) {
01108 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01109 return thread;
01110 }
01111
01112
01113 AST_LIST_LOCK(&dynamic_list);
01114 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01115 AST_LIST_UNLOCK(&dynamic_list);
01116
01117
01118 if (thread) {
01119 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01120 return thread;
01121 }
01122
01123
01124 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01125 return NULL;
01126
01127
01128 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01129 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01130 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01131
01132
01133 ast_mutex_init(&thread->lock);
01134 ast_cond_init(&thread->cond, NULL);
01135 ast_mutex_init(&thread->init_lock);
01136 ast_cond_init(&thread->init_cond, NULL);
01137 ast_mutex_lock(&thread->init_lock);
01138
01139
01140 if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01141 ast_cond_destroy(&thread->cond);
01142 ast_mutex_destroy(&thread->lock);
01143 ast_free(thread);
01144 return NULL;
01145 }
01146
01147
01148
01149 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01150
01151
01152 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01153
01154
01155 ast_mutex_unlock(&thread->init_lock);
01156
01157 return thread;
01158 }
01159
01160 #ifdef SCHED_MULTITHREADED
01161 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01162 {
01163 struct iax2_thread *thread = NULL;
01164 static time_t lasterror;
01165 static time_t t;
01166
01167 thread = find_idle_thread();
01168
01169 if (thread != NULL) {
01170 thread->schedfunc = func;
01171 thread->scheddata = data;
01172 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01173 #ifdef DEBUG_SCHED_MULTITHREAD
01174 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01175 #endif
01176 signal_condition(&thread->lock, &thread->cond);
01177 return 0;
01178 }
01179 time(&t);
01180 if (t != lasterror)
01181 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01182 lasterror = t;
01183
01184 return -1;
01185 }
01186 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01187 #endif
01188
01189 static int iax2_sched_replace(int id, struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01190 {
01191 AST_SCHED_REPLACE(id, con, when, callback, data);
01192 signal_condition(&sched_lock, &sched_cond);
01193
01194 return id;
01195 }
01196
01197 static int iax2_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data)
01198 {
01199 int res;
01200
01201 res = ast_sched_add(con, when, callback, data);
01202 signal_condition(&sched_lock, &sched_cond);
01203
01204 return res;
01205 }
01206
01207 static int send_ping(const void *data);
01208
01209 static void __send_ping(const void *data)
01210 {
01211 int callno = (long) data;
01212
01213 ast_mutex_lock(&iaxsl[callno]);
01214
01215 if (iaxs[callno]) {
01216 if (iaxs[callno]->peercallno) {
01217 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01218 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01219 } else {
01220
01221 iaxs[callno]->pingid = -1;
01222 }
01223 } else if (option_debug > 0) {
01224 ast_log(LOG_DEBUG, "I was supposed to send a PING with callno %d, but no such call exists (and I cannot remove pingid, either).\n", callno);
01225 }
01226
01227 ast_mutex_unlock(&iaxsl[callno]);
01228 }
01229
01230 static int send_ping(const void *data)
01231 {
01232 #ifdef SCHED_MULTITHREADED
01233 if (schedule_action(__send_ping, data))
01234 #endif
01235 __send_ping(data);
01236
01237 return 0;
01238 }
01239
01240 static int get_encrypt_methods(const char *s)
01241 {
01242 int e;
01243 if (!strcasecmp(s, "aes128"))
01244 e = IAX_ENCRYPT_AES128;
01245 else if (ast_true(s))
01246 e = IAX_ENCRYPT_AES128;
01247 else
01248 e = 0;
01249 return e;
01250 }
01251
01252 static int send_lagrq(const void *data);
01253
01254 static void __send_lagrq(const void *data)
01255 {
01256 int callno = (long) data;
01257
01258 ast_mutex_lock(&iaxsl[callno]);
01259
01260 if (iaxs[callno]) {
01261 if (iaxs[callno]->peercallno) {
01262 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01263 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01264 } else {
01265
01266 iaxs[callno]->lagid = -1;
01267 }
01268 } else {
01269 ast_log(LOG_WARNING, "I was supposed to send a LAGRQ with callno %d, but no such call exists (and I cannot remove lagid, either).\n", callno);
01270 }
01271
01272 ast_mutex_unlock(&iaxsl[callno]);
01273 }
01274
01275 static int send_lagrq(const void *data)
01276 {
01277 #ifdef SCHED_MULTITHREADED
01278 if (schedule_action(__send_lagrq, data))
01279 #endif
01280 __send_lagrq(data);
01281
01282 return 0;
01283 }
01284
01285 static unsigned char compress_subclass(int subclass)
01286 {
01287 int x;
01288 int power=-1;
01289
01290 if (subclass < IAX_FLAG_SC_LOG)
01291 return subclass;
01292
01293 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01294 if (subclass & (1 << x)) {
01295 if (power > -1) {
01296 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass);
01297 return 0;
01298 } else
01299 power = x;
01300 }
01301 }
01302 return power | IAX_FLAG_SC_LOG;
01303 }
01304
01305 static int uncompress_subclass(unsigned char csub)
01306 {
01307
01308 if (csub & IAX_FLAG_SC_LOG) {
01309
01310 if (csub == 0xff)
01311 return -1;
01312 else
01313 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01314 }
01315 else
01316 return csub;
01317 }
01318
01319
01320
01321
01322 static int peer_hash_cb(const void *obj, const int flags)
01323 {
01324 const struct iax2_peer *peer = obj;
01325
01326 return ast_str_hash(peer->name);
01327 }
01328
01329
01330
01331
01332 static int peer_cmp_cb(void *obj, void *arg, int flags)
01333 {
01334 struct iax2_peer *peer = obj, *peer2 = arg;
01335
01336 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01337 }
01338
01339
01340
01341
01342 static int user_hash_cb(const void *obj, const int flags)
01343 {
01344 const struct iax2_user *user = obj;
01345
01346 return ast_str_hash(user->name);
01347 }
01348
01349
01350
01351
01352 static int user_cmp_cb(void *obj, void *arg, int flags)
01353 {
01354 struct iax2_user *user = obj, *user2 = arg;
01355
01356 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01357 }
01358
01359
01360
01361
01362
01363 static struct iax2_peer *find_peer(const char *name, int realtime)
01364 {
01365 struct iax2_peer *peer = NULL;
01366 struct iax2_peer tmp_peer = {
01367 .name = name,
01368 };
01369
01370 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01371
01372
01373 if(!peer && realtime)
01374 peer = realtime_peer(name, NULL);
01375
01376 return peer;
01377 }
01378
01379 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01380 {
01381 ao2_ref(peer, +1);
01382 return peer;
01383 }
01384
01385 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01386 {
01387 ao2_ref(peer, -1);
01388 return NULL;
01389 }
01390
01391 static struct iax2_user *find_user(const char *name)
01392 {
01393 struct iax2_user tmp_user = {
01394 .name = name,
01395 };
01396
01397 return ao2_find(users, &tmp_user, OBJ_POINTER);
01398 }
01399 static inline struct iax2_user *user_ref(struct iax2_user *user)
01400 {
01401 ao2_ref(user, +1);
01402 return user;
01403 }
01404
01405 static inline struct iax2_user *user_unref(struct iax2_user *user)
01406 {
01407 ao2_ref(user, -1);
01408 return NULL;
01409 }
01410
01411 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01412 {
01413 struct iax2_peer *peer = NULL;
01414 int res = 0;
01415 struct ao2_iterator i;
01416
01417 i = ao2_iterator_init(peers, 0);
01418 while ((peer = ao2_iterator_next(&i))) {
01419 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01420 (peer->addr.sin_port == sin.sin_port)) {
01421 ast_copy_string(host, peer->name, len);
01422 peer_unref(peer);
01423 res = 1;
01424 break;
01425 }
01426 peer_unref(peer);
01427 }
01428
01429 if (!peer) {
01430 peer = realtime_peer(NULL, &sin);
01431 if (peer) {
01432 ast_copy_string(host, peer->name, len);
01433 peer_unref(peer);
01434 res = 1;
01435 }
01436 }
01437
01438 return res;
01439 }
01440
01441
01442
01443 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01444 {
01445
01446 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) {
01447 struct iax2_user *user;
01448 struct iax2_user tmp_user = {
01449 .name = pvt->username,
01450 };
01451
01452 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01453 if (user) {
01454 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01455 user_unref(user);
01456 }
01457
01458 ast_clear_flag(pvt, IAX_MAXAUTHREQ);
01459 }
01460
01461 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]);
01462 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]);
01463 AST_SCHED_DEL(sched, pvt->autoid);
01464 AST_SCHED_DEL(sched, pvt->authid);
01465 AST_SCHED_DEL(sched, pvt->initid);
01466 AST_SCHED_DEL(sched, pvt->jbid);
01467 AST_SCHED_DEL(sched, pvt->keyrotateid);
01468 }
01469
01470 static void iax2_frame_free(struct iax_frame *fr)
01471 {
01472 AST_SCHED_DEL(sched, fr->retrans);
01473 iax_frame_free(fr);
01474 }
01475
01476 static int scheduled_destroy(const void *vid)
01477 {
01478 short callno = PTR_TO_CALLNO(vid);
01479 ast_mutex_lock(&iaxsl[callno]);
01480 if (iaxs[callno]) {
01481 if (option_debug) {
01482 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01483 }
01484 iax2_destroy(callno);
01485 }
01486 ast_mutex_unlock(&iaxsl[callno]);
01487 return 0;
01488 }
01489
01490 static void pvt_destructor(void *obj)
01491 {
01492 struct chan_iax2_pvt *pvt = obj;
01493 struct iax_frame *cur = NULL;
01494
01495 ast_mutex_lock(&iaxsl[pvt->callno]);
01496 iax2_destroy_helper(pvt);
01497 ast_mutex_unlock(&iaxsl[pvt->callno]);
01498
01499
01500 ast_set_flag(pvt, IAX_ALREADYGONE);
01501
01502 AST_LIST_LOCK(&frame_queue);
01503 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
01504
01505 if (cur->callno == pvt->callno) {
01506 cur->retries = -1;
01507 }
01508 }
01509 AST_LIST_UNLOCK(&frame_queue);
01510
01511 if (pvt->reg) {
01512 pvt->reg->callno = 0;
01513 }
01514
01515 if (!pvt->owner) {
01516 jb_frame frame;
01517 if (pvt->vars) {
01518 ast_variables_destroy(pvt->vars);
01519 pvt->vars = NULL;
01520 }
01521
01522 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01523 iax2_frame_free(frame.data);
01524 }
01525
01526 jb_destroy(pvt->jb);
01527 ast_string_field_free_memory(pvt);
01528 }
01529 }
01530
01531 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01532 {
01533 struct chan_iax2_pvt *tmp;
01534 jb_conf jbconf;
01535
01536 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01537 return NULL;
01538 }
01539
01540 if (ast_string_field_init(tmp, 32)) {
01541 ao2_ref(tmp, -1);
01542 tmp = NULL;
01543 return NULL;
01544 }
01545
01546 tmp->prefs = prefs;
01547 tmp->pingid = -1;
01548 tmp->lagid = -1;
01549 tmp->autoid = -1;
01550 tmp->authid = -1;
01551 tmp->initid = -1;
01552 tmp->keyrotateid = -1;
01553
01554 ast_string_field_set(tmp,exten, "s");
01555 ast_string_field_set(tmp,host, host);
01556
01557 tmp->jb = jb_new();
01558 tmp->jbid = -1;
01559 jbconf.max_jitterbuf = maxjitterbuffer;
01560 jbconf.resync_threshold = resyncthreshold;
01561 jbconf.max_contig_interp = maxjitterinterps;
01562 jbconf.target_extra = jittertargetextra;
01563 jb_setconf(tmp->jb,&jbconf);
01564
01565 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01566
01567 return tmp;
01568 }
01569
01570 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01571 {
01572 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01573 if (new) {
01574 size_t afdatalen = new->afdatalen;
01575 memcpy(new, fr, sizeof(*new));
01576 iax_frame_wrap(new, &fr->af);
01577 new->afdatalen = afdatalen;
01578 new->data = NULL;
01579 new->datalen = 0;
01580 new->direction = DIRECTION_INGRESS;
01581 new->retrans = -1;
01582 }
01583 return new;
01584 }
01585
01586 #define NEW_PREVENT 0
01587 #define NEW_ALLOW 1
01588 #define NEW_FORCE 2
01589
01590 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01591 {
01592 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01593 (cur->addr.sin_port == sin->sin_port)) {
01594
01595 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01596 (check_dcallno ? dcallno == cur->callno : 1) ) {
01597
01598 return 1;
01599 }
01600 }
01601 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01602 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01603
01604 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01605 return 1;
01606 }
01607 return 0;
01608 }
01609
01610 static void update_max_trunk(void)
01611 {
01612 int max = TRUNK_CALL_START;
01613 int x;
01614
01615
01616 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01617 if (iaxs[x]) {
01618 max = x + 1;
01619 }
01620 }
01621
01622 maxtrunkcall = max;
01623 if (iaxdebug)
01624 ast_debug(1, "New max trunk callno is %d\n", max);
01625 }
01626
01627 static void update_max_nontrunk(void)
01628 {
01629 int max = 1;
01630 int x;
01631
01632 for (x=1;x<TRUNK_CALL_START - 1; x++) {
01633 if (iaxs[x])
01634 max = x + 1;
01635 }
01636 maxnontrunkcall = max;
01637 if (iaxdebug)
01638 ast_debug(1, "New max nontrunk callno is %d\n", max);
01639 }
01640
01641 static int make_trunk(unsigned short callno, int locked)
01642 {
01643 int x;
01644 int res= 0;
01645 struct timeval now = ast_tvnow();
01646 if (iaxs[callno]->oseqno) {
01647 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
01648 return -1;
01649 }
01650 if (callno & TRUNK_CALL_START) {
01651 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
01652 return -1;
01653 }
01654 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
01655 ast_mutex_lock(&iaxsl[x]);
01656 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01657
01658
01659
01660
01661 AST_SCHED_DEL(sched, iaxs[callno]->pingid);
01662 AST_SCHED_DEL(sched, iaxs[callno]->lagid);
01663 iaxs[x] = iaxs[callno];
01664 iaxs[x]->callno = x;
01665 iaxs[callno] = NULL;
01666
01667 iaxs[x]->pingid = iax2_sched_add(sched,
01668 ping_time * 1000, send_ping, (void *)(long)x);
01669 iaxs[x]->lagid = iax2_sched_add(sched,
01670 lagrq_time * 1000, send_lagrq, (void *)(long)x);
01671 if (locked)
01672 ast_mutex_unlock(&iaxsl[callno]);
01673 res = x;
01674 if (!locked)
01675 ast_mutex_unlock(&iaxsl[x]);
01676 break;
01677 }
01678 ast_mutex_unlock(&iaxsl[x]);
01679 }
01680 if (x >= ARRAY_LEN(iaxs) - 1) {
01681 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
01682 return -1;
01683 }
01684 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
01685
01686 update_max_trunk();
01687 update_max_nontrunk();
01688 return res;
01689 }
01690
01691 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
01692 {
01693 if (!pvt->transfercallno) {
01694 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01695 return;
01696 }
01697
01698 ao2_link(iax_transfercallno_pvts, pvt);
01699 }
01700
01701 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
01702 {
01703 if (!pvt->transfercallno) {
01704 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
01705 return;
01706 }
01707
01708 ao2_unlink(iax_transfercallno_pvts, pvt);
01709 }
01710 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
01711 {
01712 if (!pvt->peercallno) {
01713 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01714 return;
01715 }
01716
01717 ao2_link(iax_peercallno_pvts, pvt);
01718 }
01719
01720 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
01721 {
01722 if (!pvt->peercallno) {
01723 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
01724 return;
01725 }
01726
01727 ao2_unlink(iax_peercallno_pvts, pvt);
01728 }
01729
01730
01731
01732
01733 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
01734 {
01735 int res = 0;
01736 int x;
01737 struct timeval now;
01738 char host[80];
01739
01740 if (new <= NEW_ALLOW) {
01741 if (callno) {
01742 struct chan_iax2_pvt *pvt;
01743 struct chan_iax2_pvt tmp_pvt = {
01744 .callno = dcallno,
01745 .peercallno = callno,
01746 .transfercallno = callno,
01747
01748 .frames_received = check_dcallno,
01749 };
01750
01751 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
01752
01753 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01754 if (return_locked) {
01755 ast_mutex_lock(&iaxsl[pvt->callno]);
01756 }
01757 res = pvt->callno;
01758 ao2_ref(pvt, -1);
01759 pvt = NULL;
01760 return res;
01761 }
01762
01763 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
01764 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.addr));
01765 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
01766 if (return_locked) {
01767 ast_mutex_lock(&iaxsl[pvt->callno]);
01768 }
01769 res = pvt->callno;
01770 ao2_ref(pvt, -1);
01771 pvt = NULL;
01772 return res;
01773 }
01774 }
01775
01776
01777 if (dcallno) {
01778 ast_mutex_lock(&iaxsl[dcallno]);
01779 }
01780 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
01781 iaxs[dcallno]->peercallno = callno;
01782 res = dcallno;
01783 store_by_peercallno(iaxs[dcallno]);
01784 if (!res || !return_locked) {
01785 ast_mutex_unlock(&iaxsl[dcallno]);
01786 }
01787 return res;
01788 }
01789 if (dcallno) {
01790 ast_mutex_unlock(&iaxsl[dcallno]);
01791 }
01792 #ifdef IAX_OLD_FIND
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804 for (x = 1; !res && x < maxnontrunkcall; x++) {
01805 ast_mutex_lock(&iaxsl[x]);
01806 if (iaxs[x]) {
01807
01808 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01809 res = x;
01810 }
01811 }
01812 if (!res || !return_locked)
01813 ast_mutex_unlock(&iaxsl[x]);
01814 }
01815 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
01816 ast_mutex_lock(&iaxsl[x]);
01817 if (iaxs[x]) {
01818
01819 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
01820 res = x;
01821 }
01822 }
01823 if (!res || !return_locked)
01824 ast_mutex_unlock(&iaxsl[x]);
01825 }
01826 #endif
01827 }
01828 if (!res && (new >= NEW_ALLOW)) {
01829 int start, found = 0;
01830
01831
01832
01833
01834
01835
01836
01837 if (!iax2_getpeername(*sin, host, sizeof(host)))
01838 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
01839
01840 now = ast_tvnow();
01841 start = 2 + (ast_random() % (TRUNK_CALL_START - 1));
01842 for (x = start; 1; x++) {
01843 if (x == TRUNK_CALL_START) {
01844 x = 1;
01845 continue;
01846 }
01847
01848
01849 ast_mutex_lock(&iaxsl[x]);
01850 if (!iaxs[x] && ((now.tv_sec - lastused[x].tv_sec) > MIN_REUSE_TIME)) {
01851 found = 1;
01852 break;
01853 }
01854 ast_mutex_unlock(&iaxsl[x]);
01855
01856 if (x == start - 1) {
01857 break;
01858 }
01859 }
01860
01861 if (x == start - 1 && !found) {
01862 ast_log(LOG_WARNING, "No more space\n");
01863 return 0;
01864 }
01865 iaxs[x] = new_iax(sin, host);
01866 update_max_nontrunk();
01867 if (iaxs[x]) {
01868 if (iaxdebug)
01869 ast_debug(1, "Creating new call structure %d\n", x);
01870 iaxs[x]->sockfd = sockfd;
01871 iaxs[x]->addr.sin_port = sin->sin_port;
01872 iaxs[x]->addr.sin_family = sin->sin_family;
01873 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
01874 iaxs[x]->peercallno = callno;
01875 iaxs[x]->callno = x;
01876 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
01877 iaxs[x]->expiry = min_reg_expire;
01878 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
01879 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
01880 iaxs[x]->amaflags = amaflags;
01881 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
01882
01883 ast_string_field_set(iaxs[x], accountcode, accountcode);
01884 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
01885 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
01886 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
01887
01888 if (iaxs[x]->peercallno) {
01889 store_by_peercallno(iaxs[x]);
01890 }
01891 } else {
01892 ast_log(LOG_WARNING, "Out of resources\n");
01893 ast_mutex_unlock(&iaxsl[x]);
01894 return 0;
01895 }
01896 if (!return_locked)
01897 ast_mutex_unlock(&iaxsl[x]);
01898 res = x;
01899 }
01900 return res;
01901 }
01902
01903 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01904
01905 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
01906 }
01907
01908 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
01909
01910 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
01911 }
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923 static int iax2_queue_frame(int callno, struct ast_frame *f)
01924 {
01925 for (;;) {
01926 if (iaxs[callno] && iaxs[callno]->owner) {
01927 if (ast_channel_trylock(iaxs[callno]->owner)) {
01928
01929 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01930 } else {
01931 ast_queue_frame(iaxs[callno]->owner, f);
01932 ast_channel_unlock(iaxs[callno]->owner);
01933 break;
01934 }
01935 } else
01936 break;
01937 }
01938 return 0;
01939 }
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954 static int iax2_queue_hangup(int callno)
01955 {
01956 for (;;) {
01957 if (iaxs[callno] && iaxs[callno]->owner) {
01958 if (ast_channel_trylock(iaxs[callno]->owner)) {
01959
01960 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01961 } else {
01962 ast_queue_hangup(iaxs[callno]->owner);
01963 ast_channel_unlock(iaxs[callno]->owner);
01964 break;
01965 }
01966 } else
01967 break;
01968 }
01969 return 0;
01970 }
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985 static int iax2_queue_control_data(int callno,
01986 enum ast_control_frame_type control, const void *data, size_t datalen)
01987 {
01988 for (;;) {
01989 if (iaxs[callno] && iaxs[callno]->owner) {
01990 if (ast_channel_trylock(iaxs[callno]->owner)) {
01991
01992 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01993 } else {
01994 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
01995 ast_channel_unlock(iaxs[callno]->owner);
01996 break;
01997 }
01998 } else
01999 break;
02000 }
02001 return 0;
02002 }
02003 static void destroy_firmware(struct iax_firmware *cur)
02004 {
02005
02006 if (cur->fwh) {
02007 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02008 }
02009 close(cur->fd);
02010 ast_free(cur);
02011 }
02012
02013 static int try_firmware(char *s)
02014 {
02015 struct stat stbuf;
02016 struct iax_firmware *cur = NULL;
02017 int ifd, fd, res, len, chunk;
02018 struct ast_iax2_firmware_header *fwh, fwh2;
02019 struct MD5Context md5;
02020 unsigned char sum[16], buf[1024];
02021 char *s2, *last;
02022
02023 if (!(s2 = alloca(strlen(s) + 100))) {
02024 ast_log(LOG_WARNING, "Alloca failed!\n");
02025 return -1;
02026 }
02027
02028 last = strrchr(s, '/');
02029 if (last)
02030 last++;
02031 else
02032 last = s;
02033
02034 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
02035
02036 if ((res = stat(s, &stbuf) < 0)) {
02037 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
02038 return -1;
02039 }
02040
02041
02042 if (S_ISDIR(stbuf.st_mode))
02043 return -1;
02044 ifd = open(s, O_RDONLY);
02045 if (ifd < 0) {
02046 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
02047 return -1;
02048 }
02049 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
02050 if (fd < 0) {
02051 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
02052 close(ifd);
02053 return -1;
02054 }
02055
02056 unlink(s2);
02057
02058
02059 len = stbuf.st_size;
02060 while(len) {
02061 chunk = len;
02062 if (chunk > sizeof(buf))
02063 chunk = sizeof(buf);
02064 res = read(ifd, buf, chunk);
02065 if (res != chunk) {
02066 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02067 close(ifd);
02068 close(fd);
02069 return -1;
02070 }
02071 res = write(fd, buf, chunk);
02072 if (res != chunk) {
02073 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
02074 close(ifd);
02075 close(fd);
02076 return -1;
02077 }
02078 len -= chunk;
02079 }
02080 close(ifd);
02081
02082 lseek(fd, 0, SEEK_SET);
02083 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
02084 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
02085 close(fd);
02086 return -1;
02087 }
02088 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
02089 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
02090 close(fd);
02091 return -1;
02092 }
02093 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
02094 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
02095 close(fd);
02096 return -1;
02097 }
02098 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
02099 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
02100 close(fd);
02101 return -1;
02102 }
02103 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
02104 if (fwh == (void *) -1) {
02105 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
02106 close(fd);
02107 return -1;
02108 }
02109 MD5Init(&md5);
02110 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
02111 MD5Final(sum, &md5);
02112 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
02113 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
02114 munmap((void*)fwh, stbuf.st_size);
02115 close(fd);
02116 return -1;
02117 }
02118
02119 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02120 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
02121
02122 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
02123
02124 break;
02125
02126
02127 munmap((void*)fwh, stbuf.st_size);
02128 close(fd);
02129 return 0;
02130 }
02131 }
02132
02133 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
02134 cur->fd = -1;
02135 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
02136 }
02137
02138 if (cur) {
02139 if (cur->fwh)
02140 munmap((void*)cur->fwh, cur->mmaplen);
02141 if (cur->fd > -1)
02142 close(cur->fd);
02143 cur->fwh = fwh;
02144 cur->fd = fd;
02145 cur->mmaplen = stbuf.st_size;
02146 cur->dead = 0;
02147 }
02148
02149 return 0;
02150 }
02151
02152 static int iax_check_version(char *dev)
02153 {
02154 int res = 0;
02155 struct iax_firmware *cur = NULL;
02156
02157 if (ast_strlen_zero(dev))
02158 return 0;
02159
02160 AST_LIST_LOCK(&firmwares);
02161 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02162 if (!strcmp(dev, (char *)cur->fwh->devname)) {
02163 res = ntohs(cur->fwh->version);
02164 break;
02165 }
02166 }
02167 AST_LIST_UNLOCK(&firmwares);
02168
02169 return res;
02170 }
02171
02172 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
02173 {
02174 int res = -1;
02175 unsigned int bs = desc & 0xff;
02176 unsigned int start = (desc >> 8) & 0xffffff;
02177 unsigned int bytes;
02178 struct iax_firmware *cur;
02179
02180 if (ast_strlen_zero((char *)dev) || !bs)
02181 return -1;
02182
02183 start *= bs;
02184
02185 AST_LIST_LOCK(&firmwares);
02186 AST_LIST_TRAVERSE(&firmwares, cur, list) {
02187 if (strcmp((char *)dev, (char *)cur->fwh->devname))
02188 continue;
02189 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
02190 if (start < ntohl(cur->fwh->datalen)) {
02191 bytes = ntohl(cur->fwh->datalen) - start;
02192 if (bytes > bs)
02193 bytes = bs;
02194 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
02195 } else {
02196 bytes = 0;
02197 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
02198 }
02199 if (bytes == bs)
02200 res = 0;
02201 else
02202 res = 1;
02203 break;
02204 }
02205 AST_LIST_UNLOCK(&firmwares);
02206
02207 return res;
02208 }
02209
02210
02211 static void reload_firmware(int unload)
02212 {
02213 struct iax_firmware *cur = NULL;
02214 DIR *fwd;
02215 struct dirent *de;
02216 char dir[256], fn[256];
02217
02218 AST_LIST_LOCK(&firmwares);
02219
02220
02221 AST_LIST_TRAVERSE(&firmwares, cur, list)
02222 cur->dead = 1;
02223
02224
02225 if (!unload) {
02226 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
02227 fwd = opendir(dir);
02228 if (fwd) {
02229 while((de = readdir(fwd))) {
02230 if (de->d_name[0] != '.') {
02231 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
02232 if (!try_firmware(fn)) {
02233 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
02234 }
02235 }
02236 }
02237 closedir(fwd);
02238 } else
02239 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
02240 }
02241
02242
02243 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
02244 if (!cur->dead)
02245 continue;
02246 AST_LIST_REMOVE_CURRENT(list);
02247 destroy_firmware(cur);
02248 }
02249 AST_LIST_TRAVERSE_SAFE_END;
02250
02251 AST_LIST_UNLOCK(&firmwares);
02252 }
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262 static int __do_deliver(void *data)
02263 {
02264
02265
02266 struct iax_frame *fr = data;
02267 fr->retrans = -1;
02268 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
02269 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE))
02270 iax2_queue_frame(fr->callno, &fr->af);
02271
02272 iax2_frame_free(fr);
02273
02274 return 0;
02275 }
02276
02277 static int handle_error(void)
02278 {
02279
02280
02281
02282 #if 0
02283 struct sockaddr_in *sin;
02284 int res;
02285 struct msghdr m;
02286 struct sock_extended_err e;
02287 m.msg_name = NULL;
02288 m.msg_namelen = 0;
02289 m.msg_iov = NULL;
02290 m.msg_control = &e;
02291 m.msg_controllen = sizeof(e);
02292 m.msg_flags = 0;
02293 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
02294 if (res < 0)
02295 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
02296 else {
02297 if (m.msg_controllen) {
02298 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
02299 if (sin)
02300 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
02301 else
02302 ast_log(LOG_WARNING, "No address detected??\n");
02303 } else {
02304 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
02305 }
02306 }
02307 #endif
02308 return 0;
02309 }
02310
02311 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
02312 {
02313 int res;
02314 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
02315 sizeof(*sin));
02316 if (res < 0) {
02317 ast_debug(1, "Received error: %s\n", strerror(errno));
02318 handle_error();
02319 } else
02320 res = 0;
02321 return res;
02322 }
02323
02324 static int send_packet(struct iax_frame *f)
02325 {
02326 int res;
02327 int callno = f->callno;
02328
02329
02330 if (!callno || !iaxs[callno] || iaxs[callno]->error)
02331 return -1;
02332
02333
02334 if (iaxdebug)
02335 ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
02336
02337 if (f->transfer) {
02338 if (iaxdebug)
02339 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
02340 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
02341 } else {
02342 if (iaxdebug)
02343 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
02344 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
02345 }
02346 if (res < 0) {
02347 if (iaxdebug)
02348 ast_debug(1, "Received error: %s\n", strerror(errno));
02349 handle_error();
02350 } else
02351 res = 0;
02352
02353 return res;
02354 }
02355
02356
02357
02358
02359
02360 static int iax2_predestroy(int callno)
02361 {
02362 struct ast_channel *c = NULL;
02363 struct chan_iax2_pvt *pvt = iaxs[callno];
02364
02365 if (!pvt)
02366 return -1;
02367
02368 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) {
02369 iax2_destroy_helper(pvt);
02370 ast_set_flag(pvt, IAX_ALREADYGONE);
02371 }
02372
02373 if ((c = pvt->owner)) {
02374 c->tech_pvt = NULL;
02375 iax2_queue_hangup(callno);
02376 pvt->owner = NULL;
02377 ast_module_unref(ast_module_info->self);
02378 }
02379
02380 return 0;
02381 }
02382
02383 static void iax2_destroy(int callno)
02384 {
02385 struct chan_iax2_pvt *pvt = NULL;
02386 struct ast_channel *owner = NULL;
02387
02388 retry:
02389 if ((pvt = iaxs[callno])) {
02390 iax2_destroy_helper(pvt);
02391 }
02392
02393 lastused[callno] = ast_tvnow();
02394
02395 owner = pvt ? pvt->owner : NULL;
02396
02397 if (owner) {
02398 if (ast_channel_trylock(owner)) {
02399 ast_debug(3, "Avoiding IAX destroy deadlock\n");
02400 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
02401 goto retry;
02402 }
02403 }
02404
02405 if (!owner) {
02406 iaxs[callno] = NULL;
02407 }
02408
02409 if (pvt) {
02410 if (!owner) {
02411 pvt->owner = NULL;
02412 } else {
02413
02414
02415
02416 ast_queue_hangup(owner);
02417 }
02418
02419 if (pvt->peercallno) {
02420 remove_by_peercallno(pvt);
02421 }
02422
02423 if (pvt->transfercallno) {
02424 remove_by_transfercallno(pvt);
02425 }
02426
02427 if (!owner) {
02428 ao2_ref(pvt, -1);
02429 pvt = NULL;
02430 }
02431 }
02432
02433 if (owner) {
02434 ast_channel_unlock(owner);
02435 }
02436
02437 if (callno & 0x4000) {
02438 update_max_trunk();
02439 }
02440 }
02441
02442 static int update_packet(struct iax_frame *f)
02443 {
02444
02445 struct ast_iax2_full_hdr *fh = f->data;
02446 struct ast_frame af;
02447
02448
02449 if (f->encmethods) {
02450 decode_frame(&f->mydcx, fh, &af, &f->datalen);
02451 }
02452
02453 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
02454
02455 f->iseqno = iaxs[f->callno]->iseqno;
02456 fh->iseqno = f->iseqno;
02457
02458
02459 if (f->encmethods) {
02460
02461
02462 build_rand_pad(f->semirand, sizeof(f->semirand));
02463 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
02464 }
02465 return 0;
02466 }
02467
02468 static int attempt_transmit(const void *data);
02469 static void __attempt_transmit(const void *data)
02470 {
02471
02472
02473 struct iax_frame *f = (struct iax_frame *)data;
02474 int freeme = 0;
02475 int callno = f->callno;
02476
02477 if (callno)
02478 ast_mutex_lock(&iaxsl[callno]);
02479 if (callno && iaxs[callno]) {
02480 if ((f->retries < 0) ||
02481 (f->retries >= max_retries) ) {
02482
02483 if (f->retries >= max_retries) {
02484 if (f->transfer) {
02485
02486 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
02487 } else if (f->final) {
02488 if (f->final)
02489 iax2_destroy(callno);
02490 } else {
02491 if (iaxs[callno]->owner)
02492 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass, f->ts, f->oseqno);
02493 iaxs[callno]->error = ETIMEDOUT;
02494 if (iaxs[callno]->owner) {
02495 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
02496
02497 iax2_queue_frame(callno, &fr);
02498
02499 if (iaxs[callno] && iaxs[callno]->owner)
02500 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
02501 } else {
02502 if (iaxs[callno]->reg) {
02503 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
02504 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
02505 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
02506 }
02507 iax2_destroy(callno);
02508 }
02509 }
02510
02511 }
02512 freeme = 1;
02513 } else {
02514
02515 update_packet(f);
02516
02517 send_packet(f);
02518 f->retries++;
02519
02520 f->retrytime *= 10;
02521 if (f->retrytime > MAX_RETRY_TIME)
02522 f->retrytime = MAX_RETRY_TIME;
02523
02524 if (f->transfer && (f->retrytime > 1000))
02525 f->retrytime = 1000;
02526 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
02527 }
02528 } else {
02529
02530 f->retries = -1;
02531 freeme = 1;
02532 }
02533 if (callno)
02534 ast_mutex_unlock(&iaxsl[callno]);
02535
02536 if (freeme) {
02537
02538 AST_LIST_LOCK(&frame_queue);
02539 AST_LIST_REMOVE(&frame_queue, f, list);
02540 AST_LIST_UNLOCK(&frame_queue);
02541 f->retrans = -1;
02542
02543 iax2_frame_free(f);
02544 }
02545 }
02546
02547 static int attempt_transmit(const void *data)
02548 {
02549 #ifdef SCHED_MULTITHREADED
02550 if (schedule_action(__attempt_transmit, data))
02551 #endif
02552 __attempt_transmit(data);
02553 return 0;
02554 }
02555
02556 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02557 {
02558 struct iax2_peer *peer = NULL;
02559 struct iax2_user *user = NULL;
02560
02561 switch (cmd) {
02562 case CLI_INIT:
02563 e->command = "iax2 prune realtime";
02564 e->usage =
02565 "Usage: iax2 prune realtime [<peername>|all]\n"
02566 " Prunes object(s) from the cache\n";
02567 return NULL;
02568 case CLI_GENERATE:
02569 if (a->pos == 3)
02570 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
02571 return NULL;
02572 }
02573 if (a->argc != 4)
02574 return CLI_SHOWUSAGE;
02575 if (!strcmp(a->argv[3], "all")) {
02576 prune_users();
02577 prune_peers();
02578 ast_cli(a->fd, "Cache flushed successfully.\n");
02579 return CLI_SUCCESS;
02580 }
02581 peer = find_peer(a->argv[3], 0);
02582 user = find_user(a->argv[3]);
02583 if (peer || user) {
02584 if (peer) {
02585 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
02586 ast_set_flag(peer, IAX_RTAUTOCLEAR);
02587 expire_registry(peer_ref(peer));
02588 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
02589 } else {
02590 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
02591 }
02592 peer_unref(peer);
02593 }
02594 if (user) {
02595 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
02596 ast_set_flag(user, IAX_RTAUTOCLEAR);
02597 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
02598 } else {
02599 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
02600 }
02601 ao2_unlink(users,user);
02602 user_unref(user);
02603 }
02604 } else {
02605 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
02606 }
02607
02608 return CLI_SUCCESS;
02609 }
02610
02611 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02612 {
02613 switch (cmd) {
02614 case CLI_INIT:
02615 e->command = "iax2 test losspct";
02616 e->usage =
02617 "Usage: iax2 test losspct <percentage>\n"
02618 " For testing, throws away <percentage> percent of incoming packets\n";
02619 return NULL;
02620 case CLI_GENERATE:
02621 return NULL;
02622 }
02623 if (a->argc != 4)
02624 return CLI_SHOWUSAGE;
02625
02626 test_losspct = atoi(a->argv[3]);
02627
02628 return CLI_SUCCESS;
02629 }
02630
02631 #ifdef IAXTESTS
02632 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02633 {
02634 switch (cmd) {
02635 case CLI_INIT:
02636 e->command = "iax2 test late";
02637 e->usage =
02638 "Usage: iax2 test late <ms>\n"
02639 " For testing, count the next frame as <ms> ms late\n";
02640 return NULL;
02641 case CLI_GENERATE:
02642 return NULL;
02643 }
02644
02645 if (a->argc != 4)
02646 return CLI_SHOWUSAGE;
02647
02648 test_late = atoi(a->argv[3]);
02649
02650 return CLI_SUCCESS;
02651 }
02652
02653 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02654 {
02655 switch (cmd) {
02656 case CLI_INIT:
02657 e->command = "iax2 test resync";
02658 e->usage =
02659 "Usage: iax2 test resync <ms>\n"
02660 " For testing, adjust all future frames by <ms> ms\n";
02661 return NULL;
02662 case CLI_GENERATE:
02663 return NULL;
02664 }
02665
02666 if (a->argc != 4)
02667 return CLI_SHOWUSAGE;
02668
02669 test_resync = atoi(a->argv[3]);
02670
02671 return CLI_SUCCESS;
02672 }
02673
02674 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02675 {
02676 switch (cmd) {
02677 case CLI_INIT:
02678 e->command = "iax2 test jitter";
02679 e->usage =
02680 "Usage: iax2 test jitter <ms> <pct>\n"
02681 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
02682 " percentage of packets. If <pct> is not specified, adds\n"
02683 " jitter to all packets.\n";
02684 return NULL;
02685 case CLI_GENERATE:
02686 return NULL;
02687 }
02688
02689 if (a->argc < 4 || a->argc > 5)
02690 return CLI_SHOWUSAGE;
02691
02692 test_jit = atoi(a->argv[3]);
02693 if (a->argc == 5)
02694 test_jitpct = atoi(a->argv[4]);
02695
02696 return CLI_SUCCESS;
02697 }
02698 #endif
02699
02700
02701
02702 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
02703 {
02704 int res = 0;
02705 if (peer->maxms) {
02706 if (peer->lastms < 0) {
02707 ast_copy_string(status, "UNREACHABLE", statuslen);
02708 } else if (peer->lastms > peer->maxms) {
02709 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
02710 res = 1;
02711 } else if (peer->lastms) {
02712 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
02713 res = 1;
02714 } else {
02715 ast_copy_string(status, "UNKNOWN", statuslen);
02716 }
02717 } else {
02718 ast_copy_string(status, "Unmonitored", statuslen);
02719 res = -1;
02720 }
02721 return res;
02722 }
02723
02724
02725 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02726 {
02727 char status[30];
02728 char cbuf[256];
02729 struct iax2_peer *peer;
02730 char codec_buf[512];
02731 int x = 0, codec = 0, load_realtime = 0;
02732
02733 switch (cmd) {
02734 case CLI_INIT:
02735 e->command = "iax2 show peer";
02736 e->usage =
02737 "Usage: iax2 show peer <name>\n"
02738 " Display details on specific IAX peer\n";
02739 return NULL;
02740 case CLI_GENERATE:
02741 if (a->pos == 3)
02742 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
02743 return NULL;
02744 }
02745
02746 if (a->argc < 4)
02747 return CLI_SHOWUSAGE;
02748
02749 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
02750
02751 peer = find_peer(a->argv[3], load_realtime);
02752 if (peer) {
02753 ast_cli(a->fd, "\n\n");
02754 ast_cli(a->fd, " * Name : %s\n", peer->name);
02755 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
02756 ast_cli(a->fd, " Context : %s\n", peer->context);
02757 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
02758 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
02759 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
02760 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
02761 ast_cli(a->fd, " Expire : %d\n", peer->expire);
02762 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
02763 ast_cli(a->fd, " Addr->IP : %s Port %d\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
02764 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
02765 ast_cli(a->fd, " Username : %s\n", peer->username);
02766 ast_cli(a->fd, " Codecs : ");
02767 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
02768 ast_cli(a->fd, "%s\n", codec_buf);
02769
02770 ast_cli(a->fd, " Codec Order : (");
02771 for(x = 0; x < 32 ; x++) {
02772 codec = ast_codec_pref_index(&peer->prefs,x);
02773 if(!codec)
02774 break;
02775 ast_cli(a->fd, "%s", ast_getformatname(codec));
02776 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
02777 ast_cli(a->fd, "|");
02778 }
02779
02780 if (!x)
02781 ast_cli(a->fd, "none");
02782 ast_cli(a->fd, ")\n");
02783
02784 ast_cli(a->fd, " Status : ");
02785 peer_status(peer, status, sizeof(status));
02786 ast_cli(a->fd, "%s\n",status);
02787 ast_cli(a->fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
02788 ast_cli(a->fd, "\n");
02789 peer_unref(peer);
02790 } else {
02791 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
02792 ast_cli(a->fd, "\n");
02793 }
02794
02795 return CLI_SUCCESS;
02796 }
02797
02798 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state)
02799 {
02800 int which = 0;
02801 struct iax2_peer *peer;
02802 char *res = NULL;
02803 int wordlen = strlen(word);
02804 struct ao2_iterator i;
02805
02806 i = ao2_iterator_init(peers, 0);
02807 while ((peer = ao2_iterator_next(&i))) {
02808 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) {
02809 res = ast_strdup(peer->name);
02810 peer_unref(peer);
02811 break;
02812 }
02813 peer_unref(peer);
02814 }
02815
02816 return res;
02817 }
02818
02819 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02820 {
02821 struct iax_frame *cur;
02822 int cnt = 0, dead = 0, final = 0;
02823
02824 switch (cmd) {
02825 case CLI_INIT:
02826 e->command = "iax2 show stats";
02827 e->usage =
02828 "Usage: iax2 show stats\n"
02829 " Display statistics on IAX channel driver.\n";
02830 return NULL;
02831 case CLI_GENERATE:
02832 return NULL;
02833 }
02834
02835 if (a->argc != 3)
02836 return CLI_SHOWUSAGE;
02837
02838 AST_LIST_LOCK(&frame_queue);
02839 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
02840 if (cur->retries < 0)
02841 dead++;
02842 if (cur->final)
02843 final++;
02844 cnt++;
02845 }
02846 AST_LIST_UNLOCK(&frame_queue);
02847
02848 ast_cli(a->fd, " IAX Statistics\n");
02849 ast_cli(a->fd, "---------------------\n");
02850 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
02851 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
02852 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
02853 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
02854
02855 trunk_timed = trunk_untimed = 0;
02856 if (trunk_maxmtu > trunk_nmaxmtu)
02857 trunk_nmaxmtu = trunk_maxmtu;
02858
02859 return CLI_SUCCESS;
02860 }
02861
02862
02863 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02864 {
02865 int mtuv;
02866
02867 switch (cmd) {
02868 case CLI_INIT:
02869 e->command = "iax2 set mtu";
02870 e->usage =
02871 "Usage: iax2 set mtu <value>\n"
02872 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
02873 " zero to disable. Disabling means that the operating system\n"
02874 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
02875 " packet exceeds the UDP payload size. This is substantially\n"
02876 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
02877 " greater for G.711 samples.\n";
02878 return NULL;
02879 case CLI_GENERATE:
02880 return NULL;
02881 }
02882
02883 if (a->argc != 4)
02884 return CLI_SHOWUSAGE;
02885 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
02886 mtuv = MAX_TRUNK_MTU;
02887 else
02888 mtuv = atoi(a->argv[3]);
02889
02890 if (mtuv == 0) {
02891 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
02892 global_max_trunk_mtu = 0;
02893 return CLI_SUCCESS;
02894 }
02895 if (mtuv < 172 || mtuv > 4000) {
02896 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
02897 return CLI_SHOWUSAGE;
02898 }
02899 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
02900 global_max_trunk_mtu = mtuv;
02901 return CLI_SUCCESS;
02902 }
02903
02904 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02905 {
02906 struct iax2_dpcache *dp = NULL;
02907 char tmp[1024], *pc = NULL;
02908 int s, x, y;
02909 struct timeval now = ast_tvnow();
02910
02911 switch (cmd) {
02912 case CLI_INIT:
02913 e->command = "iax2 show cache";
02914 e->usage =
02915 "Usage: iax2 show cache\n"
02916 " Display currently cached IAX Dialplan results.\n";
02917 return NULL;
02918 case CLI_GENERATE:
02919 return NULL;
02920 }
02921
02922 AST_LIST_LOCK(&dpcache);
02923
02924 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
02925
02926 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
02927 s = dp->expiry.tv_sec - now.tv_sec;
02928 tmp[0] = '\0';
02929 if (dp->flags & CACHE_FLAG_EXISTS)
02930 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
02931 if (dp->flags & CACHE_FLAG_NONEXISTENT)
02932 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
02933 if (dp->flags & CACHE_FLAG_CANEXIST)
02934 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
02935 if (dp->flags & CACHE_FLAG_PENDING)
02936 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
02937 if (dp->flags & CACHE_FLAG_TIMEOUT)
02938 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
02939 if (dp->flags & CACHE_FLAG_TRANSMITTED)
02940 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
02941 if (dp->flags & CACHE_FLAG_MATCHMORE)
02942 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
02943 if (dp->flags & CACHE_FLAG_UNKNOWN)
02944 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
02945
02946 if (!ast_strlen_zero(tmp)) {
02947 tmp[strlen(tmp) - 1] = '\0';
02948 } else {
02949 ast_copy_string(tmp, "(none)", sizeof(tmp));
02950 }
02951 y = 0;
02952 pc = strchr(dp->peercontext, '@');
02953 if (!pc) {
02954 pc = dp->peercontext;
02955 } else {
02956 pc++;
02957 }
02958 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
02959 if (dp->waiters[x] > -1)
02960 y++;
02961 }
02962 if (s > 0) {
02963 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
02964 } else {
02965 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
02966 }
02967 }
02968
02969 AST_LIST_LOCK(&dpcache);
02970
02971 return CLI_SUCCESS;
02972 }
02973
02974 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
02975
02976 static void unwrap_timestamp(struct iax_frame *fr)
02977 {
02978
02979
02980 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
02981 const int lower_mask = (1 << ts_shift) - 1;
02982 const int upper_mask = ~lower_mask;
02983 const int last_upper = iaxs[fr->callno]->last & upper_mask;
02984
02985 if ( (fr->ts & upper_mask) == last_upper ) {
02986 const int x = fr->ts - iaxs[fr->callno]->last;
02987 const int threshold = (ts_shift == 15) ? 25000 : 50000;
02988
02989 if (x < -threshold) {
02990
02991
02992
02993
02994 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
02995 if (iaxdebug)
02996 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
02997 } else if (x > threshold) {
02998
02999
03000
03001
03002 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
03003 if (iaxdebug)
03004 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
03005 }
03006 }
03007 }
03008
03009 static int get_from_jb(const void *p);
03010
03011 static void update_jbsched(struct chan_iax2_pvt *pvt)
03012 {
03013 int when;
03014
03015 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
03016
03017 when = jb_next(pvt->jb) - when;
03018
03019 if (when <= 0) {
03020
03021 when = 1;
03022 }
03023
03024 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
03025 CALLNO_TO_PTR(pvt->callno));
03026 }
03027
03028 static void __get_from_jb(const void *p)
03029 {
03030 int callno = PTR_TO_CALLNO(p);
03031 struct chan_iax2_pvt *pvt = NULL;
03032 struct iax_frame *fr;
03033 jb_frame frame;
03034 int ret;
03035 long ms;
03036 long next;
03037 struct timeval now = ast_tvnow();
03038
03039
03040 ast_mutex_lock(&iaxsl[callno]);
03041 pvt = iaxs[callno];
03042 if (!pvt) {
03043
03044 ast_mutex_unlock(&iaxsl[callno]);
03045 return;
03046 }
03047
03048 pvt->jbid = -1;
03049
03050
03051
03052
03053 now.tv_usec += 1000;
03054
03055 ms = ast_tvdiff_ms(now, pvt->rxcore);
03056
03057 if(ms >= (next = jb_next(pvt->jb))) {
03058 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
03059 switch(ret) {
03060 case JB_OK:
03061 fr = frame.data;
03062 __do_deliver(fr);
03063
03064 pvt = iaxs[callno];
03065 break;
03066 case JB_INTERP:
03067 {
03068 struct ast_frame af = { 0, };
03069
03070
03071 af.frametype = AST_FRAME_VOICE;
03072 af.subclass = pvt->voiceformat;
03073 af.samples = frame.ms * 8;
03074 af.src = "IAX2 JB interpolation";
03075 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
03076 af.offset = AST_FRIENDLY_OFFSET;
03077
03078
03079
03080 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) {
03081 iax2_queue_frame(callno, &af);
03082
03083 pvt = iaxs[callno];
03084 }
03085 }
03086 break;
03087 case JB_DROP:
03088 iax2_frame_free(frame.data);
03089 break;
03090 case JB_NOFRAME:
03091 case JB_EMPTY:
03092
03093 break;
03094 default:
03095
03096 break;
03097 }
03098 }
03099 if (pvt)
03100 update_jbsched(pvt);
03101 ast_mutex_unlock(&iaxsl[callno]);
03102 }
03103
03104 static int get_from_jb(const void *data)
03105 {
03106 #ifdef SCHED_MULTITHREADED
03107 if (schedule_action(__get_from_jb, data))
03108 #endif
03109 __get_from_jb(data);
03110 return 0;
03111 }
03112
03113
03114
03115
03116
03117
03118
03119 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
03120 {
03121 int type, len;
03122 int ret;
03123 int needfree = 0;
03124 struct ast_channel *owner = NULL;
03125 struct ast_channel *bridge = NULL;
03126
03127
03128 unwrap_timestamp(fr);
03129
03130
03131 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
03132 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
03133 else {
03134 #if 0
03135 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
03136 #endif
03137 fr->af.delivery = ast_tv(0,0);
03138 }
03139
03140 type = JB_TYPE_CONTROL;
03141 len = 0;
03142
03143 if(fr->af.frametype == AST_FRAME_VOICE) {
03144 type = JB_TYPE_VOICE;
03145 len = ast_codec_get_samples(&fr->af) / 8;
03146 } else if(fr->af.frametype == AST_FRAME_CNG) {
03147 type = JB_TYPE_SILENCE;
03148 }
03149
03150 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
03151 if (tsout)
03152 *tsout = fr->ts;
03153 __do_deliver(fr);
03154 return -1;
03155 }
03156
03157 if ((owner = iaxs[fr->callno]->owner))
03158 bridge = ast_bridged_channel(owner);
03159
03160
03161
03162 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
03163 jb_frame frame;
03164
03165
03166 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
03167 __do_deliver(frame.data);
03168
03169 if (!iaxs[fr->callno])
03170 return -1;
03171 }
03172
03173 jb_reset(iaxs[fr->callno]->jb);
03174
03175 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid);
03176
03177
03178 if (tsout)
03179 *tsout = fr->ts;
03180 __do_deliver(fr);
03181 return -1;
03182 }
03183
03184
03185
03186 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
03187 calc_rxstamp(iaxs[fr->callno],fr->ts));
03188 if (ret == JB_DROP) {
03189 needfree++;
03190 } else if (ret == JB_SCHED) {
03191 update_jbsched(iaxs[fr->callno]);
03192 }
03193 if (tsout)
03194 *tsout = fr->ts;
03195 if (needfree) {
03196
03197 iax2_frame_free(fr);
03198 return -1;
03199 }
03200 return 0;
03201 }
03202
03203 static int iax2_transmit(struct iax_frame *fr)
03204 {
03205
03206
03207
03208 fr->sentyet = 0;
03209 AST_LIST_LOCK(&frame_queue);
03210 AST_LIST_INSERT_TAIL(&frame_queue, fr, list);
03211 AST_LIST_UNLOCK(&frame_queue);
03212
03213 if (netthreadid != AST_PTHREADT_NULL)
03214 pthread_kill(netthreadid, SIGURG);
03215 signal_condition(&sched_lock, &sched_cond);
03216 return 0;
03217 }
03218
03219
03220
03221 static int iax2_digit_begin(struct ast_channel *c, char digit)
03222 {
03223 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
03224 }
03225
03226 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
03227 {
03228 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
03229 }
03230
03231 static int iax2_sendtext(struct ast_channel *c, const char *text)
03232 {
03233
03234 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
03235 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
03236 }
03237
03238 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
03239 {
03240 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1);
03241 }
03242
03243 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
03244 {
03245 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
03246 }
03247
03248 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
03249 {
03250 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
03251 ast_mutex_lock(&iaxsl[callno]);
03252 if (iaxs[callno])
03253 iaxs[callno]->owner = newchan;
03254 else
03255 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
03256 ast_mutex_unlock(&iaxsl[callno]);
03257 return 0;
03258 }
03259
03260
03261
03262
03263
03264 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
03265 {
03266 struct ast_variable *var = NULL;
03267 struct ast_variable *tmp;
03268 struct iax2_peer *peer=NULL;
03269 time_t regseconds = 0, nowtime;
03270 int dynamic=0;
03271
03272 if (peername) {
03273 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
03274 if (!var && sin)
03275 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
03276 } else if (sin) {
03277 char porta[25];
03278 sprintf(porta, "%d", ntohs(sin->sin_port));
03279 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
03280 if (var) {
03281
03282 for (tmp = var; tmp; tmp = tmp->next) {
03283 if (!strcasecmp(tmp->name, "name"))
03284 peername = tmp->value;
03285 }
03286 }
03287 }
03288 if (!var && peername) {
03289 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
03290
03291
03292
03293
03294
03295
03296 if (var && sin) {
03297 for (tmp = var; tmp; tmp = tmp->next) {
03298 if (!strcasecmp(tmp->name, "host")) {
03299 struct ast_hostent ahp;
03300 struct hostent *hp;
03301 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03302
03303 ast_variables_destroy(var);
03304 var = NULL;
03305 }
03306 break;
03307 }
03308 }
03309 }
03310 }
03311 if (!var)
03312 return NULL;
03313
03314 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
03315
03316 if (!peer) {
03317 ast_variables_destroy(var);
03318 return NULL;
03319 }
03320
03321 for (tmp = var; tmp; tmp = tmp->next) {
03322
03323 if (!strcasecmp(tmp->name, "type")) {
03324 if (strcasecmp(tmp->value, "friend") &&
03325 strcasecmp(tmp->value, "peer")) {
03326
03327 peer = peer_unref(peer);
03328 break;
03329 }
03330 } else if (!strcasecmp(tmp->name, "regseconds")) {
03331 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
03332 } else if (!strcasecmp(tmp->name, "ipaddr")) {
03333 inet_aton(tmp->value, &(peer->addr.sin_addr));
03334 } else if (!strcasecmp(tmp->name, "port")) {
03335 peer->addr.sin_port = htons(atoi(tmp->value));
03336 } else if (!strcasecmp(tmp->name, "host")) {
03337 if (!strcasecmp(tmp->value, "dynamic"))
03338 dynamic = 1;
03339 }
03340 }
03341
03342 ast_variables_destroy(var);
03343
03344 if (!peer)
03345 return NULL;
03346
03347 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03348 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
03349 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) {
03350 if (peer->expire > -1) {
03351 if (!ast_sched_del(sched, peer->expire)) {
03352 peer->expire = -1;
03353 peer_unref(peer);
03354 }
03355 }
03356 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
03357 if (peer->expire == -1)
03358 peer_unref(peer);
03359 }
03360 ao2_link(peers, peer);
03361 if (ast_test_flag(peer, IAX_DYNAMIC))
03362 reg_source_db(peer);
03363 } else {
03364 ast_set_flag(peer, IAX_TEMPONLY);
03365 }
03366
03367 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
03368 time(&nowtime);
03369 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
03370 memset(&peer->addr, 0, sizeof(peer->addr));
03371 realtime_update_peer(peer->name, &peer->addr, 0);
03372 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
03373 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03374 }
03375 else {
03376 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
03377 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
03378 }
03379 }
03380
03381 return peer;
03382 }
03383
03384 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
03385 {
03386 struct ast_variable *var;
03387 struct ast_variable *tmp;
03388 struct iax2_user *user=NULL;
03389
03390 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
03391 if (!var)
03392 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
03393 if (!var && sin) {
03394 char porta[6];
03395 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
03396 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
03397 if (!var)
03398 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
03399 }
03400 if (!var) {
03401 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
03402
03403
03404
03405
03406
03407
03408 if (var) {
03409 for (tmp = var; tmp; tmp = tmp->next) {
03410 if (!strcasecmp(tmp->name, "host")) {
03411 struct ast_hostent ahp;
03412 struct hostent *hp;
03413 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(&hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
03414
03415 ast_variables_destroy(var);
03416 var = NULL;
03417 }
03418 break;
03419 }
03420 }
03421 }
03422 }
03423 if (!var)
03424 return NULL;
03425
03426 tmp = var;
03427 while(tmp) {
03428
03429 if (!strcasecmp(tmp->name, "type")) {
03430 if (strcasecmp(tmp->value, "friend") &&
03431 strcasecmp(tmp->value, "user")) {
03432 return NULL;
03433 }
03434 }
03435 tmp = tmp->next;
03436 }
03437
03438 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS));
03439
03440 ast_variables_destroy(var);
03441
03442 if (!user)
03443 return NULL;
03444
03445 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) {
03446 ast_set_flag(user, IAX_RTCACHEFRIENDS);
03447 ao2_link(users, user);
03448 } else {
03449 ast_set_flag(user, IAX_TEMPONLY);
03450 }
03451
03452 return user;
03453 }
03454
03455 static void realtime_update_peer(const char *peername, struct sockaddr_in *sin, time_t regtime)
03456 {
03457 char port[10];
03458 char regseconds[20];
03459
03460 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
03461 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
03462 ast_update_realtime("iaxpeers", "name", peername,
03463 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port,
03464 "regseconds", regseconds, SENTINEL);
03465 }
03466
03467 struct create_addr_info {
03468 int capability;
03469 unsigned int flags;
03470 int maxtime;
03471 int encmethods;
03472 int found;
03473 int sockfd;
03474 int adsi;
03475 char username[80];
03476 char secret[80];
03477 char outkey[80];
03478 char timezone[80];
03479 char prefs[32];
03480 char context[AST_MAX_CONTEXT];
03481 char peercontext[AST_MAX_CONTEXT];
03482 char mohinterpret[MAX_MUSICCLASS];
03483 char mohsuggest[MAX_MUSICCLASS];
03484 };
03485
03486 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
03487 {
03488 struct iax2_peer *peer;
03489 int res = -1;
03490 struct ast_codec_pref ourprefs;
03491
03492 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK);
03493 cai->sockfd = defaultsockfd;
03494 cai->maxtime = 0;
03495 sin->sin_family = AF_INET;
03496
03497 if (!(peer = find_peer(peername, 1))) {
03498 cai->found = 0;
03499 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) {
03500 ast_log(LOG_WARNING, "No such host: %s\n", peername);
03501 return -1;
03502 }
03503 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
03504
03505
03506 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
03507 if (c)
03508 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03509 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03510 return 0;
03511 }
03512
03513 cai->found = 1;
03514
03515
03516 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr))
03517 goto return_unref;
03518
03519
03520 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
03521 goto return_unref;
03522
03523 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
03524 cai->maxtime = peer->maxms;
03525 cai->capability = peer->capability;
03526 cai->encmethods = peer->encmethods;
03527 cai->sockfd = peer->sockfd;
03528 cai->adsi = peer->adsi;
03529 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
03530
03531 if (c) {
03532 ast_log(LOG_DEBUG, "prepending %x to prefs\n", c->nativeformats);
03533 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
03534 }
03535 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
03536 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
03537 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
03538 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
03539 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
03540 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
03541 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
03542 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
03543 if (ast_strlen_zero(peer->dbsecret)) {
03544 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
03545 } else {
03546 char *family;
03547 char *key = NULL;
03548
03549 family = ast_strdupa(peer->dbsecret);
03550 key = strchr(family, '/');
03551 if (key)
03552 *key++ = '\0';
03553 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
03554 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
03555 goto return_unref;
03556 }
03557 }
03558
03559 if (peer->addr.sin_addr.s_addr) {
03560 sin->sin_addr = peer->addr.sin_addr;
03561 sin->sin_port = peer->addr.sin_port;
03562 } else {
03563 sin->sin_addr = peer->defaddr.sin_addr;
03564 sin->sin_port = peer->defaddr.sin_port;
03565 }
03566
03567 res = 0;
03568
03569 return_unref:
03570 peer_unref(peer);
03571
03572 return res;
03573 }
03574
03575 static void __auto_congest(const void *nothing)
03576 {
03577 int callno = PTR_TO_CALLNO(nothing);
03578 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION };
03579 ast_mutex_lock(&iaxsl[callno]);
03580 if (iaxs[callno]) {
03581 iaxs[callno]->initid = -1;
03582 iax2_queue_frame(callno, &f);
03583 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
03584 }
03585 ast_mutex_unlock(&iaxsl[callno]);
03586 }
03587
03588 static int auto_congest(const void *data)
03589 {
03590 #ifdef SCHED_MULTITHREADED
03591 if (schedule_action(__auto_congest, data))
03592 #endif
03593 __auto_congest(data);
03594 return 0;
03595 }
03596
03597 static unsigned int iax2_datetime(const char *tz)
03598 {
03599 struct timeval t = ast_tvnow();
03600 struct ast_tm tm;
03601 unsigned int tmp;
03602 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
03603 tmp = (tm.tm_sec >> 1) & 0x1f;
03604 tmp |= (tm.tm_min & 0x3f) << 5;
03605 tmp |= (tm.tm_hour & 0x1f) << 11;
03606 tmp |= (tm.tm_mday & 0x1f) << 16;
03607 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
03608 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
03609 return tmp;
03610 }
03611
03612 struct parsed_dial_string {
03613 char *username;
03614 char *password;
03615 char *key;
03616 char *peer;
03617 char *port;
03618 char *exten;
03619 char *context;
03620 char *options;
03621 };
03622
03623 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno)
03624 {
03625 struct ast_iax2_full_hdr f = { .scallno = htons(0x8000 | callno), .dcallno = htons(dcallno),
03626 .ts = htonl(ts), .iseqno = seqno, .oseqno = 0, .type = AST_FRAME_IAX,
03627 .csub = compress_subclass(command) };
03628
03629 return sendto(defaultsockfd, &f, sizeof(f), 0, (struct sockaddr *)sin, sizeof(*sin));
03630 }
03631
03632
03633
03634
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
03651 {
03652 if (ast_strlen_zero(data))
03653 return;
03654
03655 pds->peer = strsep(&data, "/");
03656 pds->exten = strsep(&data, "/");
03657 pds->options = data;
03658
03659 if (pds->exten) {
03660 data = pds->exten;
03661 pds->exten = strsep(&data, "@");
03662 pds->context = data;
03663 }
03664
03665 if (strchr(pds->peer, '@')) {
03666 data = pds->peer;
03667 pds->username = strsep(&data, "@");
03668 pds->peer = data;
03669 }
03670
03671 if (pds->username) {
03672 data = pds->username;
03673 pds->username = strsep(&data, ":");
03674 pds->password = data;
03675 }
03676
03677 data = pds->peer;
03678 pds->peer = strsep(&data, ":");
03679 pds->port = data;
03680
03681
03682
03683
03684 if (pds->password && (pds->password[0] == '[')) {
03685 pds->key = ast_strip_quoted(pds->password, "[", "]");
03686 pds->password = NULL;
03687 }
03688 }
03689
03690 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
03691 {
03692 struct sockaddr_in sin;
03693 char *l=NULL, *n=NULL, *tmpstr;
03694 struct iax_ie_data ied;
03695 char *defaultrdest = "s";
03696 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03697 struct parsed_dial_string pds;
03698 struct create_addr_info cai;
03699 struct ast_var_t *var;
03700 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
03701 const char* osp_token_ptr;
03702 unsigned int osp_token_length;
03703 unsigned char osp_block_index;
03704 unsigned int osp_block_length;
03705 unsigned char osp_buffer[256];
03706
03707 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
03708 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
03709 return -1;
03710 }
03711
03712 memset(&cai, 0, sizeof(cai));
03713 cai.encmethods = iax2_encryption;
03714
03715 memset(&pds, 0, sizeof(pds));
03716 tmpstr = ast_strdupa(dest);
03717 parse_dial_string(tmpstr, &pds);
03718
03719 if (ast_strlen_zero(pds.peer)) {
03720 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
03721 return -1;
03722 }
03723
03724 if (!pds.exten) {
03725 pds.exten = defaultrdest;
03726 }
03727
03728 if (create_addr(pds.peer, c, &sin, &cai)) {
03729 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
03730 return -1;
03731 }
03732
03733 if (!pds.username && !ast_strlen_zero(cai.username))
03734 pds.username = cai.username;
03735 if (!pds.password && !ast_strlen_zero(cai.secret))
03736 pds.password = cai.secret;
03737 if (!pds.key && !ast_strlen_zero(cai.outkey))
03738 pds.key = cai.outkey;
03739 if (!pds.context && !ast_strlen_zero(cai.peercontext))
03740 pds.context = cai.peercontext;
03741
03742
03743 ast_copy_string(c->context, cai.context, sizeof(c->context));
03744
03745 if (pds.port)
03746 sin.sin_port = htons(atoi(pds.port));
03747
03748 l = c->cid.cid_num;
03749 n = c->cid.cid_name;
03750
03751
03752 memset(&ied, 0, sizeof(ied));
03753
03754
03755 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
03756 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
03757 if (pds.options && strchr(pds.options, 'a')) {
03758
03759 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
03760 }
03761
03762 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
03763
03764 if (l) {
03765 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
03766 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03767 } else {
03768 if (n)
03769 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres);
03770 else
03771 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
03772 }
03773
03774 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton);
03775 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns);
03776
03777 if (n)
03778 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
03779 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani)
03780 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani);
03781
03782 if (!ast_strlen_zero(c->language))
03783 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
03784 if (!ast_strlen_zero(c->cid.cid_dnid))
03785 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid);
03786 if (!ast_strlen_zero(c->cid.cid_rdnis))
03787 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis);
03788
03789 if (pds.context)
03790 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
03791
03792 if (pds.username)
03793 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
03794
03795 if (cai.encmethods)
03796 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
03797
03798 ast_mutex_lock(&iaxsl[callno]);
03799
03800 if (!ast_strlen_zero(c->context))
03801 ast_string_field_set(iaxs[callno], context, c->context);
03802
03803 if (pds.username)
03804 ast_string_field_set(iaxs[callno], username, pds.username);
03805
03806 iaxs[callno]->encmethods = cai.encmethods;
03807
03808 iaxs[callno]->adsi = cai.adsi;
03809
03810 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
03811 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
03812
03813 if (pds.key)
03814 ast_string_field_set(iaxs[callno], outkey, pds.key);
03815 if (pds.password)
03816 ast_string_field_set(iaxs[callno], secret, pds.password);
03817
03818 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats);
03819 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability);
03820 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
03821 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
03822
03823 if (iaxs[callno]->maxtime) {
03824
03825 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
03826 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
03827 } else if (autokill) {
03828 iaxs[callno]->pingtime = autokill / 2;
03829 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
03830 }
03831
03832
03833 osp_token_ptr = iaxs[callno]->osptoken;
03834 if (!ast_strlen_zero(osp_token_ptr)) {
03835 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
03836 osp_block_index = 0;
03837 while (osp_token_length > 0) {
03838 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
03839 osp_buffer[0] = osp_block_index;
03840 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
03841 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
03842 osp_block_index++;
03843 osp_token_ptr += osp_block_length;
03844 osp_token_length -= osp_block_length;
03845 }
03846 } else
03847 ast_log(LOG_WARNING, "OSP token is too long\n");
03848 } else if (iaxdebug)
03849 ast_debug(1, "OSP token is undefined\n");
03850
03851
03852 iaxs[callno]->sockfd = cai.sockfd;
03853
03854
03855 if (variablestore) {
03856 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
03857 ast_debug(1, "Found an IAX variable store on this channel\n");
03858 AST_LIST_LOCK(variablelist);
03859 AST_LIST_TRAVERSE(variablelist, var, entries) {
03860 char tmp[256];
03861 int i;
03862 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
03863
03864 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
03865 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
03866 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
03867 }
03868 }
03869 AST_LIST_UNLOCK(variablelist);
03870 }
03871
03872
03873 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
03874
03875 ast_mutex_unlock(&iaxsl[callno]);
03876 ast_setstate(c, AST_STATE_RINGING);
03877
03878 return 0;
03879 }
03880
03881 static int iax2_hangup(struct ast_channel *c)
03882 {
03883 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03884 struct iax_ie_data ied;
03885 int alreadygone;
03886 memset(&ied, 0, sizeof(ied));
03887 ast_mutex_lock(&iaxsl[callno]);
03888 if (callno && iaxs[callno]) {
03889 ast_debug(1, "We're hanging up %s now...\n", c->name);
03890 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE);
03891
03892 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
03893 if (!iaxs[callno]->error && !alreadygone) {
03894 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
03895 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
03896 }
03897 if (!iaxs[callno]) {
03898 ast_mutex_unlock(&iaxsl[callno]);
03899 return 0;
03900 }
03901 }
03902
03903 iax2_predestroy(callno);
03904
03905 if (iaxs[callno] && alreadygone) {
03906 ast_debug(1, "Really destroying %s now...\n", c->name);
03907 iax2_destroy(callno);
03908 } else if (iaxs[callno]) {
03909 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
03910 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
03911 iax2_destroy(callno);
03912 }
03913 }
03914 } else if (c->tech_pvt) {
03915
03916
03917
03918
03919 c->tech_pvt = NULL;
03920 }
03921 ast_mutex_unlock(&iaxsl[callno]);
03922 ast_verb(3, "Hungup '%s'\n", c->name);
03923 return 0;
03924 }
03925
03926
03927
03928
03929 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
03930 {
03931 unsigned short callno = pvt->callno;
03932
03933 if (!pvt->peercallno) {
03934
03935 int count = 10;
03936 while (count-- && pvt && !pvt->peercallno) {
03937 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03938 pvt = iaxs[callno];
03939 }
03940 if (!pvt->peercallno) {
03941 return -1;
03942 }
03943 }
03944
03945 return 0;
03946 }
03947
03948 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
03949 {
03950 struct ast_option_header *h;
03951 int res;
03952
03953 switch (option) {
03954 case AST_OPTION_TXGAIN:
03955 case AST_OPTION_RXGAIN:
03956
03957 errno = ENOSYS;
03958 return -1;
03959 default:
03960 {
03961 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
03962 struct chan_iax2_pvt *pvt;
03963
03964 ast_mutex_lock(&iaxsl[callno]);
03965 pvt = iaxs[callno];
03966
03967 if (wait_for_peercallno(pvt)) {
03968 ast_mutex_unlock(&iaxsl[callno]);
03969 return -1;
03970 }
03971
03972 ast_mutex_unlock(&iaxsl[callno]);
03973
03974 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
03975 return -1;
03976 }
03977
03978 h->flag = AST_OPTION_FLAG_REQUEST;
03979 h->option = htons(option);
03980 memcpy(h->data, data, datalen);
03981 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
03982 AST_CONTROL_OPTION, 0, (unsigned char *) h,
03983 datalen + sizeof(*h), -1);
03984 ast_free(h);
03985 return res;
03986 }
03987 }
03988 }
03989
03990 static struct ast_frame *iax2_read(struct ast_channel *c)
03991 {
03992 ast_log(LOG_NOTICE, "I should never be called!\n");
03993 return &ast_null_frame;
03994 }
03995
03996 static int iax2_key_rotate(const void *vpvt)
03997 {
03998 int res = 0;
03999 struct chan_iax2_pvt *pvt = (void *) vpvt;
04000 struct MD5Context md5;
04001 char key[17] = "";
04002 struct iax_ie_data ied = {
04003 .pos = 0,
04004 };
04005
04006 ast_mutex_lock(&iaxsl[pvt->callno]);
04007 pvt->keyrotateid =
04008 ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
04009
04010 snprintf(key, sizeof(key), "%lX", ast_random());
04011
04012 MD5Init(&md5);
04013 MD5Update(&md5, (unsigned char *) key, strlen(key));
04014 MD5Final((unsigned char *) key, &md5);
04015
04016 IAX_DEBUGDIGEST("Sending", key);
04017
04018 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
04019
04020 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
04021
04022 build_ecx_key((unsigned char *) key, pvt);
04023
04024 ast_mutex_unlock(&iaxsl[pvt->callno]);
04025
04026 return res;
04027 }
04028
04029 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
04030 {
04031 int res;
04032 struct iax_ie_data ied0;
04033 struct iax_ie_data ied1;
04034 unsigned int transferid = (unsigned int)ast_random();
04035
04036 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
04037 ast_debug(1, "transfers are not supported for encrypted calls at this time");
04038 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER);
04039 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER);
04040 return 0;
04041 }
04042
04043 memset(&ied0, 0, sizeof(ied0));
04044 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
04045 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
04046 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
04047
04048 memset(&ied1, 0, sizeof(ied1));
04049 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
04050 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
04051 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
04052
04053 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
04054 if (res)
04055 return -1;
04056 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
04057 if (res)
04058 return -1;
04059 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04060 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
04061 return 0;
04062 }
04063
04064 static void lock_both(unsigned short callno0, unsigned short callno1)
04065 {
04066 ast_mutex_lock(&iaxsl[callno0]);
04067 while (ast_mutex_trylock(&iaxsl[callno1])) {
04068 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
04069 }
04070 }
04071
04072 static void unlock_both(unsigned short callno0, unsigned short callno1)
04073 {
04074 ast_mutex_unlock(&iaxsl[callno1]);
04075 ast_mutex_unlock(&iaxsl[callno0]);
04076 }
04077
04078 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)
04079 {
04080 struct ast_channel *cs[3];
04081 struct ast_channel *who, *other;
04082 int to = -1;
04083 int res = -1;
04084 int transferstarted=0;
04085 struct ast_frame *f;
04086 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
04087 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
04088 struct timeval waittimer = {0, 0};
04089
04090
04091 if (timeoutms > 0) {
04092 return AST_BRIDGE_FAILED;
04093 }
04094
04095 timeoutms = 0;
04096
04097 lock_both(callno0, callno1);
04098 if (!iaxs[callno0] || !iaxs[callno1]) {
04099 unlock_both(callno0, callno1);
04100 return AST_BRIDGE_FAILED;
04101 }
04102
04103 if (!flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) {
04104 iaxs[callno0]->bridgecallno = callno1;
04105 iaxs[callno1]->bridgecallno = callno0;
04106 }
04107 unlock_both(callno0, callno1);
04108
04109
04110 cs[0] = c0;
04111 cs[1] = c1;
04112 for (;;) {
04113
04114 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
04115 ast_verb(3, "Can't masquerade, we're different...\n");
04116
04117 if (c0->tech == &iax2_tech) {
04118 ast_mutex_lock(&iaxsl[callno0]);
04119 iaxs[callno0]->bridgecallno = 0;
04120 ast_mutex_unlock(&iaxsl[callno0]);
04121 }
04122 if (c1->tech == &iax2_tech) {
04123 ast_mutex_lock(&iaxsl[callno1]);
04124 iaxs[callno1]->bridgecallno = 0;
04125 ast_mutex_unlock(&iaxsl[callno1]);
04126 }
04127 return AST_BRIDGE_FAILED_NOWARN;
04128 }
04129 if (c0->nativeformats != c1->nativeformats) {
04130 char buf0[255];
04131 char buf1[255];
04132 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats);
04133 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats);
04134 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1);
04135
04136 lock_both(callno0, callno1);
04137 if (iaxs[callno0])
04138 iaxs[callno0]->bridgecallno = 0;
04139 if (iaxs[callno1])
04140 iaxs[callno1]->bridgecallno = 0;
04141 unlock_both(callno0, callno1);
04142 return AST_BRIDGE_FAILED_NOWARN;
04143 }
04144
04145 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) {
04146
04147 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
04148 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA)))
04149 ast_log(LOG_WARNING, "Unable to start the transfer\n");
04150 transferstarted = 1;
04151 }
04152 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
04153
04154 struct timeval now = ast_tvnow();
04155 if (ast_tvzero(waittimer)) {
04156 waittimer = now;
04157 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
04158 c0->_softhangup |= AST_SOFTHANGUP_DEV;
04159 c1->_softhangup |= AST_SOFTHANGUP_DEV;
04160 *fo = NULL;
04161 *rc = c0;
04162 res = AST_BRIDGE_COMPLETE;
04163 break;
04164 }
04165 }
04166 to = 1000;
04167 who = ast_waitfor_n(cs, 2, &to);
04168 if (timeoutms > -1) {
04169 timeoutms -= (1000 - to);
04170 if (timeoutms < 0)
04171 timeoutms = 0;
04172 }
04173 if (!who) {
04174 if (!timeoutms) {
04175 res = AST_BRIDGE_RETRY;
04176 break;
04177 }
04178 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
04179 res = AST_BRIDGE_FAILED;
04180 break;
04181 }
04182 continue;
04183 }
04184 f = ast_read(who);
04185 if (!f) {
04186 *fo = NULL;
04187 *rc = who;
04188 res = AST_BRIDGE_COMPLETE;
04189 break;
04190 }
04191 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) {
04192 *fo = f;
04193 *rc = who;
04194 res = AST_BRIDGE_COMPLETE;
04195 break;
04196 }
04197 other = (who == c0) ? c1 : c0;
04198 if ((f->frametype == AST_FRAME_VOICE) ||
04199 (f->frametype == AST_FRAME_TEXT) ||
04200 (f->frametype == AST_FRAME_VIDEO) ||
04201 (f->frametype == AST_FRAME_IMAGE) ||
04202 (f->frametype == AST_FRAME_DTMF) ||
04203 (f->frametype == AST_FRAME_CONTROL)) {
04204
04205
04206
04207 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
04208 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
04209 *rc = who;
04210 *fo = f;
04211 res = AST_BRIDGE_COMPLETE;
04212
04213 break;
04214 }
04215
04216 ast_write(other, f);
04217 }
04218 ast_frfree(f);
04219
04220 cs[2] = cs[0];
04221 cs[0] = cs[1];
04222 cs[1] = cs[2];
04223 }
04224 lock_both(callno0, callno1);
04225 if(iaxs[callno0])
04226 iaxs[callno0]->bridgecallno = 0;
04227 if(iaxs[callno1])
04228 iaxs[callno1]->bridgecallno = 0;
04229 unlock_both(callno0, callno1);
04230 return res;
04231 }
04232
04233 static int iax2_answer(struct ast_channel *c)
04234 {
04235 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04236 ast_debug(1, "Answering IAX2 call\n");
04237 ast_mutex_lock(&iaxsl[callno]);
04238 if (iaxs[callno])
04239 iax2_ami_channelupdate(iaxs[callno]);
04240 ast_mutex_unlock(&iaxsl[callno]);
04241 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
04242 }
04243
04244 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
04245 {
04246 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04247 struct chan_iax2_pvt *pvt;
04248 int res = 0;
04249
04250 if (iaxdebug)
04251 ast_debug(1, "Indicating condition %d\n", condition);
04252
04253 ast_mutex_lock(&iaxsl[callno]);
04254 pvt = iaxs[callno];
04255
04256 if (wait_for_peercallno(pvt)) {
04257 res = -1;
04258 goto done;
04259 }
04260
04261 switch (condition) {
04262 case AST_CONTROL_HOLD:
04263 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04264 ast_moh_start(c, data, pvt->mohinterpret);
04265 goto done;
04266 }
04267 break;
04268 case AST_CONTROL_UNHOLD:
04269 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
04270 ast_moh_stop(c);
04271 goto done;
04272 }
04273 }
04274
04275 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
04276
04277 done:
04278 ast_mutex_unlock(&iaxsl[callno]);
04279
04280 return res;
04281 }
04282
04283 static int iax2_transfer(struct ast_channel *c, const char *dest)
04284 {
04285 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04286 struct iax_ie_data ied = { "", };
04287 char tmp[256], *context;
04288 ast_copy_string(tmp, dest, sizeof(tmp));
04289 context = strchr(tmp, '@');
04290 if (context) {
04291 *context = '\0';
04292 context++;
04293 }
04294 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
04295 if (context)
04296 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
04297 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
04298 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
04299 }
04300
04301 static int iax2_getpeertrunk(struct sockaddr_in sin)
04302 {
04303 struct iax2_peer *peer;
04304 int res = 0;
04305 struct ao2_iterator i;
04306
04307 i = ao2_iterator_init(peers, 0);
04308 while ((peer = ao2_iterator_next(&i))) {
04309 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
04310 (peer->addr.sin_port == sin.sin_port)) {
04311 res = ast_test_flag(peer, IAX_TRUNK);
04312 peer_unref(peer);
04313 break;
04314 }
04315 peer_unref(peer);
04316 }
04317
04318 return res;
04319 }
04320
04321
04322 static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
04323 {
04324 struct ast_channel *tmp;
04325 struct chan_iax2_pvt *i;
04326 struct ast_variable *v = NULL;
04327
04328 if (!(i = iaxs[callno])) {
04329 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
04330 return NULL;
04331 }
04332
04333
04334 ast_mutex_unlock(&iaxsl[callno]);
04335 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
04336 ast_mutex_lock(&iaxsl[callno]);
04337 if (i != iaxs[callno]) {
04338 if (tmp) {
04339
04340 ast_mutex_unlock(&iaxsl[callno]);
04341 ast_channel_free(tmp);
04342 ast_mutex_lock(&iaxsl[callno]);
04343 }
04344 return NULL;
04345 }
04346 iax2_ami_channelupdate(i);
04347 if (!tmp)
04348 return NULL;
04349 tmp->tech = &iax2_tech;
04350
04351 tmp->nativeformats = capability;
04352 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
04353 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
04354 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
04355
04356 if (!ast_strlen_zero(i->parkinglot))
04357 ast_string_field_set(tmp, parkinglot, i->parkinglot);
04358
04359
04360 if (!ast_strlen_zero(i->ani))
04361 tmp->cid.cid_ani = ast_strdup(i->ani);
04362 else
04363 tmp->cid.cid_ani = ast_strdup(i->cid_num);
04364 tmp->cid.cid_dnid = ast_strdup(i->dnid);
04365 tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
04366 tmp->cid.cid_pres = i->calling_pres;
04367 tmp->cid.cid_ton = i->calling_ton;
04368 tmp->cid.cid_tns = i->calling_tns;
04369 if (!ast_strlen_zero(i->language))
04370 ast_string_field_set(tmp, language, i->language);
04371 if (!ast_strlen_zero(i->accountcode))
04372 ast_string_field_set(tmp, accountcode, i->accountcode);
04373 if (i->amaflags)
04374 tmp->amaflags = i->amaflags;
04375 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
04376 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
04377 if (i->adsi)
04378 tmp->adsicpe = i->peeradsicpe;
04379 else
04380 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
04381 i->owner = tmp;
04382 i->capability = capability;
04383
04384
04385 if (i->vars) {
04386 for (v = i->vars ; v ; v = v->next)
04387 pbx_builtin_setvar_helper(tmp, v->name, v->value);
04388 }
04389 if (i->iaxvars) {
04390 struct ast_datastore *variablestore;
04391 struct ast_variable *var, *prev = NULL;
04392 AST_LIST_HEAD(, ast_var_t) *varlist;
04393 ast_debug(1, "Loading up the channel with IAXVARs\n");
04394 varlist = ast_calloc(1, sizeof(*varlist));
04395 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
04396 if (variablestore && varlist) {
04397 variablestore->data = varlist;
04398 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
04399 AST_LIST_HEAD_INIT(varlist);
04400 for (var = i->iaxvars; var; var = var->next) {
04401 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
04402 if (prev)
04403 ast_free(prev);
04404 prev = var;
04405 if (!newvar) {
04406
04407 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
04408 } else {
04409 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
04410 }
04411 }
04412 if (prev)
04413 ast_free(prev);
04414 i->iaxvars = NULL;
04415 ast_channel_datastore_add(i->owner, variablestore);
04416 } else {
04417 if (variablestore) {
04418 ast_datastore_free(variablestore);
04419 }
04420 if (varlist) {
04421 ast_free(varlist);
04422 }
04423 }
04424 }
04425
04426 if (state != AST_STATE_DOWN) {
04427 if (ast_pbx_start(tmp)) {
04428 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
04429 ast_hangup(tmp);
04430 i->owner = NULL;
04431 return NULL;
04432 }
04433 }
04434
04435 ast_module_ref(ast_module_info->self);
04436 return tmp;
04437 }
04438
04439 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
04440 {
04441 unsigned long int mssincetx;
04442 long int ms, pred;
04443
04444 tpeer->trunkact = *now;
04445 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
04446 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
04447
04448 tpeer->txtrunktime = *now;
04449 tpeer->lastsent = 999999;
04450 }
04451
04452 tpeer->lasttxtime = *now;
04453
04454
04455 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
04456
04457 pred = tpeer->lastsent + sampms;
04458 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
04459 ms = pred;
04460
04461
04462 if (ms == tpeer->lastsent)
04463 ms = tpeer->lastsent + 1;
04464 tpeer->lastsent = ms;
04465 return ms;
04466 }
04467
04468 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
04469 {
04470 long ms;
04471 if (ast_tvzero(iaxs[callno]->rxcore)) {
04472
04473 iaxs[callno]->rxcore = ast_tvnow();
04474
04475 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
04476 }
04477
04478 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
04479
04480 return ms + ts;
04481 }
04482
04483 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
04484 {
04485 int ms;
04486 int voice = 0;
04487 int genuine = 0;
04488 int adjust;
04489 struct timeval *delivery = NULL;
04490
04491
04492
04493
04494
04495
04496
04497
04498 if (f) {
04499 if (f->frametype == AST_FRAME_VOICE) {
04500 voice = 1;
04501 delivery = &f->delivery;
04502 } else if (f->frametype == AST_FRAME_IAX) {
04503 genuine = 1;
04504 } else if (f->frametype == AST_FRAME_CNG) {
04505 p->notsilenttx = 0;
04506 }
04507 }
04508 if (ast_tvzero(p->offset)) {
04509 p->offset = ast_tvnow();
04510
04511 p->offset.tv_usec -= p->offset.tv_usec % 20000;
04512 }
04513
04514 if (ts)
04515 return ts;
04516
04517 if (delivery && !ast_tvzero(*delivery)) {
04518 ms = ast_tvdiff_ms(*delivery, p->offset);
04519 if (iaxdebug)
04520 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
04521 } else {
04522 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
04523 if (ms < 0)
04524 ms = 0;
04525 if (voice) {
04526
04527 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546 adjust = (ms - p->nextpred);
04547 if (adjust < 0)
04548 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
04549 else if (adjust > 0)
04550 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
04551
04552 if (!p->nextpred) {
04553 p->nextpred = ms;
04554 if (p->nextpred <= p->lastsent)
04555 p->nextpred = p->lastsent + 3;
04556 }
04557 ms = p->nextpred;
04558 } else {
04559
04560
04561
04562
04563
04564
04565
04566
04567
04568 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
04569 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
04570 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
04571
04572 if (f->samples >= 8)
04573 {
04574 int diff = ms % (f->samples / 8);
04575 if (diff)
04576 ms += f->samples/8 - diff;
04577 }
04578
04579 p->nextpred = ms;
04580 p->notsilenttx = 1;
04581 }
04582 } else if ( f->frametype == AST_FRAME_VIDEO ) {
04583
04584
04585
04586
04587
04588
04589
04590
04591 if ( (unsigned int)ms < p->lastsent )
04592 ms = p->lastsent;
04593 } else {
04594
04595
04596 if (genuine) {
04597
04598 if (ms <= p->lastsent)
04599 ms = p->lastsent + 3;
04600 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
04601
04602 ms = p->lastsent + 3;
04603 }
04604 }
04605 }
04606 p->lastsent = ms;
04607 if (voice)
04608 p->nextpred = p->nextpred + f->samples / 8;
04609 return ms;
04610 }
04611
04612 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
04613 {
04614
04615
04616 int ms;
04617 #ifdef IAXTESTS
04618 int jit;
04619 #endif
04620
04621 if (ast_tvzero(p->rxcore)) {
04622 p->rxcore = ast_tvnow();
04623 if (iaxdebug)
04624 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
04625 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
04626 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
04627 #if 1
04628 if (iaxdebug)
04629 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
04630 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
04631 #endif
04632 }
04633
04634 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
04635 #ifdef IAXTESTS
04636 if (test_jit) {
04637 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
04638 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
04639 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
04640 jit = -jit;
04641 ms += jit;
04642 }
04643 }
04644 if (test_late) {
04645 ms += test_late;
04646 test_late = 0;
04647 }
04648 #endif
04649 return ms;
04650 }
04651
04652 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
04653 {
04654 struct iax2_trunk_peer *tpeer = NULL;
04655
04656
04657 AST_LIST_LOCK(&tpeers);
04658
04659 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
04660 if (!inaddrcmp(&tpeer->addr, sin)) {
04661 ast_mutex_lock(&tpeer->lock);
04662 break;
04663 }
04664 }
04665
04666 if (!tpeer) {
04667 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
04668 ast_mutex_init(&tpeer->lock);
04669 tpeer->lastsent = 9999;
04670 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
04671 tpeer->trunkact = ast_tvnow();
04672 ast_mutex_lock(&tpeer->lock);
04673 tpeer->sockfd = fd;
04674 #ifdef SO_NO_CHECK
04675 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
04676 #endif
04677 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04678 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
04679 }
04680 }
04681
04682 AST_LIST_UNLOCK(&tpeers);
04683
04684 return tpeer;
04685 }
04686
04687 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
04688 {
04689 struct ast_frame *f;
04690 struct iax2_trunk_peer *tpeer;
04691 void *tmp, *ptr;
04692 struct timeval now;
04693 int res;
04694 struct ast_iax2_meta_trunk_entry *met;
04695 struct ast_iax2_meta_trunk_mini *mtm;
04696
04697 f = &fr->af;
04698 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
04699 if (tpeer) {
04700 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
04701
04702 if (tpeer->trunkdataalloc < trunkmaxsize) {
04703 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
04704 ast_mutex_unlock(&tpeer->lock);
04705 return -1;
04706 }
04707
04708 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
04709 tpeer->trunkdata = tmp;
04710 ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc);
04711 } else {
04712 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
04713 ast_mutex_unlock(&tpeer->lock);
04714 return -1;
04715 }
04716 }
04717
04718
04719 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
04720 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) {
04721 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
04722 mtm->len = htons(f->datalen);
04723 mtm->mini.callno = htons(pvt->callno);
04724 mtm->mini.ts = htons(0xffff & fr->ts);
04725 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
04726 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
04727 } else {
04728 met = (struct ast_iax2_meta_trunk_entry *)ptr;
04729
04730 met->callno = htons(pvt->callno);
04731 met->len = htons(f->datalen);
04732
04733 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
04734 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
04735 }
04736
04737 memcpy(ptr, f->data.ptr, f->datalen);
04738 tpeer->trunkdatalen += f->datalen;
04739
04740 tpeer->calls++;
04741
04742
04743 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
04744 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
04745
04746
04747 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
04748 now = ast_tvnow();
04749 res = send_trunk(tpeer, &now);
04750 trunk_untimed ++;
04751 }
04752
04753 ast_mutex_unlock(&tpeer->lock);
04754 }
04755 return 0;
04756 }
04757
04758
04759
04760 static void build_rand_pad(unsigned char *buf, ssize_t len)
04761 {
04762 long tmp;
04763 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
04764 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
04765 buf += sizeof(tmp);
04766 len -= sizeof(tmp);
04767 }
04768 }
04769
04770 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04771 {
04772 build_ecx_key(digest, pvt);
04773 ast_aes_decrypt_key(digest, &pvt->dcx);
04774 }
04775
04776 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
04777 {
04778
04779
04780
04781 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
04782 ast_aes_encrypt_key(digest, &pvt->ecx);
04783 ast_aes_decrypt_key(digest, &pvt->mydcx);
04784 }
04785
04786 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
04787 {
04788 #if 0
04789
04790 int x;
04791 if (len % 16)
04792 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04793 for (x=0;x<len;x++)
04794 dst[x] = src[x] ^ 0xff;
04795 #else
04796 unsigned char lastblock[16] = { 0 };
04797 int x;
04798 while(len > 0) {
04799 ast_aes_decrypt(src, dst, dcx);
04800 for (x=0;x<16;x++)
04801 dst[x] ^= lastblock[x];
04802 memcpy(lastblock, src, sizeof(lastblock));
04803 dst += 16;
04804 src += 16;
04805 len -= 16;
04806 }
04807 #endif
04808 }
04809
04810 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
04811 {
04812 #if 0
04813
04814 int x;
04815 if (len % 16)
04816 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
04817 for (x=0;x<len;x++)
04818 dst[x] = src[x] ^ 0xff;
04819 #else
04820 unsigned char curblock[16] = { 0 };
04821 int x;
04822 while(len > 0) {
04823 for (x=0;x<16;x++)
04824 curblock[x] ^= src[x];
04825 ast_aes_encrypt(curblock, dst, ecx);
04826 memcpy(curblock, dst, sizeof(curblock));
04827 dst += 16;
04828 src += 16;
04829 len -= 16;
04830 }
04831 #endif
04832 }
04833
04834 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04835 {
04836 int padding;
04837 unsigned char *workspace;
04838
04839 workspace = alloca(*datalen);
04840 memset(f, 0, sizeof(*f));
04841 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04842 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04843 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
04844 return -1;
04845
04846 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
04847
04848 padding = 16 + (workspace[15] & 0x0f);
04849 if (iaxdebug)
04850 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
04851 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
04852 return -1;
04853
04854 *datalen -= padding;
04855 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04856 f->frametype = fh->type;
04857 if (f->frametype == AST_FRAME_VIDEO) {
04858 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
04859 } else {
04860 f->subclass = uncompress_subclass(fh->csub);
04861 }
04862 } else {
04863 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04864 if (iaxdebug)
04865 ast_debug(1, "Decoding mini with length %d\n", *datalen);
04866 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
04867 return -1;
04868
04869 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
04870 padding = 16 + (workspace[15] & 0x0f);
04871 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
04872 return -1;
04873 *datalen -= padding;
04874 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04875 }
04876 return 0;
04877 }
04878
04879 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
04880 {
04881 int padding;
04882 unsigned char *workspace;
04883 workspace = alloca(*datalen + 32);
04884 if (!workspace)
04885 return -1;
04886 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
04887 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
04888 if (iaxdebug)
04889 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
04890 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
04891 padding = 16 + (padding & 0xf);
04892 memcpy(workspace, poo, padding);
04893 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
04894 workspace[15] &= 0xf0;
04895 workspace[15] |= (padding & 0xf);
04896 if (iaxdebug)
04897 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
04898 *datalen += padding;
04899 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
04900 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
04901 memcpy(poo, workspace + *datalen - 32, 32);
04902 } else {
04903 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
04904 if (iaxdebug)
04905 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
04906 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
04907 padding = 16 + (padding & 0xf);
04908 memcpy(workspace, poo, padding);
04909 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
04910 workspace[15] &= 0xf0;
04911 workspace[15] |= (padding & 0x0f);
04912 *datalen += padding;
04913 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
04914 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
04915 memcpy(poo, workspace + *datalen - 32, 32);
04916 }
04917 return 0;
04918 }
04919
04920 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
04921 {
04922 int res=-1;
04923 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) {
04924
04925 struct MD5Context md5;
04926 unsigned char digest[16];
04927 char *tmppw, *stringp;
04928
04929 tmppw = ast_strdupa(iaxs[callno]->secret);
04930 stringp = tmppw;
04931 while ((tmppw = strsep(&stringp, ";"))) {
04932 MD5Init(&md5);
04933 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
04934 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
04935 MD5Final(digest, &md5);
04936 build_encryption_keys(digest, iaxs[callno]);
04937 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04938 if (!res) {
04939 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED);
04940 break;
04941 }
04942 }
04943 } else
04944 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
04945 return res;
04946 }
04947
04948 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
04949 {
04950
04951
04952
04953 struct ast_iax2_full_hdr *fh;
04954 struct ast_iax2_mini_hdr *mh;
04955 struct ast_iax2_video_hdr *vh;
04956 struct {
04957 struct iax_frame fr2;
04958 unsigned char buffer[4096];
04959 } frb;
04960 struct iax_frame *fr;
04961 int res;
04962 int sendmini=0;
04963 unsigned int lastsent;
04964 unsigned int fts;
04965
04966 frb.fr2.afdatalen = sizeof(frb.buffer);
04967
04968 if (!pvt) {
04969 ast_log(LOG_WARNING, "No private structure for packet?\n");
04970 return -1;
04971 }
04972
04973 lastsent = pvt->lastsent;
04974
04975
04976 fts = calc_timestamp(pvt, ts, f);
04977
04978
04979
04980
04981 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
04982 return 0;
04983 #if 0
04984 ast_log(LOG_NOTICE,
04985 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
04986 *("=!" + (f->frametype == AST_FRAME_VOICE)),
04987 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
04988 pvt->keyrotateid != -1 ? "" : "no "
04989 );
04990 #endif
04991 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
04992 iax2_key_rotate(pvt);
04993 }
04994
04995 if ((ast_test_flag(pvt, IAX_TRUNK) ||
04996 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
04997 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
04998 &&
04999 (f->frametype == AST_FRAME_VOICE)
05000 &&
05001 (f->subclass == pvt->svoiceformat)
05002 ) {
05003
05004 now = 1;
05005
05006 sendmini = 1;
05007 }
05008 if ( f->frametype == AST_FRAME_VIDEO ) {
05009
05010
05011
05012
05013
05014 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
05015 ((f->subclass & ~0x1) == pvt->svideoformat)
05016 ) {
05017 now = 1;
05018 sendmini = 1;
05019 } else {
05020 now = 0;
05021 sendmini = 0;
05022 }
05023 pvt->lastvsent = fts;
05024 }
05025
05026 if (now) {
05027 fr = &frb.fr2;
05028 } else
05029 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
05030 if (!fr) {
05031 ast_log(LOG_WARNING, "Out of memory\n");
05032 return -1;
05033 }
05034
05035 iax_frame_wrap(fr, f);
05036
05037 fr->ts = fts;
05038 fr->callno = pvt->callno;
05039 fr->transfer = transfer;
05040 fr->final = final;
05041 fr->encmethods = 0;
05042 if (!sendmini) {
05043
05044 if (seqno > -1)
05045 fr->oseqno = seqno;
05046 else
05047 fr->oseqno = pvt->oseqno++;
05048 fr->iseqno = pvt->iseqno;
05049 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
05050 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
05051 fh->ts = htonl(fr->ts);
05052 fh->oseqno = fr->oseqno;
05053 if (transfer) {
05054 fh->iseqno = 0;
05055 } else
05056 fh->iseqno = fr->iseqno;
05057
05058 if (!transfer)
05059 pvt->aseqno = fr->iseqno;
05060 fh->type = fr->af.frametype & 0xFF;
05061 if (fr->af.frametype == AST_FRAME_VIDEO)
05062 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6);
05063 else
05064 fh->csub = compress_subclass(fr->af.subclass);
05065 if (transfer) {
05066 fr->dcallno = pvt->transfercallno;
05067 } else
05068 fr->dcallno = pvt->peercallno;
05069 fh->dcallno = htons(fr->dcallno);
05070 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
05071 fr->data = fh;
05072 fr->retries = 0;
05073
05074 fr->retrytime = pvt->pingtime * 2;
05075 if (fr->retrytime < MIN_RETRY_TIME)
05076 fr->retrytime = MIN_RETRY_TIME;
05077 if (fr->retrytime > MAX_RETRY_TIME)
05078 fr->retrytime = MAX_RETRY_TIME;
05079
05080 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK))
05081 fr->retries = -1;
05082 else if (f->frametype == AST_FRAME_VOICE)
05083 pvt->svoiceformat = f->subclass;
05084 else if (f->frametype == AST_FRAME_VIDEO)
05085 pvt->svideoformat = f->subclass & ~0x1;
05086 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05087 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05088 if (fr->transfer)
05089 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05090 else
05091 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
05092 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
05093 fr->encmethods = pvt->encmethods;
05094 fr->ecx = pvt->ecx;
05095 fr->mydcx = pvt->mydcx;
05096 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
05097 } else
05098 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05099 }
05100
05101 if (now) {
05102 res = send_packet(fr);
05103 } else
05104 res = iax2_transmit(fr);
05105 } else {
05106 if (ast_test_flag(pvt, IAX_TRUNK)) {
05107 iax2_trunk_queue(pvt, fr);
05108 res = 0;
05109 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
05110
05111 fr->oseqno = -1;
05112 fr->iseqno = -1;
05113 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
05114 vh->zeros = 0;
05115 vh->callno = htons(0x8000 | fr->callno);
05116 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0));
05117 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
05118 fr->data = vh;
05119 fr->retries = -1;
05120 res = send_packet(fr);
05121 } else {
05122
05123 fr->oseqno = -1;
05124 fr->iseqno = -1;
05125
05126 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
05127 mh->callno = htons(fr->callno);
05128 mh->ts = htons(fr->ts & 0xFFFF);
05129 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
05130 fr->data = mh;
05131 fr->retries = -1;
05132 if (pvt->transferring == TRANSFER_MEDIAPASS)
05133 fr->transfer = 1;
05134 if (ast_test_flag(pvt, IAX_ENCRYPTED)) {
05135 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) {
05136 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
05137 } else
05138 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
05139 }
05140 res = send_packet(fr);
05141 }
05142 }
05143 return res;
05144 }
05145
05146 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05147 {
05148 regex_t regexbuf;
05149 int havepattern = 0;
05150
05151 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
05152 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
05153
05154 struct iax2_user *user = NULL;
05155 char auth[90];
05156 char *pstr = "";
05157 struct ao2_iterator i;
05158
05159 switch (cmd) {
05160 case CLI_INIT:
05161 e->command = "iax2 show users [like]";
05162 e->usage =
05163 "Usage: iax2 show users [like <pattern>]\n"
05164 " Lists all known IAX2 users.\n"
05165 " Optional regular expression pattern is used to filter the user list.\n";
05166 return NULL;
05167 case CLI_GENERATE:
05168 return NULL;
05169 }
05170
05171 switch (a->argc) {
05172 case 5:
05173 if (!strcasecmp(a->argv[3], "like")) {
05174 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
05175 return CLI_SHOWUSAGE;
05176 havepattern = 1;
05177 } else
05178 return CLI_SHOWUSAGE;
05179 case 3:
05180 break;
05181 default:
05182 return CLI_SHOWUSAGE;
05183 }
05184
05185 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
05186 i = ao2_iterator_init(users, 0);
05187 for (user = ao2_iterator_next(&i); user;
05188 user_unref(user), user = ao2_iterator_next(&i)) {
05189 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
05190 continue;
05191
05192 if (!ast_strlen_zero(user->secret)) {
05193 ast_copy_string(auth,user->secret, sizeof(auth));
05194 } else if (!ast_strlen_zero(user->inkeys)) {
05195 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
05196 } else
05197 ast_copy_string(auth, "-no secret-", sizeof(auth));
05198
05199 if(ast_test_flag(user,IAX_CODEC_NOCAP))
05200 pstr = "REQ Only";
05201 else if(ast_test_flag(user,IAX_CODEC_NOPREFS))
05202 pstr = "Disabled";
05203 else
05204 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
05205
05206 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
05207 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
05208 user->ha ? "Yes" : "No", pstr);
05209 }
05210
05211 if (havepattern)
05212 regfree(®exbuf);
05213
05214 return CLI_SUCCESS;
05215 #undef FORMAT
05216 #undef FORMAT2
05217 }
05218
05219 static int __iax2_show_peers(int manager, int fd, struct mansession *s, int argc, char *argv[])
05220 {
05221 regex_t regexbuf;
05222 int havepattern = 0;
05223 int total_peers = 0;
05224 int online_peers = 0;
05225 int offline_peers = 0;
05226 int unmonitored_peers = 0;
05227 struct ao2_iterator i;
05228
05229 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s"
05230 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s"
05231
05232 struct iax2_peer *peer = NULL;
05233 char name[256];
05234 int registeredonly=0;
05235 char *term = manager ? "\r\n" : "\n";
05236 char idtext[256] = "";
05237 switch (argc) {
05238 case 6:
05239 if (!strcasecmp(argv[3], "registered"))
05240 registeredonly = 1;
05241 else
05242 return RESULT_SHOWUSAGE;
05243 if (!strcasecmp(argv[4], "like")) {
05244 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
05245 return RESULT_SHOWUSAGE;
05246 havepattern = 1;
05247 } else
05248 return RESULT_SHOWUSAGE;
05249 break;
05250 case 5:
05251 if (!strcasecmp(argv[3], "like")) {
05252 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
05253 return RESULT_SHOWUSAGE;
05254 havepattern = 1;
05255 } else
05256 return RESULT_SHOWUSAGE;
05257 break;
05258 case 4:
05259 if (!strcasecmp(argv[3], "registered"))
05260 registeredonly = 1;
05261 else
05262 return RESULT_SHOWUSAGE;
05263 break;
05264 case 3:
05265 break;
05266 default:
05267 return RESULT_SHOWUSAGE;
05268 }
05269
05270
05271 if (!s)
05272 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term);
05273
05274 i = ao2_iterator_init(peers, 0);
05275 for (peer = ao2_iterator_next(&i); peer;
05276 peer_unref(peer), peer = ao2_iterator_next(&i)) {
05277 char nm[20];
05278 char status[20];
05279 char srch[2000];
05280 int retstatus;
05281
05282 if (registeredonly && !peer->addr.sin_addr.s_addr)
05283 continue;
05284 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0))
05285 continue;
05286
05287 if (!ast_strlen_zero(peer->username))
05288 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
05289 else
05290 ast_copy_string(name, peer->name, sizeof(name));
05291
05292 retstatus = peer_status(peer, status, sizeof(status));
05293 if (retstatus > 0)
05294 online_peers++;
05295 else if (!retstatus)
05296 offline_peers++;
05297 else
05298 unmonitored_peers++;
05299
05300 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05301
05302 snprintf(srch, sizeof(srch), FORMAT, name,
05303 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05304 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05305 nm,
05306 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
05307 peer->encmethods ? "(E)" : " ", status, term);
05308
05309 if (s)
05310 astman_append(s,
05311 "Event: PeerEntry\r\n%s"
05312 "Channeltype: IAX2\r\n"
05313 "ChanObjectType: peer\r\n"
05314 "ObjectName: %s\r\n"
05315 "IPaddress: %s\r\n"
05316 "IPport: %d\r\n"
05317 "Dynamic: %s\r\n"
05318 "Status: %s\r\n\r\n",
05319 idtext,
05320 name,
05321 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
05322 ntohs(peer->addr.sin_port),
05323 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no",
05324 status);
05325
05326 else
05327 ast_cli(fd, FORMAT, name,
05328 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
05329 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
05330 nm,
05331 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ",
05332 peer->encmethods ? "(E)" : " ", status, term);
05333 total_peers++;
05334 }
05335
05336 if (!s)
05337 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term);
05338
05339 if (havepattern)
05340 regfree(®exbuf);
05341
05342 return RESULT_SUCCESS;
05343 #undef FORMAT
05344 #undef FORMAT2
05345 }
05346
05347 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05348 {
05349 struct iax2_thread *thread = NULL;
05350 time_t t;
05351 int threadcount = 0, dynamiccount = 0;
05352 char type;
05353
05354 switch (cmd) {
05355 case CLI_INIT:
05356 e->command = "iax2 show threads";
05357 e->usage =
05358 "Usage: iax2 show threads\n"
05359 " Lists status of IAX helper threads\n";
05360 return NULL;
05361 case CLI_GENERATE:
05362 return NULL;
05363 }
05364 if (a->argc != 3)
05365 return CLI_SHOWUSAGE;
05366
05367 ast_cli(a->fd, "IAX2 Thread Information\n");
05368 time(&t);
05369 ast_cli(a->fd, "Idle Threads:\n");
05370 AST_LIST_LOCK(&idle_list);
05371 AST_LIST_TRAVERSE(&idle_list, thread, list) {
05372 #ifdef DEBUG_SCHED_MULTITHREAD
05373 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
05374 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05375 #else
05376 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05377 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05378 #endif
05379 threadcount++;
05380 }
05381 AST_LIST_UNLOCK(&idle_list);
05382 ast_cli(a->fd, "Active Threads:\n");
05383 AST_LIST_LOCK(&active_list);
05384 AST_LIST_TRAVERSE(&active_list, thread, list) {
05385 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
05386 type = 'D';
05387 else
05388 type = 'P';
05389 #ifdef DEBUG_SCHED_MULTITHREAD
05390 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
05391 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05392 #else
05393 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
05394 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05395 #endif
05396 threadcount++;
05397 }
05398 AST_LIST_UNLOCK(&active_list);
05399 ast_cli(a->fd, "Dynamic Threads:\n");
05400 AST_LIST_LOCK(&dynamic_list);
05401 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
05402 #ifdef DEBUG_SCHED_MULTITHREAD
05403 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
05404 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
05405 #else
05406 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
05407 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
05408 #endif
05409 dynamiccount++;
05410 }
05411 AST_LIST_UNLOCK(&dynamic_list);
05412 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
05413 return CLI_SUCCESS;
05414 }
05415
05416 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05417 {
05418 struct iax2_peer *p;
05419
05420 switch (cmd) {
05421 case CLI_INIT:
05422 e->command = "iax2 unregister";
05423 e->usage =
05424 "Usage: iax2 unregister <peername>\n"
05425 " Unregister (force expiration) an IAX2 peer from the registry.\n";
05426 return NULL;
05427 case CLI_GENERATE:
05428 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
05429 }
05430
05431 if (a->argc != 3)
05432 return CLI_SHOWUSAGE;
05433
05434 p = find_peer(a->argv[2], 1);
05435 if (p) {
05436 if (p->expire > 0) {
05437 struct iax2_peer tmp_peer = {
05438 .name = a->argv[2],
05439 };
05440 struct iax2_peer *peer;
05441
05442 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
05443 if (peer) {
05444 expire_registry(peer_ref(peer));
05445 peer_unref(peer);
05446 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
05447 } else {
05448 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
05449 }
05450 } else {
05451 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
05452 }
05453 } else {
05454 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
05455 }
05456 return CLI_SUCCESS;
05457 }
05458
05459 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
05460 {
05461 int which = 0;
05462 struct iax2_peer *p = NULL;
05463 char *res = NULL;
05464 int wordlen = strlen(word);
05465
05466
05467 if (pos == 2) {
05468 struct ao2_iterator i = ao2_iterator_init(peers, 0);
05469 while ((p = ao2_iterator_next(&i))) {
05470 if (!strncasecmp(p->name, word, wordlen) &&
05471 ++which > state && p->expire > 0) {
05472 res = ast_strdup(p->name);
05473 peer_unref(p);
05474 break;
05475 }
05476 peer_unref(p);
05477 }
05478 }
05479
05480 return res;
05481 }
05482
05483 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05484 {
05485 switch (cmd) {
05486 case CLI_INIT:
05487 e->command = "iax2 show peers";
05488 e->usage =
05489 "Usage: iax2 show peers [registered] [like <pattern>]\n"
05490 " Lists all known IAX2 peers.\n"
05491 " Optional 'registered' argument lists only peers with known addresses.\n"
05492 " Optional regular expression pattern is used to filter the peer list.\n";
05493 return NULL;
05494 case CLI_GENERATE:
05495 return NULL;
05496 }
05497
05498 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) {
05499 case RESULT_SHOWUSAGE:
05500 return CLI_SHOWUSAGE;
05501 case RESULT_FAILURE:
05502 return CLI_FAILURE;
05503 default:
05504 return CLI_SUCCESS;
05505 }
05506 }
05507
05508 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
05509 {
05510 ast_cli_netstats(s, -1, 0);
05511 astman_append(s, "\r\n");
05512 return RESULT_SUCCESS;
05513 }
05514
05515 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05516 {
05517 struct iax_firmware *cur = NULL;
05518
05519 switch (cmd) {
05520 case CLI_INIT:
05521 e->command = "iax2 show firmware";
05522 e->usage =
05523 "Usage: iax2 show firmware\n"
05524 " Lists all known IAX firmware images.\n";
05525 return NULL;
05526 case CLI_GENERATE:
05527 return NULL;
05528 }
05529
05530 if (a->argc != 3 && a->argc != 4)
05531 return CLI_SHOWUSAGE;
05532
05533 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
05534 AST_LIST_LOCK(&firmwares);
05535 AST_LIST_TRAVERSE(&firmwares, cur, list) {
05536 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
05537 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
05538 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
05539 }
05540 }
05541 AST_LIST_UNLOCK(&firmwares);
05542
05543 return CLI_SUCCESS;
05544 }
05545
05546
05547 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
05548 {
05549 char *a[] = { "iax2", "show", "users" };
05550 const char *id = astman_get_header(m,"ActionID");
05551 char idtext[256] = "";
05552
05553 if (!ast_strlen_zero(id))
05554 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
05555 astman_send_ack(s, m, "Peer status list will follow");
05556 return __iax2_show_peers(1, -1, s, 3, a );
05557 }
05558
05559
05560 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
05561 {
05562 struct iax2_peer *peer = NULL;
05563 int peer_count = 0;
05564 char nm[20];
05565 char status[20];
05566 const char *id = astman_get_header(m,"ActionID");
05567 char idtext[256] = "";
05568 struct ao2_iterator i;
05569
05570 if (!ast_strlen_zero(id))
05571 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
05572
05573 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
05574
05575
05576 i = ao2_iterator_init(peers, 0);
05577 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
05578
05579 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
05580 if (!ast_strlen_zero(peer->username)) {
05581 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
05582 } else {
05583 astman_append(s, "ObjectName: %s\r\n", peer->name);
05584 }
05585 astman_append(s, "ChanObjectType: peer\r\n");
05586 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-");
05587 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
05588 astman_append(s, "Mask: %s\r\n", nm);
05589 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port));
05590 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No");
05591 peer_status(peer, status, sizeof(status));
05592 astman_append(s, "Status: %s\r\n\r\n", status);
05593 peer_count++;
05594 }
05595
05596 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
05597 return RESULT_SUCCESS;
05598 }
05599
05600
05601 static char *regstate2str(int regstate)
05602 {
05603 switch(regstate) {
05604 case REG_STATE_UNREGISTERED:
05605 return "Unregistered";
05606 case REG_STATE_REGSENT:
05607 return "Request Sent";
05608 case REG_STATE_AUTHSENT:
05609 return "Auth. Sent";
05610 case REG_STATE_REGISTERED:
05611 return "Registered";
05612 case REG_STATE_REJECTED:
05613 return "Rejected";
05614 case REG_STATE_TIMEOUT:
05615 return "Timeout";
05616 case REG_STATE_NOAUTH:
05617 return "No Authentication";
05618 default:
05619 return "Unknown";
05620 }
05621 }
05622
05623 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05624 {
05625 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
05626 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
05627 struct iax2_registry *reg = NULL;
05628 char host[80];
05629 char perceived[80];
05630 int counter = 0;
05631
05632 switch (cmd) {
05633 case CLI_INIT:
05634 e->command = "iax2 show registry";
05635 e->usage =
05636 "Usage: iax2 show registry\n"
05637 " Lists all registration requests and status.\n";
05638 return NULL;
05639 case CLI_GENERATE:
05640 return NULL;
05641 }
05642 if (a->argc != 3)
05643 return CLI_SHOWUSAGE;
05644 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
05645 AST_LIST_LOCK(®istrations);
05646 AST_LIST_TRAVERSE(®istrations, reg, entry) {
05647 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port));
05648 if (reg->us.sin_addr.s_addr)
05649 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
05650 else
05651 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
05652 ast_cli(a->fd, FORMAT, host,
05653 (reg->dnsmgr) ? "Y" : "N",
05654 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
05655 counter++;
05656 }
05657 AST_LIST_UNLOCK(®istrations);
05658 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
05659 return CLI_SUCCESS;
05660 #undef FORMAT
05661 #undef FORMAT2
05662 }
05663
05664 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05665 {
05666 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s\n"
05667 #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"
05668 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
05669 int x;
05670 int numchans = 0;
05671
05672 switch (cmd) {
05673 case CLI_INIT:
05674 e->command = "iax2 show channels";
05675 e->usage =
05676 "Usage: iax2 show channels\n"
05677 " Lists all currently active IAX channels.\n";
05678 return NULL;
05679 case CLI_GENERATE:
05680 return NULL;
05681 }
05682
05683 if (a->argc != 3)
05684 return CLI_SHOWUSAGE;
05685 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format");
05686 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05687 ast_mutex_lock(&iaxsl[x]);
05688 if (iaxs[x]) {
05689 int lag, jitter, localdelay;
05690 jb_info jbinfo;
05691
05692 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05693 jb_getinfo(iaxs[x]->jb, &jbinfo);
05694 jitter = jbinfo.jitter;
05695 localdelay = jbinfo.current - jbinfo.min;
05696 } else {
05697 jitter = -1;
05698 localdelay = 0;
05699 }
05700 lag = iaxs[x]->remote_rr.delay;
05701 ast_cli(a->fd, FORMAT,
05702 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05703 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
05704 S_OR(iaxs[x]->username, "(None)"),
05705 iaxs[x]->callno, iaxs[x]->peercallno,
05706 iaxs[x]->oseqno, iaxs[x]->iseqno,
05707 lag,
05708 jitter,
05709 localdelay,
05710 ast_getformatname(iaxs[x]->voiceformat) );
05711 numchans++;
05712 }
05713 ast_mutex_unlock(&iaxsl[x]);
05714 }
05715 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05716 return CLI_SUCCESS;
05717 #undef FORMAT
05718 #undef FORMAT2
05719 #undef FORMATB
05720 }
05721
05722 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
05723 {
05724 int x;
05725 int numchans = 0;
05726 #define ACN_FORMAT1 "%-25.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d\n"
05727 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n"
05728 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
05729 ast_mutex_lock(&iaxsl[x]);
05730 if (iaxs[x]) {
05731 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
05732 jb_info jbinfo;
05733
05734 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) {
05735 jb_getinfo(iaxs[x]->jb, &jbinfo);
05736 localjitter = jbinfo.jitter;
05737 localdelay = jbinfo.current - jbinfo.min;
05738 locallost = jbinfo.frames_lost;
05739 locallosspct = jbinfo.losspct/1000;
05740 localdropped = jbinfo.frames_dropped;
05741 localooo = jbinfo.frames_ooo;
05742 } else {
05743 localjitter = -1;
05744 localdelay = 0;
05745 locallost = -1;
05746 locallosspct = -1;
05747 localdropped = 0;
05748 localooo = -1;
05749 }
05750 if (s)
05751
05752 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
05753 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05754 iaxs[x]->pingtime,
05755 localjitter,
05756 localdelay,
05757 locallost,
05758 locallosspct,
05759 localdropped,
05760 localooo,
05761 iaxs[x]->frames_received/1000,
05762 iaxs[x]->remote_rr.jitter,
05763 iaxs[x]->remote_rr.delay,
05764 iaxs[x]->remote_rr.losscnt,
05765 iaxs[x]->remote_rr.losspct,
05766 iaxs[x]->remote_rr.dropped,
05767 iaxs[x]->remote_rr.ooo,
05768 iaxs[x]->remote_rr.packets/1000);
05769 else
05770 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
05771 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
05772 iaxs[x]->pingtime,
05773 localjitter,
05774 localdelay,
05775 locallost,
05776 locallosspct,
05777 localdropped,
05778 localooo,
05779 iaxs[x]->frames_received/1000,
05780 iaxs[x]->remote_rr.jitter,
05781 iaxs[x]->remote_rr.delay,
05782 iaxs[x]->remote_rr.losscnt,
05783 iaxs[x]->remote_rr.losspct,
05784 iaxs[x]->remote_rr.dropped,
05785 iaxs[x]->remote_rr.ooo,
05786 iaxs[x]->remote_rr.packets/1000
05787 );
05788 numchans++;
05789 }
05790 ast_mutex_unlock(&iaxsl[x]);
05791 }
05792
05793 return numchans;
05794 }
05795
05796 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05797 {
05798 int numchans = 0;
05799
05800 switch (cmd) {
05801 case CLI_INIT:
05802 e->command = "iax2 show netstats";
05803 e->usage =
05804 "Usage: iax2 show netstats\n"
05805 " Lists network status for all currently active IAX channels.\n";
05806 return NULL;
05807 case CLI_GENERATE:
05808 return NULL;
05809 }
05810 if (a->argc != 3)
05811 return CLI_SHOWUSAGE;
05812 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
05813 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts\n");
05814 numchans = ast_cli_netstats(NULL, a->fd, 1);
05815 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
05816 return CLI_SUCCESS;
05817 }
05818
05819
05820
05821 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05822 {
05823 switch (cmd) {
05824 case CLI_INIT:
05825 e->command = "iax2 set debug {on|off|peer}";
05826 e->usage =
05827 "Usage: iax2 set debug {on|off|peer peername}\n"
05828 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
05829 return NULL;
05830 case CLI_GENERATE:
05831 if (a->pos == 4)
05832 return complete_iax2_peers(a->line, a->word, a->pos, a->n);
05833 return NULL;
05834 }
05835
05836 if (a->argc < e->args || a->argc > e->args + 1)
05837 return CLI_SHOWUSAGE;
05838
05839 if (!strcasecmp(a->argv[3], "peer")) {
05840 struct iax2_peer *peer;
05841
05842 if (a->argc != e->args + 1)
05843 return CLI_SHOWUSAGE;
05844
05845 peer = find_peer(a->argv[4], 1);
05846
05847 if (!peer) {
05848 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
05849 return CLI_FAILURE;
05850 }
05851
05852 debugaddr.sin_addr = peer->addr.sin_addr;
05853 debugaddr.sin_port = peer->addr.sin_port;
05854
05855 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
05856 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
05857
05858 ao2_ref(peer, -1);
05859 } else if (!strncasecmp(a->argv[3], "on", 2)) {
05860 iaxdebug = 1;
05861 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
05862 } else {
05863 iaxdebug = 0;
05864 memset(&debugaddr, 0, sizeof(debugaddr));
05865 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
05866 }
05867 return CLI_SUCCESS;
05868 }
05869
05870 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05871 {
05872 switch (cmd) {
05873 case CLI_INIT:
05874 e->command = "iax2 set debug trunk {on|off}";
05875 e->usage =
05876 "Usage: iax2 set debug trunk {on|off}\n"
05877 " Enables/Disables debugging of IAX trunking\n";
05878 return NULL;
05879 case CLI_GENERATE:
05880 return NULL;
05881 }
05882
05883 if (a->argc != e->args)
05884 return CLI_SHOWUSAGE;
05885
05886 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
05887 iaxtrunkdebug = 1;
05888 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
05889 } else {
05890 iaxtrunkdebug = 0;
05891 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
05892 }
05893 return CLI_SUCCESS;
05894 }
05895
05896 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
05897 {
05898 switch (cmd) {
05899 case CLI_INIT:
05900 e->command = "iax2 set debug jb {on|off}";
05901 e->usage =
05902 "Usage: iax2 set debug jb {on|off}\n"
05903 " Enables/Disables jitterbuffer debugging information\n";
05904 return NULL;
05905 case CLI_GENERATE:
05906 return NULL;
05907 }
05908
05909 if (a->argc != e->args)
05910 return CLI_SHOWUSAGE;
05911
05912 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
05913 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
05914 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
05915 } else {
05916 jb_setoutput(jb_error_output, jb_warning_output, NULL);
05917 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
05918 }
05919 return CLI_SUCCESS;
05920 }
05921
05922 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
05923 {
05924 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05925 int res = -1;
05926 ast_mutex_lock(&iaxsl[callno]);
05927 if (iaxs[callno]) {
05928
05929 if (!iaxs[callno]->error) {
05930 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE))
05931 res = 0;
05932
05933 else if (f->frametype == AST_FRAME_NULL)
05934 res = 0;
05935 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH))
05936 res = 0;
05937 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
05938 res = 0;
05939 else
05940
05941 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
05942 } else {
05943 ast_debug(1, "Write error: %s\n", strerror(errno));
05944 }
05945 }
05946
05947 ast_mutex_unlock(&iaxsl[callno]);
05948 return res;
05949 }
05950
05951 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
05952 int now, int transfer, int final)
05953 {
05954 struct ast_frame f = { 0, };
05955
05956 f.frametype = type;
05957 f.subclass = command;
05958 f.datalen = datalen;
05959 f.src = __FUNCTION__;
05960 f.data.ptr = (void *) data;
05961
05962 return iax2_send(i, &f, ts, seqno, now, transfer, final);
05963 }
05964
05965 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05966 {
05967 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
05968 }
05969
05970 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
05971 {
05972 int res;
05973 ast_mutex_lock(&iaxsl[callno]);
05974 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
05975 ast_mutex_unlock(&iaxsl[callno]);
05976 return res;
05977 }
05978
05979
05980
05981
05982
05983
05984 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)
05985 {
05986 int call_num = i->callno;
05987
05988 iax2_predestroy(i->callno);
05989 if (!iaxs[call_num])
05990 return -1;
05991 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
05992 }
05993
05994 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)
05995 {
05996 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
05997 }
05998
05999 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
06000 {
06001 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
06002 }
06003
06004 static int apply_context(struct iax2_context *con, const char *context)
06005 {
06006 while(con) {
06007 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
06008 return -1;
06009 con = con->next;
06010 }
06011 return 0;
06012 }
06013
06014
06015 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06016 {
06017
06018 int res = -1;
06019 int version = 2;
06020 struct iax2_user *user = NULL, *best = NULL;
06021 int bestscore = 0;
06022 int gotcapability = 0;
06023 struct ast_variable *v = NULL, *tmpvar = NULL;
06024 struct ao2_iterator i;
06025
06026 if (!iaxs[callno])
06027 return res;
06028 if (ies->called_number)
06029 ast_string_field_set(iaxs[callno], exten, ies->called_number);
06030 if (ies->calling_number) {
06031 ast_shrink_phone_number(ies->calling_number);
06032 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
06033 }
06034 if (ies->calling_name)
06035 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
06036 if (ies->calling_ani)
06037 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
06038 if (ies->dnid)
06039 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
06040 if (ies->rdnis)
06041 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
06042 if (ies->called_context)
06043 ast_string_field_set(iaxs[callno], context, ies->called_context);
06044 if (ies->language)
06045 ast_string_field_set(iaxs[callno], language, ies->language);
06046 if (ies->username)
06047 ast_string_field_set(iaxs[callno], username, ies->username);
06048 if (ies->calling_ton > -1)
06049 iaxs[callno]->calling_ton = ies->calling_ton;
06050 if (ies->calling_tns > -1)
06051 iaxs[callno]->calling_tns = ies->calling_tns;
06052 if (ies->calling_pres > -1)
06053 iaxs[callno]->calling_pres = ies->calling_pres;
06054 if (ies->format)
06055 iaxs[callno]->peerformat = ies->format;
06056 if (ies->adsicpe)
06057 iaxs[callno]->peeradsicpe = ies->adsicpe;
06058 if (ies->capability) {
06059 gotcapability = 1;
06060 iaxs[callno]->peercapability = ies->capability;
06061 }
06062 if (ies->version)
06063 version = ies->version;
06064
06065
06066 if(ies->codec_prefs) {
06067 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
06068 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
06069 }
06070
06071 if (!gotcapability)
06072 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
06073 if (version > IAX_PROTO_VERSION) {
06074 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
06075 ast_inet_ntoa(sin->sin_addr), version);
06076 return res;
06077 }
06078
06079 i = ao2_iterator_init(users, 0);
06080 while ((user = ao2_iterator_next(&i))) {
06081 if ((ast_strlen_zero(iaxs[callno]->username) ||
06082 !strcmp(iaxs[callno]->username, user->name))
06083 && ast_apply_ha(user->ha, sin)
06084 && (ast_strlen_zero(iaxs[callno]->context) ||
06085 apply_context(user->contexts, iaxs[callno]->context))) {
06086 if (!ast_strlen_zero(iaxs[callno]->username)) {
06087
06088 if (best)
06089 user_unref(best);
06090 best = user;
06091 break;
06092 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
06093
06094 if (user->ha) {
06095
06096 if (bestscore < 4) {
06097 bestscore = 4;
06098 if (best)
06099 user_unref(best);
06100 best = user;
06101 continue;
06102 }
06103 } else {
06104
06105 if (bestscore < 3) {
06106 bestscore = 3;
06107 if (best)
06108 user_unref(best);
06109 best = user;
06110 continue;
06111 }
06112 }
06113 } else {
06114 if (user->ha) {
06115
06116 if (bestscore < 2) {
06117 bestscore = 2;
06118 if (best)
06119 user_unref(best);
06120 best = user;
06121 continue;
06122 }
06123 } else {
06124
06125 if (bestscore < 1) {
06126 bestscore = 1;
06127 if (best)
06128 user_unref(best);
06129 best = user;
06130 continue;
06131 }
06132 }
06133 }
06134 }
06135 user_unref(user);
06136 }
06137 user = best;
06138 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
06139 user = realtime_user(iaxs[callno]->username, sin);
06140 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
06141 !apply_context(user->contexts, iaxs[callno]->context)) {
06142 user = user_unref(user);
06143 }
06144 }
06145 if (user) {
06146
06147
06148 for (v = user->vars ; v ; v = v->next) {
06149 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
06150 tmpvar->next = iaxs[callno]->vars;
06151 iaxs[callno]->vars = tmpvar;
06152 }
06153 }
06154
06155 if (user->maxauthreq > 0)
06156 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ);
06157 iaxs[callno]->prefs = user->prefs;
06158 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST);
06159 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS);
06160 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP);
06161 iaxs[callno]->encmethods = user->encmethods;
06162
06163 if (ast_strlen_zero(iaxs[callno]->username))
06164 ast_string_field_set(iaxs[callno], username, user->name);
06165
06166 ast_copy_flags(iaxs[callno], user, IAX_TRUNK);
06167 iaxs[callno]->capability = user->capability;
06168
06169 if (ast_strlen_zero(iaxs[callno]->context)) {
06170 if (user->contexts)
06171 ast_string_field_set(iaxs[callno], context, user->contexts->context);
06172 else
06173 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
06174 }
06175
06176 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
06177
06178 iaxs[callno]->authmethods = user->authmethods;
06179 iaxs[callno]->adsi = user->adsi;
06180
06181 if (ast_test_flag(user, IAX_HASCALLERID)) {
06182 iaxs[callno]->calling_tns = 0;
06183 iaxs[callno]->calling_ton = 0;
06184 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
06185 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
06186 ast_string_field_set(iaxs[callno], ani, user->cid_num);
06187 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
06188 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
06189 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
06190 }
06191 if (!ast_strlen_zero(user->accountcode))
06192 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
06193 if (!ast_strlen_zero(user->mohinterpret))
06194 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
06195 if (!ast_strlen_zero(user->mohsuggest))
06196 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
06197 if (!ast_strlen_zero(user->parkinglot))
06198 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
06199 if (user->amaflags)
06200 iaxs[callno]->amaflags = user->amaflags;
06201 if (!ast_strlen_zero(user->language))
06202 ast_string_field_set(iaxs[callno], language, user->language);
06203 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
06204
06205 if (!ast_strlen_zero(user->dbsecret)) {
06206 char *family, *key=NULL;
06207 char buf[80];
06208 family = ast_strdupa(user->dbsecret);
06209 key = strchr(family, '/');
06210 if (key) {
06211 *key = '\0';
06212 key++;
06213 }
06214 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
06215 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
06216 else
06217 ast_string_field_set(iaxs[callno], secret, buf);
06218 } else
06219 ast_string_field_set(iaxs[callno], secret, user->secret);
06220 res = 0;
06221 user = user_unref(user);
06222 } else {
06223
06224
06225
06226
06227 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
06228 ast_string_field_set(iaxs[callno], secret, "badsecret");
06229 iaxs[callno]->authrej = 1;
06230 if (!ast_strlen_zero(iaxs[callno]->username)) {
06231
06232 res = 0;
06233 }
06234 }
06235 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
06236 return res;
06237 }
06238
06239 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
06240 {
06241 struct ast_iax2_full_hdr fh;
06242 fh.scallno = htons(src | IAX_FLAG_FULL);
06243 fh.dcallno = htons(dst);
06244 fh.ts = 0;
06245 fh.oseqno = 0;
06246 fh.iseqno = 0;
06247 fh.type = AST_FRAME_IAX;
06248 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
06249 iax_outputframe(NULL, &fh, 0, sin, 0);
06250 #if 0
06251 if (option_debug)
06252 #endif
06253 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
06254 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
06255 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
06256 }
06257
06258 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
06259 {
06260
06261 p->encmethods &= enc;
06262 if (p->encmethods) {
06263 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
06264 p->keyrotateid = -2;
06265 }
06266 if (p->encmethods & IAX_ENCRYPT_AES128)
06267 p->encmethods = IAX_ENCRYPT_AES128;
06268 else
06269 p->encmethods = 0;
06270 }
06271 }
06272
06273
06274
06275
06276
06277
06278
06279 static int authenticate_request(int call_num)
06280 {
06281 struct iax_ie_data ied;
06282 int res = -1, authreq_restrict = 0;
06283 char challenge[10];
06284 struct chan_iax2_pvt *p = iaxs[call_num];
06285
06286 memset(&ied, 0, sizeof(ied));
06287
06288
06289 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06290 struct iax2_user *user, tmp_user = {
06291 .name = p->username,
06292 };
06293
06294 user = ao2_find(users, &tmp_user, OBJ_POINTER);
06295 if (user) {
06296 if (user->curauthreq == user->maxauthreq)
06297 authreq_restrict = 1;
06298 else
06299 user->curauthreq++;
06300 user = user_unref(user);
06301 }
06302 }
06303
06304
06305 if (authreq_restrict) {
06306 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
06307 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
06308 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
06309 return 0;
06310 }
06311
06312 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
06313 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
06314 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
06315 ast_string_field_set(p, challenge, challenge);
06316
06317 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
06318 }
06319 if (p->encmethods)
06320 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
06321
06322 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
06323
06324 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
06325
06326 if (p->encmethods)
06327 ast_set_flag(p, IAX_ENCRYPTED);
06328
06329 return res;
06330 }
06331
06332 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
06333 {
06334 char requeststr[256];
06335 char md5secret[256] = "";
06336 char secret[256] = "";
06337 char rsasecret[256] = "";
06338 int res = -1;
06339 int x;
06340 struct iax2_user *user, tmp_user = {
06341 .name = p->username,
06342 };
06343
06344 if (p->authrej) {
06345 return res;
06346 }
06347 user = ao2_find(users, &tmp_user, OBJ_POINTER);
06348 if (user) {
06349 if (ast_test_flag(p, IAX_MAXAUTHREQ)) {
06350 ast_atomic_fetchadd_int(&user->curauthreq, -1);
06351 ast_clear_flag(p, IAX_MAXAUTHREQ);
06352 }
06353 ast_string_field_set(p, host, user->name);
06354 user = user_unref(user);
06355 }
06356
06357 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
06358 return res;
06359 if (ies->password)
06360 ast_copy_string(secret, ies->password, sizeof(secret));
06361 if (ies->md5_result)
06362 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06363 if (ies->rsa_result)
06364 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06365 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
06366 struct ast_key *key;
06367 char *keyn;
06368 char tmpkey[256];
06369 char *stringp=NULL;
06370 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
06371 stringp=tmpkey;
06372 keyn = strsep(&stringp, ":");
06373 while(keyn) {
06374 key = ast_key_get(keyn, AST_KEY_PUBLIC);
06375 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
06376 res = 0;
06377 break;
06378 } else if (!key)
06379 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
06380 keyn = strsep(&stringp, ":");
06381 }
06382 } else if (p->authmethods & IAX_AUTH_MD5) {
06383 struct MD5Context md5;
06384 unsigned char digest[16];
06385 char *tmppw, *stringp;
06386
06387 tmppw = ast_strdupa(p->secret);
06388 stringp = tmppw;
06389 while((tmppw = strsep(&stringp, ";"))) {
06390 MD5Init(&md5);
06391 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
06392 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06393 MD5Final(digest, &md5);
06394
06395 for (x=0;x<16;x++)
06396 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
06397 if (!strcasecmp(requeststr, md5secret)) {
06398 res = 0;
06399 break;
06400 }
06401 }
06402 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
06403 if (!strcmp(secret, p->secret))
06404 res = 0;
06405 }
06406 return res;
06407 }
06408
06409
06410 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
06411 {
06412 char requeststr[256] = "";
06413 char peer[256] = "";
06414 char md5secret[256] = "";
06415 char rsasecret[256] = "";
06416 char secret[256] = "";
06417 struct iax2_peer *p = NULL;
06418 struct ast_key *key;
06419 char *keyn;
06420 int x;
06421 int expire = 0;
06422 int res = -1;
06423
06424 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06425
06426 if (ies->username)
06427 ast_copy_string(peer, ies->username, sizeof(peer));
06428 if (ies->password)
06429 ast_copy_string(secret, ies->password, sizeof(secret));
06430 if (ies->md5_result)
06431 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
06432 if (ies->rsa_result)
06433 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
06434 if (ies->refresh)
06435 expire = ies->refresh;
06436
06437 if (ast_strlen_zero(peer)) {
06438 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
06439 return -1;
06440 }
06441
06442
06443 ast_mutex_unlock(&iaxsl[callno]);
06444 p = find_peer(peer, 1);
06445 ast_mutex_lock(&iaxsl[callno]);
06446 if (!p || !iaxs[callno]) {
06447 if (iaxs[callno]) {
06448 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
06449
06450 ast_string_field_set(iaxs[callno], secret, "badsecret");
06451
06452
06453
06454
06455
06456
06457
06458
06459
06460 if (ast_strlen_zero(iaxs[callno]->challenge) &&
06461 !(!ast_strlen_zero(secret) && plaintext)) {
06462
06463 res = 0;
06464 }
06465 }
06466 if (authdebug && !p)
06467 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06468 goto return_unref;
06469 }
06470
06471 if (!ast_test_flag(p, IAX_DYNAMIC)) {
06472 if (authdebug)
06473 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
06474 goto return_unref;
06475 }
06476
06477 if (!ast_apply_ha(p->ha, sin)) {
06478 if (authdebug)
06479 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06480 goto return_unref;
06481 }
06482 ast_string_field_set(iaxs[callno], secret, p->secret);
06483 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
06484
06485 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06486 if (!ast_strlen_zero(p->inkeys)) {
06487 char tmpkeys[256];
06488 char *stringp=NULL;
06489 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
06490 stringp=tmpkeys;
06491 keyn = strsep(&stringp, ":");
06492 while(keyn) {
06493 key = ast_key_get(keyn, AST_KEY_PUBLIC);
06494 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
06495 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06496 break;
06497 } else if (!key)
06498 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
06499 keyn = strsep(&stringp, ":");
06500 }
06501 if (!keyn) {
06502 if (authdebug)
06503 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
06504 goto return_unref;
06505 }
06506 } else {
06507 if (authdebug)
06508 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
06509 goto return_unref;
06510 }
06511 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
06512 struct MD5Context md5;
06513 unsigned char digest[16];
06514 char *tmppw, *stringp;
06515
06516 tmppw = ast_strdupa(p->secret);
06517 stringp = tmppw;
06518 while((tmppw = strsep(&stringp, ";"))) {
06519 MD5Init(&md5);
06520 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06521 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06522 MD5Final(digest, &md5);
06523 for (x=0;x<16;x++)
06524 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
06525 if (!strcasecmp(requeststr, md5secret))
06526 break;
06527 }
06528 if (tmppw) {
06529 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06530 } else {
06531 if (authdebug)
06532 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
06533 goto return_unref;
06534 }
06535 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
06536
06537 if (strcmp(secret, p->secret)) {
06538 if (authdebug)
06539 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
06540 goto return_unref;
06541 } else
06542 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
06543 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
06544
06545 goto return_unref;
06546 }
06547 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
06548
06549
06550 res = 0;
06551
06552 return_unref:
06553 if (iaxs[callno]) {
06554 ast_string_field_set(iaxs[callno], peer, peer);
06555
06556
06557 if (expire && (expire < iaxs[callno]->expiry)) {
06558 iaxs[callno]->expiry = expire;
06559 }
06560 }
06561
06562 if (p) {
06563 peer_unref(p);
06564 }
06565 return res;
06566 }
06567
06568 static int authenticate(const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt)
06569 {
06570 int res = -1;
06571 int x;
06572 if (!ast_strlen_zero(keyn)) {
06573 if (!(authmethods & IAX_AUTH_RSA)) {
06574 if (ast_strlen_zero(secret))
06575 ast_log(LOG_NOTICE, "Asked to authenticate to %s with an RSA key, but they don't allow RSA authentication\n", ast_inet_ntoa(sin->sin_addr));
06576 } else if (ast_strlen_zero(challenge)) {
06577 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
06578 } else {
06579 char sig[256];
06580 struct ast_key *key;
06581 key = ast_key_get(keyn, AST_KEY_PRIVATE);
06582 if (!key) {
06583 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
06584 } else {
06585 if (ast_sign(key, (char*)challenge, sig)) {
06586 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
06587 res = -1;
06588 } else {
06589 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
06590 res = 0;
06591 }
06592 }
06593 }
06594 }
06595
06596 if (res && !ast_strlen_zero(secret)) {
06597 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
06598 struct MD5Context md5;
06599 unsigned char digest[16];
06600 char digres[128];
06601 MD5Init(&md5);
06602 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
06603 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
06604 MD5Final(digest, &md5);
06605
06606 for (x=0;x<16;x++)
06607 sprintf(digres + (x << 1), "%2.2x", digest[x]);
06608 if (pvt) {
06609 build_encryption_keys(digest, pvt);
06610 }
06611 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
06612 res = 0;
06613 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
06614 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
06615 res = 0;
06616 } else
06617 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
06618 }
06619 return res;
06620 }
06621
06622
06623
06624
06625
06626 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
06627 {
06628 struct iax2_peer *peer = NULL;
06629
06630 int res = -1;
06631 int authmethods = 0;
06632 struct iax_ie_data ied;
06633 uint16_t callno = p->callno;
06634
06635 memset(&ied, 0, sizeof(ied));
06636
06637 if (ies->username)
06638 ast_string_field_set(p, username, ies->username);
06639 if (ies->challenge)
06640 ast_string_field_set(p, challenge, ies->challenge);
06641 if (ies->authmethods)
06642 authmethods = ies->authmethods;
06643 if (authmethods & IAX_AUTH_MD5)
06644 merge_encryption(p, ies->encmethods);
06645 else
06646 p->encmethods = 0;
06647
06648
06649 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
06650
06651 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
06652 } else {
06653 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06654 while ((peer = ao2_iterator_next(&i))) {
06655 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
06656
06657 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
06658
06659 && (!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)))
06660
06661 ) {
06662 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
06663 if (!res) {
06664 peer_unref(peer);
06665 break;
06666 }
06667 }
06668 peer_unref(peer);
06669 }
06670 if (!peer) {
06671
06672
06673 const char *peer_name = ast_strdupa(p->peer);
06674 ast_mutex_unlock(&iaxsl[callno]);
06675 if ((peer = realtime_peer(peer_name, NULL))) {
06676 ast_mutex_lock(&iaxsl[callno]);
06677 if (!(p = iaxs[callno])) {
06678 peer_unref(peer);
06679 return -1;
06680 }
06681 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
06682 peer_unref(peer);
06683 }
06684 if (!peer) {
06685 ast_mutex_lock(&iaxsl[callno]);
06686 if (!(p = iaxs[callno]))
06687 return -1;
06688 }
06689 }
06690 }
06691 if (ies->encmethods)
06692 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
06693 if (!res) {
06694 struct ast_datastore *variablestore;
06695 struct ast_variable *var, *prev = NULL;
06696 AST_LIST_HEAD(, ast_var_t) *varlist;
06697 varlist = ast_calloc(1, sizeof(*varlist));
06698 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
06699 if (variablestore && varlist && p->owner) {
06700 variablestore->data = varlist;
06701 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
06702 AST_LIST_HEAD_INIT(varlist);
06703 for (var = ies->vars; var; var = var->next) {
06704 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
06705 if (prev)
06706 ast_free(prev);
06707 prev = var;
06708 if (!newvar) {
06709
06710 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
06711 } else {
06712 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
06713 }
06714 }
06715 if (prev)
06716 ast_free(prev);
06717 ies->vars = NULL;
06718 ast_channel_datastore_add(p->owner, variablestore);
06719 } else {
06720 if (p->owner)
06721 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
06722 if (variablestore)
06723 ast_datastore_free(variablestore);
06724 if (varlist)
06725 ast_free(varlist);
06726 }
06727 }
06728
06729 if (!res)
06730 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
06731 return res;
06732 }
06733
06734 static int iax2_do_register(struct iax2_registry *reg);
06735
06736 static void __iax2_do_register_s(const void *data)
06737 {
06738 struct iax2_registry *reg = (struct iax2_registry *)data;
06739 reg->expire = -1;
06740 iax2_do_register(reg);
06741 }
06742
06743 static int iax2_do_register_s(const void *data)
06744 {
06745 #ifdef SCHED_MULTITHREADED
06746 if (schedule_action(__iax2_do_register_s, data))
06747 #endif
06748 __iax2_do_register_s(data);
06749 return 0;
06750 }
06751
06752 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06753 {
06754 int newcall = 0;
06755 char newip[256];
06756 struct iax_ie_data ied;
06757 struct sockaddr_in new;
06758
06759
06760 memset(&ied, 0, sizeof(ied));
06761 if (ies->apparent_addr)
06762 memmove(&new, ies->apparent_addr, sizeof(new));
06763 if (ies->callno)
06764 newcall = ies->callno;
06765 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
06766 ast_log(LOG_WARNING, "Invalid transfer request\n");
06767 return -1;
06768 }
06769 pvt->transfercallno = newcall;
06770 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
06771 inet_aton(newip, &pvt->transfer.sin_addr);
06772 pvt->transfer.sin_family = AF_INET;
06773 pvt->transferring = TRANSFER_BEGIN;
06774 pvt->transferid = ies->transferid;
06775 store_by_transfercallno(pvt);
06776 if (ies->transferid)
06777 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
06778 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
06779 return 0;
06780 }
06781
06782 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
06783 {
06784 char exten[256] = "";
06785 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
06786 struct iax2_dpcache *dp = NULL;
06787
06788 if (ies->called_number)
06789 ast_copy_string(exten, ies->called_number, sizeof(exten));
06790
06791 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
06792 status = CACHE_FLAG_EXISTS;
06793 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
06794 status = CACHE_FLAG_CANEXIST;
06795 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
06796 status = CACHE_FLAG_NONEXISTENT;
06797
06798 if (ies->refresh)
06799 expiry = ies->refresh;
06800 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
06801 matchmore = CACHE_FLAG_MATCHMORE;
06802
06803 AST_LIST_LOCK(&dpcache);
06804 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
06805 if (strcmp(dp->exten, exten))
06806 continue;
06807 AST_LIST_REMOVE_CURRENT(peer_list);
06808 dp->callno = 0;
06809 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
06810 if (dp->flags & CACHE_FLAG_PENDING) {
06811 dp->flags &= ~CACHE_FLAG_PENDING;
06812 dp->flags |= status;
06813 dp->flags |= matchmore;
06814 }
06815
06816 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
06817 if (dp->waiters[x] > -1) {
06818 if (write(dp->waiters[x], "asdf", 4) < 0) {
06819 }
06820 }
06821 }
06822 }
06823 AST_LIST_TRAVERSE_SAFE_END;
06824 AST_LIST_UNLOCK(&dpcache);
06825
06826 return 0;
06827 }
06828
06829 static int complete_transfer(int callno, struct iax_ies *ies)
06830 {
06831 int peercallno = 0;
06832 struct chan_iax2_pvt *pvt = iaxs[callno];
06833 struct iax_frame *cur;
06834 jb_frame frame;
06835
06836 if (ies->callno)
06837 peercallno = ies->callno;
06838
06839 if (peercallno < 1) {
06840 ast_log(LOG_WARNING, "Invalid transfer request\n");
06841 return -1;
06842 }
06843 remove_by_transfercallno(pvt);
06844 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
06845 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
06846
06847 pvt->oseqno = 0;
06848 pvt->rseqno = 0;
06849 pvt->iseqno = 0;
06850 pvt->aseqno = 0;
06851
06852 if (pvt->peercallno) {
06853 remove_by_peercallno(pvt);
06854 }
06855 pvt->peercallno = peercallno;
06856
06857 store_by_peercallno(pvt);
06858 pvt->transferring = TRANSFER_NONE;
06859 pvt->svoiceformat = -1;
06860 pvt->voiceformat = 0;
06861 pvt->svideoformat = -1;
06862 pvt->videoformat = 0;
06863 pvt->transfercallno = -1;
06864 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
06865 memset(&pvt->offset, 0, sizeof(pvt->offset));
06866
06867 while(jb_getall(pvt->jb,&frame) == JB_OK)
06868 iax2_frame_free(frame.data);
06869 jb_reset(pvt->jb);
06870 pvt->lag = 0;
06871 pvt->last = 0;
06872 pvt->lastsent = 0;
06873 pvt->nextpred = 0;
06874 pvt->pingtime = DEFAULT_RETRY_TIME;
06875 AST_LIST_LOCK(&frame_queue);
06876 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
06877
06878
06879
06880 if (callno == cur->callno)
06881 cur->retries = -1;
06882 }
06883 AST_LIST_UNLOCK(&frame_queue);
06884 return 0;
06885 }
06886
06887
06888 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
06889 {
06890 struct iax2_registry *reg;
06891
06892 char peer[256] = "";
06893 char msgstatus[60];
06894 int refresh = 60;
06895 char ourip[256] = "<Unspecified>";
06896 struct sockaddr_in oldus;
06897 struct sockaddr_in us;
06898 int oldmsgs;
06899
06900 memset(&us, 0, sizeof(us));
06901 if (ies->apparent_addr)
06902 memmove(&us, ies->apparent_addr, sizeof(us));
06903 if (ies->username)
06904 ast_copy_string(peer, ies->username, sizeof(peer));
06905 if (ies->refresh)
06906 refresh = ies->refresh;
06907 if (ies->calling_number) {
06908
06909 }
06910 reg = iaxs[callno]->reg;
06911 if (!reg) {
06912 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
06913 return -1;
06914 }
06915 memcpy(&oldus, ®->us, sizeof(oldus));
06916 oldmsgs = reg->messages;
06917 if (inaddrcmp(®->addr, sin)) {
06918 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
06919 return -1;
06920 }
06921 memcpy(®->us, &us, sizeof(reg->us));
06922 if (ies->msgcount >= 0)
06923 reg->messages = ies->msgcount & 0xffff;
06924
06925
06926
06927 reg->refresh = refresh;
06928 reg->expire = iax2_sched_replace(reg->expire, sched,
06929 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
06930 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
06931 if (reg->messages > 255)
06932 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
06933 else if (reg->messages > 1)
06934 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
06935 else if (reg->messages > 0)
06936 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
06937 else
06938 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
06939 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
06940 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
06941 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
06942 }
06943 reg->regstate = REG_STATE_REGISTERED;
06944 return 0;
06945 }
06946
06947 static int iax2_append_register(const char *hostname, const char *username,
06948 const char *secret, const char *porta)
06949 {
06950 struct iax2_registry *reg;
06951
06952 if (!(reg = ast_calloc(1, sizeof(*reg))))
06953 return -1;
06954
06955 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
06956 ast_free(reg);
06957 return -1;
06958 }
06959
06960 ast_copy_string(reg->username, username, sizeof(reg->username));
06961
06962 if (secret)
06963 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
06964
06965 reg->expire = -1;
06966 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
06967 reg->addr.sin_family = AF_INET;
06968 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO);
06969
06970 AST_LIST_LOCK(®istrations);
06971 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
06972 AST_LIST_UNLOCK(®istrations);
06973
06974 return 0;
06975 }
06976
06977 static int iax2_register(const char *value, int lineno)
06978 {
06979 char copy[256];
06980 char *username, *hostname, *secret;
06981 char *porta;
06982 char *stringp=NULL;
06983
06984 if (!value)
06985 return -1;
06986
06987 ast_copy_string(copy, value, sizeof(copy));
06988 stringp = copy;
06989 username = strsep(&stringp, "@");
06990 hostname = strsep(&stringp, "@");
06991
06992 if (!hostname) {
06993 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
06994 return -1;
06995 }
06996
06997 stringp = username;
06998 username = strsep(&stringp, ":");
06999 secret = strsep(&stringp, ":");
07000 stringp = hostname;
07001 hostname = strsep(&stringp, ":");
07002 porta = strsep(&stringp, ":");
07003
07004 if (porta && !atoi(porta)) {
07005 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
07006 return -1;
07007 }
07008
07009 return iax2_append_register(hostname, username, secret, porta);
07010 }
07011
07012
07013 static void register_peer_exten(struct iax2_peer *peer, int onoff)
07014 {
07015 char multi[256];
07016 char *stringp, *ext;
07017 if (!ast_strlen_zero(regcontext)) {
07018 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
07019 stringp = multi;
07020 while((ext = strsep(&stringp, "&"))) {
07021 if (onoff) {
07022 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
07023 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
07024 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
07025 } else
07026 ast_context_remove_extension(regcontext, ext, 1, NULL);
07027 }
07028 }
07029 }
07030 static void prune_peers(void);
07031
07032 static void unlink_peer(struct iax2_peer *peer)
07033 {
07034 if (peer->expire > -1) {
07035 if (!ast_sched_del(sched, peer->expire)) {
07036 peer->expire = -1;
07037 peer_unref(peer);
07038 }
07039 }
07040
07041 if (peer->pokeexpire > -1) {
07042 if (!ast_sched_del(sched, peer->pokeexpire)) {
07043 peer->pokeexpire = -1;
07044 peer_unref(peer);
07045 }
07046 }
07047
07048 ao2_unlink(peers, peer);
07049 }
07050
07051 static void __expire_registry(const void *data)
07052 {
07053 struct iax2_peer *peer = (struct iax2_peer *) data;
07054
07055 if (!peer)
07056 return;
07057
07058 peer->expire = -1;
07059
07060 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
07061 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
07062 realtime_update_peer(peer->name, &peer->addr, 0);
07063 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
07064
07065 memset(&peer->addr, 0, sizeof(peer->addr));
07066
07067 peer->expiry = min_reg_expire;
07068 if (!ast_test_flag(peer, IAX_TEMPONLY))
07069 ast_db_del("IAX/Registry", peer->name);
07070 register_peer_exten(peer, 0);
07071 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
07072 if (iax2_regfunk)
07073 iax2_regfunk(peer->name, 0);
07074
07075 if (ast_test_flag(peer, IAX_RTAUTOCLEAR))
07076 unlink_peer(peer);
07077
07078 peer_unref(peer);
07079 }
07080
07081 static int expire_registry(const void *data)
07082 {
07083 #ifdef SCHED_MULTITHREADED
07084 if (schedule_action(__expire_registry, data))
07085 #endif
07086 __expire_registry(data);
07087 return 0;
07088 }
07089
07090 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
07091
07092 static void reg_source_db(struct iax2_peer *p)
07093 {
07094 char data[80];
07095 struct in_addr in;
07096 char *c, *d;
07097 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) {
07098 c = strchr(data, ':');
07099 if (c) {
07100 *c = '\0';
07101 c++;
07102 if (inet_aton(data, &in)) {
07103 d = strchr(c, ':');
07104 if (d) {
07105 *d = '\0';
07106 d++;
07107 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name,
07108 ast_inet_ntoa(in), atoi(c), atoi(d));
07109 iax2_poke_peer(p, 0);
07110 p->expiry = atoi(d);
07111 memset(&p->addr, 0, sizeof(p->addr));
07112 p->addr.sin_family = AF_INET;
07113 p->addr.sin_addr = in;
07114 p->addr.sin_port = htons(atoi(c));
07115 if (p->expire > -1) {
07116 if (!ast_sched_del(sched, p->expire)) {
07117 p->expire = -1;
07118 peer_unref(p);
07119 }
07120 }
07121 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
07122 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07123 if (p->expire == -1)
07124 peer_unref(p);
07125 if (iax2_regfunk)
07126 iax2_regfunk(p->name, 1);
07127 register_peer_exten(p, 1);
07128 }
07129
07130 }
07131 }
07132 }
07133 }
07134
07135
07136
07137
07138
07139
07140
07141 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
07142 {
07143
07144 struct iax_ie_data ied;
07145 struct iax2_peer *p;
07146 int msgcount;
07147 char data[80];
07148 int version;
07149 const char *peer_name;
07150 int res = -1;
07151
07152 memset(&ied, 0, sizeof(ied));
07153
07154 peer_name = ast_strdupa(iaxs[callno]->peer);
07155
07156
07157 ast_mutex_unlock(&iaxsl[callno]);
07158 if (!(p = find_peer(peer_name, 1))) {
07159 ast_mutex_lock(&iaxsl[callno]);
07160 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
07161 return -1;
07162 }
07163 ast_mutex_lock(&iaxsl[callno]);
07164 if (!iaxs[callno])
07165 goto return_unref;
07166
07167 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
07168 if (sin->sin_addr.s_addr) {
07169 time_t nowtime;
07170 time(&nowtime);
07171 realtime_update_peer(peer_name, sin, nowtime);
07172 } else {
07173 realtime_update_peer(peer_name, sin, 0);
07174 }
07175 }
07176 if (inaddrcmp(&p->addr, sin)) {
07177 if (iax2_regfunk)
07178 iax2_regfunk(p->name, 1);
07179
07180 memcpy(&p->addr, sin, sizeof(p->addr));
07181 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
07182 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
07183 ast_db_put("IAX/Registry", p->name, data);
07184 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
07185 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
07186 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
07187 register_peer_exten(p, 1);
07188 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
07189 } else if (!ast_test_flag(p, IAX_TEMPONLY)) {
07190 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
07191 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
07192 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
07193 register_peer_exten(p, 0);
07194 ast_db_del("IAX/Registry", p->name);
07195 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
07196 }
07197
07198
07199 iax2_poke_peer(p, callno);
07200 }
07201
07202
07203 if (!iaxs[callno]) {
07204 res = -1;
07205 goto return_unref;
07206 }
07207
07208
07209 p->sockfd = fd;
07210
07211 if (p->expire > -1) {
07212 if (!ast_sched_del(sched, p->expire)) {
07213 p->expire = -1;
07214 peer_unref(p);
07215 }
07216 }
07217
07218 if (!refresh)
07219 refresh = min_reg_expire;
07220 if (refresh > max_reg_expire) {
07221 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07222 p->name, max_reg_expire, refresh);
07223 p->expiry = max_reg_expire;
07224 } else if (refresh < min_reg_expire) {
07225 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
07226 p->name, min_reg_expire, refresh);
07227 p->expiry = min_reg_expire;
07228 } else {
07229 p->expiry = refresh;
07230 }
07231 if (p->expiry && sin->sin_addr.s_addr) {
07232 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
07233 if (p->expire == -1)
07234 peer_unref(p);
07235 }
07236 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
07237 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
07238 if (sin->sin_addr.s_addr) {
07239 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
07240 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr);
07241 if (!ast_strlen_zero(p->mailbox)) {
07242 struct ast_event *event;
07243 int new, old;
07244 char *mailbox, *context;
07245
07246 context = mailbox = ast_strdupa(p->mailbox);
07247 strsep(&context, "@");
07248 if (ast_strlen_zero(context))
07249 context = "default";
07250
07251 event = ast_event_get_cached(AST_EVENT_MWI,
07252 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
07253 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
07254 AST_EVENT_IE_END);
07255 if (event) {
07256 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
07257 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
07258 ast_event_destroy(event);
07259 } else {
07260 ast_app_inboxcount(p->mailbox, &new, &old);
07261 }
07262
07263 if (new > 255) {
07264 new = 255;
07265 }
07266 if (old > 255) {
07267 old = 255;
07268 }
07269 msgcount = (old << 8) | new;
07270
07271 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
07272 }
07273 if (ast_test_flag(p, IAX_HASCALLERID)) {
07274 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
07275 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
07276 }
07277 }
07278 version = iax_check_version(devtype);
07279 if (version)
07280 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
07281
07282 res = 0;
07283
07284 return_unref:
07285 peer_unref(p);
07286
07287 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
07288 }
07289
07290 static int registry_authrequest(int callno)
07291 {
07292 struct iax_ie_data ied;
07293 struct iax2_peer *p;
07294 char challenge[10];
07295 const char *peer_name;
07296 int sentauthmethod;
07297
07298 peer_name = ast_strdupa(iaxs[callno]->peer);
07299
07300
07301 ast_mutex_unlock(&iaxsl[callno]);
07302 if ((p = find_peer(peer_name, 1))) {
07303 last_authmethod = p->authmethods;
07304 }
07305
07306 ast_mutex_lock(&iaxsl[callno]);
07307 if (!iaxs[callno])
07308 goto return_unref;
07309
07310 memset(&ied, 0, sizeof(ied));
07311
07312
07313
07314
07315
07316
07317 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07318 if (!p) {
07319 iaxs[callno]->authmethods = sentauthmethod;
07320 }
07321 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
07322 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
07323
07324 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07325 ast_string_field_set(iaxs[callno], challenge, challenge);
07326 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
07327 }
07328 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
07329
07330 return_unref:
07331 if (p) {
07332 peer_unref(p);
07333 }
07334
07335 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
07336 }
07337
07338 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
07339 {
07340 struct iax2_registry *reg;
07341
07342 struct iax_ie_data ied;
07343 char peer[256] = "";
07344 char challenge[256] = "";
07345 int res;
07346 int authmethods = 0;
07347 if (ies->authmethods)
07348 authmethods = ies->authmethods;
07349 if (ies->username)
07350 ast_copy_string(peer, ies->username, sizeof(peer));
07351 if (ies->challenge)
07352 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
07353 memset(&ied, 0, sizeof(ied));
07354 reg = iaxs[callno]->reg;
07355 if (reg) {
07356 if (inaddrcmp(®->addr, sin)) {
07357 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
07358 return -1;
07359 }
07360 if (ast_strlen_zero(reg->secret)) {
07361 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
07362 reg->regstate = REG_STATE_NOAUTH;
07363 return -1;
07364 }
07365 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
07366 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
07367 if (reg->secret[0] == '[') {
07368 char tmpkey[256];
07369 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
07370 tmpkey[strlen(tmpkey) - 1] = '\0';
07371 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
07372 } else
07373 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
07374 if (!res) {
07375 reg->regstate = REG_STATE_AUTHSENT;
07376 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
07377 } else
07378 return -1;
07379 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
07380 } else
07381 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
07382 return -1;
07383 }
07384
07385 static void stop_stuff(int callno)
07386 {
07387 iax2_destroy_helper(iaxs[callno]);
07388 }
07389
07390 static void __auth_reject(const void *nothing)
07391 {
07392
07393 int callno = (int)(long)(nothing);
07394 struct iax_ie_data ied;
07395 ast_mutex_lock(&iaxsl[callno]);
07396 if (iaxs[callno]) {
07397 memset(&ied, 0, sizeof(ied));
07398 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
07399 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
07400 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
07401 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
07402 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
07403 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
07404 }
07405 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
07406 }
07407 ast_mutex_unlock(&iaxsl[callno]);
07408 }
07409
07410 static int auth_reject(const void *data)
07411 {
07412 int callno = (int)(long)(data);
07413 ast_mutex_lock(&iaxsl[callno]);
07414 if (iaxs[callno])
07415 iaxs[callno]->authid = -1;
07416 ast_mutex_unlock(&iaxsl[callno]);
07417 #ifdef SCHED_MULTITHREADED
07418 if (schedule_action(__auth_reject, data))
07419 #endif
07420 __auth_reject(data);
07421 return 0;
07422 }
07423
07424 static int auth_fail(int callno, int failcode)
07425 {
07426
07427
07428 if (iaxs[callno]) {
07429 iaxs[callno]->authfail = failcode;
07430 if (delayreject) {
07431 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
07432 sched, 1000, auth_reject, (void *)(long)callno);
07433 } else
07434 auth_reject((void *)(long)callno);
07435 }
07436 return 0;
07437 }
07438
07439 static void __auto_hangup(const void *nothing)
07440 {
07441
07442 int callno = (int)(long)(nothing);
07443 struct iax_ie_data ied;
07444 ast_mutex_lock(&iaxsl[callno]);
07445 if (iaxs[callno]) {
07446 memset(&ied, 0, sizeof(ied));
07447 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
07448 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
07449 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
07450 }
07451 ast_mutex_unlock(&iaxsl[callno]);
07452 }
07453
07454 static int auto_hangup(const void *data)
07455 {
07456 int callno = (int)(long)(data);
07457 ast_mutex_lock(&iaxsl[callno]);
07458 if (iaxs[callno]) {
07459 iaxs[callno]->autoid = -1;
07460 }
07461 ast_mutex_unlock(&iaxsl[callno]);
07462 #ifdef SCHED_MULTITHREADED
07463 if (schedule_action(__auto_hangup, data))
07464 #endif
07465 __auto_hangup(data);
07466 return 0;
07467 }
07468
07469 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
07470 {
07471 struct iax_ie_data ied;
07472
07473 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
07474 sched, 30000, auto_hangup, (void *)(long)callno);
07475 memset(&ied, 0, sizeof(ied));
07476 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
07477 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
07478 dp->flags |= CACHE_FLAG_TRANSMITTED;
07479 }
07480
07481 static int iax2_vnak(int callno)
07482 {
07483 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
07484 }
07485
07486 static void vnak_retransmit(int callno, int last)
07487 {
07488 struct iax_frame *f;
07489
07490 AST_LIST_LOCK(&frame_queue);
07491 AST_LIST_TRAVERSE(&frame_queue, f, list) {
07492
07493 if ((f->callno == callno) && iaxs[f->callno] &&
07494 ((unsigned char ) (f->oseqno - last) < 128) &&
07495 (f->retries >= 0)) {
07496 send_packet(f);
07497 }
07498 }
07499 AST_LIST_UNLOCK(&frame_queue);
07500 }
07501
07502 static void __iax2_poke_peer_s(const void *data)
07503 {
07504 struct iax2_peer *peer = (struct iax2_peer *)data;
07505 iax2_poke_peer(peer, 0);
07506 peer_unref(peer);
07507 }
07508
07509 static int iax2_poke_peer_s(const void *data)
07510 {
07511 struct iax2_peer *peer = (struct iax2_peer *)data;
07512 peer->pokeexpire = -1;
07513 #ifdef SCHED_MULTITHREADED
07514 if (schedule_action(__iax2_poke_peer_s, data))
07515 #endif
07516 __iax2_poke_peer_s(data);
07517 return 0;
07518 }
07519
07520 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
07521 {
07522 int res = 0;
07523 struct iax_frame *fr;
07524 struct ast_iax2_meta_hdr *meta;
07525 struct ast_iax2_meta_trunk_hdr *mth;
07526 int calls = 0;
07527
07528
07529 fr = (struct iax_frame *)tpeer->trunkdata;
07530
07531 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
07532 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
07533 if (tpeer->trunkdatalen) {
07534
07535 meta->zeros = 0;
07536 meta->metacmd = IAX_META_TRUNK;
07537 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS))
07538 meta->cmddata = IAX_META_TRUNK_MINI;
07539 else
07540 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
07541 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
07542
07543 fr->direction = DIRECTION_OUTGRESS;
07544 fr->retrans = -1;
07545 fr->transfer = 0;
07546
07547 fr->data = fr->afdata;
07548 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
07549 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
07550 calls = tpeer->calls;
07551 #if 0
07552 ast_debug(1, "Trunking %d call chunks in %d bytes to %s:%d, ts=%d\n", calls, fr->datalen, ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), ntohl(mth->ts));
07553 #endif
07554
07555 tpeer->trunkdatalen = 0;
07556 tpeer->calls = 0;
07557 }
07558 if (res < 0)
07559 return res;
07560 return calls;
07561 }
07562
07563 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
07564 {
07565
07566 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
07567 return 1;
07568 return 0;
07569 }
07570
07571 static int timing_read(int *id, int fd, short events, void *cbdata)
07572 {
07573 int res, processed = 0, totalcalls = 0;
07574 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
07575 struct timeval now = ast_tvnow();
07576
07577 if (iaxtrunkdebug)
07578 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
07579
07580 if (timer) {
07581 ast_timer_ack(timer, 1);
07582 }
07583
07584
07585 AST_LIST_LOCK(&tpeers);
07586 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
07587 processed++;
07588 res = 0;
07589 ast_mutex_lock(&tpeer->lock);
07590
07591
07592 if (!drop && iax2_trunk_expired(tpeer, &now)) {
07593
07594
07595 AST_LIST_REMOVE_CURRENT(list);
07596 drop = tpeer;
07597 } else {
07598 res = send_trunk(tpeer, &now);
07599 trunk_timed++;
07600 if (iaxtrunkdebug)
07601 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(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc);
07602 }
07603 totalcalls += res;
07604 res = 0;
07605 ast_mutex_unlock(&tpeer->lock);
07606 }
07607 AST_LIST_TRAVERSE_SAFE_END;
07608 AST_LIST_UNLOCK(&tpeers);
07609
07610 if (drop) {
07611 ast_mutex_lock(&drop->lock);
07612
07613
07614 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
07615 if (drop->trunkdata) {
07616 ast_free(drop->trunkdata);
07617 drop->trunkdata = NULL;
07618 }
07619 ast_mutex_unlock(&drop->lock);
07620 ast_mutex_destroy(&drop->lock);
07621 ast_free(drop);
07622
07623 }
07624
07625 if (iaxtrunkdebug)
07626 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
07627 iaxtrunkdebug = 0;
07628
07629 return 1;
07630 }
07631
07632 struct dpreq_data {
07633 int callno;
07634 char context[AST_MAX_EXTENSION];
07635 char callednum[AST_MAX_EXTENSION];
07636 char *callerid;
07637 };
07638
07639 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
07640 {
07641 unsigned short dpstatus = 0;
07642 struct iax_ie_data ied1;
07643 int mm;
07644
07645 memset(&ied1, 0, sizeof(ied1));
07646 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
07647
07648 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
07649 dpstatus = IAX_DPSTATUS_EXISTS;
07650 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
07651 dpstatus = IAX_DPSTATUS_CANEXIST;
07652 } else {
07653 dpstatus = IAX_DPSTATUS_NONEXISTENT;
07654 }
07655 if (ast_ignore_pattern(context, callednum))
07656 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
07657 if (mm)
07658 dpstatus |= IAX_DPSTATUS_MATCHMORE;
07659 if (!skiplock)
07660 ast_mutex_lock(&iaxsl[callno]);
07661 if (iaxs[callno]) {
07662 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
07663 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
07664 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
07665 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
07666 }
07667 if (!skiplock)
07668 ast_mutex_unlock(&iaxsl[callno]);
07669 }
07670
07671 static void *dp_lookup_thread(void *data)
07672 {
07673
07674 struct dpreq_data *dpr = data;
07675 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
07676 if (dpr->callerid)
07677 ast_free(dpr->callerid);
07678 ast_free(dpr);
07679 return NULL;
07680 }
07681
07682 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
07683 {
07684 pthread_t newthread;
07685 struct dpreq_data *dpr;
07686
07687 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
07688 return;
07689
07690 dpr->callno = callno;
07691 ast_copy_string(dpr->context, context, sizeof(dpr->context));
07692 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
07693 if (callerid)
07694 dpr->callerid = ast_strdup(callerid);
07695 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
07696 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
07697 }
07698 }
07699
07700 struct iax_dual {
07701 struct ast_channel *chan1;
07702 struct ast_channel *chan2;
07703 };
07704
07705 static void *iax_park_thread(void *stuff)
07706 {
07707 struct ast_channel *chan1, *chan2;
07708 struct iax_dual *d;
07709 struct ast_frame *f;
07710 int ext;
07711 int res;
07712 d = stuff;
07713 chan1 = d->chan1;
07714 chan2 = d->chan2;
07715 ast_free(d);
07716 f = ast_read(chan1);
07717 if (f)
07718 ast_frfree(f);
07719 res = ast_park_call(chan1, chan2, 0, &ext);
07720 ast_hangup(chan2);
07721 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
07722 return NULL;
07723 }
07724
07725 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2)
07726 {
07727 struct iax_dual *d;
07728 struct ast_channel *chan1m, *chan2m;
07729 pthread_t th;
07730 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
07731 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name);
07732 if (chan2m && chan1m) {
07733
07734 chan1m->readformat = chan1->readformat;
07735 chan1m->writeformat = chan1->writeformat;
07736 ast_channel_masquerade(chan1m, chan1);
07737
07738 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
07739 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
07740 chan1m->priority = chan1->priority;
07741
07742
07743
07744
07745 chan2m->readformat = chan2->readformat;
07746 chan2m->writeformat = chan2->writeformat;
07747 ast_channel_masquerade(chan2m, chan2);
07748
07749 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
07750 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
07751 chan2m->priority = chan2->priority;
07752 if (ast_do_masquerade(chan2m)) {
07753 ast_log(LOG_WARNING, "Masquerade failed :(\n");
07754 ast_hangup(chan2m);
07755 return -1;
07756 }
07757 } else {
07758 if (chan1m)
07759 ast_hangup(chan1m);
07760 if (chan2m)
07761 ast_hangup(chan2m);
07762 return -1;
07763 }
07764 if ((d = ast_calloc(1, sizeof(*d)))) {
07765 d->chan1 = chan1m;
07766 d->chan2 = chan2m;
07767 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
07768 return 0;
07769 }
07770 ast_free(d);
07771 }
07772 return -1;
07773 }
07774
07775
07776 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force);
07777
07778 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
07779 {
07780 unsigned int ourver;
07781 char rsi[80];
07782 snprintf(rsi, sizeof(rsi), "si-%s", si);
07783 if (iax_provision_version(&ourver, rsi, 1))
07784 return 0;
07785 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
07786 if (ourver != ver)
07787 iax2_provision(sin, sockfd, NULL, rsi, 1);
07788 return 0;
07789 }
07790
07791 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
07792 {
07793 jb_info stats;
07794 jb_getinfo(pvt->jb, &stats);
07795
07796 memset(iep, 0, sizeof(*iep));
07797
07798 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
07799 if(stats.frames_in == 0) stats.frames_in = 1;
07800 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
07801 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
07802 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
07803 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
07804 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
07805 }
07806
07807 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
07808 {
07809 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
07810 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
07811 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
07812 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
07813 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
07814 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
07815 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
07816 }
07817
07818 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
07819 {
07820 int i;
07821 unsigned int length, offset = 0;
07822 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
07823
07824 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
07825 length = ies->ospblocklength[i];
07826 if (length != 0) {
07827 if (length > IAX_MAX_OSPBLOCK_SIZE) {
07828
07829 offset = 0;
07830 break;
07831 } else {
07832 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
07833 offset += length;
07834 }
07835 } else {
07836 break;
07837 }
07838 }
07839 *(full_osptoken + offset) = '\0';
07840 if (strlen(full_osptoken) != offset) {
07841
07842 *full_osptoken = '\0';
07843 }
07844
07845 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
07846 }
07847
07848 static void log_jitterstats(unsigned short callno)
07849 {
07850 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
07851 jb_info jbinfo;
07852
07853 ast_mutex_lock(&iaxsl[callno]);
07854 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
07855 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) {
07856 jb_getinfo(iaxs[callno]->jb, &jbinfo);
07857 localjitter = jbinfo.jitter;
07858 localdelay = jbinfo.current - jbinfo.min;
07859 locallost = jbinfo.frames_lost;
07860 locallosspct = jbinfo.losspct/1000;
07861 localdropped = jbinfo.frames_dropped;
07862 localooo = jbinfo.frames_ooo;
07863 localpackets = jbinfo.frames_in;
07864 }
07865 ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n",
07866 iaxs[callno]->owner->name,
07867 iaxs[callno]->pingtime,
07868 localjitter,
07869 localdelay,
07870 locallost,
07871 locallosspct,
07872 localdropped,
07873 localooo,
07874 localpackets,
07875 iaxs[callno]->remote_rr.jitter,
07876 iaxs[callno]->remote_rr.delay,
07877 iaxs[callno]->remote_rr.losscnt,
07878 iaxs[callno]->remote_rr.losspct/1000,
07879 iaxs[callno]->remote_rr.dropped,
07880 iaxs[callno]->remote_rr.ooo,
07881 iaxs[callno]->remote_rr.packets);
07882 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n",
07883 iaxs[callno]->owner->name,
07884 iaxs[callno]->pingtime,
07885 localjitter,
07886 localdelay,
07887 locallost,
07888 locallosspct,
07889 localdropped,
07890 localooo,
07891 localpackets,
07892 iaxs[callno]->remote_rr.jitter,
07893 iaxs[callno]->remote_rr.delay,
07894 iaxs[callno]->remote_rr.losscnt,
07895 iaxs[callno]->remote_rr.losspct/1000,
07896 iaxs[callno]->remote_rr.dropped,
07897 iaxs[callno]->remote_rr.ooo,
07898 iaxs[callno]->remote_rr.packets);
07899 }
07900 ast_mutex_unlock(&iaxsl[callno]);
07901 }
07902
07903 static int socket_process(struct iax2_thread *thread);
07904
07905
07906
07907
07908 static void handle_deferred_full_frames(struct iax2_thread *thread)
07909 {
07910 struct iax2_pkt_buf *pkt_buf;
07911
07912 ast_mutex_lock(&thread->lock);
07913
07914 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
07915 ast_mutex_unlock(&thread->lock);
07916
07917 thread->buf = pkt_buf->buf;
07918 thread->buf_len = pkt_buf->len;
07919 thread->buf_size = pkt_buf->len + 1;
07920
07921 socket_process(thread);
07922
07923 thread->buf = NULL;
07924 ast_free(pkt_buf);
07925
07926 ast_mutex_lock(&thread->lock);
07927 }
07928
07929 ast_mutex_unlock(&thread->lock);
07930 }
07931
07932
07933
07934
07935
07936
07937
07938 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
07939 {
07940 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
07941 struct ast_iax2_full_hdr *fh, *cur_fh;
07942
07943 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
07944 return;
07945
07946 pkt_buf->len = from_here->buf_len;
07947 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
07948
07949 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
07950 ast_mutex_lock(&to_here->lock);
07951 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
07952 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
07953 if (fh->oseqno < cur_fh->oseqno) {
07954 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
07955 break;
07956 }
07957 }
07958 AST_LIST_TRAVERSE_SAFE_END
07959
07960 if (!cur_pkt_buf)
07961 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
07962
07963 ast_mutex_unlock(&to_here->lock);
07964 }
07965
07966 static int socket_read(int *id, int fd, short events, void *cbdata)
07967 {
07968 struct iax2_thread *thread;
07969 socklen_t len;
07970 time_t t;
07971 static time_t last_errtime = 0;
07972 struct ast_iax2_full_hdr *fh;
07973
07974 if (!(thread = find_idle_thread())) {
07975 time(&t);
07976 if (t != last_errtime)
07977 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
07978 last_errtime = t;
07979 usleep(1);
07980 return 1;
07981 }
07982
07983 len = sizeof(thread->iosin);
07984 thread->iofd = fd;
07985 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
07986 thread->buf_size = sizeof(thread->readbuf);
07987 thread->buf = thread->readbuf;
07988 if (thread->buf_len < 0) {
07989 if (errno != ECONNREFUSED && errno != EAGAIN)
07990 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
07991 handle_error();
07992 thread->iostate = IAX_IOSTATE_IDLE;
07993 signal_condition(&thread->lock, &thread->cond);
07994 return 1;
07995 }
07996 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
07997 thread->iostate = IAX_IOSTATE_IDLE;
07998 signal_condition(&thread->lock, &thread->cond);
07999 return 1;
08000 }
08001
08002
08003
08004
08005 fh = (struct ast_iax2_full_hdr *) thread->buf;
08006 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
08007 struct iax2_thread *cur = NULL;
08008 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
08009
08010 AST_LIST_LOCK(&active_list);
08011 AST_LIST_TRAVERSE(&active_list, cur, list) {
08012 if ((cur->ffinfo.callno == callno) &&
08013 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
08014 break;
08015 }
08016 if (cur) {
08017
08018
08019 defer_full_frame(thread, cur);
08020 AST_LIST_UNLOCK(&active_list);
08021 thread->iostate = IAX_IOSTATE_IDLE;
08022 signal_condition(&thread->lock, &thread->cond);
08023 return 1;
08024 } else {
08025
08026 thread->ffinfo.callno = callno;
08027 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
08028 thread->ffinfo.type = fh->type;
08029 thread->ffinfo.csub = fh->csub;
08030 }
08031 AST_LIST_UNLOCK(&active_list);
08032 }
08033
08034
08035 thread->iostate = IAX_IOSTATE_READY;
08036 #ifdef DEBUG_SCHED_MULTITHREAD
08037 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
08038 #endif
08039 signal_condition(&thread->lock, &thread->cond);
08040
08041 return 1;
08042 }
08043
08044 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
08045 struct iax_frame *fr)
08046 {
08047 unsigned char metatype;
08048 struct ast_iax2_meta_trunk_mini *mtm;
08049 struct ast_iax2_meta_trunk_hdr *mth;
08050 struct ast_iax2_meta_trunk_entry *mte;
08051 struct iax2_trunk_peer *tpeer;
08052 unsigned int ts;
08053 void *ptr;
08054 struct timeval rxtrunktime;
08055 struct ast_frame f = { 0, };
08056
08057 if (packet_len < sizeof(*meta)) {
08058 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
08059 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08060 return 1;
08061 }
08062
08063 if (meta->metacmd != IAX_META_TRUNK)
08064 return 1;
08065
08066 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
08067 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
08068 (int) (sizeof(*meta) + sizeof(*mth)));
08069 return 1;
08070 }
08071 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
08072 ts = ntohl(mth->ts);
08073 metatype = meta->cmddata;
08074 packet_len -= (sizeof(*meta) + sizeof(*mth));
08075 ptr = mth->data;
08076 tpeer = find_tpeer(sin, sockfd);
08077 if (!tpeer) {
08078 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
08079 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08080 return 1;
08081 }
08082 tpeer->trunkact = ast_tvnow();
08083 if (!ts || ast_tvzero(tpeer->rxtrunktime))
08084 tpeer->rxtrunktime = tpeer->trunkact;
08085 rxtrunktime = tpeer->rxtrunktime;
08086 ast_mutex_unlock(&tpeer->lock);
08087 while (packet_len >= sizeof(*mte)) {
08088
08089 unsigned short callno, trunked_ts, len;
08090
08091 if (metatype == IAX_META_TRUNK_MINI) {
08092 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
08093 ptr += sizeof(*mtm);
08094 packet_len -= sizeof(*mtm);
08095 len = ntohs(mtm->len);
08096 callno = ntohs(mtm->mini.callno);
08097 trunked_ts = ntohs(mtm->mini.ts);
08098 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
08099 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
08100 ptr += sizeof(*mte);
08101 packet_len -= sizeof(*mte);
08102 len = ntohs(mte->len);
08103 callno = ntohs(mte->callno);
08104 trunked_ts = 0;
08105 } else {
08106 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08107 break;
08108 }
08109
08110 if (len > packet_len)
08111 break;
08112 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
08113 if (!fr->callno)
08114 continue;
08115
08116
08117
08118
08119 memset(&f, 0, sizeof(f));
08120 f.frametype = AST_FRAME_VOICE;
08121 if (!iaxs[fr->callno]) {
08122
08123 } else if (iaxs[fr->callno]->voiceformat == 0) {
08124 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
08125 iax2_vnak(fr->callno);
08126 } else {
08127 f.subclass = iaxs[fr->callno]->voiceformat;
08128 f.datalen = len;
08129 if (f.datalen >= 0) {
08130 if (f.datalen)
08131 f.data.ptr = ptr;
08132 else
08133 f.data.ptr = NULL;
08134 if (trunked_ts)
08135 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
08136 else
08137 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
08138
08139 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08140 struct iax_frame *duped_fr;
08141
08142
08143 f.src = "IAX2";
08144 f.mallocd = 0;
08145 f.offset = 0;
08146 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
08147 f.samples = ast_codec_get_samples(&f);
08148 else
08149 f.samples = 0;
08150 fr->outoforder = 0;
08151 iax_frame_wrap(fr, &f);
08152 duped_fr = iaxfrdup2(fr);
08153 if (duped_fr)
08154 schedule_delivery(duped_fr, 1, 1, &fr->ts);
08155 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
08156 iaxs[fr->callno]->last = fr->ts;
08157 }
08158 } else {
08159 ast_log(LOG_WARNING, "Datalen < 0?\n");
08160 }
08161 }
08162 ast_mutex_unlock(&iaxsl[fr->callno]);
08163 ptr += len;
08164 packet_len -= len;
08165 }
08166
08167 return 1;
08168 }
08169
08170 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
08171 {
08172 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
08173 AST_LIST_HEAD(, ast_var_t) *varlist;
08174 struct ast_var_t *var;
08175
08176 if (!variablestore) {
08177 *buf = '\0';
08178 return 0;
08179 }
08180 varlist = variablestore->data;
08181
08182 AST_LIST_LOCK(varlist);
08183 AST_LIST_TRAVERSE(varlist, var, entries) {
08184 if (strcmp(var->name, data) == 0) {
08185 ast_copy_string(buf, var->value, len);
08186 break;
08187 }
08188 }
08189 AST_LIST_UNLOCK(varlist);
08190 return 0;
08191 }
08192
08193 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
08194 {
08195 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
08196 AST_LIST_HEAD(, ast_var_t) *varlist;
08197 struct ast_var_t *var;
08198
08199 if (!variablestore) {
08200 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08201 if (!variablestore) {
08202 ast_log(LOG_ERROR, "Memory allocation error\n");
08203 return -1;
08204 }
08205 varlist = ast_calloc(1, sizeof(*varlist));
08206 if (!varlist) {
08207 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
08208 return -1;
08209 }
08210
08211 AST_LIST_HEAD_INIT(varlist);
08212 variablestore->data = varlist;
08213 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08214 ast_channel_datastore_add(chan, variablestore);
08215 } else
08216 varlist = variablestore->data;
08217
08218 AST_LIST_LOCK(varlist);
08219 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
08220 if (strcmp(var->name, data) == 0) {
08221 AST_LIST_REMOVE_CURRENT(entries);
08222 ast_var_delete(var);
08223 break;
08224 }
08225 }
08226 AST_LIST_TRAVERSE_SAFE_END;
08227 var = ast_var_assign(data, value);
08228 if (var)
08229 AST_LIST_INSERT_TAIL(varlist, var, entries);
08230 else
08231 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
08232 AST_LIST_UNLOCK(varlist);
08233 return 0;
08234 }
08235
08236 static struct ast_custom_function iaxvar_function = {
08237 .name = "IAXVAR",
08238 .synopsis = "Sets or retrieves a remote variable",
08239 .syntax = "IAXVAR(<varname>)",
08240 .read = acf_iaxvar_read,
08241 .write = acf_iaxvar_write,
08242 };
08243
08244 static int socket_process(struct iax2_thread *thread)
08245 {
08246 struct sockaddr_in sin;
08247 int res;
08248 int updatehistory=1;
08249 int new = NEW_PREVENT;
08250 int dcallno = 0;
08251 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
08252 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
08253 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
08254 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
08255 struct iax_frame *fr;
08256 struct iax_frame *cur;
08257 struct ast_frame f = { 0, };
08258 struct ast_channel *c = NULL;
08259 struct iax2_dpcache *dp;
08260 struct iax2_peer *peer;
08261 struct iax_ies ies;
08262 struct iax_ie_data ied0, ied1;
08263 int format;
08264 int fd;
08265 int exists;
08266 int minivid = 0;
08267 char empty[32]="";
08268 struct iax_frame *duped_fr;
08269 char host_pref_buf[128];
08270 char caller_pref_buf[128];
08271 struct ast_codec_pref pref;
08272 char *using_prefs = "mine";
08273
08274
08275 fr = alloca(sizeof(*fr) + 4096);
08276 memset(fr, 0, sizeof(*fr));
08277 fr->afdatalen = 4096;
08278
08279
08280 res = thread->buf_len;
08281 fd = thread->iofd;
08282 memcpy(&sin, &thread->iosin, sizeof(sin));
08283
08284 if (res < sizeof(*mh)) {
08285 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
08286 return 1;
08287 }
08288 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
08289 if (res < sizeof(*vh)) {
08290 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a video frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
08291 return 1;
08292 }
08293
08294
08295 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
08296 minivid = 1;
08297 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
08298 return socket_process_meta(res, meta, &sin, fd, fr);
08299
08300 #ifdef DEBUG_SUPPORT
08301 if (res >= sizeof(*fh))
08302 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
08303 #endif
08304 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08305 if (res < sizeof(*fh)) {
08306 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a full frame but is too short\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
08307 return 1;
08308 }
08309
08310
08311 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
08312
08313 f.frametype = fh->type;
08314 if (f.frametype == AST_FRAME_VIDEO) {
08315 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
08316 } else {
08317 f.subclass = uncompress_subclass(fh->csub);
08318 }
08319
08320
08321 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) {
08322
08323 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohs(fh->ts), fh->iseqno + 1);
08324 return 1;
08325 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) {
08326
08327 return 1;
08328 }
08329
08330 if ((f.frametype == AST_FRAME_IAX) && ((f.subclass == IAX_COMMAND_NEW) || (f.subclass == IAX_COMMAND_REGREQ) ||
08331 (f.subclass == IAX_COMMAND_POKE) || (f.subclass == IAX_COMMAND_FWDOWNL) ||
08332 (f.subclass == IAX_COMMAND_REGREL)))
08333 new = NEW_ALLOW;
08334 } else {
08335
08336 f.frametype = AST_FRAME_NULL;
08337 f.subclass = 0;
08338 }
08339
08340 if (!fr->callno) {
08341 int check_dcallno = 0;
08342
08343
08344
08345
08346
08347
08348
08349
08350
08351
08352
08353
08354
08355 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08356 check_dcallno = f.frametype == AST_FRAME_IAX ? (f.subclass != IAX_COMMAND_PING && f.subclass != IAX_COMMAND_LAGRQ) : 1;
08357 }
08358
08359 fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno);
08360 }
08361
08362 if (fr->callno > 0)
08363 ast_mutex_lock(&iaxsl[fr->callno]);
08364
08365 if (!fr->callno || !iaxs[fr->callno]) {
08366
08367
08368 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08369
08370 if (((f.subclass != IAX_COMMAND_INVAL) &&
08371 (f.subclass != IAX_COMMAND_TXCNT) &&
08372 (f.subclass != IAX_COMMAND_TXACC) &&
08373 (f.subclass != IAX_COMMAND_FWDOWNL))||
08374 (f.frametype != AST_FRAME_IAX))
08375 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
08376 fd);
08377 }
08378 if (fr->callno > 0)
08379 ast_mutex_unlock(&iaxsl[fr->callno]);
08380 return 1;
08381 }
08382 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) {
08383 if (decrypt_frame(fr->callno, fh, &f, &res)) {
08384 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
08385 ast_mutex_unlock(&iaxsl[fr->callno]);
08386 return 1;
08387 }
08388 #ifdef DEBUG_SUPPORT
08389 else
08390 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
08391 #endif
08392 }
08393
08394
08395 iaxs[fr->callno]->frames_received++;
08396
08397 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
08398 f.subclass != IAX_COMMAND_TXCNT &&
08399 f.subclass != IAX_COMMAND_TXACC) {
08400 unsigned short new_peercallno;
08401
08402 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
08403 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
08404 if (iaxs[fr->callno]->peercallno) {
08405 remove_by_peercallno(iaxs[fr->callno]);
08406 }
08407 iaxs[fr->callno]->peercallno = new_peercallno;
08408 store_by_peercallno(iaxs[fr->callno]);
08409 }
08410 }
08411 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
08412 if (iaxdebug)
08413 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass);
08414
08415 fr->oseqno = fh->oseqno;
08416 fr->iseqno = fh->iseqno;
08417 fr->ts = ntohl(fh->ts);
08418 #ifdef IAXTESTS
08419 if (test_resync) {
08420 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
08421 fr->ts += test_resync;
08422 }
08423 #endif
08424 #if 0
08425 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
08426 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
08427 (f.subclass == IAX_COMMAND_NEW ||
08428 f.subclass == IAX_COMMAND_AUTHREQ ||
08429 f.subclass == IAX_COMMAND_ACCEPT ||
08430 f.subclass == IAX_COMMAND_REJECT)) ) )
08431 #endif
08432 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
08433 updatehistory = 0;
08434 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
08435 (iaxs[fr->callno]->iseqno ||
08436 ((f.subclass != IAX_COMMAND_TXCNT) &&
08437 (f.subclass != IAX_COMMAND_TXREADY) &&
08438 (f.subclass != IAX_COMMAND_TXREL) &&
08439 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
08440 (f.subclass != IAX_COMMAND_TXACC)) ||
08441 (f.frametype != AST_FRAME_IAX))) {
08442 if (
08443 ((f.subclass != IAX_COMMAND_ACK) &&
08444 (f.subclass != IAX_COMMAND_INVAL) &&
08445 (f.subclass != IAX_COMMAND_TXCNT) &&
08446 (f.subclass != IAX_COMMAND_TXREADY) &&
08447 (f.subclass != IAX_COMMAND_TXREL) &&
08448 (f.subclass != IAX_COMMAND_UNQUELCH ) &&
08449 (f.subclass != IAX_COMMAND_TXACC) &&
08450 (f.subclass != IAX_COMMAND_VNAK)) ||
08451 (f.frametype != AST_FRAME_IAX)) {
08452
08453 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
08454 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass);
08455
08456
08457 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
08458
08459 if ((f.frametype != AST_FRAME_IAX) ||
08460 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) {
08461 ast_debug(1, "Acking anyway\n");
08462
08463
08464 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08465 }
08466 } else {
08467
08468 iax2_vnak(fr->callno);
08469 }
08470 ast_mutex_unlock(&iaxsl[fr->callno]);
08471 return 1;
08472 }
08473 } else {
08474
08475 if (((f.subclass != IAX_COMMAND_ACK) &&
08476 (f.subclass != IAX_COMMAND_INVAL) &&
08477 (f.subclass != IAX_COMMAND_TXCNT) &&
08478 (f.subclass != IAX_COMMAND_TXACC) &&
08479 (f.subclass != IAX_COMMAND_VNAK)) ||
08480 (f.frametype != AST_FRAME_IAX))
08481 iaxs[fr->callno]->iseqno++;
08482 }
08483
08484 if (res < sizeof(*fh)) {
08485 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*fh));
08486 ast_mutex_unlock(&iaxsl[fr->callno]);
08487 return 1;
08488 }
08489
08490 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
08491 if (res < thread->buf_size)
08492 thread->buf[res++] = '\0';
08493 else
08494 thread->buf[res - 1] = '\0';
08495 }
08496 f.datalen = res - sizeof(*fh);
08497
08498
08499
08500 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
08501 ((f.subclass != IAX_COMMAND_INVAL) ||
08502 (f.frametype != AST_FRAME_IAX))) {
08503 unsigned char x;
08504 int call_to_destroy;
08505
08506 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
08507 x = fr->iseqno;
08508 else
08509 x = iaxs[fr->callno]->oseqno;
08510 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
08511
08512
08513 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
08514
08515 if (iaxdebug)
08516 ast_debug(1, "Cancelling transmission of packet %d\n", x);
08517 call_to_destroy = 0;
08518 AST_LIST_LOCK(&frame_queue);
08519 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08520
08521 if ((fr->callno == cur->callno) && (x == cur->oseqno)) {
08522 cur->retries = -1;
08523
08524 if (cur->final)
08525 call_to_destroy = fr->callno;
08526 }
08527 }
08528 AST_LIST_UNLOCK(&frame_queue);
08529 if (call_to_destroy) {
08530 if (iaxdebug)
08531 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
08532 ast_mutex_lock(&iaxsl[call_to_destroy]);
08533 iax2_destroy(call_to_destroy);
08534 ast_mutex_unlock(&iaxsl[call_to_destroy]);
08535 }
08536 }
08537
08538 if (iaxs[fr->callno])
08539 iaxs[fr->callno]->rseqno = fr->iseqno;
08540 else {
08541
08542 ast_mutex_unlock(&iaxsl[fr->callno]);
08543 return 1;
08544 }
08545 } else {
08546 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
08547 }
08548 }
08549 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
08550 ((f.frametype != AST_FRAME_IAX) ||
08551 ((f.subclass != IAX_COMMAND_TXACC) &&
08552 (f.subclass != IAX_COMMAND_TXCNT)))) {
08553
08554 ast_mutex_unlock(&iaxsl[fr->callno]);
08555 return 1;
08556 }
08557
08558 if (f.datalen) {
08559 if (f.frametype == AST_FRAME_IAX) {
08560 if (iax_parse_ies(&ies, thread->buf + sizeof(*fh), f.datalen)) {
08561 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
08562 ast_mutex_unlock(&iaxsl[fr->callno]);
08563 return 1;
08564 }
08565 f.data.ptr = NULL;
08566 f.datalen = 0;
08567 } else {
08568 f.data.ptr = thread->buf + sizeof(*fh);
08569 memset(&ies, 0, sizeof(ies));
08570 }
08571 } else {
08572 if (f.frametype == AST_FRAME_IAX)
08573 f.data.ptr = NULL;
08574 else
08575 f.data.ptr = empty;
08576 memset(&ies, 0, sizeof(ies));
08577 }
08578
08579
08580
08581
08582 if ((f.frametype == AST_FRAME_VOICE) ||
08583 (f.frametype == AST_FRAME_VIDEO) ||
08584 (f.frametype == AST_FRAME_IAX)) {
08585 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
08586 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08587 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
08588 ast_mutex_unlock(&iaxsl[fr->callno]);
08589 return 1;
08590 }
08591 }
08592
08593 if (ies.vars) {
08594 struct ast_datastore *variablestore = NULL;
08595 struct ast_variable *var, *prev = NULL;
08596 AST_LIST_HEAD(, ast_var_t) *varlist;
08597 if ((c = iaxs[fr->callno]->owner)) {
08598 varlist = ast_calloc(1, sizeof(*varlist));
08599 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08600
08601 if (variablestore && varlist) {
08602 variablestore->data = varlist;
08603 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08604 AST_LIST_HEAD_INIT(varlist);
08605 ast_debug(1, "I can haz IAX vars?\n");
08606 for (var = ies.vars; var; var = var->next) {
08607 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08608 if (prev) {
08609 ast_free(prev);
08610 }
08611 prev = var;
08612 if (!newvar) {
08613
08614 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08615 } else {
08616 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08617 }
08618 }
08619 if (prev) {
08620 ast_free(prev);
08621 }
08622 ies.vars = NULL;
08623 ast_channel_datastore_add(c, variablestore);
08624 } else {
08625 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08626 if (variablestore) {
08627 ast_datastore_free(variablestore);
08628 }
08629 if (varlist) {
08630 ast_free(varlist);
08631 }
08632 }
08633 } else {
08634
08635
08636 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
08637 for (var = ies.vars; var && var->next; var = var->next);
08638 if (var) {
08639 var->next = iaxs[fr->callno]->iaxvars;
08640 iaxs[fr->callno]->iaxvars = ies.vars;
08641 ies.vars = NULL;
08642 }
08643 }
08644 }
08645
08646 if (ies.vars) {
08647 ast_debug(1, "I have IAX variables, but they were not processed\n");
08648 }
08649 }
08650
08651 if (f.frametype == AST_FRAME_VOICE) {
08652 if (f.subclass != iaxs[fr->callno]->voiceformat) {
08653 iaxs[fr->callno]->voiceformat = f.subclass;
08654 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass);
08655 if (iaxs[fr->callno]->owner) {
08656 int orignative;
08657 retryowner:
08658 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
08659 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
08660 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner;
08661 }
08662 if (iaxs[fr->callno]) {
08663 if (iaxs[fr->callno]->owner) {
08664 orignative = iaxs[fr->callno]->owner->nativeformats;
08665 iaxs[fr->callno]->owner->nativeformats = f.subclass;
08666 if (iaxs[fr->callno]->owner->readformat)
08667 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
08668 iaxs[fr->callno]->owner->nativeformats = orignative;
08669 ast_channel_unlock(iaxs[fr->callno]->owner);
08670 }
08671 } else {
08672 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
08673
08674 if (ies.vars) {
08675 ast_variables_destroy(ies.vars);
08676 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
08677 ies.vars = NULL;
08678 }
08679 ast_mutex_unlock(&iaxsl[fr->callno]);
08680 return 1;
08681 }
08682 }
08683 }
08684 }
08685 if (f.frametype == AST_FRAME_VIDEO) {
08686 if (f.subclass != iaxs[fr->callno]->videoformat) {
08687 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1);
08688 iaxs[fr->callno]->videoformat = f.subclass & ~0x1;
08689 }
08690 }
08691 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
08692 if (f.subclass == AST_CONTROL_BUSY) {
08693 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
08694 } else if (f.subclass == AST_CONTROL_CONGESTION) {
08695 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
08696 }
08697 }
08698 if (f.frametype == AST_FRAME_IAX) {
08699 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid);
08700
08701 if (iaxdebug)
08702 ast_debug(1, "IAX subclass %d received\n", f.subclass);
08703
08704
08705 if (iaxs[fr->callno]->last < fr->ts &&
08706 f.subclass != IAX_COMMAND_ACK &&
08707 f.subclass != IAX_COMMAND_PONG &&
08708 f.subclass != IAX_COMMAND_LAGRP) {
08709 iaxs[fr->callno]->last = fr->ts;
08710 if (iaxdebug)
08711 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
08712 }
08713
08714 switch(f.subclass) {
08715 case IAX_COMMAND_ACK:
08716
08717 break;
08718 case IAX_COMMAND_QUELCH:
08719 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08720
08721 if (iaxs[fr->callno]->owner) {
08722 manager_event(EVENT_FLAG_CALL, "Hold",
08723 "Status: On\r\n"
08724 "Channel: %s\r\n"
08725 "Uniqueid: %s\r\n",
08726 iaxs[fr->callno]->owner->name,
08727 iaxs[fr->callno]->owner->uniqueid);
08728 }
08729
08730 ast_set_flag(iaxs[fr->callno], IAX_QUELCH);
08731 if (ies.musiconhold) {
08732 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08733 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
08734 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
08735 S_OR(moh_suggest, NULL),
08736 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
08737 if (!iaxs[fr->callno]) {
08738 ast_mutex_unlock(&iaxsl[fr->callno]);
08739 return 1;
08740 }
08741 }
08742 }
08743 }
08744 break;
08745 case IAX_COMMAND_UNQUELCH:
08746 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
08747
08748 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) {
08749 manager_event(EVENT_FLAG_CALL, "Hold",
08750 "Status: Off\r\n"
08751 "Channel: %s\r\n"
08752 "Uniqueid: %s\r\n",
08753 iaxs[fr->callno]->owner->name,
08754 iaxs[fr->callno]->owner->uniqueid);
08755 }
08756
08757 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH);
08758 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) {
08759 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
08760 if (!iaxs[fr->callno]) {
08761 ast_mutex_unlock(&iaxsl[fr->callno]);
08762 return 1;
08763 }
08764 }
08765 }
08766 break;
08767 case IAX_COMMAND_TXACC:
08768 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
08769
08770 AST_LIST_LOCK(&frame_queue);
08771 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
08772
08773 if ((fr->callno == cur->callno) && (cur->transfer))
08774 cur->retries = -1;
08775 }
08776 AST_LIST_UNLOCK(&frame_queue);
08777 memset(&ied1, 0, sizeof(ied1));
08778 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
08779 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
08780 iaxs[fr->callno]->transferring = TRANSFER_READY;
08781 }
08782 break;
08783 case IAX_COMMAND_NEW:
08784
08785 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
08786 break;
08787 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
08788 ast_mutex_unlock(&iaxsl[fr->callno]);
08789 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
08790 ast_mutex_lock(&iaxsl[fr->callno]);
08791 if (!iaxs[fr->callno]) {
08792 ast_mutex_unlock(&iaxsl[fr->callno]);
08793 return 1;
08794 }
08795 }
08796
08797 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
08798 int new_callno;
08799 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
08800 fr->callno = new_callno;
08801 }
08802
08803 if (delayreject)
08804 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
08805 if (check_access(fr->callno, &sin, &ies)) {
08806
08807 auth_fail(fr->callno, IAX_COMMAND_REJECT);
08808 if (authdebug)
08809 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, who was trying to reach '%s@%s'\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
08810 break;
08811 }
08812 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
08813 const char *context, *exten, *cid_num;
08814
08815 context = ast_strdupa(iaxs[fr->callno]->context);
08816 exten = ast_strdupa(iaxs[fr->callno]->exten);
08817 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
08818
08819
08820 ast_mutex_unlock(&iaxsl[fr->callno]);
08821 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
08822 ast_mutex_lock(&iaxsl[fr->callno]);
08823
08824 if (!iaxs[fr->callno]) {
08825 ast_mutex_unlock(&iaxsl[fr->callno]);
08826 return 1;
08827 }
08828 } else
08829 exists = 0;
08830
08831 save_osptoken(fr, &ies);
08832 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
08833 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
08834 memset(&ied0, 0, sizeof(ied0));
08835 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
08836 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
08837 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08838 if (!iaxs[fr->callno]) {
08839 ast_mutex_unlock(&iaxsl[fr->callno]);
08840 return 1;
08841 }
08842 if (authdebug)
08843 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
08844 } else {
08845
08846
08847 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08848 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08849 using_prefs = "reqonly";
08850 } else {
08851 using_prefs = "disabled";
08852 }
08853 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
08854 memset(&pref, 0, sizeof(pref));
08855 strcpy(caller_pref_buf, "disabled");
08856 strcpy(host_pref_buf, "disabled");
08857 } else {
08858 using_prefs = "mine";
08859
08860 if (ies.codec_prefs)
08861 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
08862 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08863
08864 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08865 pref = iaxs[fr->callno]->rprefs;
08866 using_prefs = "caller";
08867 } else {
08868 pref = iaxs[fr->callno]->prefs;
08869 }
08870 } else
08871 pref = iaxs[fr->callno]->prefs;
08872
08873 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
08874 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
08875 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
08876 }
08877 if (!format) {
08878 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08879 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
08880 if (!format) {
08881 memset(&ied0, 0, sizeof(ied0));
08882 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08883 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08884 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08885 if (!iaxs[fr->callno]) {
08886 ast_mutex_unlock(&iaxsl[fr->callno]);
08887 return 1;
08888 }
08889 if (authdebug) {
08890 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
08891 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
08892 else
08893 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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
08894 }
08895 } else {
08896
08897 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
08898 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
08899 format = 0;
08900 } else {
08901 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
08902 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
08903 memset(&pref, 0, sizeof(pref));
08904 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08905 strcpy(caller_pref_buf,"disabled");
08906 strcpy(host_pref_buf,"disabled");
08907 } else {
08908 using_prefs = "mine";
08909 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
08910
08911 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
08912 pref = iaxs[fr->callno]->prefs;
08913 } else {
08914 pref = iaxs[fr->callno]->rprefs;
08915 using_prefs = "caller";
08916 }
08917 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
08918
08919 } else
08920 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08921 }
08922 }
08923
08924 if (!format) {
08925 memset(&ied0, 0, sizeof(ied0));
08926 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
08927 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
08928 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
08929 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
08930 if (!iaxs[fr->callno]) {
08931 ast_mutex_unlock(&iaxsl[fr->callno]);
08932 return 1;
08933 }
08934 if (authdebug)
08935 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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
08936 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
08937 break;
08938 }
08939 }
08940 }
08941 if (format) {
08942
08943 memset(&ied1, 0, sizeof(ied1));
08944 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
08945 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
08946 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
08947 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
08948 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
08949 "%srequested format = %s,\n"
08950 "%srequested prefs = %s,\n"
08951 "%sactual format = %s,\n"
08952 "%shost prefs = %s,\n"
08953 "%spriority = %s\n",
08954 ast_inet_ntoa(sin.sin_addr),
08955 VERBOSE_PREFIX_4,
08956 ast_getformatname(iaxs[fr->callno]->peerformat),
08957 VERBOSE_PREFIX_4,
08958 caller_pref_buf,
08959 VERBOSE_PREFIX_4,
08960 ast_getformatname(format),
08961 VERBOSE_PREFIX_4,
08962 host_pref_buf,
08963 VERBOSE_PREFIX_4,
08964 using_prefs);
08965
08966 iaxs[fr->callno]->chosenformat = format;
08967 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART);
08968 } else {
08969 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
08970
08971 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
08972 }
08973 }
08974 }
08975 break;
08976 }
08977 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
08978 merge_encryption(iaxs[fr->callno],ies.encmethods);
08979 else
08980 iaxs[fr->callno]->encmethods = 0;
08981 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
08982 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
08983 if (!iaxs[fr->callno]) {
08984 ast_mutex_unlock(&iaxsl[fr->callno]);
08985 return 1;
08986 }
08987 break;
08988 case IAX_COMMAND_DPREQ:
08989
08990 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
08991 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
08992 if (iaxcompat) {
08993
08994 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
08995 } else {
08996
08997 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
08998 }
08999 }
09000 break;
09001 case IAX_COMMAND_HANGUP:
09002 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09003 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
09004
09005 if (ies.causecode && iaxs[fr->callno]->owner)
09006 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09007
09008 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09009 iax2_destroy(fr->callno);
09010 break;
09011 case IAX_COMMAND_REJECT:
09012
09013 if (ies.causecode && iaxs[fr->callno]->owner)
09014 iaxs[fr->callno]->owner->hangupcause = ies.causecode;
09015
09016 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09017 if (iaxs[fr->callno]->owner && authdebug)
09018 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
09019 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
09020 ies.cause ? ies.cause : "<Unknown>");
09021 ast_debug(1, "Immediately destroying %d, having received reject\n",
09022 fr->callno);
09023 }
09024
09025 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
09026 fr->ts, NULL, 0, fr->iseqno);
09027 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION))
09028 iaxs[fr->callno]->error = EPERM;
09029 iax2_destroy(fr->callno);
09030 break;
09031 case IAX_COMMAND_TRANSFER:
09032 {
09033 struct ast_channel *bridged_chan;
09034
09035 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) {
09036
09037
09038 ast_mutex_unlock(&iaxsl[fr->callno]);
09039 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name);
09040 ast_mutex_lock(&iaxsl[fr->callno]);
09041 if (!iaxs[fr->callno]) {
09042 ast_mutex_unlock(&iaxsl[fr->callno]);
09043 return 1;
09044 }
09045
09046 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name);
09047 if (!strcmp(ies.called_number, ast_parking_ext())) {
09048 struct ast_channel *saved_channel = iaxs[fr->callno]->owner;
09049 ast_mutex_unlock(&iaxsl[fr->callno]);
09050 if (iax_park(bridged_chan, saved_channel)) {
09051 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name);
09052 } else {
09053 ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name);
09054 }
09055 ast_mutex_lock(&iaxsl[fr->callno]);
09056 } else {
09057 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1))
09058 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name,
09059 ies.called_number, iaxs[fr->callno]->context);
09060 else {
09061 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name,
09062 ies.called_number, iaxs[fr->callno]->context);
09063 }
09064 }
09065 } else {
09066 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
09067 }
09068
09069 break;
09070 }
09071 case IAX_COMMAND_ACCEPT:
09072
09073 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
09074 break;
09075 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) {
09076
09077 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09078 iax2_destroy(fr->callno);
09079 break;
09080 }
09081 if (ies.format) {
09082 iaxs[fr->callno]->peerformat = ies.format;
09083 } else {
09084 if (iaxs[fr->callno]->owner)
09085 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
09086 else
09087 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
09088 }
09089 ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
09090 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
09091 memset(&ied0, 0, sizeof(ied0));
09092 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09093 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09094 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09095 if (!iaxs[fr->callno]) {
09096 ast_mutex_unlock(&iaxsl[fr->callno]);
09097 return 1;
09098 }
09099 if (authdebug)
09100 ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09101 } else {
09102 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09103 if (iaxs[fr->callno]->owner) {
09104
09105 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
09106 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
09107 retryowner2:
09108 if (ast_channel_trylock(iaxs[fr->callno]->owner)) {
09109 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
09110 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2;
09111 }
09112
09113 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
09114
09115 if (iaxs[fr->callno]->owner->writeformat)
09116 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
09117 if (iaxs[fr->callno]->owner->readformat)
09118 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
09119 ast_channel_unlock(iaxs[fr->callno]->owner);
09120 }
09121 }
09122 }
09123 if (iaxs[fr->callno]) {
09124 AST_LIST_LOCK(&dpcache);
09125 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
09126 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
09127 iax2_dprequest(dp, fr->callno);
09128 AST_LIST_UNLOCK(&dpcache);
09129 }
09130 break;
09131 case IAX_COMMAND_POKE:
09132
09133 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
09134 if (!iaxs[fr->callno]) {
09135 ast_mutex_unlock(&iaxsl[fr->callno]);
09136 return 1;
09137 }
09138 break;
09139 case IAX_COMMAND_PING:
09140 {
09141 struct iax_ie_data pingied;
09142 construct_rr(iaxs[fr->callno], &pingied);
09143
09144 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
09145 }
09146 break;
09147 case IAX_COMMAND_PONG:
09148
09149 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
09150
09151 save_rr(fr, &ies);
09152
09153
09154 log_jitterstats(fr->callno);
09155
09156 if (iaxs[fr->callno]->peerpoke) {
09157 peer = iaxs[fr->callno]->peerpoke;
09158 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
09159 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
09160 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
09161 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
09162 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
09163 }
09164 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
09165 if (iaxs[fr->callno]->pingtime > peer->maxms) {
09166 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
09167 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime);
09168 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
09169 }
09170 }
09171 peer->lastms = iaxs[fr->callno]->pingtime;
09172 if (peer->smoothing && (peer->lastms > -1))
09173 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
09174 else if (peer->smoothing && peer->lastms < 0)
09175 peer->historicms = (0 + peer->historicms) / 2;
09176 else
09177 peer->historicms = iaxs[fr->callno]->pingtime;
09178
09179
09180 if (peer->pokeexpire > -1) {
09181 if (!ast_sched_del(sched, peer->pokeexpire)) {
09182 peer_unref(peer);
09183 peer->pokeexpire = -1;
09184 }
09185 }
09186
09187 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
09188 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
09189 else
09190 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
09191 if (peer->pokeexpire == -1)
09192 peer_unref(peer);
09193
09194 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09195
09196 iax2_destroy(fr->callno);
09197 peer->callno = 0;
09198 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
09199 }
09200 break;
09201 case IAX_COMMAND_LAGRQ:
09202 case IAX_COMMAND_LAGRP:
09203 f.src = "LAGRQ";
09204 f.mallocd = 0;
09205 f.offset = 0;
09206 f.samples = 0;
09207 iax_frame_wrap(fr, &f);
09208 if(f.subclass == IAX_COMMAND_LAGRQ) {
09209
09210 fr->af.subclass = IAX_COMMAND_LAGRP;
09211 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
09212 } else {
09213
09214 unsigned int ts;
09215
09216 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
09217 iaxs[fr->callno]->lag = ts - fr->ts;
09218 if (iaxdebug)
09219 ast_debug(1, "Peer %s lag measured as %dms\n",
09220 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
09221 }
09222 break;
09223 case IAX_COMMAND_AUTHREQ:
09224 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09225 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>");
09226 break;
09227 }
09228 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
09229 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
09230 .subclass = AST_CONTROL_HANGUP,
09231 };
09232 ast_log(LOG_WARNING,
09233 "I don't know how to authenticate %s to %s\n",
09234 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
09235 iax2_queue_frame(fr->callno, &hangup_fr);
09236 }
09237 if (!iaxs[fr->callno]) {
09238 ast_mutex_unlock(&iaxsl[fr->callno]);
09239 return 1;
09240 }
09241 break;
09242 case IAX_COMMAND_AUTHREP:
09243
09244 if (delayreject)
09245 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09246
09247 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
09248 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>");
09249 break;
09250 }
09251 if (authenticate_verify(iaxs[fr->callno], &ies)) {
09252 if (authdebug)
09253 ast_log(LOG_NOTICE, "Host %s failed to authenticate as %s\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->username);
09254 memset(&ied0, 0, sizeof(ied0));
09255 auth_fail(fr->callno, IAX_COMMAND_REJECT);
09256 break;
09257 }
09258 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
09259
09260 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
09261 } else
09262 exists = 0;
09263 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
09264 if (authdebug)
09265 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
09266 memset(&ied0, 0, sizeof(ied0));
09267 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09268 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09269 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09270 if (!iaxs[fr->callno]) {
09271 ast_mutex_unlock(&iaxsl[fr->callno]);
09272 return 1;
09273 }
09274 } else {
09275
09276 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09277 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09278 using_prefs = "reqonly";
09279 } else {
09280 using_prefs = "disabled";
09281 }
09282 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
09283 memset(&pref, 0, sizeof(pref));
09284 strcpy(caller_pref_buf, "disabled");
09285 strcpy(host_pref_buf, "disabled");
09286 } else {
09287 using_prefs = "mine";
09288 if (ies.codec_prefs)
09289 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
09290 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09291 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09292 pref = iaxs[fr->callno]->rprefs;
09293 using_prefs = "caller";
09294 } else {
09295 pref = iaxs[fr->callno]->prefs;
09296 }
09297 } else
09298 pref = iaxs[fr->callno]->prefs;
09299
09300 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
09301 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
09302 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
09303 }
09304 if (!format) {
09305 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09306 ast_debug(1, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability);
09307 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
09308 }
09309 if (!format) {
09310 if (authdebug) {
09311 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09312 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09313 else
09314 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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
09315 }
09316 memset(&ied0, 0, sizeof(ied0));
09317 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09318 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09319 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09320 if (!iaxs[fr->callno]) {
09321 ast_mutex_unlock(&iaxsl[fr->callno]);
09322 return 1;
09323 }
09324 } else {
09325
09326 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
09327 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
09328 format = 0;
09329 } else {
09330 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
09331 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
09332 memset(&pref, 0, sizeof(pref));
09333 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
09334 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09335 strcpy(caller_pref_buf,"disabled");
09336 strcpy(host_pref_buf,"disabled");
09337 } else {
09338 using_prefs = "mine";
09339 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
09340
09341 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
09342 pref = iaxs[fr->callno]->prefs;
09343 } else {
09344 pref = iaxs[fr->callno]->rprefs;
09345 using_prefs = "caller";
09346 }
09347 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
09348 } else
09349 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09350 }
09351 }
09352 if (!format) {
09353 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
09354 if (authdebug) {
09355 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP))
09356 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability);
09357 else
09358 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(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability);
09359 }
09360 memset(&ied0, 0, sizeof(ied0));
09361 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
09362 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
09363 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09364 if (!iaxs[fr->callno]) {
09365 ast_mutex_unlock(&iaxsl[fr->callno]);
09366 return 1;
09367 }
09368 }
09369 }
09370 }
09371 if (format) {
09372
09373 memset(&ied1, 0, sizeof(ied1));
09374 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
09375 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
09376 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
09377 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09378 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
09379 "%srequested format = %s,\n"
09380 "%srequested prefs = %s,\n"
09381 "%sactual format = %s,\n"
09382 "%shost prefs = %s,\n"
09383 "%spriority = %s\n",
09384 ast_inet_ntoa(sin.sin_addr),
09385 VERBOSE_PREFIX_4,
09386 ast_getformatname(iaxs[fr->callno]->peerformat),
09387 VERBOSE_PREFIX_4,
09388 caller_pref_buf,
09389 VERBOSE_PREFIX_4,
09390 ast_getformatname(format),
09391 VERBOSE_PREFIX_4,
09392 host_pref_buf,
09393 VERBOSE_PREFIX_4,
09394 using_prefs);
09395
09396 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09397 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format)))
09398 iax2_destroy(fr->callno);
09399 else if (ies.vars) {
09400 struct ast_datastore *variablestore;
09401 struct ast_variable *var, *prev = NULL;
09402 AST_LIST_HEAD(, ast_var_t) *varlist;
09403 varlist = ast_calloc(1, sizeof(*varlist));
09404 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09405 if (variablestore && varlist) {
09406 variablestore->data = varlist;
09407 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09408 AST_LIST_HEAD_INIT(varlist);
09409 ast_debug(1, "I can haz IAX vars? w00t\n");
09410 for (var = ies.vars; var; var = var->next) {
09411 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09412 if (prev)
09413 ast_free(prev);
09414 prev = var;
09415 if (!newvar) {
09416
09417 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09418 } else {
09419 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09420 }
09421 }
09422 if (prev)
09423 ast_free(prev);
09424 ies.vars = NULL;
09425 ast_channel_datastore_add(c, variablestore);
09426 } else {
09427 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09428 if (variablestore)
09429 ast_datastore_free(variablestore);
09430 if (varlist)
09431 ast_free(varlist);
09432 }
09433 }
09434 } else {
09435 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09436
09437 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
09438 }
09439 }
09440 }
09441 break;
09442 case IAX_COMMAND_DIAL:
09443 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
09444 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
09445 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
09446 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
09447 if (authdebug)
09448 ast_log(LOG_NOTICE, "Rejected dial attempt from %s, request '%s@%s' does not exist\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->exten, iaxs[fr->callno]->context);
09449 memset(&ied0, 0, sizeof(ied0));
09450 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
09451 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
09452 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09453 if (!iaxs[fr->callno]) {
09454 ast_mutex_unlock(&iaxsl[fr->callno]);
09455 return 1;
09456 }
09457 } else {
09458 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09459 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat);
09460 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
09461 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
09462 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat)))
09463 iax2_destroy(fr->callno);
09464 else if (ies.vars) {
09465 struct ast_datastore *variablestore;
09466 struct ast_variable *var, *prev = NULL;
09467 AST_LIST_HEAD(, ast_var_t) *varlist;
09468 varlist = ast_calloc(1, sizeof(*varlist));
09469 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09470 ast_debug(1, "I can haz IAX vars? w00t\n");
09471 if (variablestore && varlist) {
09472 variablestore->data = varlist;
09473 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09474 AST_LIST_HEAD_INIT(varlist);
09475 for (var = ies.vars; var; var = var->next) {
09476 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
09477 if (prev)
09478 ast_free(prev);
09479 prev = var;
09480 if (!newvar) {
09481
09482 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09483 } else {
09484 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
09485 }
09486 }
09487 if (prev)
09488 ast_free(prev);
09489 ies.vars = NULL;
09490 ast_channel_datastore_add(c, variablestore);
09491 } else {
09492 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
09493 if (variablestore)
09494 ast_datastore_free(variablestore);
09495 if (varlist)
09496 ast_free(varlist);
09497 }
09498 }
09499 }
09500 }
09501 break;
09502 case IAX_COMMAND_INVAL:
09503 iaxs[fr->callno]->error = ENOTCONN;
09504 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
09505 iax2_destroy(fr->callno);
09506 ast_debug(1, "Destroying call %d\n", fr->callno);
09507 break;
09508 case IAX_COMMAND_VNAK:
09509 ast_debug(1, "Received VNAK: resending outstanding frames\n");
09510
09511 vnak_retransmit(fr->callno, fr->iseqno);
09512 break;
09513 case IAX_COMMAND_REGREQ:
09514 case IAX_COMMAND_REGREL:
09515
09516 if (delayreject)
09517 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09518 if (register_verify(fr->callno, &sin, &ies)) {
09519 if (!iaxs[fr->callno]) {
09520 ast_mutex_unlock(&iaxsl[fr->callno]);
09521 return 1;
09522 }
09523
09524 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
09525 break;
09526 }
09527 if (!iaxs[fr->callno]) {
09528 ast_mutex_unlock(&iaxsl[fr->callno]);
09529 return 1;
09530 }
09531 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
09532 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
09533
09534 if (f.subclass == IAX_COMMAND_REGREL)
09535 memset(&sin, 0, sizeof(sin));
09536 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh))
09537 ast_log(LOG_WARNING, "Registry error\n");
09538 if (!iaxs[fr->callno]) {
09539 ast_mutex_unlock(&iaxsl[fr->callno]);
09540 return 1;
09541 }
09542 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
09543 ast_mutex_unlock(&iaxsl[fr->callno]);
09544 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
09545 ast_mutex_lock(&iaxsl[fr->callno]);
09546 if (!iaxs[fr->callno]) {
09547 ast_mutex_unlock(&iaxsl[fr->callno]);
09548 return 1;
09549 }
09550 }
09551 break;
09552 }
09553 registry_authrequest(fr->callno);
09554 if (!iaxs[fr->callno]) {
09555 ast_mutex_unlock(&iaxsl[fr->callno]);
09556 return 1;
09557 }
09558 break;
09559 case IAX_COMMAND_REGACK:
09560 if (iax2_ack_registry(&ies, &sin, fr->callno))
09561 ast_log(LOG_WARNING, "Registration failure\n");
09562
09563 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09564 iax2_destroy(fr->callno);
09565 break;
09566 case IAX_COMMAND_REGREJ:
09567 if (iaxs[fr->callno]->reg) {
09568 if (authdebug) {
09569 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(sin.sin_addr));
09570 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nUsername: %s\r\nStatus: Rejected\r\nCause: %s\r\n", iaxs[fr->callno]->reg->username, ies.cause ? ies.cause : "<unknown>");
09571 }
09572 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
09573 }
09574
09575 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09576 iax2_destroy(fr->callno);
09577 break;
09578 case IAX_COMMAND_REGAUTH:
09579
09580 if (registry_rerequest(&ies, fr->callno, &sin)) {
09581 memset(&ied0, 0, sizeof(ied0));
09582 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
09583 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
09584 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09585 if (!iaxs[fr->callno]) {
09586 ast_mutex_unlock(&iaxsl[fr->callno]);
09587 return 1;
09588 }
09589 }
09590 break;
09591 case IAX_COMMAND_TXREJ:
09592 iaxs[fr->callno]->transferring = 0;
09593 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09594 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
09595 if (iaxs[fr->callno]->bridgecallno) {
09596 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
09597 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
09598 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
09599 }
09600 }
09601 break;
09602 case IAX_COMMAND_TXREADY:
09603 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
09604 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
09605 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
09606 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
09607 else
09608 iaxs[fr->callno]->transferring = TRANSFER_READY;
09609 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
09610 if (iaxs[fr->callno]->bridgecallno) {
09611 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
09612 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
09613
09614 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
09615 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09616 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09617
09618 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
09619 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
09620
09621 memset(&ied0, 0, sizeof(ied0));
09622 memset(&ied1, 0, sizeof(ied1));
09623 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09624 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09625 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
09626 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
09627 } else {
09628 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
09629 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
09630
09631 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
09632 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
09633 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
09634 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE);
09635
09636
09637 stop_stuff(fr->callno);
09638 stop_stuff(iaxs[fr->callno]->bridgecallno);
09639
09640 memset(&ied0, 0, sizeof(ied0));
09641 memset(&ied1, 0, sizeof(ied1));
09642 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
09643 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
09644 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
09645 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
09646 }
09647
09648 }
09649 }
09650 }
09651 break;
09652 case IAX_COMMAND_TXREQ:
09653 try_transfer(iaxs[fr->callno], &ies);
09654 break;
09655 case IAX_COMMAND_TXCNT:
09656 if (iaxs[fr->callno]->transferring)
09657 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
09658 break;
09659 case IAX_COMMAND_TXREL:
09660
09661 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09662 complete_transfer(fr->callno, &ies);
09663 stop_stuff(fr->callno);
09664 break;
09665 case IAX_COMMAND_TXMEDIA:
09666 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
09667 AST_LIST_LOCK(&frame_queue);
09668 AST_LIST_TRAVERSE(&frame_queue, cur, list) {
09669
09670 if ((fr->callno == cur->callno) && (cur->transfer))
09671 cur->retries = -1;
09672 }
09673 AST_LIST_UNLOCK(&frame_queue);
09674
09675 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
09676 }
09677 break;
09678 case IAX_COMMAND_RTKEY:
09679 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
09680 ast_log(LOG_WARNING,
09681 "we've been told to rotate our encryption key, "
09682 "but this isn't an encrypted call. bad things will happen.\n"
09683 );
09684 break;
09685 }
09686
09687 IAX_DEBUGDIGEST("Receiving", ies.challenge);
09688
09689 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
09690 break;
09691 case IAX_COMMAND_DPREP:
09692 complete_dpreply(iaxs[fr->callno], &ies);
09693 break;
09694 case IAX_COMMAND_UNSUPPORT:
09695 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
09696 break;
09697 case IAX_COMMAND_FWDOWNL:
09698
09699 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
09700 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
09701 break;
09702 }
09703 memset(&ied0, 0, sizeof(ied0));
09704 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
09705 if (res < 0)
09706 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
09707 else if (res > 0)
09708 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09709 else
09710 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
09711 if (!iaxs[fr->callno]) {
09712 ast_mutex_unlock(&iaxsl[fr->callno]);
09713 return 1;
09714 }
09715 break;
09716 default:
09717 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno);
09718 memset(&ied0, 0, sizeof(ied0));
09719 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass);
09720 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
09721 }
09722
09723 if (ies.vars) {
09724 ast_variables_destroy(ies.vars);
09725 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
09726 ies.vars = NULL;
09727 }
09728
09729
09730 if ((f.subclass != IAX_COMMAND_ACK) &&
09731 (f.subclass != IAX_COMMAND_TXCNT) &&
09732 (f.subclass != IAX_COMMAND_TXACC) &&
09733 (f.subclass != IAX_COMMAND_INVAL) &&
09734 (f.subclass != IAX_COMMAND_VNAK)) {
09735 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09736 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09737 }
09738 ast_mutex_unlock(&iaxsl[fr->callno]);
09739 return 1;
09740 }
09741
09742 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
09743 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
09744 } else if (minivid) {
09745 f.frametype = AST_FRAME_VIDEO;
09746 if (iaxs[fr->callno]->videoformat > 0)
09747 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0);
09748 else {
09749 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
09750 iax2_vnak(fr->callno);
09751 ast_mutex_unlock(&iaxsl[fr->callno]);
09752 return 1;
09753 }
09754 f.datalen = res - sizeof(*vh);
09755 if (f.datalen)
09756 f.data.ptr = thread->buf + sizeof(*vh);
09757 else
09758 f.data.ptr = NULL;
09759 #ifdef IAXTESTS
09760 if (test_resync) {
09761 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
09762 } else
09763 #endif
09764 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
09765 } else {
09766
09767 f.frametype = AST_FRAME_VOICE;
09768 if (iaxs[fr->callno]->voiceformat > 0)
09769 f.subclass = iaxs[fr->callno]->voiceformat;
09770 else {
09771 ast_debug(1, "Received mini frame before first full voice frame\n");
09772 iax2_vnak(fr->callno);
09773 ast_mutex_unlock(&iaxsl[fr->callno]);
09774 return 1;
09775 }
09776 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
09777 if (f.datalen < 0) {
09778 ast_log(LOG_WARNING, "Datalen < 0?\n");
09779 ast_mutex_unlock(&iaxsl[fr->callno]);
09780 return 1;
09781 }
09782 if (f.datalen)
09783 f.data.ptr = thread->buf + sizeof(*mh);
09784 else
09785 f.data.ptr = NULL;
09786 #ifdef IAXTESTS
09787 if (test_resync) {
09788 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
09789 } else
09790 #endif
09791 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
09792
09793 }
09794
09795 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09796 ast_mutex_unlock(&iaxsl[fr->callno]);
09797 return 1;
09798 }
09799
09800 f.src = "IAX2";
09801 f.mallocd = 0;
09802 f.offset = 0;
09803 f.len = 0;
09804 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
09805 f.samples = ast_codec_get_samples(&f);
09806
09807 if (f.subclass == AST_FORMAT_SLINEAR)
09808 ast_frame_byteswap_be(&f);
09809 } else
09810 f.samples = 0;
09811 iax_frame_wrap(fr, &f);
09812
09813
09814 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09815
09816 fr->outoforder = 0;
09817 } else {
09818 if (iaxdebug && iaxs[fr->callno])
09819 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last);
09820 fr->outoforder = -1;
09821 }
09822 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
09823 duped_fr = iaxfrdup2(fr);
09824 if (duped_fr) {
09825 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
09826 }
09827 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
09828 iaxs[fr->callno]->last = fr->ts;
09829 #if 1
09830 if (iaxdebug)
09831 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
09832 #endif
09833 }
09834
09835
09836 ast_mutex_unlock(&iaxsl[fr->callno]);
09837 return 1;
09838 }
09839
09840
09841 static void iax2_process_thread_cleanup(void *data)
09842 {
09843 struct iax2_thread *thread = data;
09844 ast_mutex_destroy(&thread->lock);
09845 ast_cond_destroy(&thread->cond);
09846 ast_mutex_destroy(&thread->init_lock);
09847 ast_cond_destroy(&thread->init_cond);
09848 ast_free(thread);
09849 ast_atomic_dec_and_test(&iaxactivethreadcount);
09850 }
09851
09852 static void *iax2_process_thread(void *data)
09853 {
09854 struct iax2_thread *thread = data;
09855 struct timeval wait;
09856 struct timespec ts;
09857 int put_into_idle = 0;
09858 int first_time = 1;
09859
09860 ast_atomic_fetchadd_int(&iaxactivethreadcount,1);
09861 pthread_cleanup_push(iax2_process_thread_cleanup, data);
09862 for(;;) {
09863
09864 ast_mutex_lock(&thread->lock);
09865
09866
09867 if (first_time) {
09868 signal_condition(&thread->init_lock, &thread->init_cond);
09869 first_time = 0;
09870 }
09871
09872
09873 if (put_into_idle)
09874 insert_idle_thread(thread);
09875
09876 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
09877 struct iax2_thread *t = NULL;
09878
09879 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09880 ts.tv_sec = wait.tv_sec;
09881 ts.tv_nsec = wait.tv_usec * 1000;
09882 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
09883
09884
09885 if (!put_into_idle) {
09886 ast_mutex_unlock(&thread->lock);
09887 break;
09888 }
09889 AST_LIST_LOCK(&dynamic_list);
09890
09891 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
09892 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
09893 AST_LIST_UNLOCK(&dynamic_list);
09894 if (t) {
09895
09896
09897
09898 ast_mutex_unlock(&thread->lock);
09899 break;
09900 }
09901
09902
09903
09904 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
09905 ts.tv_sec = wait.tv_sec;
09906 ts.tv_nsec = wait.tv_usec * 1000;
09907 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT)
09908 {
09909 ast_mutex_unlock(&thread->lock);
09910 break;
09911 }
09912 }
09913 } else {
09914 ast_cond_wait(&thread->cond, &thread->lock);
09915 }
09916
09917
09918 put_into_idle = 1;
09919
09920 ast_mutex_unlock(&thread->lock);
09921
09922 if (thread->iostate == IAX_IOSTATE_IDLE)
09923 continue;
09924
09925
09926 AST_LIST_LOCK(&active_list);
09927 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09928 AST_LIST_UNLOCK(&active_list);
09929
09930
09931 switch(thread->iostate) {
09932 case IAX_IOSTATE_READY:
09933 thread->actions++;
09934 thread->iostate = IAX_IOSTATE_PROCESSING;
09935 socket_process(thread);
09936 handle_deferred_full_frames(thread);
09937 break;
09938 case IAX_IOSTATE_SCHEDREADY:
09939 thread->actions++;
09940 thread->iostate = IAX_IOSTATE_PROCESSING;
09941 #ifdef SCHED_MULTITHREADED
09942 thread->schedfunc(thread->scheddata);
09943 #endif
09944 default:
09945 break;
09946 }
09947 time(&thread->checktime);
09948 thread->iostate = IAX_IOSTATE_IDLE;
09949 #ifdef DEBUG_SCHED_MULTITHREAD
09950 thread->curfunc[0]='\0';
09951 #endif
09952
09953
09954 AST_LIST_LOCK(&active_list);
09955 AST_LIST_REMOVE(&active_list, thread, list);
09956 AST_LIST_UNLOCK(&active_list);
09957
09958
09959 handle_deferred_full_frames(thread);
09960 }
09961
09962
09963
09964
09965
09966 AST_LIST_LOCK(&idle_list);
09967 AST_LIST_REMOVE(&idle_list, thread, list);
09968 AST_LIST_UNLOCK(&idle_list);
09969
09970 AST_LIST_LOCK(&dynamic_list);
09971 AST_LIST_REMOVE(&dynamic_list, thread, list);
09972 AST_LIST_UNLOCK(&dynamic_list);
09973
09974
09975
09976
09977 pthread_cleanup_pop(1);
09978 return NULL;
09979 }
09980
09981 static int iax2_do_register(struct iax2_registry *reg)
09982 {
09983 struct iax_ie_data ied;
09984 if (iaxdebug)
09985 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
09986
09987 if (reg->dnsmgr &&
09988 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) {
09989
09990 ast_dnsmgr_refresh(reg->dnsmgr);
09991 }
09992
09993
09994
09995
09996
09997 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
09998 int callno = reg->callno;
09999 ast_mutex_lock(&iaxsl[callno]);
10000 iax2_destroy(callno);
10001 ast_mutex_unlock(&iaxsl[callno]);
10002 reg->callno = 0;
10003 }
10004 if (!reg->addr.sin_addr.s_addr) {
10005 if (iaxdebug)
10006 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
10007
10008 reg->expire = iax2_sched_replace(reg->expire, sched,
10009 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10010 return -1;
10011 }
10012
10013 if (!reg->callno) {
10014 ast_debug(3, "Allocate call number\n");
10015 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0);
10016 if (reg->callno < 1) {
10017 ast_log(LOG_WARNING, "Unable to create call for registration\n");
10018 return -1;
10019 } else
10020 ast_debug(3, "Registration created on call %d\n", reg->callno);
10021 iaxs[reg->callno]->reg = reg;
10022 ast_mutex_unlock(&iaxsl[reg->callno]);
10023 }
10024
10025 reg->expire = iax2_sched_replace(reg->expire, sched,
10026 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
10027
10028 memset(&ied, 0, sizeof(ied));
10029 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
10030 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
10031 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
10032 reg->regstate = REG_STATE_REGSENT;
10033 return 0;
10034 }
10035
10036 static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force)
10037 {
10038
10039
10040 struct iax_ie_data provdata;
10041 struct iax_ie_data ied;
10042 unsigned int sig;
10043 struct sockaddr_in sin;
10044 int callno;
10045 struct create_addr_info cai;
10046
10047 memset(&cai, 0, sizeof(cai));
10048
10049 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
10050
10051 if (iax_provision_build(&provdata, &sig, template, force)) {
10052 ast_debug(1, "No provisioning found for template '%s'\n", template);
10053 return 0;
10054 }
10055
10056 if (end) {
10057 memcpy(&sin, end, sizeof(sin));
10058 cai.sockfd = sockfd;
10059 } else if (create_addr(dest, NULL, &sin, &cai))
10060 return -1;
10061
10062
10063 memset(&ied, 0, sizeof(ied));
10064 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
10065
10066 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10067 if (!callno)
10068 return -1;
10069
10070 if (iaxs[callno]) {
10071
10072 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
10073 sched, 15000, auto_hangup, (void *)(long)callno);
10074 ast_set_flag(iaxs[callno], IAX_PROVISION);
10075
10076 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
10077 }
10078 ast_mutex_unlock(&iaxsl[callno]);
10079
10080 return 1;
10081 }
10082
10083 static char *papp = "IAX2Provision";
10084 static char *psyn = "Provision a calling IAXy with a given template";
10085 static char *pdescrip =
10086 " IAX2Provision([template]): Provisions the calling IAXy (assuming\n"
10087 "the calling entity is in fact an IAXy) with the given template or\n"
10088 "default if one is not specified. Returns -1 on error or 0 on success.\n";
10089
10090
10091
10092
10093 static int iax2_prov_app(struct ast_channel *chan, void *data)
10094 {
10095 int res;
10096 char *sdata;
10097 char *opts;
10098 int force =0;
10099 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
10100 if (ast_strlen_zero(data))
10101 data = "default";
10102 sdata = ast_strdupa(data);
10103 opts = strchr(sdata, '|');
10104 if (opts)
10105 *opts='\0';
10106
10107 if (chan->tech != &iax2_tech) {
10108 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
10109 return -1;
10110 }
10111 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
10112 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
10113 return -1;
10114 }
10115 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
10116 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
10117 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
10118 sdata, res);
10119 return res;
10120 }
10121
10122 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
10123 {
10124 int force = 0;
10125 int res;
10126
10127 switch (cmd) {
10128 case CLI_INIT:
10129 e->command = "iax2 provision";
10130 e->usage =
10131 "Usage: iax2 provision <host> <template> [forced]\n"
10132 " Provisions the given peer or IP address using a template\n"
10133 " matching either 'template' or '*' if the template is not\n"
10134 " found. If 'forced' is specified, even empty provisioning\n"
10135 " fields will be provisioned as empty fields.\n";
10136 return NULL;
10137 case CLI_GENERATE:
10138 if (a->pos == 3)
10139 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
10140 return NULL;
10141 }
10142
10143 if (a->argc < 4)
10144 return CLI_SHOWUSAGE;
10145 if (a->argc > 4) {
10146 if (!strcasecmp(a->argv[4], "forced"))
10147 force = 1;
10148 else
10149 return CLI_SHOWUSAGE;
10150 }
10151 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
10152 if (res < 0)
10153 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
10154 else if (res < 1)
10155 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
10156 else
10157 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
10158 return CLI_SUCCESS;
10159 }
10160
10161 static void __iax2_poke_noanswer(const void *data)
10162 {
10163 struct iax2_peer *peer = (struct iax2_peer *)data;
10164 int callno;
10165
10166 if (peer->lastms > -1) {
10167 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
10168 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
10169 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10170 }
10171 if ((callno = peer->callno) > 0) {
10172 ast_mutex_lock(&iaxsl[callno]);
10173 iax2_destroy(callno);
10174 ast_mutex_unlock(&iaxsl[callno]);
10175 }
10176 peer->callno = 0;
10177 peer->lastms = -1;
10178
10179 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10180 if (peer->pokeexpire == -1)
10181 peer_unref(peer);
10182 }
10183
10184 static int iax2_poke_noanswer(const void *data)
10185 {
10186 struct iax2_peer *peer = (struct iax2_peer *)data;
10187 peer->pokeexpire = -1;
10188 #ifdef SCHED_MULTITHREADED
10189 if (schedule_action(__iax2_poke_noanswer, data))
10190 #endif
10191 __iax2_poke_noanswer(data);
10192 peer_unref(peer);
10193 return 0;
10194 }
10195
10196 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
10197 {
10198 struct iax2_peer *peer = obj;
10199
10200 iax2_poke_peer(peer, 0);
10201
10202 return 0;
10203 }
10204
10205 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
10206 {
10207 int callno;
10208 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) {
10209
10210
10211 peer->lastms = 0;
10212 peer->historicms = 0;
10213 peer->pokeexpire = -1;
10214 peer->callno = 0;
10215 return 0;
10216 }
10217
10218
10219 if ((callno = peer->callno) > 0) {
10220 ast_log(LOG_NOTICE, "Still have a callno...\n");
10221 ast_mutex_lock(&iaxsl[callno]);
10222 iax2_destroy(callno);
10223 ast_mutex_unlock(&iaxsl[callno]);
10224 }
10225 if (heldcall)
10226 ast_mutex_unlock(&iaxsl[heldcall]);
10227 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0);
10228 if (heldcall)
10229 ast_mutex_lock(&iaxsl[heldcall]);
10230 if (peer->callno < 1) {
10231 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
10232 return -1;
10233 }
10234
10235
10236 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
10237 iaxs[peer->callno]->peerpoke = peer;
10238
10239 if (peer->pokeexpire > -1) {
10240 if (!ast_sched_del(sched, peer->pokeexpire)) {
10241 peer->pokeexpire = -1;
10242 peer_unref(peer);
10243 }
10244 }
10245
10246
10247
10248 if (peer->lastms < 0)
10249 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
10250 else
10251 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
10252
10253 if (peer->pokeexpire == -1)
10254 peer_unref(peer);
10255
10256
10257 ast_mutex_lock(&iaxsl[callno]);
10258 if (iaxs[callno]) {
10259 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, NULL, 0, -1);
10260 }
10261 ast_mutex_unlock(&iaxsl[callno]);
10262
10263 return 0;
10264 }
10265
10266 static void free_context(struct iax2_context *con)
10267 {
10268 struct iax2_context *conl;
10269 while(con) {
10270 conl = con;
10271 con = con->next;
10272 ast_free(conl);
10273 }
10274 }
10275
10276 static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
10277 {
10278 int callno;
10279 int res;
10280 int fmt, native;
10281 struct sockaddr_in sin;
10282 struct ast_channel *c;
10283 struct parsed_dial_string pds;
10284 struct create_addr_info cai;
10285 char *tmpstr;
10286
10287 memset(&pds, 0, sizeof(pds));
10288 tmpstr = ast_strdupa(data);
10289 parse_dial_string(tmpstr, &pds);
10290
10291 if (ast_strlen_zero(pds.peer)) {
10292 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
10293 return NULL;
10294 }
10295
10296 memset(&cai, 0, sizeof(cai));
10297 cai.capability = iax2_capability;
10298
10299 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10300
10301
10302 if (create_addr(pds.peer, NULL, &sin, &cai)) {
10303 *cause = AST_CAUSE_UNREGISTERED;
10304 return NULL;
10305 }
10306
10307 if (pds.port)
10308 sin.sin_port = htons(atoi(pds.port));
10309
10310 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
10311 if (callno < 1) {
10312 ast_log(LOG_WARNING, "Unable to create call\n");
10313 *cause = AST_CAUSE_CONGESTION;
10314 return NULL;
10315 }
10316
10317
10318 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10319 if (ast_test_flag(&cai, IAX_TRUNK)) {
10320 int new_callno;
10321 if ((new_callno = make_trunk(callno, 1)) != -1)
10322 callno = new_callno;
10323 }
10324 iaxs[callno]->maxtime = cai.maxtime;
10325 if (cai.found)
10326 ast_string_field_set(iaxs[callno], host, pds.peer);
10327
10328 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability);
10329
10330 ast_mutex_unlock(&iaxsl[callno]);
10331
10332 if (c) {
10333
10334 if (c->nativeformats & format)
10335 c->nativeformats &= format;
10336 else {
10337 native = c->nativeformats;
10338 fmt = format;
10339 res = ast_translator_best_choice(&fmt, &native);
10340 if (res < 0) {
10341 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
10342 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
10343 ast_hangup(c);
10344 return NULL;
10345 }
10346 c->nativeformats = native;
10347 }
10348 c->readformat = ast_best_codec(c->nativeformats);
10349 c->writeformat = c->readformat;
10350 }
10351
10352 return c;
10353 }
10354
10355 static void *sched_thread(void *ignore)
10356 {
10357 int count;
10358 int res;
10359 struct timeval wait;
10360 struct timespec ts;
10361
10362 for (;;) {
10363 pthread_testcancel();
10364 ast_mutex_lock(&sched_lock);
10365 res = ast_sched_wait(sched);
10366 if ((res > 1000) || (res < 0))
10367 res = 1000;
10368 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000));
10369 ts.tv_sec = wait.tv_sec;
10370 ts.tv_nsec = wait.tv_usec * 1000;
10371 ast_cond_timedwait(&sched_cond, &sched_lock, &ts);
10372 ast_mutex_unlock(&sched_lock);
10373 pthread_testcancel();
10374
10375 count = ast_sched_runq(sched);
10376 if (count >= 20)
10377 ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count);
10378 }
10379
10380 return NULL;
10381 }
10382
10383 static void *network_thread(void *ignore)
10384 {
10385
10386
10387 int res, count, wakeup;
10388 struct iax_frame *f;
10389
10390 if (timer)
10391 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
10392
10393 for(;;) {
10394 pthread_testcancel();
10395
10396
10397
10398 AST_LIST_LOCK(&frame_queue);
10399 count = 0;
10400 wakeup = -1;
10401 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) {
10402 if (f->sentyet)
10403 continue;
10404
10405
10406 if (ast_mutex_trylock(&iaxsl[f->callno])) {
10407 wakeup = 1;
10408 continue;
10409 }
10410
10411 f->sentyet = 1;
10412
10413 if (iaxs[f->callno]) {
10414 send_packet(f);
10415 count++;
10416 }
10417
10418 ast_mutex_unlock(&iaxsl[f->callno]);
10419
10420 if (f->retries < 0) {
10421
10422 AST_LIST_REMOVE_CURRENT(list);
10423
10424 iax_frame_free(f);
10425 } else {
10426
10427 f->retries++;
10428 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
10429 }
10430 }
10431 AST_LIST_TRAVERSE_SAFE_END;
10432 AST_LIST_UNLOCK(&frame_queue);
10433
10434 pthread_testcancel();
10435 if (count >= 20)
10436 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count);
10437
10438
10439 res = ast_io_wait(io, wakeup);
10440 if (res >= 0) {
10441 if (res >= 20)
10442 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res);
10443 }
10444 }
10445 return NULL;
10446 }
10447
10448 static int start_network_thread(void)
10449 {
10450 struct iax2_thread *thread;
10451 int threadcount = 0;
10452 int x;
10453 for (x = 0; x < iaxthreadcount; x++) {
10454 thread = ast_calloc(1, sizeof(*thread));
10455 if (thread) {
10456 thread->type = IAX_THREAD_TYPE_POOL;
10457 thread->threadnum = ++threadcount;
10458 ast_mutex_init(&thread->lock);
10459 ast_cond_init(&thread->cond, NULL);
10460 if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) {
10461 ast_log(LOG_WARNING, "Failed to create new thread!\n");
10462 ast_free(thread);
10463 thread = NULL;
10464 }
10465 AST_LIST_LOCK(&idle_list);
10466 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
10467 AST_LIST_UNLOCK(&idle_list);
10468 }
10469 }
10470 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL);
10471 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
10472 ast_verb(2, "%d helper threads started\n", threadcount);
10473 return 0;
10474 }
10475
10476 static struct iax2_context *build_context(const char *context)
10477 {
10478 struct iax2_context *con;
10479
10480 if ((con = ast_calloc(1, sizeof(*con))))
10481 ast_copy_string(con->context, context, sizeof(con->context));
10482
10483 return con;
10484 }
10485
10486 static int get_auth_methods(const char *value)
10487 {
10488 int methods = 0;
10489 if (strstr(value, "rsa"))
10490 methods |= IAX_AUTH_RSA;
10491 if (strstr(value, "md5"))
10492 methods |= IAX_AUTH_MD5;
10493 if (strstr(value, "plaintext"))
10494 methods |= IAX_AUTH_PLAINTEXT;
10495 return methods;
10496 }
10497
10498
10499
10500
10501
10502 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
10503 {
10504 int sd;
10505 int res;
10506
10507 sd = socket(AF_INET, SOCK_DGRAM, 0);
10508 if (sd < 0) {
10509 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
10510 return -1;
10511 }
10512
10513 res = bind(sd, sa, salen);
10514 if (res < 0) {
10515 ast_debug(1, "Can't bind: %s\n", strerror(errno));
10516 close(sd);
10517 return 1;
10518 }
10519
10520 close(sd);
10521 return 0;
10522 }
10523
10524
10525
10526
10527 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
10528 {
10529 struct sockaddr_in sin;
10530 int nonlocal = 1;
10531 int port = IAX_DEFAULT_PORTNO;
10532 int sockfd = defaultsockfd;
10533 char *tmp;
10534 char *addr;
10535 char *portstr;
10536
10537 if (!(tmp = ast_strdupa(srcaddr)))
10538 return -1;
10539
10540 addr = strsep(&tmp, ":");
10541 portstr = tmp;
10542
10543 if (portstr) {
10544 port = atoi(portstr);
10545 if (port < 1)
10546 port = IAX_DEFAULT_PORTNO;
10547 }
10548
10549 if (!ast_get_ip(&sin, addr)) {
10550 struct ast_netsock *sock;
10551 int res;
10552
10553 sin.sin_port = 0;
10554 sin.sin_family = AF_INET;
10555 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
10556 if (res == 0) {
10557
10558 sin.sin_port = htons(port);
10559 if (!(sock = ast_netsock_find(netsock, &sin)))
10560 sock = ast_netsock_find(outsock, &sin);
10561 if (sock) {
10562 sockfd = ast_netsock_sockfd(sock);
10563 nonlocal = 0;
10564 } else {
10565 unsigned int orig_saddr = sin.sin_addr.s_addr;
10566
10567 sin.sin_addr.s_addr = INADDR_ANY;
10568 if (ast_netsock_find(netsock, &sin)) {
10569 sin.sin_addr.s_addr = orig_saddr;
10570 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
10571 if (sock) {
10572 sockfd = ast_netsock_sockfd(sock);
10573 ast_netsock_unref(sock);
10574 nonlocal = 0;
10575 } else {
10576 nonlocal = 2;
10577 }
10578 }
10579 }
10580 }
10581 }
10582
10583 peer->sockfd = sockfd;
10584
10585 if (nonlocal == 1) {
10586 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
10587 srcaddr, peer->name);
10588 return -1;
10589 } else if (nonlocal == 2) {
10590 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
10591 srcaddr, peer->name);
10592 return -1;
10593 } else {
10594 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
10595 return 0;
10596 }
10597 }
10598
10599 static void peer_destructor(void *obj)
10600 {
10601 struct iax2_peer *peer = obj;
10602 int callno = peer->callno;
10603
10604 ast_free_ha(peer->ha);
10605
10606 if (callno > 0) {
10607 ast_mutex_lock(&iaxsl[callno]);
10608 iax2_destroy(callno);
10609 ast_mutex_unlock(&iaxsl[callno]);
10610 }
10611
10612 register_peer_exten(peer, 0);
10613
10614 if (peer->dnsmgr)
10615 ast_dnsmgr_release(peer->dnsmgr);
10616
10617 if (peer->mwi_event_sub)
10618 ast_event_unsubscribe(peer->mwi_event_sub);
10619
10620 ast_string_field_free_memory(peer);
10621 }
10622
10623
10624 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10625 {
10626 struct iax2_peer *peer = NULL;
10627 struct ast_ha *oldha = NULL;
10628 int maskfound = 0;
10629 int found = 0;
10630 int firstpass = 1;
10631 struct iax2_peer tmp_peer = {
10632 .name = name,
10633 };
10634
10635 if (!temponly) {
10636 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
10637 if (peer && !ast_test_flag(peer, IAX_DELME))
10638 firstpass = 0;
10639 }
10640
10641 if (peer) {
10642 found++;
10643 if (firstpass) {
10644 oldha = peer->ha;
10645 peer->ha = NULL;
10646 }
10647 unlink_peer(peer);
10648 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
10649 peer->expire = -1;
10650 peer->pokeexpire = -1;
10651 peer->sockfd = defaultsockfd;
10652 if (ast_string_field_init(peer, 32))
10653 peer = peer_unref(peer);
10654 }
10655
10656 if (peer) {
10657 if (firstpass) {
10658 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF);
10659 peer->encmethods = iax2_encryption;
10660 peer->adsi = adsi;
10661 ast_string_field_set(peer,secret,"");
10662 if (!found) {
10663 ast_string_field_set(peer, name, name);
10664 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10665 peer->expiry = min_reg_expire;
10666 }
10667 peer->prefs = prefs;
10668 peer->capability = iax2_capability;
10669 peer->smoothing = 0;
10670 peer->pokefreqok = DEFAULT_FREQ_OK;
10671 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
10672 ast_string_field_set(peer,context,"");
10673 ast_string_field_set(peer,peercontext,"");
10674 ast_clear_flag(peer, IAX_HASCALLERID);
10675 ast_string_field_set(peer, cid_name, "");
10676 ast_string_field_set(peer, cid_num, "");
10677 }
10678
10679 if (!v) {
10680 v = alt;
10681 alt = NULL;
10682 }
10683 while(v) {
10684 if (!strcasecmp(v->name, "secret")) {
10685 ast_string_field_set(peer, secret, v->value);
10686 } else if (!strcasecmp(v->name, "mailbox")) {
10687 ast_string_field_set(peer, mailbox, v->value);
10688 } else if (!strcasecmp(v->name, "hasvoicemail")) {
10689 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
10690 ast_string_field_set(peer, mailbox, name);
10691 }
10692 } else if (!strcasecmp(v->name, "mohinterpret")) {
10693 ast_string_field_set(peer, mohinterpret, v->value);
10694 } else if (!strcasecmp(v->name, "mohsuggest")) {
10695 ast_string_field_set(peer, mohsuggest, v->value);
10696 } else if (!strcasecmp(v->name, "dbsecret")) {
10697 ast_string_field_set(peer, dbsecret, v->value);
10698 } else if (!strcasecmp(v->name, "trunk")) {
10699 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK);
10700 if (ast_test_flag(peer, IAX_TRUNK) && !timer) {
10701 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
10702 ast_clear_flag(peer, IAX_TRUNK);
10703 }
10704 } else if (!strcasecmp(v->name, "auth")) {
10705 peer->authmethods = get_auth_methods(v->value);
10706 } else if (!strcasecmp(v->name, "encryption")) {
10707 peer->encmethods |= get_encrypt_methods(v->value);
10708 } else if (!strcasecmp(v->name, "transfer")) {
10709 if (!strcasecmp(v->value, "mediaonly")) {
10710 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
10711 } else if (ast_true(v->value)) {
10712 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10713 } else
10714 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10715 } else if (!strcasecmp(v->name, "jitterbuffer")) {
10716 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF);
10717 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10718 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
10719 } else if (!strcasecmp(v->name, "host")) {
10720 if (!strcasecmp(v->value, "dynamic")) {
10721
10722 ast_set_flag(peer, IAX_DYNAMIC);
10723 if (!found) {
10724
10725
10726 memset(&peer->addr.sin_addr, 0, 4);
10727 if (peer->addr.sin_port) {
10728
10729 peer->defaddr.sin_port = peer->addr.sin_port;
10730 peer->addr.sin_port = 0;
10731 }
10732 }
10733 } else {
10734
10735 AST_SCHED_DEL(sched, peer->expire);
10736 ast_clear_flag(peer, IAX_DYNAMIC);
10737 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
10738 return peer_unref(peer);
10739 if (!peer->addr.sin_port)
10740 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);
10741 }
10742 if (!maskfound)
10743 inet_aton("255.255.255.255", &peer->mask);
10744 } else if (!strcasecmp(v->name, "defaultip")) {
10745 if (ast_get_ip(&peer->defaddr, v->value))
10746 return peer_unref(peer);
10747 } else if (!strcasecmp(v->name, "sourceaddress")) {
10748 peer_set_srcaddr(peer, v->value);
10749 } else if (!strcasecmp(v->name, "permit") ||
10750 !strcasecmp(v->name, "deny")) {
10751 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
10752 } else if (!strcasecmp(v->name, "mask")) {
10753 maskfound++;
10754 inet_aton(v->value, &peer->mask);
10755 } else if (!strcasecmp(v->name, "context")) {
10756 ast_string_field_set(peer, context, v->value);
10757 } else if (!strcasecmp(v->name, "regexten")) {
10758 ast_string_field_set(peer, regexten, v->value);
10759 } else if (!strcasecmp(v->name, "peercontext")) {
10760 ast_string_field_set(peer, peercontext, v->value);
10761 } else if (!strcasecmp(v->name, "port")) {
10762 if (ast_test_flag(peer, IAX_DYNAMIC))
10763 peer->defaddr.sin_port = htons(atoi(v->value));
10764 else
10765 peer->addr.sin_port = htons(atoi(v->value));
10766 } else if (!strcasecmp(v->name, "username")) {
10767 ast_string_field_set(peer, username, v->value);
10768 } else if (!strcasecmp(v->name, "allow")) {
10769 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
10770 } else if (!strcasecmp(v->name, "disallow")) {
10771 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
10772 } else if (!strcasecmp(v->name, "callerid")) {
10773 if (!ast_strlen_zero(v->value)) {
10774 char name2[80];
10775 char num2[80];
10776 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10777 ast_string_field_set(peer, cid_name, name2);
10778 ast_string_field_set(peer, cid_num, num2);
10779 } else {
10780 ast_string_field_set(peer, cid_name, "");
10781 ast_string_field_set(peer, cid_num, "");
10782 }
10783 ast_set_flag(peer, IAX_HASCALLERID);
10784 } else if (!strcasecmp(v->name, "fullname")) {
10785 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
10786 ast_set_flag(peer, IAX_HASCALLERID);
10787 } else if (!strcasecmp(v->name, "cid_number")) {
10788 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
10789 ast_set_flag(peer, IAX_HASCALLERID);
10790 } else if (!strcasecmp(v->name, "sendani")) {
10791 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI);
10792 } else if (!strcasecmp(v->name, "inkeys")) {
10793 ast_string_field_set(peer, inkeys, v->value);
10794 } else if (!strcasecmp(v->name, "outkey")) {
10795 ast_string_field_set(peer, outkey, v->value);
10796 } else if (!strcasecmp(v->name, "qualify")) {
10797 if (!strcasecmp(v->value, "no")) {
10798 peer->maxms = 0;
10799 } else if (!strcasecmp(v->value, "yes")) {
10800 peer->maxms = DEFAULT_MAXMS;
10801 } else if (sscanf(v->value, "%d", &peer->maxms) != 1) {
10802 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);
10803 peer->maxms = 0;
10804 }
10805 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
10806 peer->smoothing = ast_true(v->value);
10807 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
10808 if (sscanf(v->value, "%d", &peer->pokefreqok) != 1) {
10809 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);
10810 }
10811 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
10812 if (sscanf(v->value, "%d", &peer->pokefreqnotok) != 1) {
10813 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);
10814 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
10815 } else if (!strcasecmp(v->name, "timezone")) {
10816 ast_string_field_set(peer, zonetag, v->value);
10817 } else if (!strcasecmp(v->name, "adsi")) {
10818 peer->adsi = ast_true(v->value);
10819 }
10820
10821 v = v->next;
10822 if (!v) {
10823 v = alt;
10824 alt = NULL;
10825 }
10826 }
10827 if (!peer->authmethods)
10828 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
10829 ast_clear_flag(peer, IAX_DELME);
10830
10831 peer->addr.sin_family = AF_INET;
10832 }
10833
10834 if (oldha)
10835 ast_free_ha(oldha);
10836
10837 if (!ast_strlen_zero(peer->mailbox)) {
10838 char *mailbox, *context;
10839 context = mailbox = ast_strdupa(peer->mailbox);
10840 strsep(&context, "@");
10841 if (ast_strlen_zero(context))
10842 context = "default";
10843 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL,
10844 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
10845 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
10846 AST_EVENT_IE_END);
10847 }
10848
10849 return peer;
10850 }
10851
10852 static void user_destructor(void *obj)
10853 {
10854 struct iax2_user *user = obj;
10855
10856 ast_free_ha(user->ha);
10857 free_context(user->contexts);
10858 if(user->vars) {
10859 ast_variables_destroy(user->vars);
10860 user->vars = NULL;
10861 }
10862 ast_string_field_free_memory(user);
10863 }
10864
10865
10866 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
10867 {
10868 struct iax2_user *user = NULL;
10869 struct iax2_context *con, *conl = NULL;
10870 struct ast_ha *oldha = NULL;
10871 struct iax2_context *oldcon = NULL;
10872 int format;
10873 int firstpass=1;
10874 int oldcurauthreq = 0;
10875 char *varname = NULL, *varval = NULL;
10876 struct ast_variable *tmpvar = NULL;
10877 struct iax2_user tmp_user = {
10878 .name = name,
10879 };
10880
10881 if (!temponly) {
10882 user = ao2_find(users, &tmp_user, OBJ_POINTER);
10883 if (user && !ast_test_flag(user, IAX_DELME))
10884 firstpass = 0;
10885 }
10886
10887 if (user) {
10888 if (firstpass) {
10889 oldcurauthreq = user->curauthreq;
10890 oldha = user->ha;
10891 oldcon = user->contexts;
10892 user->ha = NULL;
10893 user->contexts = NULL;
10894 }
10895
10896 ao2_unlink(users, user);
10897 } else {
10898 user = ao2_alloc(sizeof(*user), user_destructor);
10899 }
10900
10901 if (user) {
10902 if (firstpass) {
10903 ast_string_field_free_memory(user);
10904 memset(user, 0, sizeof(struct iax2_user));
10905 if (ast_string_field_init(user, 32)) {
10906 user = user_unref(user);
10907 goto cleanup;
10908 }
10909 user->maxauthreq = maxauthreq;
10910 user->curauthreq = oldcurauthreq;
10911 user->prefs = prefs;
10912 user->capability = iax2_capability;
10913 user->encmethods = iax2_encryption;
10914 user->adsi = adsi;
10915 ast_string_field_set(user, name, name);
10916 ast_string_field_set(user, language, language);
10917 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP);
10918 ast_clear_flag(user, IAX_HASCALLERID);
10919 ast_string_field_set(user, cid_name, "");
10920 ast_string_field_set(user, cid_num, "");
10921 }
10922 if (!v) {
10923 v = alt;
10924 alt = NULL;
10925 }
10926 while(v) {
10927 if (!strcasecmp(v->name, "context")) {
10928 con = build_context(v->value);
10929 if (con) {
10930 if (conl)
10931 conl->next = con;
10932 else
10933 user->contexts = con;
10934 conl = con;
10935 }
10936 } else if (!strcasecmp(v->name, "permit") ||
10937 !strcasecmp(v->name, "deny")) {
10938 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
10939 } else if (!strcasecmp(v->name, "setvar")) {
10940 varname = ast_strdupa(v->value);
10941 if (varname && (varval = strchr(varname,'='))) {
10942 *varval = '\0';
10943 varval++;
10944 if((tmpvar = ast_variable_new(varname, varval, ""))) {
10945 tmpvar->next = user->vars;
10946 user->vars = tmpvar;
10947 }
10948 }
10949 } else if (!strcasecmp(v->name, "allow")) {
10950 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
10951 } else if (!strcasecmp(v->name, "disallow")) {
10952 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
10953 } else if (!strcasecmp(v->name, "trunk")) {
10954 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK);
10955 if (ast_test_flag(user, IAX_TRUNK) && !timer) {
10956 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
10957 ast_clear_flag(user, IAX_TRUNK);
10958 }
10959 } else if (!strcasecmp(v->name, "auth")) {
10960 user->authmethods = get_auth_methods(v->value);
10961 } else if (!strcasecmp(v->name, "encryption")) {
10962 user->encmethods |= get_encrypt_methods(v->value);
10963 } else if (!strcasecmp(v->name, "transfer")) {
10964 if (!strcasecmp(v->value, "mediaonly")) {
10965 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
10966 } else if (ast_true(v->value)) {
10967 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
10968 } else
10969 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
10970 } else if (!strcasecmp(v->name, "codecpriority")) {
10971 if(!strcasecmp(v->value, "caller"))
10972 ast_set_flag(user, IAX_CODEC_USER_FIRST);
10973 else if(!strcasecmp(v->value, "disabled"))
10974 ast_set_flag(user, IAX_CODEC_NOPREFS);
10975 else if(!strcasecmp(v->value, "reqonly")) {
10976 ast_set_flag(user, IAX_CODEC_NOCAP);
10977 ast_set_flag(user, IAX_CODEC_NOPREFS);
10978 }
10979 } else if (!strcasecmp(v->name, "jitterbuffer")) {
10980 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF);
10981 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
10982 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF);
10983 } else if (!strcasecmp(v->name, "dbsecret")) {
10984 ast_string_field_set(user, dbsecret, v->value);
10985 } else if (!strcasecmp(v->name, "secret")) {
10986 if (!ast_strlen_zero(user->secret)) {
10987 char *old = ast_strdupa(user->secret);
10988
10989 ast_string_field_build(user, secret, "%s;%s", old, v->value);
10990 } else
10991 ast_string_field_set(user, secret, v->value);
10992 } else if (!strcasecmp(v->name, "callerid")) {
10993 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
10994 char name2[80];
10995 char num2[80];
10996 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
10997 ast_string_field_set(user, cid_name, name2);
10998 ast_string_field_set(user, cid_num, num2);
10999 ast_set_flag(user, IAX_HASCALLERID);
11000 } else {
11001 ast_clear_flag(user, IAX_HASCALLERID);
11002 ast_string_field_set(user, cid_name, "");
11003 ast_string_field_set(user, cid_num, "");
11004 }
11005 } else if (!strcasecmp(v->name, "fullname")) {
11006 if (!ast_strlen_zero(v->value)) {
11007 ast_string_field_set(user, cid_name, v->value);
11008 ast_set_flag(user, IAX_HASCALLERID);
11009 } else {
11010 ast_string_field_set(user, cid_name, "");
11011 if (ast_strlen_zero(user->cid_num))
11012 ast_clear_flag(user, IAX_HASCALLERID);
11013 }
11014 } else if (!strcasecmp(v->name, "cid_number")) {
11015 if (!ast_strlen_zero(v->value)) {
11016 ast_string_field_set(user, cid_num, v->value);
11017 ast_set_flag(user, IAX_HASCALLERID);
11018 } else {
11019 ast_string_field_set(user, cid_num, "");
11020 if (ast_strlen_zero(user->cid_name))
11021 ast_clear_flag(user, IAX_HASCALLERID);
11022 }
11023 } else if (!strcasecmp(v->name, "accountcode")) {
11024 ast_string_field_set(user, accountcode, v->value);
11025 } else if (!strcasecmp(v->name, "mohinterpret")) {
11026 ast_string_field_set(user, mohinterpret, v->value);
11027 } else if (!strcasecmp(v->name, "mohsuggest")) {
11028 ast_string_field_set(user, mohsuggest, v->value);
11029 } else if (!strcasecmp(v->name, "parkinglot")) {
11030 ast_string_field_set(user, parkinglot, v->value);
11031 } else if (!strcasecmp(v->name, "language")) {
11032 ast_string_field_set(user, language, v->value);
11033 } else if (!strcasecmp(v->name, "amaflags")) {
11034 format = ast_cdr_amaflags2int(v->value);
11035 if (format < 0) {
11036 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11037 } else {
11038 user->amaflags = format;
11039 }
11040 } else if (!strcasecmp(v->name, "inkeys")) {
11041 ast_string_field_set(user, inkeys, v->value);
11042 } else if (!strcasecmp(v->name, "maxauthreq")) {
11043 user->maxauthreq = atoi(v->value);
11044 if (user->maxauthreq < 0)
11045 user->maxauthreq = 0;
11046 } else if (!strcasecmp(v->name, "adsi")) {
11047 user->adsi = ast_true(v->value);
11048 }
11049
11050 v = v->next;
11051 if (!v) {
11052 v = alt;
11053 alt = NULL;
11054 }
11055 }
11056 if (!user->authmethods) {
11057 if (!ast_strlen_zero(user->secret)) {
11058 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11059 if (!ast_strlen_zero(user->inkeys))
11060 user->authmethods |= IAX_AUTH_RSA;
11061 } else if (!ast_strlen_zero(user->inkeys)) {
11062 user->authmethods = IAX_AUTH_RSA;
11063 } else {
11064 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
11065 }
11066 }
11067 ast_clear_flag(user, IAX_DELME);
11068 }
11069 cleanup:
11070 if (oldha)
11071 ast_free_ha(oldha);
11072 if (oldcon)
11073 free_context(oldcon);
11074 return user;
11075 }
11076
11077 static int peer_delme_cb(void *obj, void *arg, int flags)
11078 {
11079 struct iax2_peer *peer = obj;
11080
11081 ast_set_flag(peer, IAX_DELME);
11082
11083 return 0;
11084 }
11085
11086 static int user_delme_cb(void *obj, void *arg, int flags)
11087 {
11088 struct iax2_user *user = obj;
11089
11090 ast_set_flag(user, IAX_DELME);
11091
11092 return 0;
11093 }
11094
11095 static void delete_users(void)
11096 {
11097 struct iax2_registry *reg;
11098
11099 ao2_callback(users, 0, user_delme_cb, NULL);
11100
11101 AST_LIST_LOCK(®istrations);
11102 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
11103 AST_SCHED_DEL(sched, reg->expire);
11104 if (reg->callno) {
11105 int callno = reg->callno;
11106 ast_mutex_lock(&iaxsl[callno]);
11107 if (iaxs[callno]) {
11108 iaxs[callno]->reg = NULL;
11109 iax2_destroy(callno);
11110 }
11111 ast_mutex_unlock(&iaxsl[callno]);
11112 }
11113 if (reg->dnsmgr)
11114 ast_dnsmgr_release(reg->dnsmgr);
11115 ast_free(reg);
11116 }
11117 AST_LIST_UNLOCK(®istrations);
11118
11119 ao2_callback(peers, 0, peer_delme_cb, NULL);
11120 }
11121
11122 static void prune_users(void)
11123 {
11124 struct iax2_user *user;
11125 struct ao2_iterator i;
11126
11127 i = ao2_iterator_init(users, 0);
11128 while ((user = ao2_iterator_next(&i))) {
11129 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) {
11130 ao2_unlink(users, user);
11131 }
11132 user_unref(user);
11133 }
11134 }
11135
11136
11137 static void prune_peers(void)
11138 {
11139 struct iax2_peer *peer;
11140 struct ao2_iterator i;
11141
11142 i = ao2_iterator_init(peers, 0);
11143 while ((peer = ao2_iterator_next(&i))) {
11144 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) {
11145 unlink_peer(peer);
11146 }
11147 peer_unref(peer);
11148 }
11149 }
11150
11151 static void set_config_destroy(void)
11152 {
11153 strcpy(accountcode, "");
11154 strcpy(language, "");
11155 strcpy(mohinterpret, "default");
11156 strcpy(mohsuggest, "");
11157 global_max_trunk_mtu = MAX_TRUNK_MTU;
11158 trunkmaxsize = MAX_TRUNKDATA;
11159 amaflags = 0;
11160 delayreject = 0;
11161 ast_clear_flag((&globalflags), IAX_NOTRANSFER);
11162 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA);
11163 ast_clear_flag((&globalflags), IAX_USEJITTERBUF);
11164 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF);
11165 delete_users();
11166 }
11167
11168
11169 static int set_config(char *config_file, int reload)
11170 {
11171 struct ast_config *cfg, *ucfg;
11172 int capability=iax2_capability;
11173 struct ast_variable *v;
11174 char *cat;
11175 const char *utype;
11176 const char *tosval;
11177 int format;
11178 int portno = IAX_DEFAULT_PORTNO;
11179 int x;
11180 int mtuv;
11181 struct iax2_user *user;
11182 struct iax2_peer *peer;
11183 struct ast_netsock *ns;
11184 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
11185 #if 0
11186 static unsigned short int last_port=0;
11187 #endif
11188
11189 cfg = ast_config_load(config_file, config_flags);
11190
11191 if (!cfg) {
11192 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
11193 return -1;
11194 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
11195 ucfg = ast_config_load("users.conf", config_flags);
11196 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
11197 return 0;
11198
11199 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11200 cfg = ast_config_load(config_file, config_flags);
11201 } else {
11202 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
11203 ucfg = ast_config_load("users.conf", config_flags);
11204 }
11205
11206 if (reload) {
11207 set_config_destroy();
11208 }
11209
11210
11211 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
11212
11213
11214 memset(&globalflags, 0, sizeof(globalflags));
11215 ast_set_flag(&globalflags, IAX_RTUPDATE);
11216
11217
11218 iax2_encryption |= IAX_ENCRYPT_KEYROTATE;
11219 #ifdef SO_NO_CHECK
11220 nochecksums = 0;
11221 #endif
11222
11223 default_parkinglot[0] = '\0';
11224
11225 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11226 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
11227
11228 maxauthreq = 3;
11229
11230 srvlookup = 0;
11231
11232 v = ast_variable_browse(cfg, "general");
11233
11234
11235 tosval = ast_variable_retrieve(cfg, "general", "tos");
11236 if (tosval) {
11237 if (ast_str2tos(tosval, &qos.tos))
11238 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
11239 }
11240
11241 tosval = ast_variable_retrieve(cfg, "general", "cos");
11242 if (tosval) {
11243 if (ast_str2cos(tosval, &qos.cos))
11244 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
11245 }
11246 while(v) {
11247 if (!strcasecmp(v->name, "bindport")){
11248 if (reload)
11249 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
11250 else
11251 portno = atoi(v->value);
11252 } else if (!strcasecmp(v->name, "pingtime"))
11253 ping_time = atoi(v->value);
11254 else if (!strcasecmp(v->name, "iaxthreadcount")) {
11255 if (reload) {
11256 if (atoi(v->value) != iaxthreadcount)
11257 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
11258 } else {
11259 iaxthreadcount = atoi(v->value);
11260 if (iaxthreadcount < 1) {
11261 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
11262 iaxthreadcount = 1;
11263 } else if (iaxthreadcount > 256) {
11264 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
11265 iaxthreadcount = 256;
11266 }
11267 }
11268 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
11269 if (reload) {
11270 AST_LIST_LOCK(&dynamic_list);
11271 iaxmaxthreadcount = atoi(v->value);
11272 AST_LIST_UNLOCK(&dynamic_list);
11273 } else {
11274 iaxmaxthreadcount = atoi(v->value);
11275 if (iaxmaxthreadcount < 0) {
11276 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
11277 iaxmaxthreadcount = 0;
11278 } else if (iaxmaxthreadcount > 256) {
11279 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
11280 iaxmaxthreadcount = 256;
11281 }
11282 }
11283 } else if (!strcasecmp(v->name, "nochecksums")) {
11284 #ifdef SO_NO_CHECK
11285 if (ast_true(v->value))
11286 nochecksums = 1;
11287 else
11288 nochecksums = 0;
11289 #else
11290 if (ast_true(v->value))
11291 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
11292 #endif
11293 }
11294 else if (!strcasecmp(v->name, "maxjitterbuffer"))
11295 maxjitterbuffer = atoi(v->value);
11296 else if (!strcasecmp(v->name, "resyncthreshold"))
11297 resyncthreshold = atoi(v->value);
11298 else if (!strcasecmp(v->name, "maxjitterinterps"))
11299 maxjitterinterps = atoi(v->value);
11300 else if (!strcasecmp(v->name, "jittertargetextra"))
11301 jittertargetextra = atoi(v->value);
11302 else if (!strcasecmp(v->name, "lagrqtime"))
11303 lagrq_time = atoi(v->value);
11304 else if (!strcasecmp(v->name, "maxregexpire"))
11305 max_reg_expire = atoi(v->value);
11306 else if (!strcasecmp(v->name, "minregexpire"))
11307 min_reg_expire = atoi(v->value);
11308 else if (!strcasecmp(v->name, "bindaddr")) {
11309 if (reload) {
11310 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
11311 } else {
11312 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
11313 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
11314 } else {
11315 if (strchr(v->value, ':'))
11316 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
11317 else
11318 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
11319 if (defaultsockfd < 0)
11320 defaultsockfd = ast_netsock_sockfd(ns);
11321 ast_netsock_unref(ns);
11322 }
11323 }
11324 } else if (!strcasecmp(v->name, "authdebug"))
11325 authdebug = ast_true(v->value);
11326 else if (!strcasecmp(v->name, "encryption"))
11327 iax2_encryption |= get_encrypt_methods(v->value);
11328 else if (!strcasecmp(v->name, "transfer")) {
11329 if (!strcasecmp(v->value, "mediaonly")) {
11330 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
11331 } else if (ast_true(v->value)) {
11332 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
11333 } else
11334 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
11335 } else if (!strcasecmp(v->name, "codecpriority")) {
11336 if(!strcasecmp(v->value, "caller"))
11337 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST);
11338 else if(!strcasecmp(v->value, "disabled"))
11339 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11340 else if(!strcasecmp(v->value, "reqonly")) {
11341 ast_set_flag((&globalflags), IAX_CODEC_NOCAP);
11342 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS);
11343 }
11344 } else if (!strcasecmp(v->name, "jitterbuffer"))
11345 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
11346 else if (!strcasecmp(v->name, "forcejitterbuffer"))
11347 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
11348 else if (!strcasecmp(v->name, "delayreject"))
11349 delayreject = ast_true(v->value);
11350 else if (!strcasecmp(v->name, "allowfwdownload"))
11351 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
11352 else if (!strcasecmp(v->name, "rtcachefriends"))
11353 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
11354 else if (!strcasecmp(v->name, "rtignoreregexpire"))
11355 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
11356 else if (!strcasecmp(v->name, "rtupdate"))
11357 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE);
11358 else if (!strcasecmp(v->name, "trunktimestamps"))
11359 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
11360 else if (!strcasecmp(v->name, "rtautoclear")) {
11361 int i = atoi(v->value);
11362 if(i > 0)
11363 global_rtautoclear = i;
11364 else
11365 i = 0;
11366 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
11367 } else if (!strcasecmp(v->name, "trunkfreq")) {
11368 trunkfreq = atoi(v->value);
11369 if (trunkfreq < 10)
11370 trunkfreq = 10;
11371 } else if (!strcasecmp(v->name, "trunkmtu")) {
11372 mtuv = atoi(v->value);
11373 if (mtuv == 0 )
11374 global_max_trunk_mtu = 0;
11375 else if (mtuv >= 172 && mtuv < 4000)
11376 global_max_trunk_mtu = mtuv;
11377 else
11378 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
11379 mtuv, v->lineno);
11380 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
11381 trunkmaxsize = atoi(v->value);
11382 if (trunkmaxsize == 0)
11383 trunkmaxsize = MAX_TRUNKDATA;
11384 } else if (!strcasecmp(v->name, "autokill")) {
11385 if (sscanf(v->value, "%d", &x) == 1) {
11386 if (x >= 0)
11387 autokill = x;
11388 else
11389 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
11390 } else if (ast_true(v->value)) {
11391 autokill = DEFAULT_MAXMS;
11392 } else {
11393 autokill = 0;
11394 }
11395 } else if (!strcasecmp(v->name, "bandwidth")) {
11396 if (!strcasecmp(v->value, "low")) {
11397 capability = IAX_CAPABILITY_LOWBANDWIDTH;
11398 } else if (!strcasecmp(v->value, "medium")) {
11399 capability = IAX_CAPABILITY_MEDBANDWIDTH;
11400 } else if (!strcasecmp(v->value, "high")) {
11401 capability = IAX_CAPABILITY_FULLBANDWIDTH;
11402 } else
11403 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
11404 } else if (!strcasecmp(v->name, "allow")) {
11405 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
11406 } else if (!strcasecmp(v->name, "disallow")) {
11407 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
11408 } else if (!strcasecmp(v->name, "register")) {
11409 iax2_register(v->value, v->lineno);
11410 } else if (!strcasecmp(v->name, "iaxcompat")) {
11411 iaxcompat = ast_true(v->value);
11412 } else if (!strcasecmp(v->name, "regcontext")) {
11413 ast_copy_string(regcontext, v->value, sizeof(regcontext));
11414
11415 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
11416 } else if (!strcasecmp(v->name, "tos")) {
11417 if (ast_str2tos(v->value, &qos.tos))
11418 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
11419 } else if (!strcasecmp(v->name, "cos")) {
11420 if (ast_str2cos(v->value, &qos.cos))
11421 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
11422 } else if (!strcasecmp(v->name, "parkinglot")) {
11423 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
11424 } else if (!strcasecmp(v->name, "accountcode")) {
11425 ast_copy_string(accountcode, v->value, sizeof(accountcode));
11426 } else if (!strcasecmp(v->name, "mohinterpret")) {
11427 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
11428 } else if (!strcasecmp(v->name, "mohsuggest")) {
11429 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
11430 } else if (!strcasecmp(v->name, "amaflags")) {
11431 format = ast_cdr_amaflags2int(v->value);
11432 if (format < 0) {
11433 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
11434 } else {
11435 amaflags = format;
11436 }
11437 } else if (!strcasecmp(v->name, "language")) {
11438 ast_copy_string(language, v->value, sizeof(language));
11439 } else if (!strcasecmp(v->name, "maxauthreq")) {
11440 maxauthreq = atoi(v->value);
11441 if (maxauthreq < 0)
11442 maxauthreq = 0;
11443 } else if (!strcasecmp(v->name, "adsi")) {
11444 adsi = ast_true(v->value);
11445 } else if (!strcasecmp(v->name, "srvlookup")) {
11446 srvlookup = ast_true(v->value);
11447 }
11448
11449 v = v->next;
11450 }
11451
11452 if (defaultsockfd < 0) {
11453 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
11454 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
11455 } else {
11456 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
11457 defaultsockfd = ast_netsock_sockfd(ns);
11458 ast_netsock_unref(ns);
11459 }
11460 }
11461 if (reload) {
11462 ast_netsock_release(outsock);
11463 outsock = ast_netsock_list_alloc();
11464 if (!outsock) {
11465 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
11466 return -1;
11467 }
11468 ast_netsock_init(outsock);
11469 }
11470
11471 if (min_reg_expire > max_reg_expire) {
11472 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
11473 min_reg_expire, max_reg_expire, max_reg_expire);
11474 min_reg_expire = max_reg_expire;
11475 }
11476 iax2_capability = capability;
11477
11478 if (ucfg) {
11479 struct ast_variable *gen;
11480 int genhasiax;
11481 int genregisteriax;
11482 const char *hasiax, *registeriax;
11483
11484 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
11485 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
11486 gen = ast_variable_browse(ucfg, "general");
11487 cat = ast_category_browse(ucfg, NULL);
11488 while (cat) {
11489 if (strcasecmp(cat, "general")) {
11490 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
11491 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
11492 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
11493
11494 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
11495 if (user) {
11496 ao2_link(users, user);
11497 user = user_unref(user);
11498 }
11499 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
11500 if (peer) {
11501 if (ast_test_flag(peer, IAX_DYNAMIC))
11502 reg_source_db(peer);
11503 ao2_link(peers, peer);
11504 peer = peer_unref(peer);
11505 }
11506 }
11507 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
11508 char tmp[256];
11509 const char *host = ast_variable_retrieve(ucfg, cat, "host");
11510 const char *username = ast_variable_retrieve(ucfg, cat, "username");
11511 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
11512 if (!host)
11513 host = ast_variable_retrieve(ucfg, "general", "host");
11514 if (!username)
11515 username = ast_variable_retrieve(ucfg, "general", "username");
11516 if (!secret)
11517 secret = ast_variable_retrieve(ucfg, "general", "secret");
11518 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
11519 if (!ast_strlen_zero(secret))
11520 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
11521 else
11522 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
11523 iax2_register(tmp, 0);
11524 }
11525 }
11526 }
11527 cat = ast_category_browse(ucfg, cat);
11528 }
11529 ast_config_destroy(ucfg);
11530 }
11531
11532 cat = ast_category_browse(cfg, NULL);
11533 while(cat) {
11534 if (strcasecmp(cat, "general")) {
11535 utype = ast_variable_retrieve(cfg, cat, "type");
11536 if (utype) {
11537 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
11538 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
11539 if (user) {
11540 ao2_link(users, user);
11541 user = user_unref(user);
11542 }
11543 }
11544 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
11545 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
11546 if (peer) {
11547 if (ast_test_flag(peer, IAX_DYNAMIC))
11548 reg_source_db(peer);
11549 ao2_link(peers, peer);
11550 peer = peer_unref(peer);
11551 }
11552 } else if (strcasecmp(utype, "user")) {
11553 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
11554 }
11555 } else
11556 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
11557 }
11558 cat = ast_category_browse(cfg, cat);
11559 }
11560 ast_config_destroy(cfg);
11561 return 1;
11562 }
11563
11564 static void poke_all_peers(void)
11565 {
11566 struct ao2_iterator i;
11567 struct iax2_peer *peer;
11568
11569 i = ao2_iterator_init(peers, 0);
11570 while ((peer = ao2_iterator_next(&i))) {
11571 iax2_poke_peer(peer, 0);
11572 peer_unref(peer);
11573 }
11574 }
11575 static int reload_config(void)
11576 {
11577 char *config = "iax.conf";
11578 struct iax2_registry *reg;
11579
11580 if (set_config(config, 1) > 0) {
11581 prune_peers();
11582 prune_users();
11583 trunk_timed = trunk_untimed = 0;
11584 trunk_nmaxmtu = trunk_maxmtu = 0;
11585 memset(&debugaddr, '\0', sizeof(debugaddr));
11586
11587 AST_LIST_LOCK(®istrations);
11588 AST_LIST_TRAVERSE(®istrations, reg, entry)
11589 iax2_do_register(reg);
11590 AST_LIST_UNLOCK(®istrations);
11591
11592
11593 poke_all_peers();
11594 }
11595
11596 reload_firmware(0);
11597 iax_provision_reload(1);
11598 ast_unload_realtime("iaxpeers");
11599
11600 return 0;
11601 }
11602
11603 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11604 {
11605 switch (cmd) {
11606 case CLI_INIT:
11607 e->command = "iax2 reload";
11608 e->usage =
11609 "Usage: iax2 reload\n"
11610 " Reloads IAX configuration from iax.conf\n";
11611 return NULL;
11612 case CLI_GENERATE:
11613 return NULL;
11614 }
11615
11616 reload_config();
11617
11618 return CLI_SUCCESS;
11619 }
11620
11621 static int reload(void)
11622 {
11623 return reload_config();
11624 }
11625
11626 static int cache_get_callno_locked(const char *data)
11627 {
11628 struct sockaddr_in sin;
11629 int x;
11630 int callno;
11631 struct iax_ie_data ied;
11632 struct create_addr_info cai;
11633 struct parsed_dial_string pds;
11634 char *tmpstr;
11635
11636 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
11637
11638
11639 if (!ast_mutex_trylock(&iaxsl[x])) {
11640 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
11641 return x;
11642 ast_mutex_unlock(&iaxsl[x]);
11643 }
11644 }
11645
11646
11647
11648 memset(&cai, 0, sizeof(cai));
11649 memset(&ied, 0, sizeof(ied));
11650 memset(&pds, 0, sizeof(pds));
11651
11652 tmpstr = ast_strdupa(data);
11653 parse_dial_string(tmpstr, &pds);
11654
11655 if (ast_strlen_zero(pds.peer)) {
11656 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
11657 return -1;
11658 }
11659
11660
11661 if (create_addr(pds.peer, NULL, &sin, &cai))
11662 return -1;
11663
11664 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
11665 pds.peer, pds.username, pds.password, pds.context);
11666
11667 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11668 if (callno < 1) {
11669 ast_log(LOG_WARNING, "Unable to create call\n");
11670 return -1;
11671 }
11672
11673 ast_string_field_set(iaxs[callno], dproot, data);
11674 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
11675
11676 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
11677 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
11678
11679
11680
11681 if (pds.exten)
11682 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
11683 if (pds.username)
11684 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
11685 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
11686 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
11687
11688 if (pds.password)
11689 ast_string_field_set(iaxs[callno], secret, pds.password);
11690 if (pds.key)
11691 ast_string_field_set(iaxs[callno], outkey, pds.key);
11692
11693 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
11694
11695 return callno;
11696 }
11697
11698 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
11699 {
11700 struct iax2_dpcache *dp = NULL;
11701 struct timeval now = ast_tvnow();
11702 int x, com[2], timeout, old = 0, outfd, doabort, callno;
11703 struct ast_channel *c = NULL;
11704 struct ast_frame *f = NULL;
11705
11706 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
11707 if (ast_tvcmp(now, dp->expiry) > 0) {
11708 AST_LIST_REMOVE_CURRENT(cache_list);
11709 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
11710 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
11711 else
11712 ast_free(dp);
11713 continue;
11714 }
11715 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
11716 break;
11717 }
11718 AST_LIST_TRAVERSE_SAFE_END;
11719
11720 if (!dp) {
11721
11722
11723 if ((callno = cache_get_callno_locked(data)) < 0) {
11724 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
11725 return NULL;
11726 }
11727 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
11728 ast_mutex_unlock(&iaxsl[callno]);
11729 return NULL;
11730 }
11731 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
11732 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
11733 dp->expiry = ast_tvnow();
11734 dp->orig = dp->expiry;
11735
11736 dp->expiry.tv_sec += iaxdefaultdpcache;
11737 dp->flags = CACHE_FLAG_PENDING;
11738 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
11739 dp->waiters[x] = -1;
11740
11741 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
11742 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
11743
11744 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
11745 iax2_dprequest(dp, callno);
11746 ast_mutex_unlock(&iaxsl[callno]);
11747 }
11748
11749
11750 if (dp->flags & CACHE_FLAG_PENDING) {
11751
11752
11753 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11754
11755 if (dp->waiters[x] < 0)
11756 break;
11757 }
11758 if (x >= ARRAY_LEN(dp->waiters)) {
11759 ast_log(LOG_WARNING, "No more waiter positions available\n");
11760 return NULL;
11761 }
11762 if (pipe(com)) {
11763 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
11764 return NULL;
11765 }
11766 dp->waiters[x] = com[1];
11767
11768 timeout = iaxdefaulttimeout * 1000;
11769
11770 AST_LIST_UNLOCK(&dpcache);
11771
11772 if (chan)
11773 old = ast_channel_defer_dtmf(chan);
11774 doabort = 0;
11775 while(timeout) {
11776 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
11777 if (outfd > -1)
11778 break;
11779 if (!c)
11780 continue;
11781 if (!(f = ast_read(c))) {
11782 doabort = 1;
11783 break;
11784 }
11785 ast_frfree(f);
11786 }
11787 if (!timeout) {
11788 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
11789 }
11790 AST_LIST_LOCK(&dpcache);
11791 dp->waiters[x] = -1;
11792 close(com[1]);
11793 close(com[0]);
11794 if (doabort) {
11795
11796
11797 if (!old && chan)
11798 ast_channel_undefer_dtmf(chan);
11799 return NULL;
11800 }
11801 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
11802
11803 if (dp->flags & CACHE_FLAG_PENDING) {
11804
11805
11806 dp->flags &= ~CACHE_FLAG_PENDING;
11807 dp->flags |= CACHE_FLAG_TIMEOUT;
11808
11809
11810 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
11811 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
11812 if (dp->waiters[x] > -1) {
11813 if (write(dp->waiters[x], "asdf", 4) < 0) {
11814 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
11815 }
11816 }
11817 }
11818 }
11819 }
11820
11821 if (!old && chan)
11822 ast_channel_undefer_dtmf(chan);
11823 }
11824 return dp;
11825 }
11826
11827
11828 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11829 {
11830 int res = 0;
11831 struct iax2_dpcache *dp = NULL;
11832 #if 0
11833 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11834 #endif
11835 if ((priority != 1) && (priority != 2))
11836 return 0;
11837
11838 AST_LIST_LOCK(&dpcache);
11839 if ((dp = find_cache(chan, data, context, exten, priority))) {
11840 if (dp->flags & CACHE_FLAG_EXISTS)
11841 res = 1;
11842 } else {
11843 ast_log(LOG_WARNING, "Unable to make DP cache\n");
11844 }
11845 AST_LIST_UNLOCK(&dpcache);
11846
11847 return res;
11848 }
11849
11850
11851 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11852 {
11853 int res = 0;
11854 struct iax2_dpcache *dp = NULL;
11855 #if 0
11856 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11857 #endif
11858 if ((priority != 1) && (priority != 2))
11859 return 0;
11860
11861 AST_LIST_LOCK(&dpcache);
11862 if ((dp = find_cache(chan, data, context, exten, priority))) {
11863 if (dp->flags & CACHE_FLAG_CANEXIST)
11864 res = 1;
11865 } else {
11866 ast_log(LOG_WARNING, "Unable to make DP cache\n");
11867 }
11868 AST_LIST_UNLOCK(&dpcache);
11869
11870 return res;
11871 }
11872
11873
11874 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11875 {
11876 int res = 0;
11877 struct iax2_dpcache *dp = NULL;
11878 #if 0
11879 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
11880 #endif
11881 if ((priority != 1) && (priority != 2))
11882 return 0;
11883
11884 AST_LIST_LOCK(&dpcache);
11885 if ((dp = find_cache(chan, data, context, exten, priority))) {
11886 if (dp->flags & CACHE_FLAG_MATCHMORE)
11887 res = 1;
11888 } else {
11889 ast_log(LOG_WARNING, "Unable to make DP cache\n");
11890 }
11891 AST_LIST_UNLOCK(&dpcache);
11892
11893 return res;
11894 }
11895
11896
11897 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
11898 {
11899 char odata[256];
11900 char req[256];
11901 char *ncontext;
11902 struct iax2_dpcache *dp = NULL;
11903 struct ast_app *dial = NULL;
11904 #if 0
11905 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);
11906 #endif
11907 if (priority == 2) {
11908
11909 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
11910 if (dialstatus) {
11911 dial = pbx_findapp(dialstatus);
11912 if (dial)
11913 pbx_exec(chan, dial, "");
11914 }
11915 return -1;
11916 } else if (priority != 1)
11917 return -1;
11918
11919 AST_LIST_LOCK(&dpcache);
11920 if ((dp = find_cache(chan, data, context, exten, priority))) {
11921 if (dp->flags & CACHE_FLAG_EXISTS) {
11922 ast_copy_string(odata, data, sizeof(odata));
11923 ncontext = strchr(odata, '/');
11924 if (ncontext) {
11925 *ncontext = '\0';
11926 ncontext++;
11927 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
11928 } else {
11929 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
11930 }
11931 ast_verb(3, "Executing Dial('%s')\n", req);
11932 } else {
11933 AST_LIST_UNLOCK(&dpcache);
11934 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
11935 return -1;
11936 }
11937 }
11938 AST_LIST_UNLOCK(&dpcache);
11939
11940 if ((dial = pbx_findapp("Dial")))
11941 return pbx_exec(chan, dial, req);
11942 else
11943 ast_log(LOG_WARNING, "No dial application registered\n");
11944
11945 return -1;
11946 }
11947
11948 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
11949 {
11950 struct iax2_peer *peer;
11951 char *peername, *colname;
11952
11953 peername = ast_strdupa(data);
11954
11955
11956 if (!strcmp(peername,"CURRENTCHANNEL")) {
11957 unsigned short callno;
11958 if (chan->tech != &iax2_tech)
11959 return -1;
11960 callno = PTR_TO_CALLNO(chan->tech_pvt);
11961 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
11962 return 0;
11963 }
11964
11965 if ((colname = strchr(peername, ',')))
11966 *colname++ = '\0';
11967 else
11968 colname = "ip";
11969
11970 if (!(peer = find_peer(peername, 1)))
11971 return -1;
11972
11973 if (!strcasecmp(colname, "ip")) {
11974 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
11975 } else if (!strcasecmp(colname, "status")) {
11976 peer_status(peer, buf, len);
11977 } else if (!strcasecmp(colname, "mailbox")) {
11978 ast_copy_string(buf, peer->mailbox, len);
11979 } else if (!strcasecmp(colname, "context")) {
11980 ast_copy_string(buf, peer->context, len);
11981 } else if (!strcasecmp(colname, "expire")) {
11982 snprintf(buf, len, "%d", peer->expire);
11983 } else if (!strcasecmp(colname, "dynamic")) {
11984 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
11985 } else if (!strcasecmp(colname, "callerid_name")) {
11986 ast_copy_string(buf, peer->cid_name, len);
11987 } else if (!strcasecmp(colname, "callerid_num")) {
11988 ast_copy_string(buf, peer->cid_num, len);
11989 } else if (!strcasecmp(colname, "codecs")) {
11990 ast_getformatname_multiple(buf, len -1, peer->capability);
11991 } else if (!strncasecmp(colname, "codec[", 6)) {
11992 char *codecnum, *ptr;
11993 int codec = 0;
11994
11995 codecnum = strchr(colname, '[');
11996 *codecnum = '\0';
11997 codecnum++;
11998 if ((ptr = strchr(codecnum, ']'))) {
11999 *ptr = '\0';
12000 }
12001 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
12002 ast_copy_string(buf, ast_getformatname(codec), len);
12003 } else {
12004 buf[0] = '\0';
12005 }
12006 } else {
12007 buf[0] = '\0';
12008 }
12009
12010 peer_unref(peer);
12011
12012 return 0;
12013 }
12014
12015 struct ast_custom_function iaxpeer_function = {
12016 .name = "IAXPEER",
12017 .synopsis = "Gets IAX peer information",
12018 .syntax = "IAXPEER(<peername|CURRENTCHANNEL>[,item])",
12019 .read = function_iaxpeer,
12020 .desc = "If peername specified, valid items are:\n"
12021 "- ip (default) The IP address.\n"
12022 "- status The peer's status (if qualify=yes)\n"
12023 "- mailbox The configured mailbox.\n"
12024 "- context The configured context.\n"
12025 "- expire The epoch time of the next expire.\n"
12026 "- dynamic Is it dynamic? (yes/no).\n"
12027 "- callerid_name The configured Caller ID name.\n"
12028 "- callerid_num The configured Caller ID number.\n"
12029 "- codecs The configured codecs.\n"
12030 "- codec[x] Preferred codec index number 'x' (beginning with zero).\n"
12031 "\n"
12032 "If CURRENTCHANNEL specified, returns IP address of current channel\n"
12033 "\n"
12034 };
12035
12036 static int acf_channel_write(struct ast_channel *chan, const char *function, char *args, const char *value)
12037 {
12038 struct chan_iax2_pvt *pvt;
12039 unsigned int callno;
12040 int res = 0;
12041
12042 if (!chan || chan->tech != &iax2_tech) {
12043 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
12044 return -1;
12045 }
12046
12047 callno = PTR_TO_CALLNO(chan->tech_pvt);
12048 ast_mutex_lock(&iaxsl[callno]);
12049 if (!(pvt = iaxs[callno])) {
12050 ast_mutex_unlock(&iaxsl[callno]);
12051 return -1;
12052 }
12053
12054 if (!strcasecmp(args, "osptoken"))
12055 ast_string_field_set(pvt, osptoken, value);
12056 else
12057 res = -1;
12058
12059 ast_mutex_unlock(&iaxsl[callno]);
12060
12061 return res;
12062 }
12063
12064 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
12065 {
12066 struct chan_iax2_pvt *pvt;
12067 unsigned int callno;
12068 int res = 0;
12069
12070 if (!chan || chan->tech != &iax2_tech) {
12071 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
12072 return -1;
12073 }
12074
12075 callno = PTR_TO_CALLNO(chan->tech_pvt);
12076 ast_mutex_lock(&iaxsl[callno]);
12077 if (!(pvt = iaxs[callno])) {
12078 ast_mutex_unlock(&iaxsl[callno]);
12079 return -1;
12080 }
12081
12082 if (!strcasecmp(args, "osptoken")) {
12083 ast_copy_string(buf, pvt->osptoken, buflen);
12084 } else if (!strcasecmp(args, "peerip")) {
12085 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
12086 } else if (!strcasecmp(args, "peername")) {
12087 ast_copy_string(buf, pvt->username, buflen);
12088 } else {
12089 res = -1;
12090 }
12091
12092 ast_mutex_unlock(&iaxsl[callno]);
12093
12094 return res;
12095 }
12096
12097
12098 static int iax2_devicestate(void *data)
12099 {
12100 struct parsed_dial_string pds;
12101 char *tmp = ast_strdupa(data);
12102 struct iax2_peer *p;
12103 int res = AST_DEVICE_INVALID;
12104
12105 memset(&pds, 0, sizeof(pds));
12106 parse_dial_string(tmp, &pds);
12107
12108 if (ast_strlen_zero(pds.peer)) {
12109 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12110 return res;
12111 }
12112
12113 ast_debug(3, "Checking device state for device %s\n", pds.peer);
12114
12115
12116 if (!(p = find_peer(pds.peer, 1)))
12117 return res;
12118
12119 res = AST_DEVICE_UNAVAILABLE;
12120 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
12121 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
12122
12123 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) &&
12124 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
12125
12126
12127 if (p->historicms == 0 || p->historicms <= p->maxms)
12128
12129 res = AST_DEVICE_UNKNOWN;
12130 }
12131
12132 peer_unref(p);
12133
12134 return res;
12135 }
12136
12137 static struct ast_switch iax2_switch =
12138 {
12139 name: "IAX2",
12140 description: "IAX Remote Dialplan Switch",
12141 exists: iax2_exists,
12142 canmatch: iax2_canmatch,
12143 exec: iax2_exec,
12144 matchmore: iax2_matchmore,
12145 };
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251 static struct ast_cli_entry cli_iax2[] = {
12252 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
12253 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
12254 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
12255 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
12256 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
12257 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
12258 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
12259 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
12260 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
12261 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
12262 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
12263 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
12264 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
12265 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
12266 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
12267 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
12268 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
12269 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
12270 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
12271 #ifdef IAXTESTS
12272 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
12273 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
12274 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
12275 #endif
12276 };
12277
12278 static int __unload_module(void)
12279 {
12280 struct iax2_thread *thread = NULL;
12281 struct ast_context *con;
12282 int x;
12283
12284
12285
12286
12287
12288 if (netthreadid != AST_PTHREADT_NULL) {
12289 AST_LIST_LOCK(&frame_queue);
12290 ast_mutex_lock(&sched_lock);
12291 pthread_cancel(netthreadid);
12292 ast_cond_signal(&sched_cond);
12293 ast_mutex_unlock(&sched_lock);
12294 AST_LIST_UNLOCK(&frame_queue);
12295 pthread_join(netthreadid, NULL);
12296 }
12297 if (schedthreadid != AST_PTHREADT_NULL) {
12298 ast_mutex_lock(&sched_lock);
12299 pthread_cancel(schedthreadid);
12300 ast_cond_signal(&sched_cond);
12301 ast_mutex_unlock(&sched_lock);
12302 pthread_join(schedthreadid, NULL);
12303 }
12304
12305
12306 AST_LIST_LOCK(&idle_list);
12307 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list)))
12308 pthread_cancel(thread->threadid);
12309 AST_LIST_UNLOCK(&idle_list);
12310
12311 AST_LIST_LOCK(&active_list);
12312 while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list)))
12313 pthread_cancel(thread->threadid);
12314 AST_LIST_UNLOCK(&active_list);
12315
12316 AST_LIST_LOCK(&dynamic_list);
12317 while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list)))
12318 pthread_cancel(thread->threadid);
12319 AST_LIST_UNLOCK(&dynamic_list);
12320
12321
12322 while(0 < iaxactivethreadcount)
12323 usleep(10000);
12324
12325 ast_netsock_release(netsock);
12326 ast_netsock_release(outsock);
12327 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
12328 if (iaxs[x]) {
12329 iax2_destroy(x);
12330 }
12331 }
12332 ast_manager_unregister( "IAXpeers" );
12333 ast_manager_unregister( "IAXpeerlist" );
12334 ast_manager_unregister( "IAXnetstats" );
12335 ast_unregister_application(papp);
12336 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12337 ast_unregister_switch(&iax2_switch);
12338 ast_channel_unregister(&iax2_tech);
12339 delete_users();
12340 iax_provision_unload();
12341 sched_context_destroy(sched);
12342 reload_firmware(1);
12343
12344 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12345 ast_mutex_destroy(&iaxsl[x]);
12346 }
12347
12348 ao2_ref(peers, -1);
12349 ao2_ref(users, -1);
12350 ao2_ref(iax_peercallno_pvts, -1);
12351 ao2_ref(iax_transfercallno_pvts, -1);
12352 if (timer) {
12353 ast_timer_close(timer);
12354 }
12355
12356 con = ast_context_find(regcontext);
12357 if (con)
12358 ast_context_destroy(con, "IAX2");
12359 ast_unload_realtime("iaxpeers");
12360 return 0;
12361 }
12362
12363 static int unload_module(void)
12364 {
12365 ast_custom_function_unregister(&iaxpeer_function);
12366 ast_custom_function_unregister(&iaxvar_function);
12367 return __unload_module();
12368 }
12369
12370 static int peer_set_sock_cb(void *obj, void *arg, int flags)
12371 {
12372 struct iax2_peer *peer = obj;
12373
12374 if (peer->sockfd < 0)
12375 peer->sockfd = defaultsockfd;
12376
12377 return 0;
12378 }
12379
12380 static int pvt_hash_cb(const void *obj, const int flags)
12381 {
12382 const struct chan_iax2_pvt *pvt = obj;
12383
12384 return pvt->peercallno;
12385 }
12386
12387 static int pvt_cmp_cb(void *obj, void *arg, int flags)
12388 {
12389 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12390
12391
12392
12393
12394 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
12395 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12396 }
12397
12398 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
12399 {
12400 const struct chan_iax2_pvt *pvt = obj;
12401
12402 return pvt->transfercallno;
12403 }
12404
12405 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
12406 {
12407 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
12408
12409
12410
12411
12412 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
12413 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
12414 }
12415
12416 static int load_module(void)
12417 {
12418 char *config = "iax.conf";
12419 int x = 0;
12420 struct iax2_registry *reg = NULL;
12421
12422 peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb);
12423 if (!peers)
12424 return AST_MODULE_LOAD_FAILURE;
12425 users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb);
12426 if (!users) {
12427 ao2_ref(peers, -1);
12428 return AST_MODULE_LOAD_FAILURE;
12429 }
12430 iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb);
12431 if (!iax_peercallno_pvts) {
12432 ao2_ref(peers, -1);
12433 ao2_ref(users, -1);
12434 return AST_MODULE_LOAD_FAILURE;
12435 }
12436 iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb);
12437 if (!iax_transfercallno_pvts) {
12438 ao2_ref(peers, -1);
12439 ao2_ref(users, -1);
12440 ao2_ref(iax_peercallno_pvts, -1);
12441 return AST_MODULE_LOAD_FAILURE;
12442 }
12443 ast_custom_function_register(&iaxpeer_function);
12444 ast_custom_function_register(&iaxvar_function);
12445
12446 iax_set_output(iax_debug_output);
12447 iax_set_error(iax_error_output);
12448 jb_setoutput(jb_error_output, jb_warning_output, NULL);
12449
12450 memset(iaxs, 0, sizeof(iaxs));
12451
12452 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
12453 ast_mutex_init(&iaxsl[x]);
12454 }
12455
12456 ast_cond_init(&sched_cond, NULL);
12457
12458 if (!(sched = sched_context_create())) {
12459 ast_log(LOG_ERROR, "Failed to create scheduler context\n");
12460 return AST_MODULE_LOAD_FAILURE;
12461 }
12462
12463 if (!(io = io_context_create())) {
12464 ast_log(LOG_ERROR, "Failed to create I/O context\n");
12465 sched_context_destroy(sched);
12466 return AST_MODULE_LOAD_FAILURE;
12467 }
12468
12469 if (!(netsock = ast_netsock_list_alloc())) {
12470 ast_log(LOG_ERROR, "Failed to create netsock list\n");
12471 io_context_destroy(io);
12472 sched_context_destroy(sched);
12473 return AST_MODULE_LOAD_FAILURE;
12474 }
12475 ast_netsock_init(netsock);
12476
12477 outsock = ast_netsock_list_alloc();
12478 if (!outsock) {
12479 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
12480 io_context_destroy(io);
12481 sched_context_destroy(sched);
12482 return AST_MODULE_LOAD_FAILURE;
12483 }
12484 ast_netsock_init(outsock);
12485
12486 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry));
12487
12488 ast_register_application(papp, iax2_prov_app, psyn, pdescrip);
12489
12490 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" );
12491 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" );
12492 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" );
12493
12494 if ((timer = ast_timer_open())) {
12495 ast_timer_set_rate(timer, trunkfreq);
12496 }
12497
12498 if (set_config(config, 0) == -1) {
12499 return AST_MODULE_LOAD_DECLINE;
12500 }
12501
12502 if (ast_channel_register(&iax2_tech)) {
12503 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
12504 __unload_module();
12505 return AST_MODULE_LOAD_FAILURE;
12506 }
12507
12508 if (ast_register_switch(&iax2_switch))
12509 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
12510
12511 if (start_network_thread()) {
12512 ast_log(LOG_ERROR, "Unable to start network thread\n");
12513 __unload_module();
12514 return AST_MODULE_LOAD_FAILURE;
12515 } else
12516 ast_verb(2, "IAX Ready and Listening\n");
12517
12518 AST_LIST_LOCK(®istrations);
12519 AST_LIST_TRAVERSE(®istrations, reg, entry)
12520 iax2_do_register(reg);
12521 AST_LIST_UNLOCK(®istrations);
12522
12523 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
12524 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
12525
12526
12527 reload_firmware(0);
12528 iax_provision_reload(0);
12529
12530 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
12531
12532 return AST_MODULE_LOAD_SUCCESS;
12533 }
12534
12535 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Inter Asterisk eXchange (Ver 2)",
12536 .load = load_module,
12537 .unload = unload_module,
12538 .reload = reload,
12539 );