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
00038
00039 #include "asterisk.h"
00040
00041 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 348735 $")
00042
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <strings.h>
00054 #include <netdb.h>
00055 #include <fcntl.h>
00056 #include <sys/stat.h>
00057 #include <regex.h>
00058
00059 #include "asterisk/paths.h"
00060
00061 #include "asterisk/lock.h"
00062 #include "asterisk/frame.h"
00063 #include "asterisk/channel.h"
00064 #include "asterisk/module.h"
00065 #include "asterisk/pbx.h"
00066 #include "asterisk/sched.h"
00067 #include "asterisk/io.h"
00068 #include "asterisk/config.h"
00069 #include "asterisk/cli.h"
00070 #include "asterisk/translate.h"
00071 #include "asterisk/md5.h"
00072 #include "asterisk/cdr.h"
00073 #include "asterisk/crypto.h"
00074 #include "asterisk/acl.h"
00075 #include "asterisk/manager.h"
00076 #include "asterisk/callerid.h"
00077 #include "asterisk/app.h"
00078 #include "asterisk/astdb.h"
00079 #include "asterisk/musiconhold.h"
00080 #include "asterisk/features.h"
00081 #include "asterisk/utils.h"
00082 #include "asterisk/causes.h"
00083 #include "asterisk/localtime.h"
00084 #include "asterisk/dnsmgr.h"
00085 #include "asterisk/devicestate.h"
00086 #include "asterisk/netsock.h"
00087 #include "asterisk/stringfields.h"
00088 #include "asterisk/linkedlists.h"
00089 #include "asterisk/event.h"
00090 #include "asterisk/astobj2.h"
00091 #include "asterisk/timing.h"
00092 #include "asterisk/taskprocessor.h"
00093 #include "asterisk/test.h"
00094 #include "asterisk/data.h"
00095 #include "asterisk/netsock2.h"
00096
00097 #include "iax2.h"
00098 #include "iax2-parser.h"
00099 #include "iax2-provision.h"
00100 #include "jitterbuf.h"
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 #define SCHED_MULTITHREADED
00228
00229
00230
00231 #define DEBUG_SCHED_MULTITHREAD
00232
00233
00234 #ifdef SO_NO_CHECK
00235 static int nochecksums = 0;
00236 #endif
00237
00238 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00239 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00240
00241 #define DEFAULT_THREAD_COUNT 10
00242 #define DEFAULT_MAX_THREAD_COUNT 100
00243 #define DEFAULT_RETRY_TIME 1000
00244 #define MEMORY_SIZE 100
00245 #define DEFAULT_DROP 3
00246
00247 #define DEBUG_SUPPORT
00248
00249 #define MIN_REUSE_TIME 60
00250
00251
00252 #define GAMMA (0.01)
00253
00254 static struct ast_codec_pref prefs;
00255
00256 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00257
00258
00259
00260
00261 #define MAX_TRUNK_MTU 1240
00262
00263 static int global_max_trunk_mtu;
00264 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00265
00266 #define DEFAULT_CONTEXT "default"
00267
00268 static char default_parkinglot[AST_MAX_CONTEXT];
00269
00270 static char language[MAX_LANGUAGE] = "";
00271 static char regcontext[AST_MAX_CONTEXT] = "";
00272
00273 static struct ast_event_sub *network_change_event_subscription;
00274 static int network_change_event_sched_id = -1;
00275
00276 static int maxauthreq = 3;
00277 static int max_retries = 4;
00278 static int ping_time = 21;
00279 static int lagrq_time = 10;
00280 static int maxjitterbuffer=1000;
00281 static int resyncthreshold=1000;
00282 static int maxjitterinterps=10;
00283 static int jittertargetextra = 40;
00284
00285 #define MAX_TRUNKDATA 640 * 200
00286
00287 static int trunkfreq = 20;
00288 static int trunkmaxsize = MAX_TRUNKDATA;
00289
00290 static int authdebug = 1;
00291 static int autokill = 0;
00292 static int iaxcompat = 0;
00293 static int last_authmethod = 0;
00294
00295 static int iaxdefaultdpcache=10 * 60;
00296
00297 static int iaxdefaulttimeout = 5;
00298
00299 static struct {
00300 unsigned int tos;
00301 unsigned int cos;
00302 } qos = { 0, 0 };
00303
00304 static int min_reg_expire;
00305 static int max_reg_expire;
00306
00307 static int srvlookup = 0;
00308
00309 static struct ast_timer *timer;
00310
00311 static struct ast_netsock_list *netsock;
00312 static struct ast_netsock_list *outsock;
00313 static int defaultsockfd = -1;
00314
00315 static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00316
00317
00318 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00319
00320 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00321 ~AST_FORMAT_SLINEAR & \
00322 ~AST_FORMAT_SLINEAR16 & \
00323 ~AST_FORMAT_SIREN7 & \
00324 ~AST_FORMAT_SIREN14 & \
00325 ~AST_FORMAT_G719 & \
00326 ~AST_FORMAT_ULAW & \
00327 ~AST_FORMAT_ALAW & \
00328 ~AST_FORMAT_G722)
00329
00330 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00331 ~AST_FORMAT_G726 & \
00332 ~AST_FORMAT_G726_AAL2 & \
00333 ~AST_FORMAT_ADPCM)
00334
00335 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00336 ~AST_FORMAT_G723_1)
00337
00338
00339 #define DEFAULT_MAXMS 2000
00340 #define DEFAULT_FREQ_OK 60 * 1000
00341 #define DEFAULT_FREQ_NOTOK 10 * 1000
00342
00343
00344 #define IAX_CALLENCRYPTED(pvt) \
00345 (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
00346
00347 #define IAX_DEBUGDIGEST(msg, key) do { \
00348 int idx; \
00349 char digest[33] = ""; \
00350 \
00351 if (!iaxdebug) \
00352 break; \
00353 \
00354 for (idx = 0; idx < 16; idx++) \
00355 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00356 \
00357 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00358 } while(0)
00359
00360 static struct io_context *io;
00361 static struct ast_sched_thread *sched;
00362
00363 #define DONT_RESCHEDULE -2
00364
00365 static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00366
00367 static int iaxdebug = 0;
00368
00369 static int iaxtrunkdebug = 0;
00370
00371 static int test_losspct = 0;
00372 #ifdef IAXTESTS
00373 static int test_late = 0;
00374 static int test_resync = 0;
00375 static int test_jit = 0;
00376 static int test_jitpct = 0;
00377 #endif
00378
00379 static char accountcode[AST_MAX_ACCOUNT_CODE];
00380 static char mohinterpret[MAX_MUSICCLASS];
00381 static char mohsuggest[MAX_MUSICCLASS];
00382 static int amaflags = 0;
00383 static int adsi = 0;
00384 static int delayreject = 0;
00385 static int iax2_encryption = 0;
00386
00387 static struct ast_flags64 globalflags = { 0 };
00388
00389 static pthread_t netthreadid = AST_PTHREADT_NULL;
00390
00391 enum iax2_state {
00392 IAX_STATE_STARTED = (1 << 0),
00393 IAX_STATE_AUTHENTICATED = (1 << 1),
00394 IAX_STATE_TBD = (1 << 2),
00395 };
00396
00397 struct iax2_context {
00398 char context[AST_MAX_CONTEXT];
00399 struct iax2_context *next;
00400 };
00401
00402
00403 #define IAX_HASCALLERID (uint64_t)(1 << 0)
00404 #define IAX_DELME (uint64_t)(1 << 1)
00405 #define IAX_TEMPONLY (uint64_t)(1 << 2)
00406 #define IAX_TRUNK (uint64_t)(1 << 3)
00407 #define IAX_NOTRANSFER (uint64_t)(1 << 4)
00408 #define IAX_USEJITTERBUF (uint64_t)(1 << 5)
00409 #define IAX_DYNAMIC (uint64_t)(1 << 6)
00410 #define IAX_SENDANI (uint64_t)(1 << 7)
00411 #define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8)
00412 #define IAX_ALREADYGONE (uint64_t)(1 << 9)
00413 #define IAX_PROVISION (uint64_t)(1 << 10)
00414 #define IAX_QUELCH (uint64_t)(1 << 11)
00415 #define IAX_ENCRYPTED (uint64_t)(1 << 12)
00416 #define IAX_KEYPOPULATED (uint64_t)(1 << 13)
00417 #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14)
00418 #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15)
00419 #define IAX_CODEC_NOCAP (uint64_t)(1 << 16)
00420 #define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17)
00421 #define IAX_RTUPDATE (uint64_t)(1 << 18)
00422 #define IAX_RTAUTOCLEAR (uint64_t)(1 << 19)
00423 #define IAX_FORCEJITTERBUF (uint64_t)(1 << 20)
00424 #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21)
00425 #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22)
00426 #define IAX_TRANSFERMEDIA (uint64_t)(1 << 23)
00427 #define IAX_MAXAUTHREQ (uint64_t)(1 << 24)
00428 #define IAX_DELAYPBXSTART (uint64_t)(1 << 25)
00429 #define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26)
00430 #define IAX_IMMEDIATE (uint64_t)(1 << 27)
00431 #define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28)
00432 #define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29)
00433 #define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30)
00434 #define IAX_SHRINKCALLERID (uint64_t)(1 << 31)
00435 static int global_rtautoclear = 120;
00436
00437 static int reload_config(void);
00438
00439
00440
00441
00442 enum calltoken_peer_enum {
00443
00444 CALLTOKEN_DEFAULT = 0,
00445
00446 CALLTOKEN_YES = 1,
00447
00448
00449 CALLTOKEN_AUTO = 2,
00450
00451 CALLTOKEN_NO = 3,
00452 };
00453
00454 struct iax2_user {
00455 AST_DECLARE_STRING_FIELDS(
00456 AST_STRING_FIELD(name);
00457 AST_STRING_FIELD(secret);
00458 AST_STRING_FIELD(dbsecret);
00459 AST_STRING_FIELD(accountcode);
00460 AST_STRING_FIELD(mohinterpret);
00461 AST_STRING_FIELD(mohsuggest);
00462 AST_STRING_FIELD(inkeys);
00463 AST_STRING_FIELD(language);
00464 AST_STRING_FIELD(cid_num);
00465 AST_STRING_FIELD(cid_name);
00466 AST_STRING_FIELD(parkinglot);
00467 );
00468
00469 int authmethods;
00470 int encmethods;
00471 int amaflags;
00472 int adsi;
00473 uint64_t flags;
00474 format_t capability;
00475 int maxauthreq;
00476 int curauthreq;
00477 struct ast_codec_pref prefs;
00478 struct ast_ha *ha;
00479 struct iax2_context *contexts;
00480 struct ast_variable *vars;
00481 enum calltoken_peer_enum calltoken_required;
00482 };
00483
00484 struct iax2_peer {
00485 AST_DECLARE_STRING_FIELDS(
00486 AST_STRING_FIELD(name);
00487 AST_STRING_FIELD(username);
00488 AST_STRING_FIELD(secret);
00489 AST_STRING_FIELD(dbsecret);
00490 AST_STRING_FIELD(outkey);
00491
00492 AST_STRING_FIELD(regexten);
00493 AST_STRING_FIELD(context);
00494 AST_STRING_FIELD(peercontext);
00495 AST_STRING_FIELD(mailbox);
00496 AST_STRING_FIELD(mohinterpret);
00497 AST_STRING_FIELD(mohsuggest);
00498 AST_STRING_FIELD(inkeys);
00499
00500 AST_STRING_FIELD(cid_num);
00501 AST_STRING_FIELD(cid_name);
00502 AST_STRING_FIELD(zonetag);
00503 AST_STRING_FIELD(parkinglot);
00504 );
00505 struct ast_codec_pref prefs;
00506 struct ast_dnsmgr_entry *dnsmgr;
00507 struct ast_sockaddr addr;
00508 int formats;
00509 int sockfd;
00510 struct in_addr mask;
00511 int adsi;
00512 uint64_t flags;
00513
00514
00515 struct sockaddr_in defaddr;
00516 int authmethods;
00517 int encmethods;
00518
00519 int expire;
00520 int expiry;
00521 format_t capability;
00522
00523
00524 int callno;
00525 int pokeexpire;
00526 int lastms;
00527 int maxms;
00528
00529 int pokefreqok;
00530 int pokefreqnotok;
00531 int historicms;
00532 int smoothing;
00533 uint16_t maxcallno;
00534
00535 struct ast_event_sub *mwi_event_sub;
00536
00537 struct ast_ha *ha;
00538 enum calltoken_peer_enum calltoken_required;
00539 };
00540
00541 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00542
00543 struct iax2_trunk_peer {
00544 ast_mutex_t lock;
00545 int sockfd;
00546 struct sockaddr_in addr;
00547 struct timeval txtrunktime;
00548 struct timeval rxtrunktime;
00549 struct timeval lasttxtime;
00550 struct timeval trunkact;
00551 unsigned int lastsent;
00552
00553 unsigned char *trunkdata;
00554 unsigned int trunkdatalen;
00555 unsigned int trunkdataalloc;
00556 int trunkmaxmtu;
00557 int trunkerror;
00558 int calls;
00559 AST_LIST_ENTRY(iax2_trunk_peer) list;
00560 };
00561
00562 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00563
00564 struct iax_firmware {
00565 AST_LIST_ENTRY(iax_firmware) list;
00566 int fd;
00567 int mmaplen;
00568 int dead;
00569 struct ast_iax2_firmware_header *fwh;
00570 unsigned char *buf;
00571 };
00572
00573 enum iax_reg_state {
00574 REG_STATE_UNREGISTERED = 0,
00575 REG_STATE_REGSENT,
00576 REG_STATE_AUTHSENT,
00577 REG_STATE_REGISTERED,
00578 REG_STATE_REJECTED,
00579 REG_STATE_TIMEOUT,
00580 REG_STATE_NOAUTH
00581 };
00582
00583 enum iax_transfer_state {
00584 TRANSFER_NONE = 0,
00585 TRANSFER_BEGIN,
00586 TRANSFER_READY,
00587 TRANSFER_RELEASED,
00588 TRANSFER_PASSTHROUGH,
00589 TRANSFER_MBEGIN,
00590 TRANSFER_MREADY,
00591 TRANSFER_MRELEASED,
00592 TRANSFER_MPASSTHROUGH,
00593 TRANSFER_MEDIA,
00594 TRANSFER_MEDIAPASS
00595 };
00596
00597 struct iax2_registry {
00598 struct ast_sockaddr addr;
00599 char username[80];
00600 char secret[80];
00601 int expire;
00602 int refresh;
00603 enum iax_reg_state regstate;
00604 int messages;
00605 int callno;
00606 struct sockaddr_in us;
00607 struct ast_dnsmgr_entry *dnsmgr;
00608 AST_LIST_ENTRY(iax2_registry) entry;
00609 };
00610
00611 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00612
00613
00614 #define MIN_RETRY_TIME 100
00615 #define MAX_RETRY_TIME 10000
00616
00617 #define MAX_JITTER_BUFFER 50
00618 #define MIN_JITTER_BUFFER 10
00619
00620 #define DEFAULT_TRUNKDATA 640 * 10
00621
00622 #define MAX_TIMESTAMP_SKEW 160
00623
00624
00625 #define TS_GAP_FOR_JB_RESYNC 5000
00626
00627
00628 #define MARK_IAX_SUBCLASS_TX 0x8000
00629
00630 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00631 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00632 static int iaxdynamicthreadcount = 0;
00633 static int iaxdynamicthreadnum = 0;
00634 static int iaxactivethreadcount = 0;
00635
00636 struct iax_rr {
00637 int jitter;
00638 int losspct;
00639 int losscnt;
00640 int packets;
00641 int delay;
00642 int dropped;
00643 int ooo;
00644 };
00645
00646 struct iax2_pvt_ref;
00647
00648 struct chan_iax2_pvt {
00649
00650 int sockfd;
00651
00652 format_t voiceformat;
00653
00654 format_t videoformat;
00655
00656 format_t svoiceformat;
00657
00658 format_t svideoformat;
00659
00660 format_t capability;
00661
00662 unsigned int last;
00663
00664 unsigned int lastsent;
00665
00666 unsigned int lastvsent;
00667
00668 unsigned int nextpred;
00669
00670 int first_iax_message;
00671
00672 int last_iax_message;
00673
00674 unsigned int notsilenttx:1;
00675
00676 unsigned int pingtime;
00677
00678 int maxtime;
00679
00680 struct sockaddr_in addr;
00681
00682 struct ast_codec_pref prefs;
00683
00684 struct ast_codec_pref rprefs;
00685
00686 unsigned short callno;
00687
00688 struct callno_entry *callno_entry;
00689
00690 unsigned short peercallno;
00691
00692
00693
00694 format_t chosenformat;
00695
00696 format_t peerformat;
00697
00698 format_t peercapability;
00699
00700 struct timeval offset;
00701
00702 struct timeval rxcore;
00703
00704 jitterbuf *jb;
00705
00706 int jbid;
00707
00708 int lag;
00709
00710 int error;
00711
00712 struct ast_channel *owner;
00713
00714 struct ast_flags state;
00715
00716 int expiry;
00717
00718 unsigned char oseqno;
00719
00720 unsigned char rseqno;
00721
00722 unsigned char iseqno;
00723
00724 unsigned char aseqno;
00725
00726 AST_DECLARE_STRING_FIELDS(
00727
00728 AST_STRING_FIELD(peer);
00729
00730 AST_STRING_FIELD(context);
00731
00732 AST_STRING_FIELD(cid_num);
00733 AST_STRING_FIELD(cid_name);
00734
00735 AST_STRING_FIELD(ani);
00736
00737 AST_STRING_FIELD(dnid);
00738
00739 AST_STRING_FIELD(rdnis);
00740
00741 AST_STRING_FIELD(exten);
00742
00743 AST_STRING_FIELD(username);
00744
00745 AST_STRING_FIELD(secret);
00746
00747 AST_STRING_FIELD(challenge);
00748
00749 AST_STRING_FIELD(inkeys);
00750
00751 AST_STRING_FIELD(outkey);
00752
00753 AST_STRING_FIELD(language);
00754
00755 AST_STRING_FIELD(host);
00756
00757 AST_STRING_FIELD(dproot);
00758 AST_STRING_FIELD(accountcode);
00759 AST_STRING_FIELD(mohinterpret);
00760 AST_STRING_FIELD(mohsuggest);
00761
00762 AST_STRING_FIELD(osptoken);
00763
00764 AST_STRING_FIELD(parkinglot);
00765 );
00766
00767 int authrej;
00768
00769 int authmethods;
00770
00771 int encmethods;
00772
00773 ast_aes_encrypt_key ecx;
00774
00775 ast_aes_decrypt_key mydcx;
00776
00777 ast_aes_decrypt_key dcx;
00778
00779
00780 int keyrotateid;
00781
00782 unsigned char semirand[32];
00783
00784 struct iax2_registry *reg;
00785
00786 struct iax2_peer *peerpoke;
00787
00788 uint64_t flags;
00789 int adsi;
00790
00791
00792 enum iax_transfer_state transferring;
00793
00794 int transferid;
00795
00796 struct sockaddr_in transfer;
00797
00798 unsigned short transfercallno;
00799
00800 ast_aes_encrypt_key tdcx;
00801
00802
00803 int peeradsicpe;
00804
00805
00806 unsigned short bridgecallno;
00807
00808 int pingid;
00809 int lagid;
00810 int autoid;
00811 int authid;
00812 int authfail;
00813 int initid;
00814 int calling_ton;
00815 int calling_tns;
00816 int calling_pres;
00817 int amaflags;
00818 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00819
00820 struct ast_variable *vars;
00821
00822 struct ast_variable *iaxvars;
00823
00824 struct iax_rr remote_rr;
00825
00826 int min;
00827
00828 int frames_dropped;
00829
00830 int frames_received;
00831
00832 unsigned char calltoken_ie_len;
00833
00834 char hold_signaling;
00835
00836 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00837 };
00838
00839 struct signaling_queue_entry {
00840 struct ast_frame f;
00841 AST_LIST_ENTRY(signaling_queue_entry) next;
00842 };
00843
00844
00845 static struct ao2_container *callno_pool;
00846
00847
00848 static struct ao2_container *callno_pool_trunk;
00849
00850 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861 static AST_LIST_HEAD_NOLOCK(, iax_frame) frame_queue[IAX_MAX_CALLS + 1];
00862
00863 static struct ast_taskprocessor *transmit_processor;
00864
00865 static int randomcalltokendata;
00866
00867 static const time_t MAX_CALLTOKEN_DELAY = 10;
00868
00869
00870
00871
00872
00873
00874
00875
00876 #ifdef LOW_MEMORY
00877 #define MAX_PEER_BUCKETS 17
00878 #else
00879 #define MAX_PEER_BUCKETS 563
00880 #endif
00881 static struct ao2_container *peers;
00882
00883 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00884 static struct ao2_container *users;
00885
00886
00887 static struct ao2_container *peercnts;
00888
00889
00890 static struct ao2_container *callno_limits;
00891
00892
00893 static struct ao2_container *calltoken_ignores;
00894
00895 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00896
00897 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00898
00899 static uint16_t global_maxcallno;
00900
00901
00902 static uint16_t global_maxcallno_nonval;
00903
00904 static uint16_t total_nonval_callno_used = 0;
00905
00906
00907
00908 struct peercnt {
00909
00910 unsigned long addr;
00911
00912 uint16_t cur;
00913
00914 uint16_t limit;
00915
00916
00917 unsigned char reg;
00918 };
00919
00920
00921 struct addr_range {
00922
00923 struct ast_ha ha;
00924
00925 uint16_t limit;
00926
00927 unsigned char delme;
00928 };
00929
00930 struct callno_entry {
00931
00932 uint16_t callno;
00933
00934 unsigned char validated;
00935 };
00936
00937 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00938
00939 enum {
00940
00941 CACHE_FLAG_EXISTS = (1 << 0),
00942
00943 CACHE_FLAG_NONEXISTENT = (1 << 1),
00944
00945 CACHE_FLAG_CANEXIST = (1 << 2),
00946
00947 CACHE_FLAG_PENDING = (1 << 3),
00948
00949 CACHE_FLAG_TIMEOUT = (1 << 4),
00950
00951 CACHE_FLAG_TRANSMITTED = (1 << 5),
00952
00953 CACHE_FLAG_UNKNOWN = (1 << 6),
00954
00955 CACHE_FLAG_MATCHMORE = (1 << 7),
00956 };
00957
00958 struct iax2_dpcache {
00959 char peercontext[AST_MAX_CONTEXT];
00960 char exten[AST_MAX_EXTENSION];
00961 struct timeval orig;
00962 struct timeval expiry;
00963 int flags;
00964 unsigned short callno;
00965 int waiters[256];
00966 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00967 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00968 };
00969
00970 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00971
00972 static void reg_source_db(struct iax2_peer *p);
00973 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00974 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00975
00976 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00977 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags);
00978 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00979
00980 enum iax2_thread_iostate {
00981 IAX_IOSTATE_IDLE,
00982 IAX_IOSTATE_READY,
00983 IAX_IOSTATE_PROCESSING,
00984 IAX_IOSTATE_SCHEDREADY,
00985 };
00986
00987 enum iax2_thread_type {
00988 IAX_THREAD_TYPE_POOL,
00989 IAX_THREAD_TYPE_DYNAMIC,
00990 };
00991
00992 struct iax2_pkt_buf {
00993 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00994 size_t len;
00995 unsigned char buf[1];
00996 };
00997
00998 struct iax2_thread {
00999 AST_LIST_ENTRY(iax2_thread) list;
01000 enum iax2_thread_type type;
01001 enum iax2_thread_iostate iostate;
01002 #ifdef SCHED_MULTITHREADED
01003 void (*schedfunc)(const void *);
01004 const void *scheddata;
01005 #endif
01006 #ifdef DEBUG_SCHED_MULTITHREAD
01007 char curfunc[80];
01008 #endif
01009 int actions;
01010 pthread_t threadid;
01011 int threadnum;
01012 struct sockaddr_in iosin;
01013 unsigned char readbuf[4096];
01014 unsigned char *buf;
01015 ssize_t buf_len;
01016 size_t buf_size;
01017 int iofd;
01018 time_t checktime;
01019 ast_mutex_t lock;
01020 ast_cond_t cond;
01021 ast_mutex_t init_lock;
01022 ast_cond_t init_cond;
01023
01024
01025
01026
01027 struct {
01028 unsigned short callno;
01029 struct sockaddr_in sin;
01030 unsigned char type;
01031 unsigned char csub;
01032 } ffinfo;
01033
01034
01035
01036 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
01037 unsigned char stop;
01038 };
01039
01040
01041 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
01042 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
01043 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
01044
01045 static void *iax2_process_thread(void *data);
01046 static void iax2_destroy(int callno);
01047
01048 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
01049 {
01050 ast_mutex_lock(lock);
01051 ast_cond_signal(cond);
01052 ast_mutex_unlock(lock);
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS + 1];
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 static struct ao2_container *iax_peercallno_pvts;
01075
01076
01077
01078
01079
01080
01081
01082
01083 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
01084
01085
01086
01087
01088
01089
01090 static struct ao2_container *iax_transfercallno_pvts;
01091
01092
01093
01094 #define TRUNK_CALL_START IAX_MAX_CALLS / 2
01095
01096
01097 static struct sockaddr_in debugaddr;
01098
01099 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
01100 {
01101 if (iaxdebug ||
01102 (sin && debugaddr.sin_addr.s_addr &&
01103 (!ntohs(debugaddr.sin_port) ||
01104 debugaddr.sin_port == sin->sin_port) &&
01105 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01106 if (iaxdebug) {
01107 iax_showframe(f, fhi, rx, sin, datalen);
01108 } else {
01109 iaxdebug = 1;
01110 iax_showframe(f, fhi, rx, sin, datalen);
01111 iaxdebug = 0;
01112 }
01113 }
01114 }
01115
01116 static void iax_debug_output(const char *data)
01117 {
01118 if (iaxdebug)
01119 ast_verbose("%s", data);
01120 }
01121
01122 static void iax_error_output(const char *data)
01123 {
01124 ast_log(LOG_WARNING, "%s", data);
01125 }
01126
01127 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
01128 {
01129 va_list args;
01130 char buf[1024];
01131
01132 va_start(args, fmt);
01133 vsnprintf(buf, sizeof(buf), fmt, args);
01134 va_end(args);
01135
01136 ast_log(LOG_ERROR, "%s", buf);
01137 }
01138
01139 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01140 {
01141 va_list args;
01142 char buf[1024];
01143
01144 va_start(args, fmt);
01145 vsnprintf(buf, sizeof(buf), fmt, args);
01146 va_end(args);
01147
01148 ast_log(LOG_WARNING, "%s", buf);
01149 }
01150
01151 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01152 {
01153 va_list args;
01154 char buf[1024];
01155
01156 va_start(args, fmt);
01157 vsnprintf(buf, sizeof(buf), fmt, args);
01158 va_end(args);
01159
01160 ast_verbose("%s", buf);
01161 }
01162
01163 static int maxtrunkcall = TRUNK_CALL_START;
01164 static int maxnontrunkcall = 1;
01165
01166 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);
01167 static int expire_registry(const void *data);
01168 static int iax2_answer(struct ast_channel *c);
01169 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01170 static int iax2_devicestate(void *data);
01171 static int iax2_digit_begin(struct ast_channel *c, char digit);
01172 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01173 static int iax2_do_register(struct iax2_registry *reg);
01174 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01175 static int iax2_hangup(struct ast_channel *c);
01176 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01177 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01178 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force);
01179 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01180 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01181 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01182 static int iax2_sendtext(struct ast_channel *c, const char *text);
01183 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01184 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen);
01185 static int iax2_transfer(struct ast_channel *c, const char *dest);
01186 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01187 static int iax2_sched_add(struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data);
01188
01189 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01190 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01191 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01192 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01193 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01194 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01195 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
01196 static struct ast_frame *iax2_read(struct ast_channel *c);
01197 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01198 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01199 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime);
01200 static void *iax2_dup_variable_datastore(void *);
01201 static void prune_peers(void);
01202 static void prune_users(void);
01203 static void iax2_free_variable_datastore(void *);
01204
01205 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01206 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01207 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01208 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01209 static void build_rand_pad(unsigned char *buf, ssize_t len);
01210 static struct callno_entry *get_unused_callno(int trunk, int validated);
01211 static int replace_callno(const void *obj);
01212 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01213 static void network_change_event_cb(const struct ast_event *, void *);
01214
01215 static const struct ast_channel_tech iax2_tech = {
01216 .type = "IAX2",
01217 .description = tdesc,
01218 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01219 .properties = AST_CHAN_TP_WANTSJITTER,
01220 .requester = iax2_request,
01221 .devicestate = iax2_devicestate,
01222 .send_digit_begin = iax2_digit_begin,
01223 .send_digit_end = iax2_digit_end,
01224 .send_text = iax2_sendtext,
01225 .send_image = iax2_sendimage,
01226 .send_html = iax2_sendhtml,
01227 .call = iax2_call,
01228 .hangup = iax2_hangup,
01229 .answer = iax2_answer,
01230 .read = iax2_read,
01231 .write = iax2_write,
01232 .write_video = iax2_write,
01233 .indicate = iax2_indicate,
01234 .setoption = iax2_setoption,
01235 .queryoption = iax2_queryoption,
01236 .bridge = iax2_bridge,
01237 .transfer = iax2_transfer,
01238 .fixup = iax2_fixup,
01239 .func_channel_read = acf_channel_read,
01240 };
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259 static void iax2_lock_owner(int callno)
01260 {
01261 for (;;) {
01262 if (!iaxs[callno] || !iaxs[callno]->owner) {
01263
01264 break;
01265 }
01266 if (!ast_channel_trylock(iaxs[callno]->owner)) {
01267
01268 break;
01269 }
01270
01271 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01272 }
01273 }
01274
01275 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01276 {
01277
01278
01279
01280 }
01281
01282 static void network_change_event_subscribe(void)
01283 {
01284 if (!network_change_event_subscription) {
01285 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE,
01286 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END);
01287 }
01288 }
01289
01290 static void network_change_event_unsubscribe(void)
01291 {
01292 if (network_change_event_subscription) {
01293 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription);
01294 }
01295 }
01296
01297 static int network_change_event_sched_cb(const void *data)
01298 {
01299 struct iax2_registry *reg;
01300 network_change_event_sched_id = -1;
01301 AST_LIST_LOCK(®istrations);
01302 AST_LIST_TRAVERSE(®istrations, reg, entry) {
01303 iax2_do_register(reg);
01304 }
01305 AST_LIST_UNLOCK(®istrations);
01306
01307 return 0;
01308 }
01309
01310 static void network_change_event_cb(const struct ast_event *event, void *userdata)
01311 {
01312 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n");
01313 if (network_change_event_sched_id == -1) {
01314 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
01315 }
01316
01317 }
01318
01319
01320
01321
01322 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01323 {
01324 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01325 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01326 pvt->owner ? pvt->owner->name : "",
01327 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01328 }
01329
01330 static struct ast_datastore_info iax2_variable_datastore_info = {
01331 .type = "IAX2_VARIABLE",
01332 .duplicate = iax2_dup_variable_datastore,
01333 .destroy = iax2_free_variable_datastore,
01334 };
01335
01336 static void *iax2_dup_variable_datastore(void *old)
01337 {
01338 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01339 struct ast_var_t *oldvar, *newvar;
01340
01341 newlist = ast_calloc(sizeof(*newlist), 1);
01342 if (!newlist) {
01343 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01344 return NULL;
01345 }
01346
01347 AST_LIST_HEAD_INIT(newlist);
01348 AST_LIST_LOCK(oldlist);
01349 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01350 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01351 if (newvar)
01352 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01353 else
01354 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01355 }
01356 AST_LIST_UNLOCK(oldlist);
01357 return newlist;
01358 }
01359
01360 static void iax2_free_variable_datastore(void *old)
01361 {
01362 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01363 struct ast_var_t *oldvar;
01364
01365 AST_LIST_LOCK(oldlist);
01366 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01367 ast_free(oldvar);
01368 }
01369 AST_LIST_UNLOCK(oldlist);
01370 AST_LIST_HEAD_DESTROY(oldlist);
01371 ast_free(oldlist);
01372 }
01373
01374
01375
01376
01377
01378 static void insert_idle_thread(struct iax2_thread *thread)
01379 {
01380 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01381 AST_LIST_LOCK(&dynamic_list);
01382 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01383 AST_LIST_UNLOCK(&dynamic_list);
01384 } else {
01385 AST_LIST_LOCK(&idle_list);
01386 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01387 AST_LIST_UNLOCK(&idle_list);
01388 }
01389
01390 return;
01391 }
01392
01393 static struct iax2_thread *find_idle_thread(void)
01394 {
01395 struct iax2_thread *thread = NULL;
01396
01397
01398 AST_LIST_LOCK(&idle_list);
01399 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01400 AST_LIST_UNLOCK(&idle_list);
01401
01402
01403 if (thread) {
01404 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01405 return thread;
01406 }
01407
01408
01409 AST_LIST_LOCK(&dynamic_list);
01410 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01411 AST_LIST_UNLOCK(&dynamic_list);
01412
01413
01414 if (thread) {
01415 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01416 return thread;
01417 }
01418
01419
01420 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01421 return NULL;
01422
01423
01424 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01425 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01426 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01427
01428
01429 ast_mutex_init(&thread->lock);
01430 ast_cond_init(&thread->cond, NULL);
01431 ast_mutex_init(&thread->init_lock);
01432 ast_cond_init(&thread->init_cond, NULL);
01433 ast_mutex_lock(&thread->init_lock);
01434
01435
01436 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01437 ast_cond_destroy(&thread->cond);
01438 ast_mutex_destroy(&thread->lock);
01439 ast_mutex_unlock(&thread->init_lock);
01440 ast_cond_destroy(&thread->init_cond);
01441 ast_mutex_destroy(&thread->init_lock);
01442 ast_free(thread);
01443 return NULL;
01444 }
01445
01446
01447
01448 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01449
01450
01451 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01452
01453
01454 ast_mutex_unlock(&thread->init_lock);
01455
01456 return thread;
01457 }
01458
01459 #ifdef SCHED_MULTITHREADED
01460 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01461 {
01462 struct iax2_thread *thread = NULL;
01463 static time_t lasterror;
01464 static time_t t;
01465
01466 thread = find_idle_thread();
01467
01468 if (thread != NULL) {
01469 thread->schedfunc = func;
01470 thread->scheddata = data;
01471 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01472 #ifdef DEBUG_SCHED_MULTITHREAD
01473 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01474 #endif
01475 signal_condition(&thread->lock, &thread->cond);
01476 return 0;
01477 }
01478 time(&t);
01479 if (t != lasterror)
01480 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01481 lasterror = t;
01482
01483 return -1;
01484 }
01485 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01486 #endif
01487
01488 static int iax2_sched_replace(int id, struct ast_sched_thread *st, int when,
01489 ast_sched_cb callback, const void *data)
01490 {
01491 ast_sched_thread_del(st, id);
01492
01493 return ast_sched_thread_add(st, when, callback, data);
01494 }
01495
01496 static int iax2_sched_add(struct ast_sched_thread *st, int when,
01497 ast_sched_cb callback, const void *data)
01498 {
01499 return ast_sched_thread_add(st, when, callback, data);
01500 }
01501
01502 static int send_ping(const void *data);
01503
01504 static void __send_ping(const void *data)
01505 {
01506 int callno = (long) data;
01507
01508 ast_mutex_lock(&iaxsl[callno]);
01509
01510 if (iaxs[callno]) {
01511 if (iaxs[callno]->peercallno) {
01512 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01513 if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01514 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01515 }
01516 }
01517 } else {
01518 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01519 }
01520
01521 ast_mutex_unlock(&iaxsl[callno]);
01522 }
01523
01524 static int send_ping(const void *data)
01525 {
01526 int callno = (long) data;
01527 ast_mutex_lock(&iaxsl[callno]);
01528 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01529 iaxs[callno]->pingid = -1;
01530 }
01531 ast_mutex_unlock(&iaxsl[callno]);
01532
01533 #ifdef SCHED_MULTITHREADED
01534 if (schedule_action(__send_ping, data))
01535 #endif
01536 __send_ping(data);
01537
01538 return 0;
01539 }
01540
01541 static void encmethods_to_str(int e, struct ast_str *buf)
01542 {
01543 ast_str_set(&buf, 0, "(");
01544 if (e & IAX_ENCRYPT_AES128) {
01545 ast_str_append(&buf, 0, "aes128");
01546 }
01547 if (e & IAX_ENCRYPT_KEYROTATE) {
01548 ast_str_append(&buf, 0, ",keyrotate");
01549 }
01550 if (ast_str_strlen(buf) > 1) {
01551 ast_str_append(&buf, 0, ")");
01552 } else {
01553 ast_str_set(&buf, 0, "No");
01554 }
01555 }
01556
01557 static int get_encrypt_methods(const char *s)
01558 {
01559 int e;
01560 if (!strcasecmp(s, "aes128"))
01561 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01562 else if (ast_true(s))
01563 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01564 else
01565 e = 0;
01566 return e;
01567 }
01568
01569 static int send_lagrq(const void *data);
01570
01571 static void __send_lagrq(const void *data)
01572 {
01573 int callno = (long) data;
01574
01575 ast_mutex_lock(&iaxsl[callno]);
01576
01577 if (iaxs[callno]) {
01578 if (iaxs[callno]->peercallno) {
01579 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01580 if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01581 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01582 }
01583 }
01584 } else {
01585 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01586 }
01587
01588 ast_mutex_unlock(&iaxsl[callno]);
01589 }
01590
01591 static int send_lagrq(const void *data)
01592 {
01593 int callno = (long) data;
01594 ast_mutex_lock(&iaxsl[callno]);
01595 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01596 iaxs[callno]->lagid = -1;
01597 }
01598 ast_mutex_unlock(&iaxsl[callno]);
01599
01600 #ifdef SCHED_MULTITHREADED
01601 if (schedule_action(__send_lagrq, data))
01602 #endif
01603 __send_lagrq(data);
01604 return 0;
01605 }
01606
01607 static unsigned char compress_subclass(format_t subclass)
01608 {
01609 int x;
01610 int power=-1;
01611
01612 if (subclass < IAX_FLAG_SC_LOG)
01613 return subclass;
01614
01615 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01616 if (subclass & (1LL << x)) {
01617 if (power > -1) {
01618 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
01619 return 0;
01620 } else
01621 power = x;
01622 }
01623 }
01624 return power | IAX_FLAG_SC_LOG;
01625 }
01626
01627 static format_t uncompress_subclass(unsigned char csub)
01628 {
01629
01630 if (csub & IAX_FLAG_SC_LOG) {
01631
01632 if (csub == 0xff)
01633 return -1;
01634 else
01635 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01636 }
01637 else
01638 return csub;
01639 }
01640
01641
01642
01643
01644 static int peer_hash_cb(const void *obj, const int flags)
01645 {
01646 const struct iax2_peer *peer = obj;
01647
01648 return ast_str_hash(peer->name);
01649 }
01650
01651
01652
01653
01654 static int peer_cmp_cb(void *obj, void *arg, int flags)
01655 {
01656 struct iax2_peer *peer = obj, *peer2 = arg;
01657
01658 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01659 }
01660
01661
01662
01663
01664 static int user_hash_cb(const void *obj, const int flags)
01665 {
01666 const struct iax2_user *user = obj;
01667
01668 return ast_str_hash(user->name);
01669 }
01670
01671
01672
01673
01674 static int user_cmp_cb(void *obj, void *arg, int flags)
01675 {
01676 struct iax2_user *user = obj, *user2 = arg;
01677
01678 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01679 }
01680
01681
01682
01683
01684
01685 static struct iax2_peer *find_peer(const char *name, int realtime)
01686 {
01687 struct iax2_peer *peer = NULL;
01688 struct iax2_peer tmp_peer = {
01689 .name = name,
01690 };
01691
01692 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01693
01694
01695 if(!peer && realtime)
01696 peer = realtime_peer(name, NULL);
01697
01698 return peer;
01699 }
01700
01701 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01702 {
01703 ao2_ref(peer, +1);
01704 return peer;
01705 }
01706
01707 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01708 {
01709 ao2_ref(peer, -1);
01710 return NULL;
01711 }
01712
01713 static struct iax2_user *find_user(const char *name)
01714 {
01715 struct iax2_user tmp_user = {
01716 .name = name,
01717 };
01718
01719 return ao2_find(users, &tmp_user, OBJ_POINTER);
01720 }
01721 static inline struct iax2_user *user_ref(struct iax2_user *user)
01722 {
01723 ao2_ref(user, +1);
01724 return user;
01725 }
01726
01727 static inline struct iax2_user *user_unref(struct iax2_user *user)
01728 {
01729 ao2_ref(user, -1);
01730 return NULL;
01731 }
01732
01733 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01734 {
01735 struct iax2_peer *peer = NULL;
01736 int res = 0;
01737 struct ao2_iterator i;
01738
01739 i = ao2_iterator_init(peers, 0);
01740 while ((peer = ao2_iterator_next(&i))) {
01741 struct sockaddr_in peer_addr;
01742
01743 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
01744
01745 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01746 (peer_addr.sin_port == sin.sin_port)) {
01747 ast_copy_string(host, peer->name, len);
01748 peer_unref(peer);
01749 res = 1;
01750 break;
01751 }
01752 peer_unref(peer);
01753 }
01754 ao2_iterator_destroy(&i);
01755
01756 if (!peer) {
01757 peer = realtime_peer(NULL, &sin);
01758 if (peer) {
01759 ast_copy_string(host, peer->name, len);
01760 peer_unref(peer);
01761 res = 1;
01762 }
01763 }
01764
01765 return res;
01766 }
01767
01768
01769
01770 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01771 {
01772
01773 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
01774 struct iax2_user *user;
01775 struct iax2_user tmp_user = {
01776 .name = pvt->username,
01777 };
01778
01779 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01780 if (user) {
01781 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01782 user_unref(user);
01783 }
01784
01785 ast_clear_flag64(pvt, IAX_MAXAUTHREQ);
01786 }
01787
01788 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01789 pvt->pingid = DONT_RESCHEDULE;
01790 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01791 pvt->lagid = DONT_RESCHEDULE;
01792 ast_sched_thread_del(sched, pvt->autoid);
01793 ast_sched_thread_del(sched, pvt->authid);
01794 ast_sched_thread_del(sched, pvt->initid);
01795 ast_sched_thread_del(sched, pvt->jbid);
01796 ast_sched_thread_del(sched, pvt->keyrotateid);
01797 }
01798
01799 static void iax2_frame_free(struct iax_frame *fr)
01800 {
01801 ast_sched_thread_del(sched, fr->retrans);
01802 iax_frame_free(fr);
01803 }
01804
01805 static int scheduled_destroy(const void *vid)
01806 {
01807 unsigned short callno = PTR_TO_CALLNO(vid);
01808 ast_mutex_lock(&iaxsl[callno]);
01809 if (iaxs[callno]) {
01810 if (option_debug) {
01811 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01812 }
01813 iax2_destroy(callno);
01814 }
01815 ast_mutex_unlock(&iaxsl[callno]);
01816 return 0;
01817 }
01818
01819 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01820 {
01821 if (s->f.datalen) {
01822 ast_free(s->f.data.ptr);
01823 }
01824 ast_free(s);
01825 }
01826
01827
01828
01829 static void send_signaling(struct chan_iax2_pvt *pvt)
01830 {
01831 struct signaling_queue_entry *s = NULL;
01832
01833 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01834 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01835 free_signaling_queue_entry(s);
01836 }
01837 pvt->hold_signaling = 0;
01838 }
01839
01840
01841
01842 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01843 {
01844 struct signaling_queue_entry *new;
01845
01846 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01847 return 1;
01848 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01849 return -1;
01850 }
01851
01852 memcpy(&new->f, f, sizeof(new->f));
01853
01854 if (new->f.datalen) {
01855 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01856 free_signaling_queue_entry(new);
01857 return -1;
01858 }
01859 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01860 }
01861 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01862
01863 return 0;
01864 }
01865
01866 static void pvt_destructor(void *obj)
01867 {
01868 struct chan_iax2_pvt *pvt = obj;
01869 struct iax_frame *cur = NULL;
01870 struct signaling_queue_entry *s = NULL;
01871
01872 ast_mutex_lock(&iaxsl[pvt->callno]);
01873
01874 iax2_destroy_helper(pvt);
01875
01876 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01877 pvt->callno_entry = NULL;
01878
01879
01880 ast_set_flag64(pvt, IAX_ALREADYGONE);
01881
01882 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
01883
01884 cur->retries = -1;
01885 }
01886
01887 ast_mutex_unlock(&iaxsl[pvt->callno]);
01888
01889 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01890 free_signaling_queue_entry(s);
01891 }
01892
01893 if (pvt->reg) {
01894 pvt->reg->callno = 0;
01895 }
01896
01897 if (!pvt->owner) {
01898 jb_frame frame;
01899 if (pvt->vars) {
01900 ast_variables_destroy(pvt->vars);
01901 pvt->vars = NULL;
01902 }
01903
01904 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01905 iax2_frame_free(frame.data);
01906 }
01907
01908 jb_destroy(pvt->jb);
01909 ast_string_field_free_memory(pvt);
01910 }
01911 }
01912
01913 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01914 {
01915 struct chan_iax2_pvt *tmp;
01916 jb_conf jbconf;
01917
01918 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01919 return NULL;
01920 }
01921
01922 if (ast_string_field_init(tmp, 32)) {
01923 ao2_ref(tmp, -1);
01924 tmp = NULL;
01925 return NULL;
01926 }
01927
01928 tmp->prefs = prefs;
01929 tmp->pingid = -1;
01930 tmp->lagid = -1;
01931 tmp->autoid = -1;
01932 tmp->authid = -1;
01933 tmp->initid = -1;
01934 tmp->keyrotateid = -1;
01935
01936 ast_string_field_set(tmp,exten, "s");
01937 ast_string_field_set(tmp,host, host);
01938
01939 tmp->jb = jb_new();
01940 tmp->jbid = -1;
01941 jbconf.max_jitterbuf = maxjitterbuffer;
01942 jbconf.resync_threshold = resyncthreshold;
01943 jbconf.max_contig_interp = maxjitterinterps;
01944 jbconf.target_extra = jittertargetextra;
01945 jb_setconf(tmp->jb,&jbconf);
01946
01947 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01948
01949 tmp->hold_signaling = 1;
01950 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01951
01952 return tmp;
01953 }
01954
01955 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01956 {
01957 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01958 if (new) {
01959 size_t afdatalen = new->afdatalen;
01960 memcpy(new, fr, sizeof(*new));
01961 iax_frame_wrap(new, &fr->af);
01962 new->afdatalen = afdatalen;
01963 new->data = NULL;
01964 new->datalen = 0;
01965 new->direction = DIRECTION_INGRESS;
01966 new->retrans = -1;
01967 }
01968 return new;
01969 }
01970
01971
01972 enum {
01973
01974 NEW_PREVENT = 0,
01975
01976 NEW_ALLOW = 1,
01977
01978 NEW_FORCE = 2,
01979
01980
01981 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01982 };
01983
01984 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01985 {
01986 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01987 (cur->addr.sin_port == sin->sin_port)) {
01988
01989 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01990 (check_dcallno ? dcallno == cur->callno : 1) ) {
01991
01992 return 1;
01993 }
01994 }
01995 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01996 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01997
01998 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01999 return 1;
02000 }
02001 return 0;
02002 }
02003
02004 static void update_max_trunk(void)
02005 {
02006 int max = TRUNK_CALL_START;
02007 int x;
02008
02009
02010 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
02011 if (iaxs[x]) {
02012 max = x + 1;
02013 }
02014 }
02015
02016 maxtrunkcall = max;
02017 if (iaxdebug)
02018 ast_debug(1, "New max trunk callno is %d\n", max);
02019 }
02020
02021 static void update_max_nontrunk(void)
02022 {
02023 int max = 1;
02024 int x;
02025
02026 for (x=1;x<TRUNK_CALL_START - 1; x++) {
02027 if (iaxs[x])
02028 max = x + 1;
02029 }
02030 maxnontrunkcall = max;
02031 if (iaxdebug)
02032 ast_debug(1, "New max nontrunk callno is %d\n", max);
02033 }
02034
02035 static int make_trunk(unsigned short callno, int locked)
02036 {
02037 int x;
02038 int res= 0;
02039 struct callno_entry *callno_entry;
02040 if (iaxs[callno]->oseqno) {
02041 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02042 return -1;
02043 }
02044 if (callno & TRUNK_CALL_START) {
02045 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02046 return -1;
02047 }
02048
02049 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02050 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02051 return -1;
02052 }
02053
02054 x = callno_entry->callno;
02055 ast_mutex_lock(&iaxsl[x]);
02056
02057
02058
02059
02060
02061 ast_sched_thread_del(sched, iaxs[callno]->pingid);
02062 ast_sched_thread_del(sched, iaxs[callno]->lagid);
02063 iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02064 iaxs[x] = iaxs[callno];
02065 iaxs[x]->callno = x;
02066
02067
02068
02069 if (iaxs[x]->callno_entry) {
02070 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02071 }
02072 iaxs[x]->callno_entry = callno_entry;
02073
02074 iaxs[callno] = NULL;
02075
02076 iaxs[x]->pingid = iax2_sched_add(sched,
02077 ping_time * 1000, send_ping, (void *)(long)x);
02078 iaxs[x]->lagid = iax2_sched_add(sched,
02079 lagrq_time * 1000, send_lagrq, (void *)(long)x);
02080
02081 if (locked)
02082 ast_mutex_unlock(&iaxsl[callno]);
02083 res = x;
02084 if (!locked)
02085 ast_mutex_unlock(&iaxsl[x]);
02086
02087 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02088
02089 update_max_trunk();
02090 update_max_nontrunk();
02091 return res;
02092 }
02093
02094 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
02095 {
02096 if (!pvt->transfercallno) {
02097 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02098 return;
02099 }
02100
02101 ao2_link(iax_transfercallno_pvts, pvt);
02102 }
02103
02104 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
02105 {
02106 if (!pvt->transfercallno) {
02107 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02108 return;
02109 }
02110
02111 ao2_unlink(iax_transfercallno_pvts, pvt);
02112 }
02113 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
02114 {
02115 if (!pvt->peercallno) {
02116 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02117 return;
02118 }
02119
02120 ao2_link(iax_peercallno_pvts, pvt);
02121 }
02122
02123 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
02124 {
02125 if (!pvt->peercallno) {
02126 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02127 return;
02128 }
02129
02130 ao2_unlink(iax_peercallno_pvts, pvt);
02131 }
02132
02133 static int addr_range_delme_cb(void *obj, void *arg, int flags)
02134 {
02135 struct addr_range *lim = obj;
02136 lim->delme = 1;
02137 return 0;
02138 }
02139
02140 static int addr_range_hash_cb(const void *obj, const int flags)
02141 {
02142 const struct addr_range *lim = obj;
02143 struct sockaddr_in sin;
02144 ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02145 return abs((int) sin.sin_addr.s_addr);
02146 }
02147
02148 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
02149 {
02150 struct addr_range *lim1 = obj, *lim2 = arg;
02151 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02152 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02153 CMP_MATCH | CMP_STOP : 0;
02154 }
02155
02156 static int peercnt_hash_cb(const void *obj, const int flags)
02157 {
02158 const struct peercnt *peercnt = obj;
02159 return abs((int) peercnt->addr);
02160 }
02161
02162 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
02163 {
02164 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02165 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02166 }
02167
02168 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
02169 {
02170 struct addr_range *addr_range = obj;
02171 struct sockaddr_in *sin = arg;
02172 struct sockaddr_in ha_netmask_sin;
02173 struct sockaddr_in ha_addr_sin;
02174
02175 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02176 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02177
02178 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02179 return CMP_MATCH | CMP_STOP;
02180 }
02181 return 0;
02182 }
02183
02184
02185
02186
02187
02188
02189 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
02190 {
02191 struct addr_range *addr_range;
02192 struct iax2_peer *peer = NULL;
02193 struct iax2_user *user = NULL;
02194
02195 const char *find = S_OR(name, "guest");
02196 int res = 1;
02197 int optional = 0;
02198 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02199
02200
02201
02202
02203
02204
02205
02206 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02207 ao2_ref(addr_range, -1);
02208 optional = 1;
02209 }
02210
02211
02212 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02213 calltoken_required = user->calltoken_required;
02214 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02215 calltoken_required = user->calltoken_required;
02216 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02217 calltoken_required = peer->calltoken_required;
02218 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02219 calltoken_required = peer->calltoken_required;
02220 }
02221
02222 if (peer) {
02223 peer_unref(peer);
02224 }
02225 if (user) {
02226 user_unref(user);
02227 }
02228
02229 ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
02230 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02231 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02232 res = 0;
02233 }
02234
02235 return res;
02236 }
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 static void set_peercnt_limit(struct peercnt *peercnt)
02249 {
02250 uint16_t limit = global_maxcallno;
02251 struct addr_range *addr_range;
02252 struct sockaddr_in sin = {
02253 .sin_addr.s_addr = peercnt->addr,
02254 };
02255
02256
02257 if (peercnt->reg && peercnt->limit) {
02258 return;
02259 }
02260
02261 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02262 limit = addr_range->limit;
02263 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02264 ao2_ref(addr_range, -1);
02265 }
02266
02267 peercnt->limit = limit;
02268 }
02269
02270
02271
02272
02273
02274 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02275 {
02276 struct peercnt *peercnt = obj;
02277
02278 set_peercnt_limit(peercnt);
02279 ast_debug(1, "Reset limits for peercnts table\n");
02280
02281 return 0;
02282 }
02283
02284
02285
02286
02287
02288 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02289 {
02290 struct addr_range *addr_range = obj;
02291
02292 return addr_range->delme ? CMP_MATCH : 0;
02293 }
02294
02295
02296
02297
02298
02299 static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
02300 {
02301
02302 struct peercnt *peercnt;
02303 struct peercnt tmp = {
02304 .addr = 0,
02305 };
02306 struct sockaddr_in sin;
02307
02308 ast_sockaddr_to_sin(sockaddr, &sin);
02309
02310 tmp.addr = sin.sin_addr.s_addr;
02311
02312 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02313 peercnt->reg = reg;
02314 if (limit) {
02315 peercnt->limit = limit;
02316 } else {
02317 set_peercnt_limit(peercnt);
02318 }
02319 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02320 ao2_ref(peercnt, -1);
02321 }
02322 }
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332 static int peercnt_add(struct sockaddr_in *sin)
02333 {
02334 struct peercnt *peercnt;
02335 unsigned long addr = sin->sin_addr.s_addr;
02336 int res = 0;
02337 struct peercnt tmp = {
02338 .addr = addr,
02339 };
02340
02341
02342
02343
02344
02345
02346
02347 ao2_lock(peercnts);
02348 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02349 ao2_lock(peercnt);
02350 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02351 ao2_lock(peercnt);
02352
02353 peercnt->addr = addr;
02354 set_peercnt_limit(peercnt);
02355
02356
02357 ao2_link(peercnts, peercnt);
02358 } else {
02359 ao2_unlock(peercnts);
02360 return -1;
02361 }
02362
02363
02364 if (peercnt->limit > peercnt->cur) {
02365 peercnt->cur++;
02366 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02367 } else {
02368 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02369 res = -1;
02370 }
02371
02372
02373 ao2_unlock(peercnt);
02374 ao2_unlock(peercnts);
02375 ao2_ref(peercnt, -1);
02376
02377 return res;
02378 }
02379
02380
02381
02382
02383
02384 static void peercnt_remove(struct peercnt *peercnt)
02385 {
02386 struct sockaddr_in sin = {
02387 .sin_addr.s_addr = peercnt->addr,
02388 };
02389
02390 if (peercnt) {
02391
02392
02393
02394 ao2_lock(peercnts);
02395 peercnt->cur--;
02396 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02397
02398 if (peercnt->cur == 0) {
02399 ao2_unlink(peercnts, peercnt);
02400 }
02401 ao2_unlock(peercnts);
02402 }
02403 }
02404
02405
02406
02407
02408
02409 static int peercnt_remove_cb(const void *obj)
02410 {
02411 struct peercnt *peercnt = (struct peercnt *) obj;
02412
02413 peercnt_remove(peercnt);
02414 ao2_ref(peercnt, -1);
02415
02416 return 0;
02417 }
02418
02419
02420
02421
02422
02423 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02424 {
02425 struct peercnt *peercnt;
02426 struct peercnt tmp = {
02427 .addr = sin->sin_addr.s_addr,
02428 };
02429
02430 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02431 peercnt_remove(peercnt);
02432 ao2_ref(peercnt, -1);
02433 }
02434 return 0;
02435 }
02436
02437
02438
02439
02440
02441 static void build_callno_limits(struct ast_variable *v)
02442 {
02443 struct addr_range *addr_range = NULL;
02444 struct addr_range tmp;
02445 struct ast_ha *ha;
02446 int limit;
02447 int error;
02448 int found;
02449
02450 for (; v; v = v->next) {
02451 limit = -1;
02452 error = 0;
02453 found = 0;
02454 ha = ast_append_ha("permit", v->name, NULL, &error);
02455
02456
02457 if (error) {
02458 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02459 continue;
02460 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02461 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02462 ast_free_ha(ha);
02463 continue;
02464 }
02465
02466 ast_copy_ha(ha, &tmp.ha);
02467
02468 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02469 ao2_lock(addr_range);
02470 found = 1;
02471 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02472 ast_free_ha(ha);
02473 return;
02474 }
02475
02476
02477 ast_copy_ha(ha, &addr_range->ha);
02478 ast_free_ha(ha);
02479 addr_range->limit = limit;
02480 addr_range->delme = 0;
02481
02482
02483 if (found) {
02484 ao2_unlock(addr_range);
02485 } else {
02486 ao2_link(callno_limits, addr_range);
02487 }
02488 ao2_ref(addr_range, -1);
02489 }
02490 }
02491
02492
02493
02494
02495
02496 static int add_calltoken_ignore(const char *addr)
02497 {
02498 struct addr_range tmp;
02499 struct addr_range *addr_range = NULL;
02500 struct ast_ha *ha = NULL;
02501 int error = 0;
02502
02503 if (ast_strlen_zero(addr)) {
02504 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02505 return -1;
02506 }
02507
02508 ha = ast_append_ha("permit", addr, NULL, &error);
02509
02510
02511 if (error) {
02512 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02513 return -1;
02514 }
02515
02516 ast_copy_ha(ha, &tmp.ha);
02517
02518 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02519 ao2_lock(addr_range);
02520 addr_range->delme = 0;
02521 ao2_unlock(addr_range);
02522 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02523
02524 ast_copy_ha(ha, &addr_range->ha);
02525 ao2_link(calltoken_ignores, addr_range);
02526 } else {
02527 ast_free_ha(ha);
02528 return -1;
02529 }
02530
02531 ast_free_ha(ha);
02532 ao2_ref(addr_range, -1);
02533
02534 return 0;
02535 }
02536
02537 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02538 {
02539 struct ao2_iterator i;
02540 struct peercnt *peercnt;
02541 struct sockaddr_in sin;
02542 int found = 0;
02543
02544 switch (cmd) {
02545 case CLI_INIT:
02546 e->command = "iax2 show callnumber usage";
02547 e->usage =
02548 "Usage: iax2 show callnumber usage [IP address]\n"
02549 " Shows current IP addresses which are consuming iax2 call numbers\n";
02550 return NULL;
02551 case CLI_GENERATE:
02552 return NULL;
02553 case CLI_HANDLER:
02554 if (a->argc < 4 || a->argc > 5)
02555 return CLI_SHOWUSAGE;
02556
02557 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02558 i = ao2_iterator_init(peercnts, 0);
02559 while ((peercnt = ao2_iterator_next(&i))) {
02560 sin.sin_addr.s_addr = peercnt->addr;
02561 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02562 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02563 found = 1;
02564 break;
02565 } else {
02566 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02567 }
02568 ao2_ref(peercnt, -1);
02569 }
02570 ao2_iterator_destroy(&i);
02571
02572 if (a->argc == 4) {
02573 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02574 "Non-CallToken Validated Callno Used: %d\n",
02575 global_maxcallno_nonval,
02576 total_nonval_callno_used);
02577
02578 ast_cli(a->fd, "Total Available Callno: %d\n"
02579 "Regular Callno Available: %d\n"
02580 "Trunk Callno Available: %d\n",
02581 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02582 ao2_container_count(callno_pool),
02583 ao2_container_count(callno_pool_trunk));
02584 } else if (a->argc == 5 && !found) {
02585 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02586 }
02587
02588
02589 return CLI_SUCCESS;
02590 default:
02591 return NULL;
02592 }
02593 }
02594
02595 static struct callno_entry *get_unused_callno(int trunk, int validated)
02596 {
02597 struct callno_entry *callno_entry = NULL;
02598 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02599 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02600
02601 return NULL;
02602 }
02603
02604
02605
02606 ao2_lock(callno_pool);
02607
02608
02609
02610
02611 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02612 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02613 ao2_unlock(callno_pool);
02614 return NULL;
02615 }
02616
02617
02618
02619 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02620
02621 if (callno_entry) {
02622 callno_entry->validated = validated;
02623 if (!validated) {
02624 total_nonval_callno_used++;
02625 }
02626 }
02627
02628 ao2_unlock(callno_pool);
02629 return callno_entry;
02630 }
02631
02632 static int replace_callno(const void *obj)
02633 {
02634 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02635
02636
02637
02638 ao2_lock(callno_pool);
02639
02640 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02641 total_nonval_callno_used--;
02642 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02643 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02644 }
02645
02646 if (callno_entry->callno < TRUNK_CALL_START) {
02647 ao2_link(callno_pool, callno_entry);
02648 } else {
02649 ao2_link(callno_pool_trunk, callno_entry);
02650 }
02651 ao2_ref(callno_entry, -1);
02652
02653 ao2_unlock(callno_pool);
02654 return 0;
02655 }
02656
02657 static int callno_hash(const void *obj, const int flags)
02658 {
02659 return abs(ast_random());
02660 }
02661
02662 static int create_callno_pools(void)
02663 {
02664 uint16_t i;
02665
02666 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02667 return -1;
02668 }
02669
02670 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02671 return -1;
02672 }
02673
02674
02675 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02676 struct callno_entry *callno_entry;
02677
02678 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02679 return -1;
02680 }
02681
02682 callno_entry->callno = i;
02683
02684 if (i < TRUNK_CALL_START) {
02685 ao2_link(callno_pool, callno_entry);
02686 } else {
02687 ao2_link(callno_pool_trunk, callno_entry);
02688 }
02689
02690 ao2_ref(callno_entry, -1);
02691 }
02692
02693 return 0;
02694 }
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02705 {
02706 int i;
02707 struct peercnt *peercnt;
02708 struct peercnt tmp = {
02709 .addr = sin->sin_addr.s_addr,
02710 };
02711
02712 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02713
02714 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02715 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02716 if (i == -1) {
02717 ao2_ref(peercnt, -1);
02718 }
02719 }
02720
02721 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02722 }
02723
02724
02725
02726
02727
02728
02729
02730
02731 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02732 {
02733 if (frametype != AST_FRAME_IAX) {
02734 return 0;
02735 }
02736 switch (subclass) {
02737 case IAX_COMMAND_NEW:
02738 case IAX_COMMAND_REGREQ:
02739 case IAX_COMMAND_FWDOWNL:
02740 case IAX_COMMAND_REGREL:
02741 return 1;
02742 case IAX_COMMAND_POKE:
02743 if (!inbound) {
02744 return 1;
02745 }
02746 break;
02747 }
02748 return 0;
02749 }
02750
02751
02752
02753
02754 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02755 {
02756 int res = 0;
02757 int x;
02758
02759
02760 int validated = (new > NEW_ALLOW) ? 1 : 0;
02761 char host[80];
02762
02763 if (new <= NEW_ALLOW) {
02764 if (callno) {
02765 struct chan_iax2_pvt *pvt;
02766 struct chan_iax2_pvt tmp_pvt = {
02767 .callno = dcallno,
02768 .peercallno = callno,
02769 .transfercallno = callno,
02770
02771 .frames_received = check_dcallno,
02772 };
02773
02774 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02775
02776 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02777 if (return_locked) {
02778 ast_mutex_lock(&iaxsl[pvt->callno]);
02779 }
02780 res = pvt->callno;
02781 ao2_ref(pvt, -1);
02782 pvt = NULL;
02783 return res;
02784 }
02785
02786 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02787 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02788 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02789 if (return_locked) {
02790 ast_mutex_lock(&iaxsl[pvt->callno]);
02791 }
02792 res = pvt->callno;
02793 ao2_ref(pvt, -1);
02794 pvt = NULL;
02795 return res;
02796 }
02797 }
02798
02799
02800 if (dcallno) {
02801 ast_mutex_lock(&iaxsl[dcallno]);
02802 }
02803 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02804 iaxs[dcallno]->peercallno = callno;
02805 res = dcallno;
02806 store_by_peercallno(iaxs[dcallno]);
02807 if (!res || !return_locked) {
02808 ast_mutex_unlock(&iaxsl[dcallno]);
02809 }
02810 return res;
02811 }
02812 if (dcallno) {
02813 ast_mutex_unlock(&iaxsl[dcallno]);
02814 }
02815 #ifdef IAX_OLD_FIND
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827 for (x = 1; !res && x < maxnontrunkcall; x++) {
02828 ast_mutex_lock(&iaxsl[x]);
02829 if (iaxs[x]) {
02830
02831 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02832 res = x;
02833 }
02834 }
02835 if (!res || !return_locked)
02836 ast_mutex_unlock(&iaxsl[x]);
02837 }
02838 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02839 ast_mutex_lock(&iaxsl[x]);
02840 if (iaxs[x]) {
02841
02842 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02843 res = x;
02844 }
02845 }
02846 if (!res || !return_locked)
02847 ast_mutex_unlock(&iaxsl[x]);
02848 }
02849 #endif
02850 }
02851 if (!res && (new >= NEW_ALLOW)) {
02852 struct callno_entry *callno_entry;
02853
02854
02855
02856
02857
02858
02859 if (!iax2_getpeername(*sin, host, sizeof(host)))
02860 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02861
02862 if (peercnt_add(sin)) {
02863
02864
02865 return 0;
02866 }
02867
02868 if (!(callno_entry = get_unused_callno(0, validated))) {
02869
02870
02871 peercnt_remove_by_addr(sin);
02872 ast_log(LOG_WARNING, "No more space\n");
02873 return 0;
02874 }
02875 x = callno_entry->callno;
02876 ast_mutex_lock(&iaxsl[x]);
02877
02878 iaxs[x] = new_iax(sin, host);
02879 update_max_nontrunk();
02880 if (iaxs[x]) {
02881 if (iaxdebug)
02882 ast_debug(1, "Creating new call structure %d\n", x);
02883 iaxs[x]->callno_entry = callno_entry;
02884 iaxs[x]->sockfd = sockfd;
02885 iaxs[x]->addr.sin_port = sin->sin_port;
02886 iaxs[x]->addr.sin_family = sin->sin_family;
02887 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02888 iaxs[x]->peercallno = callno;
02889 iaxs[x]->callno = x;
02890 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02891 iaxs[x]->expiry = min_reg_expire;
02892 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02893 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02894 iaxs[x]->amaflags = amaflags;
02895 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02896 ast_string_field_set(iaxs[x], accountcode, accountcode);
02897 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02898 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02899 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02900
02901 if (iaxs[x]->peercallno) {
02902 store_by_peercallno(iaxs[x]);
02903 }
02904 } else {
02905 ast_log(LOG_WARNING, "Out of resources\n");
02906 ast_mutex_unlock(&iaxsl[x]);
02907 replace_callno(callno_entry);
02908 return 0;
02909 }
02910 if (!return_locked)
02911 ast_mutex_unlock(&iaxsl[x]);
02912 res = x;
02913 }
02914 return res;
02915 }
02916
02917 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02918 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02919 }
02920
02921 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02922
02923 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02924 }
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936 static int iax2_queue_frame(int callno, struct ast_frame *f)
02937 {
02938 iax2_lock_owner(callno);
02939 if (iaxs[callno] && iaxs[callno]->owner) {
02940 ast_queue_frame(iaxs[callno]->owner, f);
02941 ast_channel_unlock(iaxs[callno]->owner);
02942 }
02943 return 0;
02944 }
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959 static int iax2_queue_hangup(int callno)
02960 {
02961 iax2_lock_owner(callno);
02962 if (iaxs[callno] && iaxs[callno]->owner) {
02963 ast_queue_hangup(iaxs[callno]->owner);
02964 ast_channel_unlock(iaxs[callno]->owner);
02965 }
02966 return 0;
02967 }
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982 static int iax2_queue_control_data(int callno,
02983 enum ast_control_frame_type control, const void *data, size_t datalen)
02984 {
02985 iax2_lock_owner(callno);
02986 if (iaxs[callno] && iaxs[callno]->owner) {
02987 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02988 ast_channel_unlock(iaxs[callno]->owner);
02989 }
02990 return 0;
02991 }
02992 static void destroy_firmware(struct iax_firmware *cur)
02993 {
02994
02995 if (cur->fwh) {
02996 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02997 }
02998 close(cur->fd);
02999 ast_free(cur);
03000 }
03001
03002 static int try_firmware(char *s)
03003 {
03004 struct stat stbuf;
03005 struct iax_firmware *cur = NULL;
03006 int ifd, fd, res, len, chunk;
03007 struct ast_iax2_firmware_header *fwh, fwh2;
03008 struct MD5Context md5;
03009 unsigned char sum[16], buf[1024];
03010 char *s2, *last;
03011
03012 if (!(s2 = alloca(strlen(s) + 100))) {
03013 ast_log(LOG_WARNING, "Alloca failed!\n");
03014 return -1;
03015 }
03016
03017 last = strrchr(s, '/');
03018 if (last)
03019 last++;
03020 else
03021 last = s;
03022
03023 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03024
03025 if ((res = stat(s, &stbuf) < 0)) {
03026 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03027 return -1;
03028 }
03029
03030
03031 if (S_ISDIR(stbuf.st_mode))
03032 return -1;
03033 ifd = open(s, O_RDONLY);
03034 if (ifd < 0) {
03035 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03036 return -1;
03037 }
03038 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03039 if (fd < 0) {
03040 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03041 close(ifd);
03042 return -1;
03043 }
03044
03045 unlink(s2);
03046
03047
03048 len = stbuf.st_size;
03049 while(len) {
03050 chunk = len;
03051 if (chunk > sizeof(buf))
03052 chunk = sizeof(buf);
03053 res = read(ifd, buf, chunk);
03054 if (res != chunk) {
03055 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03056 close(ifd);
03057 close(fd);
03058 return -1;
03059 }
03060 res = write(fd, buf, chunk);
03061 if (res != chunk) {
03062 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03063 close(ifd);
03064 close(fd);
03065 return -1;
03066 }
03067 len -= chunk;
03068 }
03069 close(ifd);
03070
03071 lseek(fd, 0, SEEK_SET);
03072 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03073 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03074 close(fd);
03075 return -1;
03076 }
03077 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03078 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03079 close(fd);
03080 return -1;
03081 }
03082 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03083 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03084 close(fd);
03085 return -1;
03086 }
03087 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03088 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03089 close(fd);
03090 return -1;
03091 }
03092 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
03093 if (fwh == MAP_FAILED) {
03094 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03095 close(fd);
03096 return -1;
03097 }
03098 MD5Init(&md5);
03099 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03100 MD5Final(sum, &md5);
03101 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03102 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03103 munmap((void*)fwh, stbuf.st_size);
03104 close(fd);
03105 return -1;
03106 }
03107
03108 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03109 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03110
03111 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03112
03113 break;
03114
03115
03116 munmap((void*)fwh, stbuf.st_size);
03117 close(fd);
03118 return 0;
03119 }
03120 }
03121
03122 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03123 cur->fd = -1;
03124 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03125 }
03126
03127 if (cur) {
03128 if (cur->fwh)
03129 munmap((void*)cur->fwh, cur->mmaplen);
03130 if (cur->fd > -1)
03131 close(cur->fd);
03132 cur->fwh = fwh;
03133 cur->fd = fd;
03134 cur->mmaplen = stbuf.st_size;
03135 cur->dead = 0;
03136 }
03137
03138 return 0;
03139 }
03140
03141 static int iax_check_version(char *dev)
03142 {
03143 int res = 0;
03144 struct iax_firmware *cur = NULL;
03145
03146 if (ast_strlen_zero(dev))
03147 return 0;
03148
03149 AST_LIST_LOCK(&firmwares);
03150 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03151 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03152 res = ntohs(cur->fwh->version);
03153 break;
03154 }
03155 }
03156 AST_LIST_UNLOCK(&firmwares);
03157
03158 return res;
03159 }
03160
03161 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03162 {
03163 int res = -1;
03164 unsigned int bs = desc & 0xff;
03165 unsigned int start = (desc >> 8) & 0xffffff;
03166 unsigned int bytes;
03167 struct iax_firmware *cur;
03168
03169 if (ast_strlen_zero((char *)dev) || !bs)
03170 return -1;
03171
03172 start *= bs;
03173
03174 AST_LIST_LOCK(&firmwares);
03175 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03176 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03177 continue;
03178 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03179 if (start < ntohl(cur->fwh->datalen)) {
03180 bytes = ntohl(cur->fwh->datalen) - start;
03181 if (bytes > bs)
03182 bytes = bs;
03183 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03184 } else {
03185 bytes = 0;
03186 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03187 }
03188 if (bytes == bs)
03189 res = 0;
03190 else
03191 res = 1;
03192 break;
03193 }
03194 AST_LIST_UNLOCK(&firmwares);
03195
03196 return res;
03197 }
03198
03199
03200 static void reload_firmware(int unload)
03201 {
03202 struct iax_firmware *cur = NULL;
03203 DIR *fwd;
03204 struct dirent *de;
03205 char dir[256], fn[256];
03206
03207 AST_LIST_LOCK(&firmwares);
03208
03209
03210 AST_LIST_TRAVERSE(&firmwares, cur, list)
03211 cur->dead = 1;
03212
03213
03214 if (!unload) {
03215 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03216 fwd = opendir(dir);
03217 if (fwd) {
03218 while((de = readdir(fwd))) {
03219 if (de->d_name[0] != '.') {
03220 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03221 if (!try_firmware(fn)) {
03222 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03223 }
03224 }
03225 }
03226 closedir(fwd);
03227 } else
03228 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03229 }
03230
03231
03232 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03233 if (!cur->dead)
03234 continue;
03235 AST_LIST_REMOVE_CURRENT(list);
03236 destroy_firmware(cur);
03237 }
03238 AST_LIST_TRAVERSE_SAFE_END;
03239
03240 AST_LIST_UNLOCK(&firmwares);
03241 }
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251 static int __do_deliver(void *data)
03252 {
03253
03254
03255 struct iax_frame *fr = data;
03256 fr->retrans = -1;
03257 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03258 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03259 iax2_queue_frame(fr->callno, &fr->af);
03260
03261 iax2_frame_free(fr);
03262
03263 return 0;
03264 }
03265
03266 static int handle_error(void)
03267 {
03268
03269
03270
03271 #if 0
03272 struct sockaddr_in *sin;
03273 int res;
03274 struct msghdr m;
03275 struct sock_extended_err e;
03276 m.msg_name = NULL;
03277 m.msg_namelen = 0;
03278 m.msg_iov = NULL;
03279 m.msg_control = &e;
03280 m.msg_controllen = sizeof(e);
03281 m.msg_flags = 0;
03282 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03283 if (res < 0)
03284 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03285 else {
03286 if (m.msg_controllen) {
03287 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03288 if (sin)
03289 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03290 else
03291 ast_log(LOG_WARNING, "No address detected??\n");
03292 } else {
03293 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03294 }
03295 }
03296 #endif
03297 return 0;
03298 }
03299
03300 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03301 {
03302 int res;
03303 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03304 sizeof(*sin));
03305 if (res < 0) {
03306 ast_debug(1, "Received error: %s\n", strerror(errno));
03307 handle_error();
03308 } else
03309 res = 0;
03310 return res;
03311 }
03312
03313 static int send_packet(struct iax_frame *f)
03314 {
03315 int res;
03316 int callno = f->callno;
03317
03318
03319 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03320 return -1;
03321
03322
03323 if (iaxdebug)
03324 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));
03325
03326 if (f->transfer) {
03327 if (iaxdebug)
03328 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03329 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03330 } else {
03331 if (iaxdebug)
03332 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03333 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03334 }
03335 if (res < 0) {
03336 if (iaxdebug)
03337 ast_debug(1, "Received error: %s\n", strerror(errno));
03338 handle_error();
03339 } else
03340 res = 0;
03341
03342 return res;
03343 }
03344
03345
03346
03347
03348
03349 static int iax2_predestroy(int callno)
03350 {
03351 struct ast_channel *c = NULL;
03352 struct chan_iax2_pvt *pvt = iaxs[callno];
03353
03354 if (!pvt)
03355 return -1;
03356
03357 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03358 iax2_destroy_helper(pvt);
03359 ast_set_flag64(pvt, IAX_ALREADYGONE);
03360 }
03361
03362 if ((c = pvt->owner)) {
03363 c->tech_pvt = NULL;
03364 iax2_queue_hangup(callno);
03365 pvt->owner = NULL;
03366 ast_module_unref(ast_module_info->self);
03367 }
03368
03369 return 0;
03370 }
03371
03372 static void iax2_destroy(int callno)
03373 {
03374 struct chan_iax2_pvt *pvt = NULL;
03375 struct ast_channel *owner = NULL;
03376
03377 retry:
03378 if ((pvt = iaxs[callno])) {
03379 #if 0
03380
03381
03382
03383
03384
03385
03386
03387 iax2_destroy_helper(pvt);
03388 #endif
03389 }
03390
03391 owner = pvt ? pvt->owner : NULL;
03392
03393 if (owner) {
03394 if (ast_channel_trylock(owner)) {
03395 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03396 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03397 goto retry;
03398 }
03399 }
03400
03401 if (!owner) {
03402 iaxs[callno] = NULL;
03403 }
03404
03405 if (pvt) {
03406 if (!owner) {
03407 pvt->owner = NULL;
03408 } else {
03409
03410
03411
03412 ast_queue_hangup(owner);
03413 }
03414
03415 if (pvt->peercallno) {
03416 remove_by_peercallno(pvt);
03417 }
03418
03419 if (pvt->transfercallno) {
03420 remove_by_transfercallno(pvt);
03421 }
03422
03423 if (!owner) {
03424 ao2_ref(pvt, -1);
03425 pvt = NULL;
03426 }
03427 }
03428
03429 if (owner) {
03430 ast_channel_unlock(owner);
03431 }
03432
03433 if (callno & 0x4000) {
03434 update_max_trunk();
03435 }
03436 }
03437
03438 static int update_packet(struct iax_frame *f)
03439 {
03440
03441 struct ast_iax2_full_hdr *fh = f->data;
03442 struct ast_frame af;
03443
03444
03445 if (f->encmethods) {
03446 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03447 }
03448
03449 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03450
03451 f->iseqno = iaxs[f->callno]->iseqno;
03452 fh->iseqno = f->iseqno;
03453
03454
03455 if (f->encmethods) {
03456
03457
03458 build_rand_pad(f->semirand, sizeof(f->semirand));
03459 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03460 }
03461 return 0;
03462 }
03463
03464 static int attempt_transmit(const void *data);
03465 static void __attempt_transmit(const void *data)
03466 {
03467
03468
03469 struct iax_frame *f = (struct iax_frame *)data;
03470 int freeme = 0;
03471 int callno = f->callno;
03472
03473 if (callno)
03474 ast_mutex_lock(&iaxsl[callno]);
03475 if (callno && iaxs[callno]) {
03476 if ((f->retries < 0) ||
03477 (f->retries >= max_retries) ) {
03478
03479 if (f->retries >= max_retries) {
03480 if (f->transfer) {
03481
03482 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03483 } else if (f->final) {
03484 iax2_destroy(callno);
03485 } else {
03486 if (iaxs[callno]->owner)
03487 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, 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.integer, f->ts, f->oseqno);
03488 iaxs[callno]->error = ETIMEDOUT;
03489 if (iaxs[callno]->owner) {
03490 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03491
03492 iax2_queue_frame(callno, &fr);
03493
03494 if (iaxs[callno] && iaxs[callno]->owner)
03495 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03496 } else {
03497 if (iaxs[callno]->reg) {
03498 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03499 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03500 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03501 }
03502 iax2_destroy(callno);
03503 }
03504 }
03505
03506 }
03507 freeme = 1;
03508 } else {
03509
03510 update_packet(f);
03511
03512 send_packet(f);
03513 f->retries++;
03514
03515 f->retrytime *= 10;
03516 if (f->retrytime > MAX_RETRY_TIME)
03517 f->retrytime = MAX_RETRY_TIME;
03518
03519 if (f->transfer && (f->retrytime > 1000))
03520 f->retrytime = 1000;
03521 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03522 }
03523 } else {
03524
03525 f->retries = -1;
03526 freeme = 1;
03527 }
03528
03529 if (freeme) {
03530
03531 AST_LIST_REMOVE(&frame_queue[callno], f, list);
03532 ast_mutex_unlock(&iaxsl[callno]);
03533 f->retrans = -1;
03534
03535 iax2_frame_free(f);
03536 } else if (callno) {
03537 ast_mutex_unlock(&iaxsl[callno]);
03538 }
03539 }
03540
03541 static int attempt_transmit(const void *data)
03542 {
03543 #ifdef SCHED_MULTITHREADED
03544 if (schedule_action(__attempt_transmit, data))
03545 #endif
03546 __attempt_transmit(data);
03547 return 0;
03548 }
03549
03550 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03551 {
03552 struct iax2_peer *peer = NULL;
03553 struct iax2_user *user = NULL;
03554 static const char * const choices[] = { "all", NULL };
03555 char *cmplt;
03556
03557 switch (cmd) {
03558 case CLI_INIT:
03559 e->command = "iax2 prune realtime";
03560 e->usage =
03561 "Usage: iax2 prune realtime [<peername>|all]\n"
03562 " Prunes object(s) from the cache\n";
03563 return NULL;
03564 case CLI_GENERATE:
03565 if (a->pos == 3) {
03566 cmplt = ast_cli_complete(a->word, choices, a->n);
03567 if (!cmplt)
03568 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03569 return cmplt;
03570 }
03571 return NULL;
03572 }
03573 if (a->argc != 4)
03574 return CLI_SHOWUSAGE;
03575 if (!strcmp(a->argv[3], "all")) {
03576 prune_users();
03577 prune_peers();
03578 ast_cli(a->fd, "Cache flushed successfully.\n");
03579 return CLI_SUCCESS;
03580 }
03581 peer = find_peer(a->argv[3], 0);
03582 user = find_user(a->argv[3]);
03583 if (peer || user) {
03584 if (peer) {
03585 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03586 ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03587 expire_registry(peer_ref(peer));
03588 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03589 } else {
03590 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03591 }
03592 peer_unref(peer);
03593 }
03594 if (user) {
03595 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03596 ast_set_flag64(user, IAX_RTAUTOCLEAR);
03597 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03598 } else {
03599 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03600 }
03601 ao2_unlink(users,user);
03602 user_unref(user);
03603 }
03604 } else {
03605 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03606 }
03607
03608 return CLI_SUCCESS;
03609 }
03610
03611 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03612 {
03613 switch (cmd) {
03614 case CLI_INIT:
03615 e->command = "iax2 test losspct";
03616 e->usage =
03617 "Usage: iax2 test losspct <percentage>\n"
03618 " For testing, throws away <percentage> percent of incoming packets\n";
03619 return NULL;
03620 case CLI_GENERATE:
03621 return NULL;
03622 }
03623 if (a->argc != 4)
03624 return CLI_SHOWUSAGE;
03625
03626 test_losspct = atoi(a->argv[3]);
03627
03628 return CLI_SUCCESS;
03629 }
03630
03631 #ifdef IAXTESTS
03632 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03633 {
03634 switch (cmd) {
03635 case CLI_INIT:
03636 e->command = "iax2 test late";
03637 e->usage =
03638 "Usage: iax2 test late <ms>\n"
03639 " For testing, count the next frame as <ms> ms late\n";
03640 return NULL;
03641 case CLI_GENERATE:
03642 return NULL;
03643 }
03644
03645 if (a->argc != 4)
03646 return CLI_SHOWUSAGE;
03647
03648 test_late = atoi(a->argv[3]);
03649
03650 return CLI_SUCCESS;
03651 }
03652
03653 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03654 {
03655 switch (cmd) {
03656 case CLI_INIT:
03657 e->command = "iax2 test resync";
03658 e->usage =
03659 "Usage: iax2 test resync <ms>\n"
03660 " For testing, adjust all future frames by <ms> ms\n";
03661 return NULL;
03662 case CLI_GENERATE:
03663 return NULL;
03664 }
03665
03666 if (a->argc != 4)
03667 return CLI_SHOWUSAGE;
03668
03669 test_resync = atoi(a->argv[3]);
03670
03671 return CLI_SUCCESS;
03672 }
03673
03674 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03675 {
03676 switch (cmd) {
03677 case CLI_INIT:
03678 e->command = "iax2 test jitter";
03679 e->usage =
03680 "Usage: iax2 test jitter <ms> <pct>\n"
03681 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03682 " percentage of packets. If <pct> is not specified, adds\n"
03683 " jitter to all packets.\n";
03684 return NULL;
03685 case CLI_GENERATE:
03686 return NULL;
03687 }
03688
03689 if (a->argc < 4 || a->argc > 5)
03690 return CLI_SHOWUSAGE;
03691
03692 test_jit = atoi(a->argv[3]);
03693 if (a->argc == 5)
03694 test_jitpct = atoi(a->argv[4]);
03695
03696 return CLI_SUCCESS;
03697 }
03698 #endif
03699
03700
03701
03702 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03703 {
03704 int res = 0;
03705 if (peer->maxms) {
03706 if (peer->lastms < 0) {
03707 ast_copy_string(status, "UNREACHABLE", statuslen);
03708 } else if (peer->lastms > peer->maxms) {
03709 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03710 res = 1;
03711 } else if (peer->lastms) {
03712 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03713 res = 1;
03714 } else {
03715 ast_copy_string(status, "UNKNOWN", statuslen);
03716 }
03717 } else {
03718 ast_copy_string(status, "Unmonitored", statuslen);
03719 res = -1;
03720 }
03721 return res;
03722 }
03723
03724
03725 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03726 {
03727 char status[30];
03728 char cbuf[256];
03729 struct iax2_peer *peer;
03730 char codec_buf[512];
03731 struct ast_str *encmethods = ast_str_alloca(256);
03732 int x = 0, codec = 0, load_realtime = 0;
03733
03734 switch (cmd) {
03735 case CLI_INIT:
03736 e->command = "iax2 show peer";
03737 e->usage =
03738 "Usage: iax2 show peer <name>\n"
03739 " Display details on specific IAX peer\n";
03740 return NULL;
03741 case CLI_GENERATE:
03742 if (a->pos == 3)
03743 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03744 return NULL;
03745 }
03746
03747 if (a->argc < 4)
03748 return CLI_SHOWUSAGE;
03749
03750 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03751
03752 peer = find_peer(a->argv[3], load_realtime);
03753 if (peer) {
03754 struct sockaddr_in peer_addr;
03755
03756 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03757
03758 encmethods_to_str(peer->encmethods, encmethods);
03759 ast_cli(a->fd, "\n\n");
03760 ast_cli(a->fd, " * Name : %s\n", peer->name);
03761 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03762 ast_cli(a->fd, " Context : %s\n", peer->context);
03763 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03764 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03765 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03766 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03767 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03768 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03769 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03770 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03771 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03772 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03773 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));
03774 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03775 ast_cli(a->fd, " Username : %s\n", peer->username);
03776 ast_cli(a->fd, " Codecs : ");
03777 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03778 ast_cli(a->fd, "%s\n", codec_buf);
03779
03780 ast_cli(a->fd, " Codec Order : (");
03781 for(x = 0; x < 32 ; x++) {
03782 codec = ast_codec_pref_index(&peer->prefs,x);
03783 if(!codec)
03784 break;
03785 ast_cli(a->fd, "%s", ast_getformatname(codec));
03786 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03787 ast_cli(a->fd, "|");
03788 }
03789
03790 if (!x)
03791 ast_cli(a->fd, "none");
03792 ast_cli(a->fd, ")\n");
03793
03794 ast_cli(a->fd, " Status : ");
03795 peer_status(peer, status, sizeof(status));
03796 ast_cli(a->fd, "%s\n",status);
03797 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");
03798 ast_cli(a->fd, "\n");
03799 peer_unref(peer);
03800 } else {
03801 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03802 ast_cli(a->fd, "\n");
03803 }
03804
03805 return CLI_SUCCESS;
03806 }
03807
03808 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
03809 {
03810 int which = 0;
03811 struct iax2_peer *peer;
03812 char *res = NULL;
03813 int wordlen = strlen(word);
03814 struct ao2_iterator i;
03815
03816 i = ao2_iterator_init(peers, 0);
03817 while ((peer = ao2_iterator_next(&i))) {
03818 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03819 && (!flags || ast_test_flag64(peer, flags))) {
03820 res = ast_strdup(peer->name);
03821 peer_unref(peer);
03822 break;
03823 }
03824 peer_unref(peer);
03825 }
03826 ao2_iterator_destroy(&i);
03827
03828 return res;
03829 }
03830
03831 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03832 {
03833 struct iax_frame *cur;
03834 int cnt = 0, dead = 0, final = 0, i = 0;
03835
03836 switch (cmd) {
03837 case CLI_INIT:
03838 e->command = "iax2 show stats";
03839 e->usage =
03840 "Usage: iax2 show stats\n"
03841 " Display statistics on IAX channel driver.\n";
03842 return NULL;
03843 case CLI_GENERATE:
03844 return NULL;
03845 }
03846
03847 if (a->argc != 3)
03848 return CLI_SHOWUSAGE;
03849
03850 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03851 ast_mutex_lock(&iaxsl[i]);
03852 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03853 if (cur->retries < 0)
03854 dead++;
03855 if (cur->final)
03856 final++;
03857 cnt++;
03858 }
03859 ast_mutex_unlock(&iaxsl[i]);
03860 }
03861
03862 ast_cli(a->fd, " IAX Statistics\n");
03863 ast_cli(a->fd, "---------------------\n");
03864 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03865 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03866 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03867 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03868
03869 trunk_timed = trunk_untimed = 0;
03870 if (trunk_maxmtu > trunk_nmaxmtu)
03871 trunk_nmaxmtu = trunk_maxmtu;
03872
03873 return CLI_SUCCESS;
03874 }
03875
03876
03877 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03878 {
03879 int mtuv;
03880
03881 switch (cmd) {
03882 case CLI_INIT:
03883 e->command = "iax2 set mtu";
03884 e->usage =
03885 "Usage: iax2 set mtu <value>\n"
03886 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03887 " zero to disable. Disabling means that the operating system\n"
03888 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03889 " packet exceeds the UDP payload size. This is substantially\n"
03890 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03891 " greater for G.711 samples.\n";
03892 return NULL;
03893 case CLI_GENERATE:
03894 return NULL;
03895 }
03896
03897 if (a->argc != 4)
03898 return CLI_SHOWUSAGE;
03899 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03900 mtuv = MAX_TRUNK_MTU;
03901 else
03902 mtuv = atoi(a->argv[3]);
03903
03904 if (mtuv == 0) {
03905 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03906 global_max_trunk_mtu = 0;
03907 return CLI_SUCCESS;
03908 }
03909 if (mtuv < 172 || mtuv > 4000) {
03910 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03911 return CLI_SHOWUSAGE;
03912 }
03913 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03914 global_max_trunk_mtu = mtuv;
03915 return CLI_SUCCESS;
03916 }
03917
03918 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03919 {
03920 struct iax2_dpcache *dp = NULL;
03921 char tmp[1024], *pc = NULL;
03922 int s, x, y;
03923 struct timeval now = ast_tvnow();
03924
03925 switch (cmd) {
03926 case CLI_INIT:
03927 e->command = "iax2 show cache";
03928 e->usage =
03929 "Usage: iax2 show cache\n"
03930 " Display currently cached IAX Dialplan results.\n";
03931 return NULL;
03932 case CLI_GENERATE:
03933 return NULL;
03934 }
03935
03936 AST_LIST_LOCK(&dpcache);
03937
03938 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03939
03940 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03941 s = dp->expiry.tv_sec - now.tv_sec;
03942 tmp[0] = '\0';
03943 if (dp->flags & CACHE_FLAG_EXISTS)
03944 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03945 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03946 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03947 if (dp->flags & CACHE_FLAG_CANEXIST)
03948 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03949 if (dp->flags & CACHE_FLAG_PENDING)
03950 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03951 if (dp->flags & CACHE_FLAG_TIMEOUT)
03952 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03953 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03954 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03955 if (dp->flags & CACHE_FLAG_MATCHMORE)
03956 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03957 if (dp->flags & CACHE_FLAG_UNKNOWN)
03958 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03959
03960 if (!ast_strlen_zero(tmp)) {
03961 tmp[strlen(tmp) - 1] = '\0';
03962 } else {
03963 ast_copy_string(tmp, "(none)", sizeof(tmp));
03964 }
03965 y = 0;
03966 pc = strchr(dp->peercontext, '@');
03967 if (!pc) {
03968 pc = dp->peercontext;
03969 } else {
03970 pc++;
03971 }
03972 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03973 if (dp->waiters[x] > -1)
03974 y++;
03975 }
03976 if (s > 0) {
03977 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03978 } else {
03979 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03980 }
03981 }
03982
03983 AST_LIST_UNLOCK(&dpcache);
03984
03985 return CLI_SUCCESS;
03986 }
03987
03988 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03989
03990 static void unwrap_timestamp(struct iax_frame *fr)
03991 {
03992
03993
03994 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03995 const int lower_mask = (1 << ts_shift) - 1;
03996 const int upper_mask = ~lower_mask;
03997 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03998
03999 if ( (fr->ts & upper_mask) == last_upper ) {
04000 const int x = fr->ts - iaxs[fr->callno]->last;
04001 const int threshold = (ts_shift == 15) ? 25000 : 50000;
04002
04003 if (x < -threshold) {
04004
04005
04006
04007
04008 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04009 if (iaxdebug)
04010 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04011 } else if (x > threshold) {
04012
04013
04014
04015
04016 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04017 if (iaxdebug)
04018 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04019 }
04020 }
04021 }
04022
04023 static int get_from_jb(const void *p);
04024
04025 static void update_jbsched(struct chan_iax2_pvt *pvt)
04026 {
04027 int when;
04028
04029 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04030
04031 when = jb_next(pvt->jb) - when;
04032
04033 if (when <= 0) {
04034
04035 when = 1;
04036 }
04037
04038 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
04039 CALLNO_TO_PTR(pvt->callno));
04040 }
04041
04042 static void __get_from_jb(const void *p)
04043 {
04044 int callno = PTR_TO_CALLNO(p);
04045 struct chan_iax2_pvt *pvt = NULL;
04046 struct iax_frame *fr;
04047 jb_frame frame;
04048 int ret;
04049 long ms;
04050 long next;
04051 struct timeval now = ast_tvnow();
04052
04053
04054 ast_mutex_lock(&iaxsl[callno]);
04055 pvt = iaxs[callno];
04056 if (!pvt) {
04057
04058 ast_mutex_unlock(&iaxsl[callno]);
04059 return;
04060 }
04061
04062 pvt->jbid = -1;
04063
04064
04065
04066
04067 now.tv_usec += 1000;
04068
04069 ms = ast_tvdiff_ms(now, pvt->rxcore);
04070
04071 if(ms >= (next = jb_next(pvt->jb))) {
04072 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04073 switch(ret) {
04074 case JB_OK:
04075 fr = frame.data;
04076 __do_deliver(fr);
04077
04078 pvt = iaxs[callno];
04079 break;
04080 case JB_INTERP:
04081 {
04082 struct ast_frame af = { 0, };
04083
04084
04085 af.frametype = AST_FRAME_VOICE;
04086 af.subclass.codec = pvt->voiceformat;
04087 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04088 af.src = "IAX2 JB interpolation";
04089 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04090 af.offset = AST_FRIENDLY_OFFSET;
04091
04092
04093
04094 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04095 iax2_queue_frame(callno, &af);
04096
04097 pvt = iaxs[callno];
04098 }
04099 }
04100 break;
04101 case JB_DROP:
04102 iax2_frame_free(frame.data);
04103 break;
04104 case JB_NOFRAME:
04105 case JB_EMPTY:
04106
04107 break;
04108 default:
04109
04110 break;
04111 }
04112 }
04113 if (pvt)
04114 update_jbsched(pvt);
04115 ast_mutex_unlock(&iaxsl[callno]);
04116 }
04117
04118 static int get_from_jb(const void *data)
04119 {
04120 #ifdef SCHED_MULTITHREADED
04121 if (schedule_action(__get_from_jb, data))
04122 #endif
04123 __get_from_jb(data);
04124 return 0;
04125 }
04126
04127
04128
04129
04130
04131
04132
04133 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
04134 {
04135 int type, len;
04136 int ret;
04137 int needfree = 0;
04138 struct ast_channel *owner = NULL;
04139 struct ast_channel *bridge = NULL;
04140
04141
04142 unwrap_timestamp(fr);
04143
04144
04145 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04146 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04147 else {
04148 #if 0
04149 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04150 #endif
04151 fr->af.delivery = ast_tv(0,0);
04152 }
04153
04154 type = JB_TYPE_CONTROL;
04155 len = 0;
04156
04157 if(fr->af.frametype == AST_FRAME_VOICE) {
04158 type = JB_TYPE_VOICE;
04159 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04160 } else if(fr->af.frametype == AST_FRAME_CNG) {
04161 type = JB_TYPE_SILENCE;
04162 }
04163
04164 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04165 if (tsout)
04166 *tsout = fr->ts;
04167 __do_deliver(fr);
04168 return -1;
04169 }
04170
04171 iax2_lock_owner(fr->callno);
04172 if (!iaxs[fr->callno]) {
04173
04174 iax2_frame_free(fr);
04175 return -1;
04176 }
04177 if ((owner = iaxs[fr->callno]->owner))
04178 bridge = ast_bridged_channel(owner);
04179
04180
04181
04182 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04183 jb_frame frame;
04184
04185 ast_channel_unlock(owner);
04186
04187
04188 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04189 __do_deliver(frame.data);
04190
04191 if (!iaxs[fr->callno])
04192 return -1;
04193 }
04194
04195 jb_reset(iaxs[fr->callno]->jb);
04196
04197 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04198
04199
04200 if (tsout)
04201 *tsout = fr->ts;
04202 __do_deliver(fr);
04203 return -1;
04204 }
04205 if (owner) {
04206 ast_channel_unlock(owner);
04207 }
04208
04209
04210
04211 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04212 calc_rxstamp(iaxs[fr->callno],fr->ts));
04213 if (ret == JB_DROP) {
04214 needfree++;
04215 } else if (ret == JB_SCHED) {
04216 update_jbsched(iaxs[fr->callno]);
04217 }
04218 if (tsout)
04219 *tsout = fr->ts;
04220 if (needfree) {
04221
04222 iax2_frame_free(fr);
04223 return -1;
04224 }
04225 return 0;
04226 }
04227
04228 static int transmit_frame(void *data)
04229 {
04230 struct iax_frame *fr = data;
04231
04232 ast_mutex_lock(&iaxsl[fr->callno]);
04233
04234 fr->sentyet = 1;
04235
04236 if (iaxs[fr->callno]) {
04237 send_packet(fr);
04238 }
04239
04240 if (fr->retries < 0) {
04241 ast_mutex_unlock(&iaxsl[fr->callno]);
04242
04243 iax_frame_free(fr);
04244 } else {
04245
04246 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04247 fr->retries++;
04248 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04249 ast_mutex_unlock(&iaxsl[fr->callno]);
04250 }
04251
04252 return 0;
04253 }
04254
04255 static int iax2_transmit(struct iax_frame *fr)
04256 {
04257 fr->sentyet = 0;
04258
04259 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04260 }
04261
04262 static int iax2_digit_begin(struct ast_channel *c, char digit)
04263 {
04264 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04265 }
04266
04267 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04268 {
04269 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04270 }
04271
04272 static int iax2_sendtext(struct ast_channel *c, const char *text)
04273 {
04274
04275 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04276 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04277 }
04278
04279 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04280 {
04281 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04282 }
04283
04284 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04285 {
04286 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04287 }
04288
04289 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04290 {
04291 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04292 ast_mutex_lock(&iaxsl[callno]);
04293 if (iaxs[callno])
04294 iaxs[callno]->owner = newchan;
04295 else
04296 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04297 ast_mutex_unlock(&iaxsl[callno]);
04298 return 0;
04299 }
04300
04301
04302
04303
04304
04305 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04306 {
04307 struct ast_variable *var = NULL;
04308 struct ast_variable *tmp;
04309 struct iax2_peer *peer=NULL;
04310 time_t regseconds = 0, nowtime;
04311 int dynamic=0;
04312
04313 if (peername) {
04314 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04315 if (!var && sin)
04316 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04317 } else if (sin) {
04318 char porta[25];
04319 sprintf(porta, "%d", ntohs(sin->sin_port));
04320 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04321 if (var) {
04322
04323 for (tmp = var; tmp; tmp = tmp->next) {
04324 if (!strcasecmp(tmp->name, "name"))
04325 peername = tmp->value;
04326 }
04327 }
04328 }
04329 if (!var && peername) {
04330 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04331
04332
04333
04334
04335
04336
04337 if (var && sin) {
04338 for (tmp = var; tmp; tmp = tmp->next) {
04339 if (!strcasecmp(tmp->name, "host")) {
04340 struct ast_hostent ahp;
04341 struct hostent *hp;
04342 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04343
04344 ast_variables_destroy(var);
04345 var = NULL;
04346 }
04347 break;
04348 }
04349 }
04350 }
04351 }
04352 if (!var)
04353 return NULL;
04354
04355 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04356
04357 if (!peer) {
04358 ast_variables_destroy(var);
04359 return NULL;
04360 }
04361
04362 for (tmp = var; tmp; tmp = tmp->next) {
04363
04364 if (!strcasecmp(tmp->name, "type")) {
04365 if (strcasecmp(tmp->value, "friend") &&
04366 strcasecmp(tmp->value, "peer")) {
04367
04368 peer = peer_unref(peer);
04369 break;
04370 }
04371 } else if (!strcasecmp(tmp->name, "regseconds")) {
04372 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04373 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04374 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE);
04375 } else if (!strcasecmp(tmp->name, "port")) {
04376 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04377 } else if (!strcasecmp(tmp->name, "host")) {
04378 if (!strcasecmp(tmp->value, "dynamic"))
04379 dynamic = 1;
04380 }
04381 }
04382
04383 ast_variables_destroy(var);
04384
04385 if (!peer)
04386 return NULL;
04387
04388 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04389 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04390 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04391 if (peer->expire > -1) {
04392 if (!ast_sched_thread_del(sched, peer->expire)) {
04393 peer->expire = -1;
04394 peer_unref(peer);
04395 }
04396 }
04397 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04398 if (peer->expire == -1)
04399 peer_unref(peer);
04400 }
04401 ao2_link(peers, peer);
04402 if (ast_test_flag64(peer, IAX_DYNAMIC))
04403 reg_source_db(peer);
04404 } else {
04405 ast_set_flag64(peer, IAX_TEMPONLY);
04406 }
04407
04408 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04409 time(&nowtime);
04410 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04411 memset(&peer->addr, 0, sizeof(peer->addr));
04412 realtime_update_peer(peer->name, &peer->addr, 0);
04413 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04414 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04415 }
04416 else {
04417 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04418 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04419 }
04420 }
04421
04422 return peer;
04423 }
04424
04425 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04426 {
04427 struct ast_variable *var;
04428 struct ast_variable *tmp;
04429 struct iax2_user *user=NULL;
04430
04431 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04432 if (!var)
04433 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04434 if (!var && sin) {
04435 char porta[6];
04436 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04437 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04438 if (!var)
04439 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04440 }
04441 if (!var) {
04442 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04443
04444
04445
04446
04447
04448
04449 if (var) {
04450 for (tmp = var; tmp; tmp = tmp->next) {
04451 if (!strcasecmp(tmp->name, "host")) {
04452 struct ast_hostent ahp;
04453 struct hostent *hp;
04454 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04455
04456 ast_variables_destroy(var);
04457 var = NULL;
04458 }
04459 break;
04460 }
04461 }
04462 }
04463 }
04464 if (!var)
04465 return NULL;
04466
04467 tmp = var;
04468 while(tmp) {
04469
04470 if (!strcasecmp(tmp->name, "type")) {
04471 if (strcasecmp(tmp->value, "friend") &&
04472 strcasecmp(tmp->value, "user")) {
04473 return NULL;
04474 }
04475 }
04476 tmp = tmp->next;
04477 }
04478
04479 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04480
04481 ast_variables_destroy(var);
04482
04483 if (!user)
04484 return NULL;
04485
04486 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04487 ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04488 ao2_link(users, user);
04489 } else {
04490 ast_set_flag64(user, IAX_TEMPONLY);
04491 }
04492
04493 return user;
04494 }
04495
04496 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
04497 {
04498 char port[10];
04499 char regseconds[20];
04500 const char *sysname = ast_config_AST_SYSTEM_NAME;
04501 char *syslabel = NULL;
04502
04503 if (ast_strlen_zero(sysname))
04504 sysname = NULL;
04505 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04506 syslabel = "regserver";
04507
04508 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04509 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04510 ast_update_realtime("iaxpeers", "name", peername,
04511 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port,
04512 "regseconds", regseconds, syslabel, sysname, SENTINEL);
04513 }
04514
04515 struct create_addr_info {
04516 format_t capability;
04517 uint64_t flags;
04518 int maxtime;
04519 int encmethods;
04520 int found;
04521 int sockfd;
04522 int adsi;
04523 char username[80];
04524 char secret[80];
04525 char outkey[80];
04526 char timezone[80];
04527 char prefs[32];
04528 char cid_num[80];
04529 char cid_name[80];
04530 char context[AST_MAX_CONTEXT];
04531 char peercontext[AST_MAX_CONTEXT];
04532 char mohinterpret[MAX_MUSICCLASS];
04533 char mohsuggest[MAX_MUSICCLASS];
04534 };
04535
04536 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04537 {
04538 struct iax2_peer *peer;
04539 int res = -1;
04540 struct ast_codec_pref ourprefs;
04541 struct sockaddr_in peer_addr;
04542
04543 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04544 cai->sockfd = defaultsockfd;
04545 cai->maxtime = 0;
04546 sin->sin_family = AF_INET;
04547
04548 if (!(peer = find_peer(peername, 1))) {
04549 struct ast_sockaddr sin_tmp;
04550
04551 cai->found = 0;
04552 sin_tmp.ss.ss_family = AF_INET;
04553 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04554 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04555 return -1;
04556 }
04557 ast_sockaddr_to_sin(&sin_tmp, sin);
04558 if (sin->sin_port == 0) {
04559 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04560 }
04561
04562
04563 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04564 if (c)
04565 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04566 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04567 return 0;
04568 }
04569
04570 cai->found = 1;
04571
04572 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04573
04574
04575 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04576 goto return_unref;
04577 }
04578
04579
04580 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04581 goto return_unref;
04582
04583 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04584 cai->maxtime = peer->maxms;
04585 cai->capability = peer->capability;
04586 cai->encmethods = peer->encmethods;
04587 cai->sockfd = peer->sockfd;
04588 cai->adsi = peer->adsi;
04589 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04590
04591 if (c) {
04592 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04593 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04594 }
04595 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04596 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04597 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04598 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04599 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04600 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04601 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04602 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04603 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04604 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04605 if (ast_strlen_zero(peer->dbsecret)) {
04606 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04607 } else {
04608 char *family;
04609 char *key = NULL;
04610
04611 family = ast_strdupa(peer->dbsecret);
04612 key = strchr(family, '/');
04613 if (key)
04614 *key++ = '\0';
04615 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04616 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04617 goto return_unref;
04618 }
04619 }
04620
04621 if (peer_addr.sin_addr.s_addr) {
04622 sin->sin_addr = peer_addr.sin_addr;
04623 sin->sin_port = peer_addr.sin_port;
04624 } else {
04625 sin->sin_addr = peer->defaddr.sin_addr;
04626 sin->sin_port = peer->defaddr.sin_port;
04627 }
04628
04629 res = 0;
04630
04631 return_unref:
04632 peer_unref(peer);
04633
04634 return res;
04635 }
04636
04637 static void __auto_congest(const void *nothing)
04638 {
04639 int callno = PTR_TO_CALLNO(nothing);
04640 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04641 ast_mutex_lock(&iaxsl[callno]);
04642 if (iaxs[callno]) {
04643 iaxs[callno]->initid = -1;
04644 iax2_queue_frame(callno, &f);
04645 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04646 }
04647 ast_mutex_unlock(&iaxsl[callno]);
04648 }
04649
04650 static int auto_congest(const void *data)
04651 {
04652 #ifdef SCHED_MULTITHREADED
04653 if (schedule_action(__auto_congest, data))
04654 #endif
04655 __auto_congest(data);
04656 return 0;
04657 }
04658
04659 static unsigned int iax2_datetime(const char *tz)
04660 {
04661 struct timeval t = ast_tvnow();
04662 struct ast_tm tm;
04663 unsigned int tmp;
04664 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04665 tmp = (tm.tm_sec >> 1) & 0x1f;
04666 tmp |= (tm.tm_min & 0x3f) << 5;
04667 tmp |= (tm.tm_hour & 0x1f) << 11;
04668 tmp |= (tm.tm_mday & 0x1f) << 16;
04669 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04670 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04671 return tmp;
04672 }
04673
04674 struct parsed_dial_string {
04675 char *username;
04676 char *password;
04677 char *key;
04678 char *peer;
04679 char *port;
04680 char *exten;
04681 char *context;
04682 char *options;
04683 };
04684
04685 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04686 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04687 int sockfd, struct iax_ie_data *ied)
04688 {
04689 struct {
04690 struct ast_iax2_full_hdr f;
04691 struct iax_ie_data ied;
04692 } data;
04693 size_t size = sizeof(struct ast_iax2_full_hdr);
04694
04695 if (ied) {
04696 size += ied->pos;
04697 memcpy(&data.ied, ied->buf, ied->pos);
04698 }
04699
04700 data.f.scallno = htons(0x8000 | callno);
04701 data.f.dcallno = htons(dcallno);
04702 data.f.ts = htonl(ts);
04703 data.f.iseqno = seqno;
04704 data.f.oseqno = 0;
04705 data.f.type = AST_FRAME_IAX;
04706 data.f.csub = compress_subclass(command);
04707
04708 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04709 }
04710
04711 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04712 {
04713
04714 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04715 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04716 ied->buf[ied->pos++] = 0;
04717 pvt->calltoken_ie_len = 2;
04718 }
04719 }
04720
04721 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04722 {
04723 struct chan_iax2_pvt *pvt = iaxs[callno];
04724 int frametype = f->af.frametype;
04725 int subclass = f->af.subclass.integer;
04726 struct {
04727 struct ast_iax2_full_hdr fh;
04728 struct iax_ie_data ied;
04729 } data = {
04730 .ied.buf = { 0 },
04731 .ied.pos = 0,
04732 };
04733
04734 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04735
04736 if (!pvt) {
04737 return;
04738 }
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04752 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04753 (f->datalen > sizeof(data))) {
04754
04755 return;
04756 }
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772 memcpy(&data, f->data, f->datalen);
04773 data.ied.pos = ie_data_pos;
04774
04775
04776
04777 data.ied.pos -= pvt->calltoken_ie_len;
04778 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04779
04780
04781 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04782
04783
04784 AST_LIST_REMOVE(&frame_queue[callno], f, list);
04785
04786
04787 iax2_frame_free(f);
04788
04789
04790 pvt->oseqno = 0;
04791 pvt->rseqno = 0;
04792 pvt->iseqno = 0;
04793 pvt->aseqno = 0;
04794 if (pvt->peercallno) {
04795 remove_by_peercallno(pvt);
04796 pvt->peercallno = 0;
04797 }
04798
04799
04800 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04801 }
04802
04803 static void requirecalltoken_mark_auto(const char *name, int subclass)
04804 {
04805 struct iax2_user *user = NULL;
04806 struct iax2_peer *peer = NULL;
04807
04808 if (ast_strlen_zero(name)) {
04809 return;
04810 }
04811
04812 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04813 user->calltoken_required = CALLTOKEN_YES;
04814 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04815 peer->calltoken_required = CALLTOKEN_YES;
04816 }
04817
04818 if (peer) {
04819 peer_unref(peer);
04820 }
04821 if (user) {
04822 user_unref(user);
04823 }
04824 }
04825
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04844 struct sockaddr_in *sin, int fd)
04845 {
04846 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04847 #define CALLTOKEN_IE_FORMAT "%u?%s"
04848 struct ast_str *buf = ast_str_alloca(256);
04849 time_t t = time(NULL);
04850 char hash[41];
04851 int subclass = uncompress_subclass(fh->csub);
04852
04853
04854 if (ies->calltoken && !ies->calltokendata) {
04855 struct iax_ie_data ied = {
04856 .buf = { 0 },
04857 .pos = 0,
04858 };
04859
04860
04861 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04862 ast_sha1_hash(hash, ast_str_buffer(buf));
04863
04864 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04865 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04866 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04867
04868 return 1;
04869
04870
04871 } else if (ies->calltoken && ies->calltokendata) {
04872 char *rec_hash = NULL;
04873 char *rec_ts = NULL;
04874 unsigned int rec_time;
04875
04876
04877 rec_hash = strchr((char *) ies->calltokendata, '?');
04878 if (rec_hash) {
04879 *rec_hash++ = '\0';
04880 rec_ts = (char *) ies->calltokendata;
04881 }
04882
04883
04884 if (!rec_hash || !rec_ts) {
04885 goto reject;
04886 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04887 goto reject;
04888 }
04889
04890
04891 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04892 ast_sha1_hash(hash, ast_str_buffer(buf));
04893
04894
04895 if (strcmp(hash, rec_hash)) {
04896 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04897 goto reject;
04898 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04899 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04900 goto reject;
04901 }
04902
04903
04904
04905 requirecalltoken_mark_auto(ies->username, subclass);
04906 return 0;
04907
04908
04909 } else {
04910 if (calltoken_required(sin, ies->username, subclass)) {
04911 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest"));
04912 goto reject;
04913 }
04914 return 0;
04915 }
04916
04917 reject:
04918
04919 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04920 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04921 } else {
04922 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04923 }
04924
04925 return 1;
04926 }
04927
04928
04929
04930
04931
04932
04933
04934
04935
04936
04937
04938
04939
04940
04941
04942
04943
04944
04945
04946 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04947 {
04948 if (ast_strlen_zero(data))
04949 return;
04950
04951 pds->peer = strsep(&data, "/");
04952 pds->exten = strsep(&data, "/");
04953 pds->options = data;
04954
04955 if (pds->exten) {
04956 data = pds->exten;
04957 pds->exten = strsep(&data, "@");
04958 pds->context = data;
04959 }
04960
04961 if (strchr(pds->peer, '@')) {
04962 data = pds->peer;
04963 pds->username = strsep(&data, "@");
04964 pds->peer = data;
04965 }
04966
04967 if (pds->username) {
04968 data = pds->username;
04969 pds->username = strsep(&data, ":");
04970 pds->password = data;
04971 }
04972
04973 data = pds->peer;
04974 pds->peer = strsep(&data, ":");
04975 pds->port = data;
04976
04977
04978
04979
04980 if (pds->password && (pds->password[0] == '[')) {
04981 pds->key = ast_strip_quoted(pds->password, "[", "]");
04982 pds->password = NULL;
04983 }
04984 }
04985
04986 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04987 {
04988 struct sockaddr_in sin;
04989 char *l=NULL, *n=NULL, *tmpstr;
04990 struct iax_ie_data ied;
04991 char *defaultrdest = "s";
04992 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04993 struct parsed_dial_string pds;
04994 struct create_addr_info cai;
04995 struct ast_var_t *var;
04996 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04997 const char* osp_token_ptr;
04998 unsigned int osp_token_length;
04999 unsigned char osp_block_index;
05000 unsigned int osp_block_length;
05001 unsigned char osp_buffer[256];
05002
05003 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05004 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
05005 return -1;
05006 }
05007
05008 memset(&cai, 0, sizeof(cai));
05009 cai.encmethods = iax2_encryption;
05010
05011 memset(&pds, 0, sizeof(pds));
05012 tmpstr = ast_strdupa(dest);
05013 parse_dial_string(tmpstr, &pds);
05014
05015 if (ast_strlen_zero(pds.peer)) {
05016 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05017 return -1;
05018 }
05019 if (!pds.exten) {
05020 pds.exten = defaultrdest;
05021 }
05022 if (create_addr(pds.peer, c, &sin, &cai)) {
05023 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05024 return -1;
05025 }
05026 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05027 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05028 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05029 return -1;
05030 }
05031 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05032 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05033 return -1;
05034 }
05035 if (!pds.username && !ast_strlen_zero(cai.username))
05036 pds.username = cai.username;
05037 if (!pds.password && !ast_strlen_zero(cai.secret))
05038 pds.password = cai.secret;
05039 if (!pds.key && !ast_strlen_zero(cai.outkey))
05040 pds.key = cai.outkey;
05041 if (!pds.context && !ast_strlen_zero(cai.peercontext))
05042 pds.context = cai.peercontext;
05043
05044
05045 ast_copy_string(c->context, cai.context, sizeof(c->context));
05046
05047 if (pds.port)
05048 sin.sin_port = htons(atoi(pds.port));
05049
05050 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05051 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05052
05053
05054 memset(&ied, 0, sizeof(ied));
05055
05056
05057 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05058 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05059 if (pds.options && strchr(pds.options, 'a')) {
05060
05061 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05062 }
05063
05064
05065 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05066
05067 if (l) {
05068 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05069 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05070 ast_party_id_presentation(&c->connected.id));
05071 } else if (n) {
05072 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05073 ast_party_id_presentation(&c->connected.id));
05074 } else {
05075 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05076 }
05077
05078 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05079 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05080
05081 if (n)
05082 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05083 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05084 && c->connected.ani.number.valid
05085 && c->connected.ani.number.str) {
05086 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05087 }
05088
05089 if (!ast_strlen_zero(c->language))
05090 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
05091 if (!ast_strlen_zero(c->dialed.number.str)) {
05092 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05093 }
05094 if (c->redirecting.from.number.valid
05095 && !ast_strlen_zero(c->redirecting.from.number.str)) {
05096 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05097 }
05098
05099 if (pds.context)
05100 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05101
05102 if (pds.username)
05103 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05104
05105 if (cai.encmethods)
05106 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05107
05108 ast_mutex_lock(&iaxsl[callno]);
05109
05110 if (!ast_strlen_zero(c->context))
05111 ast_string_field_set(iaxs[callno], context, c->context);
05112
05113 if (pds.username)
05114 ast_string_field_set(iaxs[callno], username, pds.username);
05115
05116 iaxs[callno]->encmethods = cai.encmethods;
05117
05118 iaxs[callno]->adsi = cai.adsi;
05119
05120 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05121 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05122
05123 if (pds.key)
05124 ast_string_field_set(iaxs[callno], outkey, pds.key);
05125 if (pds.password)
05126 ast_string_field_set(iaxs[callno], secret, pds.password);
05127
05128 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
05129 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
05130 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05131 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05132 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05133 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05134
05135 if (iaxs[callno]->maxtime) {
05136
05137 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05138 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05139 } else if (autokill) {
05140 iaxs[callno]->pingtime = autokill / 2;
05141 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05142 }
05143
05144
05145 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05146 if (!ast_strlen_zero(osp_token_ptr)) {
05147 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05148 osp_block_index = 0;
05149 while (osp_token_length > 0) {
05150 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05151 osp_buffer[0] = osp_block_index;
05152 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05153 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05154 osp_block_index++;
05155 osp_token_ptr += osp_block_length;
05156 osp_token_length -= osp_block_length;
05157 }
05158 } else
05159 ast_log(LOG_WARNING, "OSP token is too long\n");
05160 } else if (iaxdebug)
05161 ast_debug(1, "OSP token is undefined\n");
05162
05163
05164 iaxs[callno]->sockfd = cai.sockfd;
05165
05166
05167 if (variablestore) {
05168 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05169 ast_debug(1, "Found an IAX variable store on this channel\n");
05170 AST_LIST_LOCK(variablelist);
05171 AST_LIST_TRAVERSE(variablelist, var, entries) {
05172 char tmp[256];
05173 int i;
05174 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05175
05176 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05177 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05178 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05179 }
05180 }
05181 AST_LIST_UNLOCK(variablelist);
05182 }
05183
05184
05185 add_empty_calltoken_ie(iaxs[callno], &ied);
05186 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05187
05188 ast_mutex_unlock(&iaxsl[callno]);
05189 ast_setstate(c, AST_STATE_RINGING);
05190
05191 return 0;
05192 }
05193
05194 static int iax2_hangup(struct ast_channel *c)
05195 {
05196 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05197 struct iax_ie_data ied;
05198 int alreadygone;
05199 memset(&ied, 0, sizeof(ied));
05200 ast_mutex_lock(&iaxsl[callno]);
05201 if (callno && iaxs[callno]) {
05202 ast_debug(1, "We're hanging up %s now...\n", c->name);
05203 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05204
05205 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05206 if (!iaxs[callno]->error && !alreadygone) {
05207 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05208 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05209 }
05210 if (!iaxs[callno]) {
05211 ast_mutex_unlock(&iaxsl[callno]);
05212 return 0;
05213 }
05214 }
05215
05216 iax2_predestroy(callno);
05217
05218 if (iaxs[callno] && alreadygone) {
05219 ast_debug(1, "Really destroying %s now...\n", c->name);
05220 iax2_destroy(callno);
05221 } else if (iaxs[callno]) {
05222 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05223 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05224 iax2_destroy(callno);
05225 }
05226 }
05227 } else if (c->tech_pvt) {
05228
05229
05230
05231
05232 c->tech_pvt = NULL;
05233 }
05234 ast_mutex_unlock(&iaxsl[callno]);
05235 ast_verb(3, "Hungup '%s'\n", c->name);
05236 return 0;
05237 }
05238
05239
05240
05241
05242 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05243 {
05244 unsigned short callno = pvt->callno;
05245
05246 if (!pvt->peercallno) {
05247
05248 int count = 10;
05249 while (count-- && pvt && !pvt->peercallno) {
05250 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05251 pvt = iaxs[callno];
05252 }
05253 if (!pvt->peercallno) {
05254 return -1;
05255 }
05256 }
05257
05258 return 0;
05259 }
05260
05261 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05262 {
05263 struct ast_option_header *h;
05264 int res;
05265
05266 switch (option) {
05267 case AST_OPTION_TXGAIN:
05268 case AST_OPTION_RXGAIN:
05269
05270 errno = ENOSYS;
05271 return -1;
05272 case AST_OPTION_OPRMODE:
05273 errno = EINVAL;
05274 return -1;
05275 case AST_OPTION_SECURE_SIGNALING:
05276 case AST_OPTION_SECURE_MEDIA:
05277 {
05278 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05279 ast_mutex_lock(&iaxsl[callno]);
05280 if ((*(int *) data)) {
05281 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05282 } else {
05283 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05284 }
05285 ast_mutex_unlock(&iaxsl[callno]);
05286 return 0;
05287 }
05288
05289
05290
05291
05292 case AST_OPTION_TONE_VERIFY:
05293 case AST_OPTION_TDD:
05294 case AST_OPTION_RELAXDTMF:
05295 case AST_OPTION_AUDIO_MODE:
05296 case AST_OPTION_DIGIT_DETECT:
05297 case AST_OPTION_FAX_DETECT:
05298 {
05299 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05300 struct chan_iax2_pvt *pvt;
05301
05302 ast_mutex_lock(&iaxsl[callno]);
05303 pvt = iaxs[callno];
05304
05305 if (wait_for_peercallno(pvt)) {
05306 ast_mutex_unlock(&iaxsl[callno]);
05307 return -1;
05308 }
05309
05310 ast_mutex_unlock(&iaxsl[callno]);
05311
05312 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05313 return -1;
05314 }
05315
05316 h->flag = AST_OPTION_FLAG_REQUEST;
05317 h->option = htons(option);
05318 memcpy(h->data, data, datalen);
05319 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05320 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05321 datalen + sizeof(*h), -1);
05322 ast_free(h);
05323 return res;
05324 }
05325 default:
05326 return -1;
05327 }
05328
05329
05330 return -1;
05331 }
05332
05333 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
05334 {
05335 switch (option) {
05336 case AST_OPTION_SECURE_SIGNALING:
05337 case AST_OPTION_SECURE_MEDIA:
05338 {
05339 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05340 ast_mutex_lock(&iaxsl[callno]);
05341 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05342 ast_mutex_unlock(&iaxsl[callno]);
05343 return 0;
05344 }
05345 default:
05346 return -1;
05347 }
05348 }
05349
05350 static struct ast_frame *iax2_read(struct ast_channel *c)
05351 {
05352 ast_debug(1, "I should never be called!\n");
05353 return &ast_null_frame;
05354 }
05355
05356 static int iax2_key_rotate(const void *vpvt)
05357 {
05358 int res = 0;
05359 struct chan_iax2_pvt *pvt = (void *) vpvt;
05360 struct MD5Context md5;
05361 char key[17] = "";
05362 struct iax_ie_data ied = {
05363 .pos = 0,
05364 };
05365
05366 ast_mutex_lock(&iaxsl[pvt->callno]);
05367 pvt->keyrotateid =
05368 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05369
05370 snprintf(key, sizeof(key), "%lX", ast_random());
05371
05372 MD5Init(&md5);
05373 MD5Update(&md5, (unsigned char *) key, strlen(key));
05374 MD5Final((unsigned char *) key, &md5);
05375
05376 IAX_DEBUGDIGEST("Sending", key);
05377
05378 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05379
05380 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05381
05382 build_ecx_key((unsigned char *) key, pvt);
05383
05384 ast_mutex_unlock(&iaxsl[pvt->callno]);
05385
05386 return res;
05387 }
05388
05389 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05390 {
05391 int res;
05392 struct iax_ie_data ied0;
05393 struct iax_ie_data ied1;
05394 unsigned int transferid = (unsigned int)ast_random();
05395
05396 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05397 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05398 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05399 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05400 return 0;
05401 }
05402
05403 memset(&ied0, 0, sizeof(ied0));
05404 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05405 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05406 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05407
05408 memset(&ied1, 0, sizeof(ied1));
05409 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05410 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05411 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05412
05413 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05414 if (res)
05415 return -1;
05416 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05417 if (res)
05418 return -1;
05419 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05420 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05421 return 0;
05422 }
05423
05424 static void lock_both(unsigned short callno0, unsigned short callno1)
05425 {
05426 ast_mutex_lock(&iaxsl[callno0]);
05427 while (ast_mutex_trylock(&iaxsl[callno1])) {
05428 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05429 }
05430 }
05431
05432 static void unlock_both(unsigned short callno0, unsigned short callno1)
05433 {
05434 ast_mutex_unlock(&iaxsl[callno1]);
05435 ast_mutex_unlock(&iaxsl[callno0]);
05436 }
05437
05438 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)
05439 {
05440 struct ast_channel *cs[3];
05441 struct ast_channel *who, *other;
05442 int to = -1;
05443 int res = -1;
05444 int transferstarted=0;
05445 struct ast_frame *f;
05446 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05447 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05448 struct timeval waittimer = {0, 0};
05449
05450
05451 if (timeoutms > 0) {
05452 return AST_BRIDGE_FAILED;
05453 }
05454
05455 timeoutms = -1;
05456
05457 lock_both(callno0, callno1);
05458 if (!iaxs[callno0] || !iaxs[callno1]) {
05459 unlock_both(callno0, callno1);
05460 return AST_BRIDGE_FAILED;
05461 }
05462
05463 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05464 iaxs[callno0]->bridgecallno = callno1;
05465 iaxs[callno1]->bridgecallno = callno0;
05466 }
05467 unlock_both(callno0, callno1);
05468
05469
05470 cs[0] = c0;
05471 cs[1] = c1;
05472 for (;;) {
05473
05474 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05475 ast_verb(3, "Can't masquerade, we're different...\n");
05476
05477 if (c0->tech == &iax2_tech) {
05478 ast_mutex_lock(&iaxsl[callno0]);
05479 iaxs[callno0]->bridgecallno = 0;
05480 ast_mutex_unlock(&iaxsl[callno0]);
05481 }
05482 if (c1->tech == &iax2_tech) {
05483 ast_mutex_lock(&iaxsl[callno1]);
05484 iaxs[callno1]->bridgecallno = 0;
05485 ast_mutex_unlock(&iaxsl[callno1]);
05486 }
05487 return AST_BRIDGE_FAILED_NOWARN;
05488 }
05489 if (c0->nativeformats != c1->nativeformats) {
05490 char buf0[256];
05491 char buf1[256];
05492 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05493 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05494 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05495
05496 lock_both(callno0, callno1);
05497 if (iaxs[callno0])
05498 iaxs[callno0]->bridgecallno = 0;
05499 if (iaxs[callno1])
05500 iaxs[callno1]->bridgecallno = 0;
05501 unlock_both(callno0, callno1);
05502 return AST_BRIDGE_FAILED_NOWARN;
05503 }
05504
05505 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05506
05507 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05508 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05509 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05510 transferstarted = 1;
05511 }
05512 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05513
05514 struct timeval now = ast_tvnow();
05515 if (ast_tvzero(waittimer)) {
05516 waittimer = now;
05517 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05518 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05519 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05520 *fo = NULL;
05521 *rc = c0;
05522 res = AST_BRIDGE_COMPLETE;
05523 break;
05524 }
05525 }
05526 to = 1000;
05527 who = ast_waitfor_n(cs, 2, &to);
05528 if (timeoutms > -1) {
05529 timeoutms -= (1000 - to);
05530 if (timeoutms < 0)
05531 timeoutms = 0;
05532 }
05533 if (!who) {
05534 if (!timeoutms) {
05535 res = AST_BRIDGE_RETRY;
05536 break;
05537 }
05538 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05539 res = AST_BRIDGE_FAILED;
05540 break;
05541 }
05542 continue;
05543 }
05544 f = ast_read(who);
05545 if (!f) {
05546 *fo = NULL;
05547 *rc = who;
05548 res = AST_BRIDGE_COMPLETE;
05549 break;
05550 }
05551 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05552 *fo = f;
05553 *rc = who;
05554 res = AST_BRIDGE_COMPLETE;
05555 break;
05556 }
05557 other = (who == c0) ? c1 : c0;
05558 if ((f->frametype == AST_FRAME_VOICE) ||
05559 (f->frametype == AST_FRAME_TEXT) ||
05560 (f->frametype == AST_FRAME_VIDEO) ||
05561 (f->frametype == AST_FRAME_IMAGE) ||
05562 (f->frametype == AST_FRAME_DTMF) ||
05563 (f->frametype == AST_FRAME_CONTROL)) {
05564
05565
05566
05567 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05568 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05569 *rc = who;
05570 *fo = f;
05571 res = AST_BRIDGE_COMPLETE;
05572
05573 break;
05574 }
05575
05576 ast_write(other, f);
05577 }
05578 ast_frfree(f);
05579
05580 cs[2] = cs[0];
05581 cs[0] = cs[1];
05582 cs[1] = cs[2];
05583 }
05584 lock_both(callno0, callno1);
05585 if(iaxs[callno0])
05586 iaxs[callno0]->bridgecallno = 0;
05587 if(iaxs[callno1])
05588 iaxs[callno1]->bridgecallno = 0;
05589 unlock_both(callno0, callno1);
05590 return res;
05591 }
05592
05593 static int iax2_answer(struct ast_channel *c)
05594 {
05595 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05596 ast_debug(1, "Answering IAX2 call\n");
05597 ast_mutex_lock(&iaxsl[callno]);
05598 if (iaxs[callno])
05599 iax2_ami_channelupdate(iaxs[callno]);
05600 ast_mutex_unlock(&iaxsl[callno]);
05601 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05602 }
05603
05604 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05605 {
05606 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05607 struct chan_iax2_pvt *pvt;
05608 int res = 0;
05609
05610 if (iaxdebug)
05611 ast_debug(1, "Indicating condition %d\n", condition);
05612
05613 ast_mutex_lock(&iaxsl[callno]);
05614 pvt = iaxs[callno];
05615
05616 if (wait_for_peercallno(pvt)) {
05617 res = -1;
05618 goto done;
05619 }
05620
05621 switch (condition) {
05622 case AST_CONTROL_HOLD:
05623 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05624 ast_moh_start(c, data, pvt->mohinterpret);
05625 goto done;
05626 }
05627 break;
05628 case AST_CONTROL_UNHOLD:
05629 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05630 ast_moh_stop(c);
05631 goto done;
05632 }
05633 break;
05634 case AST_CONTROL_CONNECTED_LINE:
05635 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05636 goto done;
05637 break;
05638 }
05639
05640 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05641
05642 done:
05643 ast_mutex_unlock(&iaxsl[callno]);
05644
05645 return res;
05646 }
05647
05648 static int iax2_transfer(struct ast_channel *c, const char *dest)
05649 {
05650 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05651 struct iax_ie_data ied = { "", };
05652 char tmp[256], *context;
05653 enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05654 ast_copy_string(tmp, dest, sizeof(tmp));
05655 context = strchr(tmp, '@');
05656 if (context) {
05657 *context = '\0';
05658 context++;
05659 }
05660 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05661 if (context)
05662 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05663 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05664 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05665 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05666 }
05667
05668 static int iax2_getpeertrunk(struct sockaddr_in sin)
05669 {
05670 struct iax2_peer *peer;
05671 int res = 0;
05672 struct ao2_iterator i;
05673
05674 i = ao2_iterator_init(peers, 0);
05675 while ((peer = ao2_iterator_next(&i))) {
05676 struct sockaddr_in peer_addr;
05677
05678 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05679
05680 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05681 (peer_addr.sin_port == sin.sin_port)) {
05682 res = ast_test_flag64(peer, IAX_TRUNK);
05683 peer_unref(peer);
05684 break;
05685 }
05686 peer_unref(peer);
05687 }
05688 ao2_iterator_destroy(&i);
05689
05690 return res;
05691 }
05692
05693
05694 static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
05695 {
05696 struct ast_channel *tmp;
05697 struct chan_iax2_pvt *i;
05698 struct ast_variable *v = NULL;
05699
05700 if (!(i = iaxs[callno])) {
05701 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05702 return NULL;
05703 }
05704
05705
05706 ast_mutex_unlock(&iaxsl[callno]);
05707 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
05708 ast_mutex_lock(&iaxsl[callno]);
05709 if (i != iaxs[callno]) {
05710 if (tmp) {
05711
05712 ast_mutex_unlock(&iaxsl[callno]);
05713 tmp = ast_channel_release(tmp);
05714 ast_mutex_lock(&iaxsl[callno]);
05715 }
05716 return NULL;
05717 }
05718 iax2_ami_channelupdate(i);
05719 if (!tmp)
05720 return NULL;
05721 tmp->tech = &iax2_tech;
05722
05723 tmp->nativeformats = capability;
05724 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05725 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05726 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05727
05728 if (!ast_strlen_zero(i->parkinglot))
05729 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05730
05731
05732 if (!ast_strlen_zero(i->ani)) {
05733 tmp->caller.ani.number.valid = 1;
05734 tmp->caller.ani.number.str = ast_strdup(i->ani);
05735 } else if (!ast_strlen_zero(i->cid_num)) {
05736 tmp->caller.ani.number.valid = 1;
05737 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05738 }
05739 tmp->dialed.number.str = ast_strdup(i->dnid);
05740 if (!ast_strlen_zero(i->rdnis)) {
05741 tmp->redirecting.from.number.valid = 1;
05742 tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05743 }
05744 tmp->caller.id.name.presentation = i->calling_pres;
05745 tmp->caller.id.number.presentation = i->calling_pres;
05746 tmp->caller.id.number.plan = i->calling_ton;
05747 tmp->dialed.transit_network_select = i->calling_tns;
05748 if (!ast_strlen_zero(i->language))
05749 ast_string_field_set(tmp, language, i->language);
05750 if (!ast_strlen_zero(i->accountcode))
05751 ast_string_field_set(tmp, accountcode, i->accountcode);
05752 if (i->amaflags)
05753 tmp->amaflags = i->amaflags;
05754 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05755 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05756 if (i->adsi)
05757 tmp->adsicpe = i->peeradsicpe;
05758 else
05759 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05760 i->owner = tmp;
05761 i->capability = capability;
05762
05763
05764 if (i->vars) {
05765 for (v = i->vars ; v ; v = v->next)
05766 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05767 }
05768 if (i->iaxvars) {
05769 struct ast_datastore *variablestore;
05770 struct ast_variable *var, *prev = NULL;
05771 AST_LIST_HEAD(, ast_var_t) *varlist;
05772 ast_debug(1, "Loading up the channel with IAXVARs\n");
05773 varlist = ast_calloc(1, sizeof(*varlist));
05774 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05775 if (variablestore && varlist) {
05776 variablestore->data = varlist;
05777 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05778 AST_LIST_HEAD_INIT(varlist);
05779 for (var = i->iaxvars; var; var = var->next) {
05780 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05781 if (prev)
05782 ast_free(prev);
05783 prev = var;
05784 if (!newvar) {
05785
05786 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05787 } else {
05788 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05789 }
05790 }
05791 if (prev)
05792 ast_free(prev);
05793 i->iaxvars = NULL;
05794 ast_channel_datastore_add(i->owner, variablestore);
05795 } else {
05796 if (variablestore) {
05797 ast_datastore_free(variablestore);
05798 }
05799 if (varlist) {
05800 ast_free(varlist);
05801 }
05802 }
05803 }
05804
05805 if (state != AST_STATE_DOWN) {
05806 if (ast_pbx_start(tmp)) {
05807 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05808 ast_hangup(tmp);
05809 i->owner = NULL;
05810 return NULL;
05811 }
05812 }
05813
05814 ast_module_ref(ast_module_info->self);
05815 return tmp;
05816 }
05817
05818 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05819 {
05820 unsigned long int mssincetx;
05821 long int ms, pred;
05822
05823 tpeer->trunkact = *now;
05824 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05825 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05826
05827 tpeer->txtrunktime = *now;
05828 tpeer->lastsent = 999999;
05829 }
05830
05831 tpeer->lasttxtime = *now;
05832
05833
05834 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05835
05836 pred = tpeer->lastsent + sampms;
05837 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05838 ms = pred;
05839
05840
05841 if (ms == tpeer->lastsent)
05842 ms = tpeer->lastsent + 1;
05843 tpeer->lastsent = ms;
05844 return ms;
05845 }
05846
05847 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05848 {
05849 long ms;
05850 if (ast_tvzero(iaxs[callno]->rxcore)) {
05851
05852 iaxs[callno]->rxcore = ast_tvnow();
05853
05854 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05855 }
05856
05857 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05858
05859 return ms + ts;
05860 }
05861
05862 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05863 {
05864 int ms;
05865 int voice = 0;
05866 int genuine = 0;
05867 int adjust;
05868 int rate = ast_format_rate(f->subclass.codec) / 1000;
05869 struct timeval *delivery = NULL;
05870
05871
05872
05873
05874
05875
05876
05877
05878 if (f) {
05879 if (f->frametype == AST_FRAME_VOICE) {
05880 voice = 1;
05881 delivery = &f->delivery;
05882 } else if (f->frametype == AST_FRAME_IAX) {
05883 genuine = 1;
05884 } else if (f->frametype == AST_FRAME_CNG) {
05885 p->notsilenttx = 0;
05886 }
05887 }
05888 if (ast_tvzero(p->offset)) {
05889 p->offset = ast_tvnow();
05890
05891 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05892 }
05893
05894 if (ts)
05895 return ts;
05896
05897 if (delivery && !ast_tvzero(*delivery)) {
05898 ms = ast_tvdiff_ms(*delivery, p->offset);
05899 if (ms < 0) {
05900 ms = 0;
05901 }
05902 if (iaxdebug)
05903 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05904 } else {
05905 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05906 if (ms < 0)
05907 ms = 0;
05908 if (voice) {
05909
05910 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921
05922
05923
05924
05925
05926
05927
05928
05929 adjust = (ms - p->nextpred);
05930 if (adjust < 0)
05931 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05932 else if (adjust > 0)
05933 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05934
05935 if (!p->nextpred) {
05936 p->nextpred = ms;
05937 if (p->nextpred <= p->lastsent)
05938 p->nextpred = p->lastsent + 3;
05939 }
05940 ms = p->nextpred;
05941 } else {
05942
05943
05944
05945
05946
05947
05948
05949
05950
05951 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05952 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05953 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05954
05955 if (f->samples >= rate)
05956 {
05957 int diff = ms % (f->samples / rate);
05958 if (diff)
05959 ms += f->samples/rate - diff;
05960 }
05961
05962 p->nextpred = ms;
05963 p->notsilenttx = 1;
05964 }
05965 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05966
05967
05968
05969
05970
05971
05972
05973
05974 if ( (unsigned int)ms < p->lastsent )
05975 ms = p->lastsent;
05976 } else {
05977
05978
05979 if (genuine) {
05980
05981 if (ms <= p->lastsent)
05982 ms = p->lastsent + 3;
05983 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05984
05985 ms = p->lastsent + 3;
05986 }
05987 }
05988 }
05989 p->lastsent = ms;
05990 if (voice)
05991 p->nextpred = p->nextpred + f->samples / rate;
05992 return ms;
05993 }
05994
05995 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05996 {
05997
05998
05999 int ms;
06000 #ifdef IAXTESTS
06001 int jit;
06002 #endif
06003
06004 if (ast_tvzero(p->rxcore)) {
06005 p->rxcore = ast_tvnow();
06006 if (iaxdebug)
06007 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06008 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06009 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06010 #if 1
06011 if (iaxdebug)
06012 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06013 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06014 #endif
06015 }
06016
06017 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06018 #ifdef IAXTESTS
06019 if (test_jit) {
06020 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06021 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06022 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06023 jit = -jit;
06024 ms += jit;
06025 }
06026 }
06027 if (test_late) {
06028 ms += test_late;
06029 test_late = 0;
06030 }
06031 #endif
06032 return ms;
06033 }
06034
06035 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
06036 {
06037 struct iax2_trunk_peer *tpeer = NULL;
06038
06039
06040 AST_LIST_LOCK(&tpeers);
06041
06042 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06043 if (!inaddrcmp(&tpeer->addr, sin)) {
06044 ast_mutex_lock(&tpeer->lock);
06045 break;
06046 }
06047 }
06048
06049 if (!tpeer) {
06050 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06051 ast_mutex_init(&tpeer->lock);
06052 tpeer->lastsent = 9999;
06053 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06054 tpeer->trunkact = ast_tvnow();
06055 ast_mutex_lock(&tpeer->lock);
06056 tpeer->sockfd = fd;
06057 #ifdef SO_NO_CHECK
06058 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06059 #endif
06060 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06061 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06062 }
06063 }
06064
06065 AST_LIST_UNLOCK(&tpeers);
06066
06067 return tpeer;
06068 }
06069
06070 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
06071 {
06072 struct ast_frame *f;
06073 struct iax2_trunk_peer *tpeer;
06074 void *tmp, *ptr;
06075 struct timeval now;
06076 struct ast_iax2_meta_trunk_entry *met;
06077 struct ast_iax2_meta_trunk_mini *mtm;
06078
06079 f = &fr->af;
06080 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06081 if (tpeer) {
06082 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06083
06084 if (tpeer->trunkdataalloc < trunkmaxsize) {
06085 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06086 ast_mutex_unlock(&tpeer->lock);
06087 return -1;
06088 }
06089
06090 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06091 tpeer->trunkdata = tmp;
06092 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);
06093 } else {
06094 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));
06095 ast_mutex_unlock(&tpeer->lock);
06096 return -1;
06097 }
06098 }
06099
06100
06101 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06102 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06103 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06104 mtm->len = htons(f->datalen);
06105 mtm->mini.callno = htons(pvt->callno);
06106 mtm->mini.ts = htons(0xffff & fr->ts);
06107 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06108 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06109 } else {
06110 met = (struct ast_iax2_meta_trunk_entry *)ptr;
06111
06112 met->callno = htons(pvt->callno);
06113 met->len = htons(f->datalen);
06114
06115 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06116 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06117 }
06118
06119 memcpy(ptr, f->data.ptr, f->datalen);
06120 tpeer->trunkdatalen += f->datalen;
06121
06122 tpeer->calls++;
06123
06124
06125 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
06126 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
06127
06128
06129 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06130 now = ast_tvnow();
06131 send_trunk(tpeer, &now);
06132 trunk_untimed ++;
06133 }
06134
06135 ast_mutex_unlock(&tpeer->lock);
06136 }
06137 return 0;
06138 }
06139
06140
06141
06142 static void build_rand_pad(unsigned char *buf, ssize_t len)
06143 {
06144 long tmp;
06145 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06146 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06147 buf += sizeof(tmp);
06148 len -= sizeof(tmp);
06149 }
06150 }
06151
06152 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06153 {
06154 build_ecx_key(digest, pvt);
06155 ast_aes_set_decrypt_key(digest, &pvt->dcx);
06156 }
06157
06158 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06159 {
06160
06161
06162
06163 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06164 ast_aes_set_encrypt_key(digest, &pvt->ecx);
06165 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06166 }
06167
06168 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
06169 {
06170 #if 0
06171
06172 int x;
06173 if (len % 16)
06174 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06175 for (x=0;x<len;x++)
06176 dst[x] = src[x] ^ 0xff;
06177 #else
06178 unsigned char lastblock[16] = { 0 };
06179 int x;
06180 while(len > 0) {
06181 ast_aes_decrypt(src, dst, dcx);
06182 for (x=0;x<16;x++)
06183 dst[x] ^= lastblock[x];
06184 memcpy(lastblock, src, sizeof(lastblock));
06185 dst += 16;
06186 src += 16;
06187 len -= 16;
06188 }
06189 #endif
06190 }
06191
06192 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
06193 {
06194 #if 0
06195
06196 int x;
06197 if (len % 16)
06198 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06199 for (x=0;x<len;x++)
06200 dst[x] = src[x] ^ 0xff;
06201 #else
06202 unsigned char curblock[16] = { 0 };
06203 int x;
06204 while(len > 0) {
06205 for (x=0;x<16;x++)
06206 curblock[x] ^= src[x];
06207 ast_aes_encrypt(curblock, dst, ecx);
06208 memcpy(curblock, dst, sizeof(curblock));
06209 dst += 16;
06210 src += 16;
06211 len -= 16;
06212 }
06213 #endif
06214 }
06215
06216 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06217 {
06218 int padding;
06219 unsigned char *workspace;
06220
06221 workspace = alloca(*datalen);
06222 memset(f, 0, sizeof(*f));
06223 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06224 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06225 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06226 return -1;
06227
06228 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06229
06230 padding = 16 + (workspace[15] & 0x0f);
06231 if (iaxdebug)
06232 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06233 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06234 return -1;
06235
06236 *datalen -= padding;
06237 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06238 f->frametype = fh->type;
06239 if (f->frametype == AST_FRAME_VIDEO) {
06240 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06241 } else if (f->frametype == AST_FRAME_VOICE) {
06242 f->subclass.codec = uncompress_subclass(fh->csub);
06243 } else {
06244 f->subclass.integer = uncompress_subclass(fh->csub);
06245 }
06246 } else {
06247 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06248 if (iaxdebug)
06249 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06250 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06251 return -1;
06252
06253 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06254 padding = 16 + (workspace[15] & 0x0f);
06255 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06256 return -1;
06257 *datalen -= padding;
06258 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06259 }
06260 return 0;
06261 }
06262
06263 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06264 {
06265 int padding;
06266 unsigned char *workspace;
06267 workspace = alloca(*datalen + 32);
06268 if (!workspace)
06269 return -1;
06270 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06271 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06272 if (iaxdebug)
06273 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06274 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06275 padding = 16 + (padding & 0xf);
06276 memcpy(workspace, poo, padding);
06277 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06278 workspace[15] &= 0xf0;
06279 workspace[15] |= (padding & 0xf);
06280 if (iaxdebug)
06281 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06282 *datalen += padding;
06283 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06284 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06285 memcpy(poo, workspace + *datalen - 32, 32);
06286 } else {
06287 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06288 if (iaxdebug)
06289 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06290 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06291 padding = 16 + (padding & 0xf);
06292 memcpy(workspace, poo, padding);
06293 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06294 workspace[15] &= 0xf0;
06295 workspace[15] |= (padding & 0x0f);
06296 *datalen += padding;
06297 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06298 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06299 memcpy(poo, workspace + *datalen - 32, 32);
06300 }
06301 return 0;
06302 }
06303
06304 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06305 {
06306 int res=-1;
06307 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06308
06309 struct MD5Context md5;
06310 unsigned char digest[16];
06311 char *tmppw, *stringp;
06312
06313 tmppw = ast_strdupa(iaxs[callno]->secret);
06314 stringp = tmppw;
06315 while ((tmppw = strsep(&stringp, ";"))) {
06316 MD5Init(&md5);
06317 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06318 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06319 MD5Final(digest, &md5);
06320 build_encryption_keys(digest, iaxs[callno]);
06321 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06322 if (!res) {
06323 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06324 break;
06325 }
06326 }
06327 } else
06328 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06329 return res;
06330 }
06331
06332 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06333 {
06334
06335
06336
06337 struct ast_iax2_full_hdr *fh;
06338 struct ast_iax2_mini_hdr *mh;
06339 struct ast_iax2_video_hdr *vh;
06340 struct {
06341 struct iax_frame fr2;
06342 unsigned char buffer[4096];
06343 } frb;
06344 struct iax_frame *fr;
06345 int res;
06346 int sendmini=0;
06347 unsigned int lastsent;
06348 unsigned int fts;
06349
06350 frb.fr2.afdatalen = sizeof(frb.buffer);
06351
06352 if (!pvt) {
06353 ast_log(LOG_WARNING, "No private structure for packet?\n");
06354 return -1;
06355 }
06356
06357 lastsent = pvt->lastsent;
06358
06359
06360 fts = calc_timestamp(pvt, ts, f);
06361
06362
06363
06364
06365 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06366 return 0;
06367 #if 0
06368 ast_log(LOG_NOTICE,
06369 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06370 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06371 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06372 pvt->keyrotateid != -1 ? "" : "no "
06373 );
06374 #endif
06375 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06376 iax2_key_rotate(pvt);
06377 }
06378
06379 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
06380 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06381 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06382 &&
06383 (f->frametype == AST_FRAME_VOICE)
06384 &&
06385 (f->subclass.codec == pvt->svoiceformat)
06386 ) {
06387
06388 now = 1;
06389
06390 sendmini = 1;
06391 }
06392 if ( f->frametype == AST_FRAME_VIDEO ) {
06393
06394
06395
06396
06397
06398 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06399 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06400 ) {
06401 now = 1;
06402 sendmini = 1;
06403 } else {
06404 now = 0;
06405 sendmini = 0;
06406 }
06407 pvt->lastvsent = fts;
06408 }
06409 if (f->frametype == AST_FRAME_IAX) {
06410
06411 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06412 if (!pvt->first_iax_message) {
06413 pvt->first_iax_message = pvt->last_iax_message;
06414 }
06415 }
06416
06417 if (now) {
06418 fr = &frb.fr2;
06419 } else
06420 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag64(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO));
06421 if (!fr) {
06422 ast_log(LOG_WARNING, "Out of memory\n");
06423 return -1;
06424 }
06425
06426 iax_frame_wrap(fr, f);
06427
06428 fr->ts = fts;
06429 fr->callno = pvt->callno;
06430 fr->transfer = transfer;
06431 fr->final = final;
06432 fr->encmethods = 0;
06433 if (!sendmini) {
06434
06435 if (seqno > -1)
06436 fr->oseqno = seqno;
06437 else
06438 fr->oseqno = pvt->oseqno++;
06439 fr->iseqno = pvt->iseqno;
06440 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06441 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06442 fh->ts = htonl(fr->ts);
06443 fh->oseqno = fr->oseqno;
06444 if (transfer) {
06445 fh->iseqno = 0;
06446 } else
06447 fh->iseqno = fr->iseqno;
06448
06449 if (!transfer)
06450 pvt->aseqno = fr->iseqno;
06451 fh->type = fr->af.frametype & 0xFF;
06452
06453 if (fr->af.frametype == AST_FRAME_VIDEO) {
06454 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06455 } else if (fr->af.frametype == AST_FRAME_VOICE) {
06456 fh->csub = compress_subclass(fr->af.subclass.codec);
06457 } else {
06458 fh->csub = compress_subclass(fr->af.subclass.integer);
06459 }
06460
06461 if (transfer) {
06462 fr->dcallno = pvt->transfercallno;
06463 } else
06464 fr->dcallno = pvt->peercallno;
06465 fh->dcallno = htons(fr->dcallno);
06466 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06467 fr->data = fh;
06468 fr->retries = 0;
06469
06470 fr->retrytime = pvt->pingtime * 2;
06471 if (fr->retrytime < MIN_RETRY_TIME)
06472 fr->retrytime = MIN_RETRY_TIME;
06473 if (fr->retrytime > MAX_RETRY_TIME)
06474 fr->retrytime = MAX_RETRY_TIME;
06475
06476 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06477 fr->retries = -1;
06478 else if (f->frametype == AST_FRAME_VOICE)
06479 pvt->svoiceformat = f->subclass.codec;
06480 else if (f->frametype == AST_FRAME_VIDEO)
06481 pvt->svideoformat = f->subclass.codec & ~0x1LL;
06482 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06483 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06484 if (fr->transfer)
06485 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06486 else
06487 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06488 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06489 fr->encmethods = pvt->encmethods;
06490 fr->ecx = pvt->ecx;
06491 fr->mydcx = pvt->mydcx;
06492 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06493 } else
06494 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06495 }
06496
06497 if (now) {
06498 res = send_packet(fr);
06499 } else
06500 res = iax2_transmit(fr);
06501 } else {
06502 if (ast_test_flag64(pvt, IAX_TRUNK)) {
06503 iax2_trunk_queue(pvt, fr);
06504 res = 0;
06505 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06506
06507 fr->oseqno = -1;
06508 fr->iseqno = -1;
06509 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06510 vh->zeros = 0;
06511 vh->callno = htons(0x8000 | fr->callno);
06512 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06513 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06514 fr->data = vh;
06515 fr->retries = -1;
06516 res = send_packet(fr);
06517 } else {
06518
06519 fr->oseqno = -1;
06520 fr->iseqno = -1;
06521
06522 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06523 mh->callno = htons(fr->callno);
06524 mh->ts = htons(fr->ts & 0xFFFF);
06525 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06526 fr->data = mh;
06527 fr->retries = -1;
06528 if (pvt->transferring == TRANSFER_MEDIAPASS)
06529 fr->transfer = 1;
06530 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06531 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06532 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06533 } else
06534 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06535 }
06536 res = send_packet(fr);
06537 }
06538 }
06539 return res;
06540 }
06541
06542 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06543 {
06544 regex_t regexbuf;
06545 int havepattern = 0;
06546
06547 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06548 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06549
06550 struct iax2_user *user = NULL;
06551 char auth[90];
06552 char *pstr = "";
06553 struct ao2_iterator i;
06554
06555 switch (cmd) {
06556 case CLI_INIT:
06557 e->command = "iax2 show users [like]";
06558 e->usage =
06559 "Usage: iax2 show users [like <pattern>]\n"
06560 " Lists all known IAX2 users.\n"
06561 " Optional regular expression pattern is used to filter the user list.\n";
06562 return NULL;
06563 case CLI_GENERATE:
06564 return NULL;
06565 }
06566
06567 switch (a->argc) {
06568 case 5:
06569 if (!strcasecmp(a->argv[3], "like")) {
06570 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06571 return CLI_SHOWUSAGE;
06572 havepattern = 1;
06573 } else
06574 return CLI_SHOWUSAGE;
06575 case 3:
06576 break;
06577 default:
06578 return CLI_SHOWUSAGE;
06579 }
06580
06581 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06582 i = ao2_iterator_init(users, 0);
06583 for (user = ao2_iterator_next(&i); user;
06584 user_unref(user), user = ao2_iterator_next(&i)) {
06585 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06586 continue;
06587
06588 if (!ast_strlen_zero(user->secret)) {
06589 ast_copy_string(auth,user->secret, sizeof(auth));
06590 } else if (!ast_strlen_zero(user->inkeys)) {
06591 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06592 } else
06593 ast_copy_string(auth, "-no secret-", sizeof(auth));
06594
06595 if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06596 pstr = "REQ Only";
06597 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06598 pstr = "Disabled";
06599 else
06600 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06601
06602 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06603 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06604 user->ha ? "Yes" : "No", pstr);
06605 }
06606 ao2_iterator_destroy(&i);
06607
06608 if (havepattern)
06609 regfree(®exbuf);
06610
06611 return CLI_SUCCESS;
06612 #undef FORMAT
06613 #undef FORMAT2
06614 }
06615
06616 static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
06617 {
06618 regex_t regexbuf;
06619 int havepattern = 0;
06620 int total_peers = 0;
06621 int online_peers = 0;
06622 int offline_peers = 0;
06623 int unmonitored_peers = 0;
06624 struct ao2_iterator i;
06625
06626 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
06627 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
06628
06629 struct iax2_peer *peer = NULL;
06630 char name[256];
06631 struct ast_str *encmethods = ast_str_alloca(256);
06632 int registeredonly=0;
06633 char idtext[256] = "";
06634 switch (argc) {
06635 case 6:
06636 if (!strcasecmp(argv[3], "registered"))
06637 registeredonly = 1;
06638 else
06639 return RESULT_SHOWUSAGE;
06640 if (!strcasecmp(argv[4], "like")) {
06641 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06642 return RESULT_SHOWUSAGE;
06643 havepattern = 1;
06644 } else
06645 return RESULT_SHOWUSAGE;
06646 break;
06647 case 5:
06648 if (!strcasecmp(argv[3], "like")) {
06649 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06650 return RESULT_SHOWUSAGE;
06651 havepattern = 1;
06652 } else
06653 return RESULT_SHOWUSAGE;
06654 break;
06655 case 4:
06656 if (!strcasecmp(argv[3], "registered"))
06657 registeredonly = 1;
06658 else
06659 return RESULT_SHOWUSAGE;
06660 break;
06661 case 3:
06662 break;
06663 default:
06664 return RESULT_SHOWUSAGE;
06665 }
06666
06667
06668 if (!s)
06669 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status");
06670
06671 i = ao2_iterator_init(peers, 0);
06672 for (peer = ao2_iterator_next(&i); peer;
06673 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06674 char nm[20];
06675 char status[20];
06676 int retstatus;
06677 struct sockaddr_in peer_addr;
06678
06679 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06680
06681 if (registeredonly && !peer_addr.sin_addr.s_addr) {
06682 continue;
06683 }
06684 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
06685 continue;
06686 }
06687
06688 if (!ast_strlen_zero(peer->username))
06689 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06690 else
06691 ast_copy_string(name, peer->name, sizeof(name));
06692
06693 encmethods_to_str(peer->encmethods, encmethods);
06694 retstatus = peer_status(peer, status, sizeof(status));
06695 if (retstatus > 0)
06696 online_peers++;
06697 else if (!retstatus)
06698 offline_peers++;
06699 else
06700 unmonitored_peers++;
06701
06702 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06703
06704 if (s) {
06705 astman_append(s,
06706 "Event: PeerEntry\r\n%s"
06707 "Channeltype: IAX2\r\n"
06708 "ObjectName: %s\r\n"
06709 "ChanObjectType: peer\r\n"
06710 "IPaddress: %s\r\n"
06711 "IPport: %d\r\n"
06712 "Dynamic: %s\r\n"
06713 "Trunk: %s\r\n"
06714 "Encryption: %s\r\n"
06715 "Status: %s\r\n\r\n",
06716 idtext,
06717 name,
06718 ast_sockaddr_stringify_addr(&peer->addr),
06719 ast_sockaddr_port(&peer->addr),
06720 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06721 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06722 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06723 status);
06724 } else {
06725 ast_cli(fd, FORMAT, name,
06726 ast_sockaddr_stringify_addr(&peer->addr),
06727 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06728 nm,
06729 ast_sockaddr_port(&peer->addr),
06730 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
06731 peer->encmethods ? "(E)" : " ",
06732 status);
06733 }
06734 total_peers++;
06735 }
06736 ao2_iterator_destroy(&i);
06737
06738 if (!s)
06739 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06740 total_peers, online_peers, offline_peers, unmonitored_peers);
06741
06742 if (havepattern)
06743 regfree(®exbuf);
06744
06745 if (total)
06746 *total = total_peers;
06747
06748 return RESULT_SUCCESS;
06749 #undef FORMAT
06750 #undef FORMAT2
06751 }
06752
06753 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06754 {
06755 struct iax2_thread *thread = NULL;
06756 time_t t;
06757 int threadcount = 0, dynamiccount = 0;
06758 char type;
06759
06760 switch (cmd) {
06761 case CLI_INIT:
06762 e->command = "iax2 show threads";
06763 e->usage =
06764 "Usage: iax2 show threads\n"
06765 " Lists status of IAX helper threads\n";
06766 return NULL;
06767 case CLI_GENERATE:
06768 return NULL;
06769 }
06770 if (a->argc != 3)
06771 return CLI_SHOWUSAGE;
06772
06773 ast_cli(a->fd, "IAX2 Thread Information\n");
06774 time(&t);
06775 ast_cli(a->fd, "Idle Threads:\n");
06776 AST_LIST_LOCK(&idle_list);
06777 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06778 #ifdef DEBUG_SCHED_MULTITHREAD
06779 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06780 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06781 #else
06782 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06783 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06784 #endif
06785 threadcount++;
06786 }
06787 AST_LIST_UNLOCK(&idle_list);
06788 ast_cli(a->fd, "Active Threads:\n");
06789 AST_LIST_LOCK(&active_list);
06790 AST_LIST_TRAVERSE(&active_list, thread, list) {
06791 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06792 type = 'D';
06793 else
06794 type = 'P';
06795 #ifdef DEBUG_SCHED_MULTITHREAD
06796 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06797 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06798 #else
06799 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06800 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06801 #endif
06802 threadcount++;
06803 }
06804 AST_LIST_UNLOCK(&active_list);
06805 ast_cli(a->fd, "Dynamic Threads:\n");
06806 AST_LIST_LOCK(&dynamic_list);
06807 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06808 #ifdef DEBUG_SCHED_MULTITHREAD
06809 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06810 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06811 #else
06812 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06813 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06814 #endif
06815 dynamiccount++;
06816 }
06817 AST_LIST_UNLOCK(&dynamic_list);
06818 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06819 return CLI_SUCCESS;
06820 }
06821
06822 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06823 {
06824 struct iax2_peer *p;
06825
06826 switch (cmd) {
06827 case CLI_INIT:
06828 e->command = "iax2 unregister";
06829 e->usage =
06830 "Usage: iax2 unregister <peername>\n"
06831 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06832 return NULL;
06833 case CLI_GENERATE:
06834 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06835 }
06836
06837 if (a->argc != 3)
06838 return CLI_SHOWUSAGE;
06839
06840 p = find_peer(a->argv[2], 1);
06841 if (p) {
06842 if (p->expire > 0) {
06843 struct iax2_peer tmp_peer = {
06844 .name = a->argv[2],
06845 };
06846 struct iax2_peer *peer;
06847
06848 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06849 if (peer) {
06850 expire_registry(peer_ref(peer));
06851 peer_unref(peer);
06852 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06853 } else {
06854 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06855 }
06856 } else {
06857 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06858 }
06859 } else {
06860 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06861 }
06862 return CLI_SUCCESS;
06863 }
06864
06865 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06866 {
06867 int which = 0;
06868 struct iax2_peer *p = NULL;
06869 char *res = NULL;
06870 int wordlen = strlen(word);
06871
06872
06873 if (pos == 2) {
06874 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06875 while ((p = ao2_iterator_next(&i))) {
06876 if (!strncasecmp(p->name, word, wordlen) &&
06877 ++which > state && p->expire > 0) {
06878 res = ast_strdup(p->name);
06879 peer_unref(p);
06880 break;
06881 }
06882 peer_unref(p);
06883 }
06884 ao2_iterator_destroy(&i);
06885 }
06886
06887 return res;
06888 }
06889
06890 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06891 {
06892 switch (cmd) {
06893 case CLI_INIT:
06894 e->command = "iax2 show peers";
06895 e->usage =
06896 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06897 " Lists all known IAX2 peers.\n"
06898 " Optional 'registered' argument lists only peers with known addresses.\n"
06899 " Optional regular expression pattern is used to filter the peer list.\n";
06900 return NULL;
06901 case CLI_GENERATE:
06902 return NULL;
06903 }
06904
06905 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06906 case RESULT_SHOWUSAGE:
06907 return CLI_SHOWUSAGE;
06908 case RESULT_FAILURE:
06909 return CLI_FAILURE;
06910 default:
06911 return CLI_SUCCESS;
06912 }
06913 }
06914
06915 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06916 {
06917 ast_cli_netstats(s, -1, 0);
06918 astman_append(s, "\r\n");
06919 return RESULT_SUCCESS;
06920 }
06921
06922 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06923 {
06924 struct iax_firmware *cur = NULL;
06925
06926 switch (cmd) {
06927 case CLI_INIT:
06928 e->command = "iax2 show firmware";
06929 e->usage =
06930 "Usage: iax2 show firmware\n"
06931 " Lists all known IAX firmware images.\n";
06932 return NULL;
06933 case CLI_GENERATE:
06934 return NULL;
06935 }
06936
06937 if (a->argc != 3 && a->argc != 4)
06938 return CLI_SHOWUSAGE;
06939
06940 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06941 AST_LIST_LOCK(&firmwares);
06942 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06943 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06944 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06945 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06946 }
06947 }
06948 AST_LIST_UNLOCK(&firmwares);
06949
06950 return CLI_SUCCESS;
06951 }
06952
06953
06954 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06955 {
06956 static const char * const a[] = { "iax2", "show", "peers" };
06957 const char *id = astman_get_header(m,"ActionID");
06958 char idtext[256] = "";
06959 int total = 0;
06960
06961 if (!ast_strlen_zero(id))
06962 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06963
06964 astman_send_listack(s, m, "Peer status list will follow", "start");
06965
06966 __iax2_show_peers(-1, &total, s, 3, a);
06967
06968 astman_append(s,
06969 "Event: PeerlistComplete\r\n"
06970 "EventList: Complete\r\n"
06971 "ListItems: %d\r\n"
06972 "%s"
06973 "\r\n", total, idtext);
06974 return 0;
06975 }
06976
06977
06978 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06979 {
06980 struct iax2_peer *peer = NULL;
06981 int peer_count = 0;
06982 char nm[20];
06983 char status[20];
06984 const char *id = astman_get_header(m,"ActionID");
06985 char idtext[256] = "";
06986 struct ast_str *encmethods = ast_str_alloca(256);
06987 struct ao2_iterator i;
06988
06989 if (!ast_strlen_zero(id))
06990 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06991
06992 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06993
06994
06995 i = ao2_iterator_init(peers, 0);
06996 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06997 encmethods_to_str(peer->encmethods, encmethods);
06998 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06999 if (!ast_strlen_zero(peer->username)) {
07000 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07001 } else {
07002 astman_append(s, "ObjectName: %s\r\n", peer->name);
07003 }
07004 astman_append(s, "ChanObjectType: peer\r\n");
07005 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07006 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07007 astman_append(s, "Mask: %s\r\n", nm);
07008 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07009 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07010 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07011 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07012 peer_status(peer, status, sizeof(status));
07013 astman_append(s, "Status: %s\r\n\r\n", status);
07014 peer_count++;
07015 }
07016 ao2_iterator_destroy(&i);
07017
07018 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07019 return RESULT_SUCCESS;
07020 }
07021
07022
07023 static char *regstate2str(int regstate)
07024 {
07025 switch(regstate) {
07026 case REG_STATE_UNREGISTERED:
07027 return "Unregistered";
07028 case REG_STATE_REGSENT:
07029 return "Request Sent";
07030 case REG_STATE_AUTHSENT:
07031 return "Auth. Sent";
07032 case REG_STATE_REGISTERED:
07033 return "Registered";
07034 case REG_STATE_REJECTED:
07035 return "Rejected";
07036 case REG_STATE_TIMEOUT:
07037 return "Timeout";
07038 case REG_STATE_NOAUTH:
07039 return "No Authentication";
07040 default:
07041 return "Unknown";
07042 }
07043 }
07044
07045 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07046 {
07047 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
07048 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
07049 struct iax2_registry *reg = NULL;
07050 char host[80];
07051 char perceived[80];
07052 int counter = 0;
07053
07054 switch (cmd) {
07055 case CLI_INIT:
07056 e->command = "iax2 show registry";
07057 e->usage =
07058 "Usage: iax2 show registry\n"
07059 " Lists all registration requests and status.\n";
07060 return NULL;
07061 case CLI_GENERATE:
07062 return NULL;
07063 }
07064 if (a->argc != 3)
07065 return CLI_SHOWUSAGE;
07066 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07067 AST_LIST_LOCK(®istrations);
07068 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07069 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07070 if (reg->us.sin_addr.s_addr)
07071 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07072 else
07073 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07074 ast_cli(a->fd, FORMAT, host,
07075 (reg->dnsmgr) ? "Y" : "N",
07076 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07077 counter++;
07078 }
07079 AST_LIST_UNLOCK(®istrations);
07080 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07081 return CLI_SUCCESS;
07082 #undef FORMAT
07083 #undef FORMAT2
07084 }
07085
07086 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
07087 {
07088 const char *id = astman_get_header(m, "ActionID");
07089 struct iax2_registry *reg = NULL;
07090 char idtext[256] = "";
07091 char host[80] = "";
07092 char perceived[80] = "";
07093 int total = 0;
07094
07095 if (!ast_strlen_zero(id))
07096 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07097
07098 astman_send_listack(s, m, "Registrations will follow", "start");
07099
07100 AST_LIST_LOCK(®istrations);
07101 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07102 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07103
07104 if (reg->us.sin_addr.s_addr) {
07105 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07106 } else {
07107 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07108 }
07109
07110 astman_append(s,
07111 "Event: RegistryEntry\r\n"
07112 "%s"
07113 "Host: %s\r\n"
07114 "DNSmanager: %s\r\n"
07115 "Username: %s\r\n"
07116 "Perceived: %s\r\n"
07117 "Refresh: %d\r\n"
07118 "State: %s\r\n"
07119 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
07120 reg->refresh, regstate2str(reg->regstate));
07121
07122 total++;
07123 }
07124 AST_LIST_UNLOCK(®istrations);
07125
07126 astman_append(s,
07127 "Event: RegistrationsComplete\r\n"
07128 "EventList: Complete\r\n"
07129 "ListItems: %d\r\n"
07130 "%s"
07131 "\r\n", total, idtext);
07132
07133 return 0;
07134 }
07135
07136 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07137 {
07138 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
07139 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n"
07140 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
07141 int x;
07142 int numchans = 0;
07143 char first_message[10] = { 0, };
07144 char last_message[10] = { 0, };
07145
07146 switch (cmd) {
07147 case CLI_INIT:
07148 e->command = "iax2 show channels";
07149 e->usage =
07150 "Usage: iax2 show channels\n"
07151 " Lists all currently active IAX channels.\n";
07152 return NULL;
07153 case CLI_GENERATE:
07154 return NULL;
07155 }
07156
07157 if (a->argc != 3)
07158 return CLI_SHOWUSAGE;
07159 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07160 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07161 ast_mutex_lock(&iaxsl[x]);
07162 if (iaxs[x]) {
07163 int lag, jitter, localdelay;
07164 jb_info jbinfo;
07165 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07166 jb_getinfo(iaxs[x]->jb, &jbinfo);
07167 jitter = jbinfo.jitter;
07168 localdelay = jbinfo.current - jbinfo.min;
07169 } else {
07170 jitter = -1;
07171 localdelay = 0;
07172 }
07173
07174 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07175 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07176 lag = iaxs[x]->remote_rr.delay;
07177 ast_cli(a->fd, FORMAT,
07178 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07179 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07180 S_OR(iaxs[x]->username, "(None)"),
07181 iaxs[x]->callno, iaxs[x]->peercallno,
07182 iaxs[x]->oseqno, iaxs[x]->iseqno,
07183 lag,
07184 jitter,
07185 localdelay,
07186 ast_getformatname(iaxs[x]->voiceformat),
07187 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07188 first_message,
07189 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07190 last_message);
07191 numchans++;
07192 }
07193 ast_mutex_unlock(&iaxsl[x]);
07194 }
07195 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07196 return CLI_SUCCESS;
07197 #undef FORMAT
07198 #undef FORMAT2
07199 #undef FORMATB
07200 }
07201
07202 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07203 {
07204 int x;
07205 int numchans = 0;
07206 char first_message[10] = { 0, };
07207 char last_message[10] = { 0, };
07208 #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n"
07209 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07210 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07211 ast_mutex_lock(&iaxsl[x]);
07212 if (iaxs[x]) {
07213 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07214 jb_info jbinfo;
07215 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07216 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07217
07218 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07219 jb_getinfo(iaxs[x]->jb, &jbinfo);
07220 localjitter = jbinfo.jitter;
07221 localdelay = jbinfo.current - jbinfo.min;
07222 locallost = jbinfo.frames_lost;
07223 locallosspct = jbinfo.losspct/1000;
07224 localdropped = jbinfo.frames_dropped;
07225 localooo = jbinfo.frames_ooo;
07226 } else {
07227 localjitter = -1;
07228 localdelay = 0;
07229 locallost = -1;
07230 locallosspct = -1;
07231 localdropped = 0;
07232 localooo = -1;
07233 }
07234 if (s)
07235 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07236 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07237 iaxs[x]->pingtime,
07238 localjitter,
07239 localdelay,
07240 locallost,
07241 locallosspct,
07242 localdropped,
07243 localooo,
07244 iaxs[x]->frames_received/1000,
07245 iaxs[x]->remote_rr.jitter,
07246 iaxs[x]->remote_rr.delay,
07247 iaxs[x]->remote_rr.losscnt,
07248 iaxs[x]->remote_rr.losspct,
07249 iaxs[x]->remote_rr.dropped,
07250 iaxs[x]->remote_rr.ooo,
07251 iaxs[x]->remote_rr.packets/1000,
07252 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07253 first_message,
07254 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07255 last_message);
07256 else
07257 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07258 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07259 iaxs[x]->pingtime,
07260 localjitter,
07261 localdelay,
07262 locallost,
07263 locallosspct,
07264 localdropped,
07265 localooo,
07266 iaxs[x]->frames_received/1000,
07267 iaxs[x]->remote_rr.jitter,
07268 iaxs[x]->remote_rr.delay,
07269 iaxs[x]->remote_rr.losscnt,
07270 iaxs[x]->remote_rr.losspct,
07271 iaxs[x]->remote_rr.dropped,
07272 iaxs[x]->remote_rr.ooo,
07273 iaxs[x]->remote_rr.packets/1000,
07274 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07275 first_message,
07276 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07277 last_message);
07278 numchans++;
07279 }
07280 ast_mutex_unlock(&iaxsl[x]);
07281 }
07282
07283 return numchans;
07284 }
07285
07286 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07287 {
07288 int numchans = 0;
07289
07290 switch (cmd) {
07291 case CLI_INIT:
07292 e->command = "iax2 show netstats";
07293 e->usage =
07294 "Usage: iax2 show netstats\n"
07295 " Lists network status for all currently active IAX channels.\n";
07296 return NULL;
07297 case CLI_GENERATE:
07298 return NULL;
07299 }
07300 if (a->argc != 3)
07301 return CLI_SHOWUSAGE;
07302 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07303 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07304 numchans = ast_cli_netstats(NULL, a->fd, 1);
07305 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07306 return CLI_SUCCESS;
07307 }
07308
07309 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07310 {
07311 switch (cmd) {
07312 case CLI_INIT:
07313 e->command = "iax2 set debug {on|off|peer}";
07314 e->usage =
07315 "Usage: iax2 set debug {on|off|peer peername}\n"
07316 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07317 return NULL;
07318 case CLI_GENERATE:
07319 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07320 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07321 return NULL;
07322 }
07323
07324 if (a->argc < e->args || a->argc > e->args + 1)
07325 return CLI_SHOWUSAGE;
07326
07327 if (!strcasecmp(a->argv[3], "peer")) {
07328 struct iax2_peer *peer;
07329 struct sockaddr_in peer_addr;
07330
07331
07332 if (a->argc != e->args + 1)
07333 return CLI_SHOWUSAGE;
07334
07335 peer = find_peer(a->argv[4], 1);
07336
07337 if (!peer) {
07338 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07339 return CLI_FAILURE;
07340 }
07341
07342 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07343
07344 debugaddr.sin_addr = peer_addr.sin_addr;
07345 debugaddr.sin_port = peer_addr.sin_port;
07346
07347 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07348 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07349
07350 ao2_ref(peer, -1);
07351 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07352 iaxdebug = 1;
07353 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07354 } else {
07355 iaxdebug = 0;
07356 memset(&debugaddr, 0, sizeof(debugaddr));
07357 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07358 }
07359 return CLI_SUCCESS;
07360 }
07361
07362 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07363 {
07364 switch (cmd) {
07365 case CLI_INIT:
07366 e->command = "iax2 set debug trunk {on|off}";
07367 e->usage =
07368 "Usage: iax2 set debug trunk {on|off}\n"
07369 " Enables/Disables debugging of IAX trunking\n";
07370 return NULL;
07371 case CLI_GENERATE:
07372 return NULL;
07373 }
07374
07375 if (a->argc != e->args)
07376 return CLI_SHOWUSAGE;
07377
07378 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07379 iaxtrunkdebug = 1;
07380 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07381 } else {
07382 iaxtrunkdebug = 0;
07383 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07384 }
07385 return CLI_SUCCESS;
07386 }
07387
07388 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07389 {
07390 switch (cmd) {
07391 case CLI_INIT:
07392 e->command = "iax2 set debug jb {on|off}";
07393 e->usage =
07394 "Usage: iax2 set debug jb {on|off}\n"
07395 " Enables/Disables jitterbuffer debugging information\n";
07396 return NULL;
07397 case CLI_GENERATE:
07398 return NULL;
07399 }
07400
07401 if (a->argc != e->args)
07402 return CLI_SHOWUSAGE;
07403
07404 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07405 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07406 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07407 } else {
07408 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07409 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07410 }
07411 return CLI_SUCCESS;
07412 }
07413
07414 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07415 {
07416 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07417 int res = -1;
07418 ast_mutex_lock(&iaxsl[callno]);
07419 if (iaxs[callno]) {
07420
07421 if (!iaxs[callno]->error) {
07422 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07423 res = 0;
07424
07425 else if (f->frametype == AST_FRAME_NULL)
07426 res = 0;
07427 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07428 res = 0;
07429 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07430 res = 0;
07431 else
07432
07433 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07434 } else {
07435 ast_debug(1, "Write error: %s\n", strerror(errno));
07436 }
07437 }
07438
07439 ast_mutex_unlock(&iaxsl[callno]);
07440 return res;
07441 }
07442
07443 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07444 int now, int transfer, int final)
07445 {
07446 struct ast_frame f = { 0, };
07447 int res = 0;
07448
07449 f.frametype = type;
07450 f.subclass.integer = command;
07451 f.datalen = datalen;
07452 f.src = __FUNCTION__;
07453 f.data.ptr = (void *) data;
07454
07455 if ((res = queue_signalling(i, &f)) <= 0) {
07456 return res;
07457 }
07458
07459 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07460 }
07461
07462 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07463 {
07464 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07465 }
07466
07467 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07468 {
07469 int res;
07470 ast_mutex_lock(&iaxsl[callno]);
07471 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07472 ast_mutex_unlock(&iaxsl[callno]);
07473 return res;
07474 }
07475
07476
07477
07478
07479
07480
07481 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)
07482 {
07483 int call_num = i->callno;
07484
07485 iax2_predestroy(i->callno);
07486 if (!iaxs[call_num])
07487 return -1;
07488 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07489 }
07490
07491 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)
07492 {
07493 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07494 }
07495
07496 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07497 {
07498 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07499 }
07500
07501 static int apply_context(struct iax2_context *con, const char *context)
07502 {
07503 while(con) {
07504 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07505 return -1;
07506 con = con->next;
07507 }
07508 return 0;
07509 }
07510
07511
07512 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07513 {
07514
07515 int res = -1;
07516 int version = 2;
07517 struct iax2_user *user = NULL, *best = NULL;
07518 int bestscore = 0;
07519 int gotcapability = 0;
07520 struct ast_variable *v = NULL, *tmpvar = NULL;
07521 struct ao2_iterator i;
07522 struct ast_sockaddr addr;
07523
07524 if (!iaxs[callno])
07525 return res;
07526 if (ies->called_number)
07527 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07528 if (ies->calling_number) {
07529 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07530 ast_shrink_phone_number(ies->calling_number);
07531 }
07532 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07533 }
07534 if (ies->calling_name)
07535 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07536 if (ies->calling_ani)
07537 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07538 if (ies->dnid)
07539 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07540 if (ies->rdnis)
07541 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07542 if (ies->called_context)
07543 ast_string_field_set(iaxs[callno], context, ies->called_context);
07544 if (ies->language)
07545 ast_string_field_set(iaxs[callno], language, ies->language);
07546 if (ies->username)
07547 ast_string_field_set(iaxs[callno], username, ies->username);
07548 if (ies->calling_ton > -1)
07549 iaxs[callno]->calling_ton = ies->calling_ton;
07550 if (ies->calling_tns > -1)
07551 iaxs[callno]->calling_tns = ies->calling_tns;
07552 if (ies->calling_pres > -1)
07553 iaxs[callno]->calling_pres = ies->calling_pres;
07554 if (ies->format)
07555 iaxs[callno]->peerformat = ies->format;
07556 if (ies->adsicpe)
07557 iaxs[callno]->peeradsicpe = ies->adsicpe;
07558 if (ies->capability) {
07559 gotcapability = 1;
07560 iaxs[callno]->peercapability = ies->capability;
07561 }
07562 if (ies->version)
07563 version = ies->version;
07564
07565
07566 if (ies->codec_prefs) {
07567 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07568 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07569 }
07570
07571 if (!gotcapability)
07572 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07573 if (version > IAX_PROTO_VERSION) {
07574 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07575 ast_inet_ntoa(sin->sin_addr), version);
07576 return res;
07577 }
07578
07579 i = ao2_iterator_init(users, 0);
07580 ast_sockaddr_from_sin(&addr, sin);
07581 while ((user = ao2_iterator_next(&i))) {
07582 if ((ast_strlen_zero(iaxs[callno]->username) ||
07583 !strcmp(iaxs[callno]->username, user->name))
07584 && ast_apply_ha(user->ha, &addr)
07585 && (ast_strlen_zero(iaxs[callno]->context) ||
07586 apply_context(user->contexts, iaxs[callno]->context))) {
07587 if (!ast_strlen_zero(iaxs[callno]->username)) {
07588
07589 if (best)
07590 user_unref(best);
07591 best = user;
07592 break;
07593 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07594
07595 if (user->ha) {
07596
07597 if (bestscore < 4) {
07598 bestscore = 4;
07599 if (best)
07600 user_unref(best);
07601 best = user;
07602 continue;
07603 }
07604 } else {
07605
07606 if (bestscore < 3) {
07607 bestscore = 3;
07608 if (best)
07609 user_unref(best);
07610 best = user;
07611 continue;
07612 }
07613 }
07614 } else {
07615 if (user->ha) {
07616
07617 if (bestscore < 2) {
07618 bestscore = 2;
07619 if (best)
07620 user_unref(best);
07621 best = user;
07622 continue;
07623 }
07624 } else {
07625
07626 if (bestscore < 1) {
07627 bestscore = 1;
07628 if (best)
07629 user_unref(best);
07630 best = user;
07631 continue;
07632 }
07633 }
07634 }
07635 }
07636 user_unref(user);
07637 }
07638 ao2_iterator_destroy(&i);
07639 user = best;
07640 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07641 user = realtime_user(iaxs[callno]->username, sin);
07642 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07643 !apply_context(user->contexts, iaxs[callno]->context)) {
07644 user = user_unref(user);
07645 }
07646 }
07647 if (user) {
07648
07649
07650 for (v = user->vars ; v ; v = v->next) {
07651 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07652 tmpvar->next = iaxs[callno]->vars;
07653 iaxs[callno]->vars = tmpvar;
07654 }
07655 }
07656
07657 if (user->maxauthreq > 0)
07658 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07659 iaxs[callno]->prefs = user->prefs;
07660 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07661 iaxs[callno]->encmethods = user->encmethods;
07662
07663 if (ast_strlen_zero(iaxs[callno]->username))
07664 ast_string_field_set(iaxs[callno], username, user->name);
07665
07666 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07667 iaxs[callno]->capability = user->capability;
07668
07669 if (ast_strlen_zero(iaxs[callno]->context)) {
07670 if (user->contexts)
07671 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07672 else
07673 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07674 }
07675
07676 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07677
07678 iaxs[callno]->authmethods = user->authmethods;
07679 iaxs[callno]->adsi = user->adsi;
07680
07681 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07682 iaxs[callno]->calling_tns = 0;
07683 iaxs[callno]->calling_ton = 0;
07684 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07685 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07686 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07687 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07688 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07689 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07690 }
07691 if (!ast_strlen_zero(user->accountcode))
07692 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07693 if (!ast_strlen_zero(user->mohinterpret))
07694 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07695 if (!ast_strlen_zero(user->mohsuggest))
07696 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07697 if (!ast_strlen_zero(user->parkinglot))
07698 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07699 if (user->amaflags)
07700 iaxs[callno]->amaflags = user->amaflags;
07701 if (!ast_strlen_zero(user->language))
07702 ast_string_field_set(iaxs[callno], language, user->language);
07703 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07704
07705 if (!ast_strlen_zero(user->dbsecret)) {
07706 char *family, *key=NULL;
07707 char buf[80];
07708 family = ast_strdupa(user->dbsecret);
07709 key = strchr(family, '/');
07710 if (key) {
07711 *key = '\0';
07712 key++;
07713 }
07714 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07715 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07716 else
07717 ast_string_field_set(iaxs[callno], secret, buf);
07718 } else
07719 ast_string_field_set(iaxs[callno], secret, user->secret);
07720 res = 0;
07721 user = user_unref(user);
07722 } else {
07723
07724
07725
07726
07727 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07728 ast_string_field_set(iaxs[callno], secret, "badsecret");
07729 iaxs[callno]->authrej = 1;
07730 if (!ast_strlen_zero(iaxs[callno]->username)) {
07731
07732 res = 0;
07733 }
07734 }
07735 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07736 return res;
07737 }
07738
07739 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07740 {
07741 struct ast_iax2_full_hdr fh;
07742 fh.scallno = htons(src | IAX_FLAG_FULL);
07743 fh.dcallno = htons(dst);
07744 fh.ts = 0;
07745 fh.oseqno = 0;
07746 fh.iseqno = 0;
07747 fh.type = AST_FRAME_IAX;
07748 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07749 iax_outputframe(NULL, &fh, 0, sin, 0);
07750 #if 0
07751 if (option_debug)
07752 #endif
07753 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07754 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07755 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07756 }
07757
07758 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07759 {
07760
07761 p->encmethods &= enc;
07762 if (p->encmethods) {
07763 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07764 p->keyrotateid = -2;
07765 }
07766 if (p->encmethods & IAX_ENCRYPT_AES128)
07767 p->encmethods = IAX_ENCRYPT_AES128;
07768 else
07769 p->encmethods = 0;
07770 }
07771 }
07772
07773
07774
07775
07776
07777
07778
07779 static int authenticate_request(int call_num)
07780 {
07781 struct iax_ie_data ied;
07782 int res = -1, authreq_restrict = 0;
07783 char challenge[10];
07784 struct chan_iax2_pvt *p = iaxs[call_num];
07785
07786 memset(&ied, 0, sizeof(ied));
07787
07788
07789 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07790 struct iax2_user *user, tmp_user = {
07791 .name = p->username,
07792 };
07793
07794 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07795 if (user) {
07796 if (user->curauthreq == user->maxauthreq)
07797 authreq_restrict = 1;
07798 else
07799 user->curauthreq++;
07800 user = user_unref(user);
07801 }
07802 }
07803
07804
07805 if (authreq_restrict) {
07806 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07807 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07808 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07809 return 0;
07810 }
07811
07812 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07813 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07814 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07815 ast_string_field_set(p, challenge, challenge);
07816
07817 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07818 }
07819 if (p->encmethods)
07820 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07821
07822 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07823
07824 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07825
07826 if (p->encmethods)
07827 ast_set_flag64(p, IAX_ENCRYPTED);
07828
07829 return res;
07830 }
07831
07832 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07833 {
07834 char requeststr[256];
07835 char md5secret[256] = "";
07836 char secret[256] = "";
07837 char rsasecret[256] = "";
07838 int res = -1;
07839 int x;
07840 struct iax2_user *user, tmp_user = {
07841 .name = p->username,
07842 };
07843
07844 if (p->authrej) {
07845 return res;
07846 }
07847 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07848 if (user) {
07849 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07850 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07851 ast_clear_flag64(p, IAX_MAXAUTHREQ);
07852 }
07853 ast_string_field_set(p, host, user->name);
07854 user = user_unref(user);
07855 }
07856 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07857 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07858 return res;
07859 }
07860 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07861 return res;
07862 if (ies->password)
07863 ast_copy_string(secret, ies->password, sizeof(secret));
07864 if (ies->md5_result)
07865 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07866 if (ies->rsa_result)
07867 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07868 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07869 struct ast_key *key;
07870 char *keyn;
07871 char tmpkey[256];
07872 char *stringp=NULL;
07873 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07874 stringp=tmpkey;
07875 keyn = strsep(&stringp, ":");
07876 while(keyn) {
07877 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07878 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07879 res = 0;
07880 break;
07881 } else if (!key)
07882 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07883 keyn = strsep(&stringp, ":");
07884 }
07885 } else if (p->authmethods & IAX_AUTH_MD5) {
07886 struct MD5Context md5;
07887 unsigned char digest[16];
07888 char *tmppw, *stringp;
07889
07890 tmppw = ast_strdupa(p->secret);
07891 stringp = tmppw;
07892 while((tmppw = strsep(&stringp, ";"))) {
07893 MD5Init(&md5);
07894 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07895 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07896 MD5Final(digest, &md5);
07897
07898 for (x=0;x<16;x++)
07899 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07900 if (!strcasecmp(requeststr, md5secret)) {
07901 res = 0;
07902 break;
07903 }
07904 }
07905 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07906 if (!strcmp(secret, p->secret))
07907 res = 0;
07908 }
07909 return res;
07910 }
07911
07912
07913 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07914 {
07915 char requeststr[256] = "";
07916 char peer[256] = "";
07917 char md5secret[256] = "";
07918 char rsasecret[256] = "";
07919 char secret[256] = "";
07920 struct iax2_peer *p = NULL;
07921 struct ast_key *key;
07922 char *keyn;
07923 int x;
07924 int expire = 0;
07925 int res = -1;
07926 struct ast_sockaddr addr;
07927
07928 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07929
07930 if (ies->username)
07931 ast_copy_string(peer, ies->username, sizeof(peer));
07932 if (ies->password)
07933 ast_copy_string(secret, ies->password, sizeof(secret));
07934 if (ies->md5_result)
07935 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07936 if (ies->rsa_result)
07937 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07938 if (ies->refresh)
07939 expire = ies->refresh;
07940
07941 if (ast_strlen_zero(peer)) {
07942 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07943 return -1;
07944 }
07945
07946
07947 ast_mutex_unlock(&iaxsl[callno]);
07948 p = find_peer(peer, 1);
07949 ast_mutex_lock(&iaxsl[callno]);
07950 if (!p || !iaxs[callno]) {
07951 if (iaxs[callno]) {
07952 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07953
07954 ast_string_field_set(iaxs[callno], secret, "badsecret");
07955
07956
07957
07958
07959
07960
07961
07962
07963
07964 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07965 !(!ast_strlen_zero(secret) && plaintext)) {
07966
07967 res = 0;
07968 }
07969 }
07970 if (authdebug && !p)
07971 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07972 goto return_unref;
07973 }
07974
07975 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
07976 if (authdebug)
07977 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07978 goto return_unref;
07979 }
07980
07981 ast_sockaddr_from_sin(&addr, sin);
07982 if (!ast_apply_ha(p->ha, &addr)) {
07983 if (authdebug)
07984 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07985 goto return_unref;
07986 }
07987 ast_string_field_set(iaxs[callno], secret, p->secret);
07988 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07989
07990 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07991 if (!ast_strlen_zero(p->inkeys)) {
07992 char tmpkeys[256];
07993 char *stringp=NULL;
07994 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07995 stringp=tmpkeys;
07996 keyn = strsep(&stringp, ":");
07997 while(keyn) {
07998 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07999 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
08000 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08001 break;
08002 } else if (!key)
08003 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08004 keyn = strsep(&stringp, ":");
08005 }
08006 if (!keyn) {
08007 if (authdebug)
08008 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08009 goto return_unref;
08010 }
08011 } else {
08012 if (authdebug)
08013 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08014 goto return_unref;
08015 }
08016 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08017 struct MD5Context md5;
08018 unsigned char digest[16];
08019 char *tmppw, *stringp;
08020
08021 tmppw = ast_strdupa(p->secret);
08022 stringp = tmppw;
08023 while((tmppw = strsep(&stringp, ";"))) {
08024 MD5Init(&md5);
08025 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08026 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08027 MD5Final(digest, &md5);
08028 for (x=0;x<16;x++)
08029 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08030 if (!strcasecmp(requeststr, md5secret))
08031 break;
08032 }
08033 if (tmppw) {
08034 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08035 } else {
08036 if (authdebug)
08037 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08038 goto return_unref;
08039 }
08040 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08041
08042 if (strcmp(secret, p->secret)) {
08043 if (authdebug)
08044 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08045 goto return_unref;
08046 } else
08047 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08048 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08049
08050 goto return_unref;
08051 }
08052 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08053
08054
08055 res = 0;
08056
08057 return_unref:
08058 if (iaxs[callno]) {
08059 ast_string_field_set(iaxs[callno], peer, peer);
08060
08061
08062 if (expire && (expire < iaxs[callno]->expiry)) {
08063 iaxs[callno]->expiry = expire;
08064 }
08065 }
08066
08067 if (p) {
08068 peer_unref(p);
08069 }
08070 return res;
08071 }
08072
08073 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)
08074 {
08075 int res = -1;
08076 int x;
08077 if (!ast_strlen_zero(keyn)) {
08078 if (!(authmethods & IAX_AUTH_RSA)) {
08079 if (ast_strlen_zero(secret))
08080 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));
08081 } else if (ast_strlen_zero(challenge)) {
08082 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08083 } else {
08084 char sig[256];
08085 struct ast_key *key;
08086 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08087 if (!key) {
08088 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08089 } else {
08090 if (ast_sign(key, (char*)challenge, sig)) {
08091 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08092 res = -1;
08093 } else {
08094 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08095 res = 0;
08096 }
08097 }
08098 }
08099 }
08100
08101 if (res && !ast_strlen_zero(secret)) {
08102 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08103 struct MD5Context md5;
08104 unsigned char digest[16];
08105 char digres[128];
08106 MD5Init(&md5);
08107 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08108 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08109 MD5Final(digest, &md5);
08110
08111 for (x=0;x<16;x++)
08112 sprintf(digres + (x << 1), "%2.2x", digest[x]);
08113 if (pvt) {
08114 build_encryption_keys(digest, pvt);
08115 }
08116 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08117 res = 0;
08118 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08119 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08120 res = 0;
08121 } else
08122 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08123 }
08124 return res;
08125 }
08126
08127
08128
08129
08130
08131 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08132 {
08133 struct iax2_peer *peer = NULL;
08134
08135 int res = -1;
08136 int authmethods = 0;
08137 struct iax_ie_data ied;
08138 uint16_t callno = p->callno;
08139
08140 memset(&ied, 0, sizeof(ied));
08141
08142 if (ies->username)
08143 ast_string_field_set(p, username, ies->username);
08144 if (ies->challenge)
08145 ast_string_field_set(p, challenge, ies->challenge);
08146 if (ies->authmethods)
08147 authmethods = ies->authmethods;
08148 if (authmethods & IAX_AUTH_MD5)
08149 merge_encryption(p, ies->encmethods);
08150 else
08151 p->encmethods = 0;
08152
08153
08154 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08155
08156 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08157 } else {
08158 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08159 while ((peer = ao2_iterator_next(&i))) {
08160 struct sockaddr_in peer_addr;
08161
08162 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08163
08164 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08165
08166 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08167
08168 && (!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)))
08169
08170 ) {
08171 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08172 if (!res) {
08173 peer_unref(peer);
08174 break;
08175 }
08176 }
08177 peer_unref(peer);
08178 }
08179 ao2_iterator_destroy(&i);
08180 if (!peer) {
08181
08182
08183 const char *peer_name = ast_strdupa(p->peer);
08184 ast_mutex_unlock(&iaxsl[callno]);
08185 if ((peer = realtime_peer(peer_name, NULL))) {
08186 ast_mutex_lock(&iaxsl[callno]);
08187 if (!(p = iaxs[callno])) {
08188 peer_unref(peer);
08189 return -1;
08190 }
08191 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08192 peer_unref(peer);
08193 }
08194 if (!peer) {
08195 ast_mutex_lock(&iaxsl[callno]);
08196 if (!(p = iaxs[callno]))
08197 return -1;
08198 }
08199 }
08200 }
08201
08202 if (ies->encmethods) {
08203 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08204 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08205 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08206 return -1;
08207 }
08208 if (!res) {
08209 struct ast_datastore *variablestore;
08210 struct ast_variable *var, *prev = NULL;
08211 AST_LIST_HEAD(, ast_var_t) *varlist;
08212 varlist = ast_calloc(1, sizeof(*varlist));
08213 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08214 if (variablestore && varlist && p->owner) {
08215 variablestore->data = varlist;
08216 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08217 AST_LIST_HEAD_INIT(varlist);
08218 for (var = ies->vars; var; var = var->next) {
08219 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08220 if (prev)
08221 ast_free(prev);
08222 prev = var;
08223 if (!newvar) {
08224
08225 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08226 } else {
08227 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08228 }
08229 }
08230 if (prev)
08231 ast_free(prev);
08232 ies->vars = NULL;
08233 ast_channel_datastore_add(p->owner, variablestore);
08234 } else {
08235 if (p->owner)
08236 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08237 if (variablestore)
08238 ast_datastore_free(variablestore);
08239 if (varlist)
08240 ast_free(varlist);
08241 }
08242 }
08243
08244 if (!res)
08245 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08246 return res;
08247 }
08248
08249 static int iax2_do_register(struct iax2_registry *reg);
08250
08251 static void __iax2_do_register_s(const void *data)
08252 {
08253 struct iax2_registry *reg = (struct iax2_registry *)data;
08254 reg->expire = -1;
08255 iax2_do_register(reg);
08256 }
08257
08258 static int iax2_do_register_s(const void *data)
08259 {
08260 #ifdef SCHED_MULTITHREADED
08261 if (schedule_action(__iax2_do_register_s, data))
08262 #endif
08263 __iax2_do_register_s(data);
08264 return 0;
08265 }
08266
08267 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08268 {
08269 int newcall = 0;
08270 char newip[256];
08271 struct iax_ie_data ied;
08272 struct sockaddr_in new;
08273
08274
08275 memset(&ied, 0, sizeof(ied));
08276 if (ies->apparent_addr)
08277 memmove(&new, ies->apparent_addr, sizeof(new));
08278 if (ies->callno)
08279 newcall = ies->callno;
08280 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08281 ast_log(LOG_WARNING, "Invalid transfer request\n");
08282 return -1;
08283 }
08284 pvt->transfercallno = newcall;
08285 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08286 inet_aton(newip, &pvt->transfer.sin_addr);
08287 pvt->transfer.sin_family = AF_INET;
08288 pvt->transferid = ies->transferid;
08289
08290
08291 if (pvt->transferring == TRANSFER_NONE) {
08292 store_by_transfercallno(pvt);
08293 }
08294 pvt->transferring = TRANSFER_BEGIN;
08295
08296 if (ies->transferid)
08297 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08298 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08299 return 0;
08300 }
08301
08302 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08303 {
08304 char exten[256] = "";
08305 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08306 struct iax2_dpcache *dp = NULL;
08307
08308 if (ies->called_number)
08309 ast_copy_string(exten, ies->called_number, sizeof(exten));
08310
08311 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08312 status = CACHE_FLAG_EXISTS;
08313 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08314 status = CACHE_FLAG_CANEXIST;
08315 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08316 status = CACHE_FLAG_NONEXISTENT;
08317
08318 if (ies->refresh)
08319 expiry = ies->refresh;
08320 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08321 matchmore = CACHE_FLAG_MATCHMORE;
08322
08323 AST_LIST_LOCK(&dpcache);
08324 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08325 if (strcmp(dp->exten, exten))
08326 continue;
08327 AST_LIST_REMOVE_CURRENT(peer_list);
08328 dp->callno = 0;
08329 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08330 if (dp->flags & CACHE_FLAG_PENDING) {
08331 dp->flags &= ~CACHE_FLAG_PENDING;
08332 dp->flags |= status;
08333 dp->flags |= matchmore;
08334 }
08335
08336 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08337 if (dp->waiters[x] > -1) {
08338 if (write(dp->waiters[x], "asdf", 4) < 0) {
08339 }
08340 }
08341 }
08342 }
08343 AST_LIST_TRAVERSE_SAFE_END;
08344 AST_LIST_UNLOCK(&dpcache);
08345
08346 return 0;
08347 }
08348
08349 static int complete_transfer(int callno, struct iax_ies *ies)
08350 {
08351 int peercallno = 0;
08352 struct chan_iax2_pvt *pvt = iaxs[callno];
08353 struct iax_frame *cur;
08354 jb_frame frame;
08355
08356 if (ies->callno)
08357 peercallno = ies->callno;
08358
08359 if (peercallno < 1) {
08360 ast_log(LOG_WARNING, "Invalid transfer request\n");
08361 return -1;
08362 }
08363 remove_by_transfercallno(pvt);
08364
08365
08366
08367 peercnt_remove_by_addr(&pvt->addr);
08368 peercnt_add(&pvt->transfer);
08369
08370 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08371 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08372
08373 pvt->oseqno = 0;
08374 pvt->rseqno = 0;
08375 pvt->iseqno = 0;
08376 pvt->aseqno = 0;
08377
08378 if (pvt->peercallno) {
08379 remove_by_peercallno(pvt);
08380 }
08381 pvt->peercallno = peercallno;
08382
08383 store_by_peercallno(pvt);
08384 pvt->transferring = TRANSFER_NONE;
08385 pvt->svoiceformat = -1;
08386 pvt->voiceformat = 0;
08387 pvt->svideoformat = -1;
08388 pvt->videoformat = 0;
08389 pvt->transfercallno = 0;
08390 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08391 memset(&pvt->offset, 0, sizeof(pvt->offset));
08392
08393 while(jb_getall(pvt->jb,&frame) == JB_OK)
08394 iax2_frame_free(frame.data);
08395 jb_reset(pvt->jb);
08396 pvt->lag = 0;
08397 pvt->last = 0;
08398 pvt->lastsent = 0;
08399 pvt->nextpred = 0;
08400 pvt->pingtime = DEFAULT_RETRY_TIME;
08401 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08402
08403
08404
08405 cur->retries = -1;
08406 }
08407 return 0;
08408 }
08409
08410
08411 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08412 {
08413 struct iax2_registry *reg;
08414
08415 char peer[256] = "";
08416 char msgstatus[60];
08417 int refresh = 60;
08418 char ourip[256] = "<Unspecified>";
08419 struct sockaddr_in oldus;
08420 struct sockaddr_in us;
08421 int oldmsgs;
08422 struct sockaddr_in reg_addr;
08423
08424 memset(&us, 0, sizeof(us));
08425 if (ies->apparent_addr) {
08426 memmove(&us, ies->apparent_addr, sizeof(us));
08427 }
08428 if (ies->username) {
08429 ast_copy_string(peer, ies->username, sizeof(peer));
08430 }
08431 if (ies->refresh) {
08432 refresh = ies->refresh;
08433 }
08434 if (ies->calling_number) {
08435
08436 }
08437 reg = iaxs[callno]->reg;
08438 if (!reg) {
08439 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08440 return -1;
08441 }
08442 memcpy(&oldus, ®->us, sizeof(oldus));
08443 oldmsgs = reg->messages;
08444 ast_sockaddr_to_sin(®->addr, ®_addr);
08445 if (inaddrcmp(®_addr, sin)) {
08446 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08447 return -1;
08448 }
08449 memcpy(®->us, &us, sizeof(reg->us));
08450 if (ies->msgcount >= 0) {
08451 reg->messages = ies->msgcount & 0xffff;
08452 }
08453
08454
08455
08456 reg->refresh = refresh;
08457 reg->expire = iax2_sched_replace(reg->expire, sched,
08458 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08459 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08460 if (reg->messages > 255) {
08461 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08462 } else if (reg->messages > 1) {
08463 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08464 } else if (reg->messages > 0) {
08465 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08466 } else {
08467 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08468 }
08469 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08470 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08471 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08472 }
08473 reg->regstate = REG_STATE_REGISTERED;
08474 return 0;
08475 }
08476
08477 static int iax2_append_register(const char *hostname, const char *username,
08478 const char *secret, const char *porta)
08479 {
08480 struct iax2_registry *reg;
08481
08482 if (!(reg = ast_calloc(1, sizeof(*reg))))
08483 return -1;
08484
08485 reg->addr.ss.ss_family = AF_INET;
08486 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08487 ast_free(reg);
08488 return -1;
08489 }
08490
08491 ast_copy_string(reg->username, username, sizeof(reg->username));
08492
08493 if (secret)
08494 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08495
08496 reg->expire = -1;
08497 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08498 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08499
08500 AST_LIST_LOCK(®istrations);
08501 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08502 AST_LIST_UNLOCK(®istrations);
08503
08504 return 0;
08505 }
08506
08507 static int iax2_register(const char *value, int lineno)
08508 {
08509 char copy[256];
08510 char *username, *hostname, *secret;
08511 char *porta;
08512 char *stringp=NULL;
08513
08514 if (!value)
08515 return -1;
08516
08517 ast_copy_string(copy, value, sizeof(copy));
08518 stringp = copy;
08519 username = strsep(&stringp, "@");
08520 hostname = strsep(&stringp, "@");
08521
08522 if (!hostname) {
08523 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08524 return -1;
08525 }
08526
08527 stringp = username;
08528 username = strsep(&stringp, ":");
08529 secret = strsep(&stringp, ":");
08530 stringp = hostname;
08531 hostname = strsep(&stringp, ":");
08532 porta = strsep(&stringp, ":");
08533
08534 if (porta && !atoi(porta)) {
08535 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08536 return -1;
08537 }
08538
08539 return iax2_append_register(hostname, username, secret, porta);
08540 }
08541
08542
08543 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08544 {
08545 char multi[256];
08546 char *stringp, *ext;
08547 if (!ast_strlen_zero(regcontext)) {
08548 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08549 stringp = multi;
08550 while((ext = strsep(&stringp, "&"))) {
08551 if (onoff) {
08552 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08553 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08554 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08555 } else
08556 ast_context_remove_extension(regcontext, ext, 1, NULL);
08557 }
08558 }
08559 }
08560 static void prune_peers(void);
08561
08562 static void unlink_peer(struct iax2_peer *peer)
08563 {
08564 if (peer->expire > -1) {
08565 if (!ast_sched_thread_del(sched, peer->expire)) {
08566 peer->expire = -1;
08567 peer_unref(peer);
08568 }
08569 }
08570
08571 if (peer->pokeexpire > -1) {
08572 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08573 peer->pokeexpire = -1;
08574 peer_unref(peer);
08575 }
08576 }
08577
08578 ao2_unlink(peers, peer);
08579 }
08580
08581 static void __expire_registry(const void *data)
08582 {
08583 struct iax2_peer *peer = (struct iax2_peer *) data;
08584
08585 if (!peer)
08586 return;
08587 if (peer->expire == -1) {
08588
08589 return;
08590 }
08591
08592 peer->expire = -1;
08593
08594 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08595 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08596 realtime_update_peer(peer->name, &peer->addr, 0);
08597 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08598
08599 peercnt_modify(0, 0, &peer->addr);
08600
08601 memset(&peer->addr, 0, sizeof(peer->addr));
08602
08603 peer->expiry = min_reg_expire;
08604 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08605 ast_db_del("IAX/Registry", peer->name);
08606 register_peer_exten(peer, 0);
08607 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08608 if (iax2_regfunk)
08609 iax2_regfunk(peer->name, 0);
08610
08611 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08612 unlink_peer(peer);
08613
08614 peer_unref(peer);
08615 }
08616
08617 static int expire_registry(const void *data)
08618 {
08619 #ifdef SCHED_MULTITHREADED
08620 if (schedule_action(__expire_registry, data))
08621 #endif
08622 __expire_registry(data);
08623 return 0;
08624 }
08625
08626 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08627
08628 static void reg_source_db(struct iax2_peer *p)
08629 {
08630 char data[80];
08631 char *expiry;
08632
08633 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08634 return;
08635 }
08636
08637 expiry = strrchr(data, ':');
08638 if (!expiry) {
08639 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08640 }
08641 *expiry++ = '\0';
08642
08643 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08644 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08645 return;
08646 }
08647
08648 p->expiry = atoi(expiry);
08649
08650 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08651 ast_sockaddr_stringify(&p->addr), p->expiry);
08652
08653 iax2_poke_peer(p, 0);
08654 if (p->expire > -1) {
08655 if (!ast_sched_thread_del(sched, p->expire)) {
08656 p->expire = -1;
08657 peer_unref(p);
08658 }
08659 }
08660
08661 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08662
08663 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08664 if (p->expire == -1) {
08665 peer_unref(p);
08666 }
08667
08668 if (iax2_regfunk) {
08669 iax2_regfunk(p->name, 1);
08670 }
08671
08672 register_peer_exten(p, 1);
08673 }
08674
08675
08676
08677
08678
08679
08680
08681 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08682 {
08683
08684 struct iax_ie_data ied = {
08685 .pos = 0,
08686 };
08687 struct iax2_peer *p;
08688 int msgcount;
08689 char data[80];
08690 int version;
08691 const char *peer_name;
08692 int res = -1;
08693 struct ast_sockaddr sockaddr;
08694
08695 ast_sockaddr_from_sin(&sockaddr, sin);
08696
08697 peer_name = ast_strdupa(iaxs[callno]->peer);
08698
08699
08700 ast_mutex_unlock(&iaxsl[callno]);
08701 if (!(p = find_peer(peer_name, 1))) {
08702 ast_mutex_lock(&iaxsl[callno]);
08703 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08704 return -1;
08705 }
08706 ast_mutex_lock(&iaxsl[callno]);
08707 if (!iaxs[callno])
08708 goto return_unref;
08709
08710 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08711 if (sin->sin_addr.s_addr) {
08712 time_t nowtime;
08713 time(&nowtime);
08714 realtime_update_peer(peer_name, &sockaddr, nowtime);
08715 } else {
08716 realtime_update_peer(peer_name, &sockaddr, 0);
08717 }
08718 }
08719
08720 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08721 if (iax2_regfunk) {
08722 iax2_regfunk(p->name, 1);
08723 }
08724
08725
08726 peercnt_modify(0, 0, &p->addr);
08727
08728
08729 ast_sockaddr_from_sin(&p->addr, sin);
08730
08731 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08732 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08733 ast_db_put("IAX/Registry", p->name, data);
08734 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08735 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08736 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08737 register_peer_exten(p, 1);
08738 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08739 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08740 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08741 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08742 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08743 register_peer_exten(p, 0);
08744 ast_db_del("IAX/Registry", p->name);
08745 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08746 }
08747
08748
08749 iax2_poke_peer(p, callno);
08750 }
08751
08752
08753 if (p->maxcallno) {
08754 peercnt_modify(1, p->maxcallno, &p->addr);
08755 }
08756
08757
08758 if (!iaxs[callno]) {
08759 res = -1;
08760 goto return_unref;
08761 }
08762
08763
08764 p->sockfd = fd;
08765
08766 if (p->expire > -1) {
08767 if (!ast_sched_thread_del(sched, p->expire)) {
08768 p->expire = -1;
08769 peer_unref(p);
08770 }
08771 }
08772
08773 if (!refresh)
08774 refresh = min_reg_expire;
08775 if (refresh > max_reg_expire) {
08776 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08777 p->name, max_reg_expire, refresh);
08778 p->expiry = max_reg_expire;
08779 } else if (refresh < min_reg_expire) {
08780 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08781 p->name, min_reg_expire, refresh);
08782 p->expiry = min_reg_expire;
08783 } else {
08784 p->expiry = refresh;
08785 }
08786 if (p->expiry && sin->sin_addr.s_addr) {
08787 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08788 if (p->expire == -1)
08789 peer_unref(p);
08790 }
08791 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08792 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08793 if (sin->sin_addr.s_addr) {
08794 struct sockaddr_in peer_addr;
08795
08796 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08797
08798 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08799 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08800 if (!ast_strlen_zero(p->mailbox)) {
08801 struct ast_event *event;
08802 int new, old;
08803 char *mailbox, *context;
08804
08805 context = mailbox = ast_strdupa(p->mailbox);
08806 strsep(&context, "@");
08807 if (ast_strlen_zero(context))
08808 context = "default";
08809
08810 event = ast_event_get_cached(AST_EVENT_MWI,
08811 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08812 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08813 AST_EVENT_IE_END);
08814 if (event) {
08815 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08816 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08817 ast_event_destroy(event);
08818 } else {
08819 ast_app_inboxcount(p->mailbox, &new, &old);
08820 }
08821
08822 if (new > 255) {
08823 new = 255;
08824 }
08825 if (old > 255) {
08826 old = 255;
08827 }
08828 msgcount = (old << 8) | new;
08829
08830 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08831 }
08832 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08833 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08834 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08835 }
08836 }
08837 version = iax_check_version(devtype);
08838 if (version)
08839 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08840
08841 res = 0;
08842
08843 return_unref:
08844 peer_unref(p);
08845
08846 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08847 }
08848
08849 static int registry_authrequest(int callno)
08850 {
08851 struct iax_ie_data ied;
08852 struct iax2_peer *p;
08853 char challenge[10];
08854 const char *peer_name;
08855 int sentauthmethod;
08856
08857 peer_name = ast_strdupa(iaxs[callno]->peer);
08858
08859
08860 ast_mutex_unlock(&iaxsl[callno]);
08861 if ((p = find_peer(peer_name, 1))) {
08862 last_authmethod = p->authmethods;
08863 }
08864
08865 ast_mutex_lock(&iaxsl[callno]);
08866 if (!iaxs[callno])
08867 goto return_unref;
08868
08869 memset(&ied, 0, sizeof(ied));
08870
08871
08872
08873
08874
08875
08876 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08877 if (!p) {
08878 iaxs[callno]->authmethods = sentauthmethod;
08879 }
08880 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08881 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08882
08883 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08884 ast_string_field_set(iaxs[callno], challenge, challenge);
08885 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08886 }
08887 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08888
08889 return_unref:
08890 if (p) {
08891 peer_unref(p);
08892 }
08893
08894 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08895 }
08896
08897 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08898 {
08899 struct iax2_registry *reg;
08900
08901 struct iax_ie_data ied;
08902 char peer[256] = "";
08903 char challenge[256] = "";
08904 int res;
08905 int authmethods = 0;
08906 if (ies->authmethods)
08907 authmethods = ies->authmethods;
08908 if (ies->username)
08909 ast_copy_string(peer, ies->username, sizeof(peer));
08910 if (ies->challenge)
08911 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08912 memset(&ied, 0, sizeof(ied));
08913 reg = iaxs[callno]->reg;
08914 if (reg) {
08915 struct sockaddr_in reg_addr;
08916
08917 ast_sockaddr_to_sin(®->addr, ®_addr);
08918
08919 if (inaddrcmp(®_addr, sin)) {
08920 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08921 return -1;
08922 }
08923 if (ast_strlen_zero(reg->secret)) {
08924 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08925 reg->regstate = REG_STATE_NOAUTH;
08926 return -1;
08927 }
08928 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08929 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08930 if (reg->secret[0] == '[') {
08931 char tmpkey[256];
08932 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08933 tmpkey[strlen(tmpkey) - 1] = '\0';
08934 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08935 } else
08936 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08937 if (!res) {
08938 reg->regstate = REG_STATE_AUTHSENT;
08939 add_empty_calltoken_ie(iaxs[callno], &ied);
08940 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08941 } else
08942 return -1;
08943 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08944 } else
08945 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08946 return -1;
08947 }
08948
08949 static void stop_stuff(int callno)
08950 {
08951 iax2_destroy_helper(iaxs[callno]);
08952 }
08953
08954 static void __auth_reject(const void *nothing)
08955 {
08956
08957 int callno = (int)(long)(nothing);
08958 struct iax_ie_data ied;
08959 ast_mutex_lock(&iaxsl[callno]);
08960 if (iaxs[callno]) {
08961 memset(&ied, 0, sizeof(ied));
08962 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08963 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08964 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08965 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08966 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08967 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08968 }
08969 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08970 }
08971 ast_mutex_unlock(&iaxsl[callno]);
08972 }
08973
08974 static int auth_reject(const void *data)
08975 {
08976 int callno = (int)(long)(data);
08977 ast_mutex_lock(&iaxsl[callno]);
08978 if (iaxs[callno])
08979 iaxs[callno]->authid = -1;
08980 ast_mutex_unlock(&iaxsl[callno]);
08981 #ifdef SCHED_MULTITHREADED
08982 if (schedule_action(__auth_reject, data))
08983 #endif
08984 __auth_reject(data);
08985 return 0;
08986 }
08987
08988 static int auth_fail(int callno, int failcode)
08989 {
08990
08991
08992 if (iaxs[callno]) {
08993 iaxs[callno]->authfail = failcode;
08994 if (delayreject) {
08995 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08996 sched, 1000, auth_reject, (void *)(long)callno);
08997 } else
08998 auth_reject((void *)(long)callno);
08999 }
09000 return 0;
09001 }
09002
09003 static void __auto_hangup(const void *nothing)
09004 {
09005
09006 int callno = (int)(long)(nothing);
09007 struct iax_ie_data ied;
09008 ast_mutex_lock(&iaxsl[callno]);
09009 if (iaxs[callno]) {
09010 memset(&ied, 0, sizeof(ied));
09011 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09012 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09013 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09014 }
09015 ast_mutex_unlock(&iaxsl[callno]);
09016 }
09017
09018 static int auto_hangup(const void *data)
09019 {
09020 int callno = (int)(long)(data);
09021 ast_mutex_lock(&iaxsl[callno]);
09022 if (iaxs[callno]) {
09023 iaxs[callno]->autoid = -1;
09024 }
09025 ast_mutex_unlock(&iaxsl[callno]);
09026 #ifdef SCHED_MULTITHREADED
09027 if (schedule_action(__auto_hangup, data))
09028 #endif
09029 __auto_hangup(data);
09030 return 0;
09031 }
09032
09033 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09034 {
09035 struct iax_ie_data ied;
09036
09037 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09038 sched, 30000, auto_hangup, (void *)(long)callno);
09039 memset(&ied, 0, sizeof(ied));
09040 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09041 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09042 dp->flags |= CACHE_FLAG_TRANSMITTED;
09043 }
09044
09045 static int iax2_vnak(int callno)
09046 {
09047 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09048 }
09049
09050 static void vnak_retransmit(int callno, int last)
09051 {
09052 struct iax_frame *f;
09053
09054 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09055
09056 if (((unsigned char) (f->oseqno - last) < 128) &&
09057 (f->retries >= 0)) {
09058 send_packet(f);
09059 }
09060 }
09061 }
09062
09063 static void __iax2_poke_peer_s(const void *data)
09064 {
09065 struct iax2_peer *peer = (struct iax2_peer *)data;
09066 iax2_poke_peer(peer, 0);
09067 peer_unref(peer);
09068 }
09069
09070 static int iax2_poke_peer_s(const void *data)
09071 {
09072 struct iax2_peer *peer = (struct iax2_peer *)data;
09073 peer->pokeexpire = -1;
09074 #ifdef SCHED_MULTITHREADED
09075 if (schedule_action(__iax2_poke_peer_s, data))
09076 #endif
09077 __iax2_poke_peer_s(data);
09078 return 0;
09079 }
09080
09081 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09082 {
09083 int res = 0;
09084 struct iax_frame *fr;
09085 struct ast_iax2_meta_hdr *meta;
09086 struct ast_iax2_meta_trunk_hdr *mth;
09087 int calls = 0;
09088
09089
09090 fr = (struct iax_frame *)tpeer->trunkdata;
09091
09092 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09093 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09094 if (tpeer->trunkdatalen) {
09095
09096 meta->zeros = 0;
09097 meta->metacmd = IAX_META_TRUNK;
09098 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09099 meta->cmddata = IAX_META_TRUNK_MINI;
09100 else
09101 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09102 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09103
09104 fr->direction = DIRECTION_OUTGRESS;
09105 fr->retrans = -1;
09106 fr->transfer = 0;
09107
09108 fr->data = fr->afdata;
09109 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09110 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09111 calls = tpeer->calls;
09112 #if 0
09113 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));
09114 #endif
09115
09116 tpeer->trunkdatalen = 0;
09117 tpeer->calls = 0;
09118 }
09119 if (res < 0)
09120 return res;
09121 return calls;
09122 }
09123
09124 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09125 {
09126
09127 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09128 return 1;
09129 return 0;
09130 }
09131
09132 static int timing_read(int *id, int fd, short events, void *cbdata)
09133 {
09134 int res, processed = 0, totalcalls = 0;
09135 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09136 struct timeval now = ast_tvnow();
09137
09138 if (iaxtrunkdebug)
09139 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09140
09141 if (timer) {
09142 ast_timer_ack(timer, 1);
09143 }
09144
09145
09146 AST_LIST_LOCK(&tpeers);
09147 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09148 processed++;
09149 res = 0;
09150 ast_mutex_lock(&tpeer->lock);
09151
09152
09153 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09154
09155
09156 AST_LIST_REMOVE_CURRENT(list);
09157 drop = tpeer;
09158 } else {
09159 res = send_trunk(tpeer, &now);
09160 trunk_timed++;
09161 if (iaxtrunkdebug)
09162 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);
09163 }
09164 totalcalls += res;
09165 res = 0;
09166 ast_mutex_unlock(&tpeer->lock);
09167 }
09168 AST_LIST_TRAVERSE_SAFE_END;
09169 AST_LIST_UNLOCK(&tpeers);
09170
09171 if (drop) {
09172 ast_mutex_lock(&drop->lock);
09173
09174
09175 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09176 if (drop->trunkdata) {
09177 ast_free(drop->trunkdata);
09178 drop->trunkdata = NULL;
09179 }
09180 ast_mutex_unlock(&drop->lock);
09181 ast_mutex_destroy(&drop->lock);
09182 ast_free(drop);
09183
09184 }
09185
09186 if (iaxtrunkdebug)
09187 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09188 iaxtrunkdebug = 0;
09189
09190 return 1;
09191 }
09192
09193 struct dpreq_data {
09194 int callno;
09195 char context[AST_MAX_EXTENSION];
09196 char callednum[AST_MAX_EXTENSION];
09197 char *callerid;
09198 };
09199
09200 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09201 {
09202 unsigned short dpstatus = 0;
09203 struct iax_ie_data ied1;
09204 int mm;
09205
09206 memset(&ied1, 0, sizeof(ied1));
09207 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09208
09209 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09210 dpstatus = IAX_DPSTATUS_EXISTS;
09211 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09212 dpstatus = IAX_DPSTATUS_CANEXIST;
09213 } else {
09214 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09215 }
09216 if (ast_ignore_pattern(context, callednum))
09217 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09218 if (mm)
09219 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09220 if (!skiplock)
09221 ast_mutex_lock(&iaxsl[callno]);
09222 if (iaxs[callno]) {
09223 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09224 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09225 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09226 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09227 }
09228 if (!skiplock)
09229 ast_mutex_unlock(&iaxsl[callno]);
09230 }
09231
09232 static void *dp_lookup_thread(void *data)
09233 {
09234
09235 struct dpreq_data *dpr = data;
09236 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09237 if (dpr->callerid)
09238 ast_free(dpr->callerid);
09239 ast_free(dpr);
09240 return NULL;
09241 }
09242
09243 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09244 {
09245 pthread_t newthread;
09246 struct dpreq_data *dpr;
09247
09248 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09249 return;
09250
09251 dpr->callno = callno;
09252 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09253 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09254 if (callerid)
09255 dpr->callerid = ast_strdup(callerid);
09256 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09257 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09258 }
09259 }
09260
09261 struct iax_dual {
09262 struct ast_channel *chan1;
09263 struct ast_channel *chan2;
09264 char *park_exten;
09265 char *park_context;
09266 };
09267
09268 static void *iax_park_thread(void *stuff)
09269 {
09270 struct iax_dual *d;
09271 int res;
09272 int ext = 0;
09273
09274 d = stuff;
09275
09276 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09277 d->chan2->name, d->chan1->name);
09278
09279 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09280 if (res) {
09281
09282 ast_hangup(d->chan1);
09283 } else {
09284 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09285 }
09286 ast_hangup(d->chan2);
09287
09288 ast_free(d->park_exten);
09289 ast_free(d->park_context);
09290 ast_free(d);
09291 return NULL;
09292 }
09293
09294
09295 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
09296 {
09297 struct iax_dual *d;
09298 struct ast_channel *chan1m, *chan2m;
09299 pthread_t th;
09300
09301 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09302 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09303 d = ast_calloc(1, sizeof(*d));
09304 if (!chan1m || !chan2m || !d) {
09305 if (chan1m) {
09306 ast_hangup(chan1m);
09307 }
09308 if (chan2m) {
09309 ast_hangup(chan2m);
09310 }
09311 ast_free(d);
09312 return -1;
09313 }
09314 d->park_exten = ast_strdup(park_exten);
09315 d->park_context = ast_strdup(park_context);
09316 if (!d->park_exten || !d->park_context) {
09317 ast_hangup(chan1m);
09318 ast_hangup(chan2m);
09319 ast_free(d->park_exten);
09320 ast_free(d->park_context);
09321 ast_free(d);
09322 return -1;
09323 }
09324
09325
09326 chan1m->readformat = chan1->readformat;
09327 chan1m->writeformat = chan1->writeformat;
09328
09329
09330 if (ast_channel_masquerade(chan1m, chan1)) {
09331 ast_hangup(chan1m);
09332 ast_hangup(chan2m);
09333 ast_free(d->park_exten);
09334 ast_free(d->park_context);
09335 ast_free(d);
09336 return -1;
09337 }
09338
09339
09340 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09341 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09342 chan1m->priority = chan1->priority;
09343
09344 ast_do_masquerade(chan1m);
09345
09346
09347
09348
09349
09350 chan2m->readformat = chan2->readformat;
09351 chan2m->writeformat = chan2->writeformat;
09352 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09353
09354
09355 if (ast_channel_masquerade(chan2m, chan2)) {
09356 ast_hangup(chan1m);
09357 ast_hangup(chan2m);
09358 ast_free(d->park_exten);
09359 ast_free(d->park_context);
09360 ast_free(d);
09361 return -1;
09362 }
09363
09364
09365 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09366 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09367 chan2m->priority = chan2->priority;
09368
09369 ast_do_masquerade(chan2m);
09370
09371 d->chan1 = chan1m;
09372 d->chan2 = chan2m;
09373 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09374
09375 ast_hangup(chan1m);
09376 ast_hangup(chan2m);
09377 ast_free(d->park_exten);
09378 ast_free(d->park_context);
09379 ast_free(d);
09380 return -1;
09381 }
09382 return 0;
09383 }
09384
09385 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09386 {
09387 unsigned int ourver;
09388 char rsi[80];
09389 snprintf(rsi, sizeof(rsi), "si-%s", si);
09390 if (iax_provision_version(&ourver, rsi, 1))
09391 return 0;
09392 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09393 if (ourver != ver)
09394 iax2_provision(sin, sockfd, NULL, rsi, 1);
09395 return 0;
09396 }
09397
09398 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09399 {
09400 jb_info stats;
09401 jb_getinfo(pvt->jb, &stats);
09402
09403 memset(iep, 0, sizeof(*iep));
09404
09405 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09406 if(stats.frames_in == 0) stats.frames_in = 1;
09407 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09408 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09409 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09410 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09411 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09412 }
09413
09414 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09415 {
09416 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09417 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09418 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09419 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09420 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09421 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09422 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09423 }
09424
09425 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09426 {
09427 int i;
09428 unsigned int length, offset = 0;
09429 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09430
09431 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09432 length = ies->ospblocklength[i];
09433 if (length != 0) {
09434 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09435
09436 offset = 0;
09437 break;
09438 } else {
09439 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09440 offset += length;
09441 }
09442 } else {
09443 break;
09444 }
09445 }
09446 *(full_osptoken + offset) = '\0';
09447 if (strlen(full_osptoken) != offset) {
09448
09449 *full_osptoken = '\0';
09450 }
09451
09452 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09453 }
09454
09455 static void log_jitterstats(unsigned short callno)
09456 {
09457 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09458 jb_info jbinfo;
09459
09460 ast_mutex_lock(&iaxsl[callno]);
09461 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09462 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09463 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09464 localjitter = jbinfo.jitter;
09465 localdelay = jbinfo.current - jbinfo.min;
09466 locallost = jbinfo.frames_lost;
09467 locallosspct = jbinfo.losspct/1000;
09468 localdropped = jbinfo.frames_dropped;
09469 localooo = jbinfo.frames_ooo;
09470 localpackets = jbinfo.frames_in;
09471 }
09472 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",
09473 iaxs[callno]->owner->name,
09474 iaxs[callno]->pingtime,
09475 localjitter,
09476 localdelay,
09477 locallost,
09478 locallosspct,
09479 localdropped,
09480 localooo,
09481 localpackets,
09482 iaxs[callno]->remote_rr.jitter,
09483 iaxs[callno]->remote_rr.delay,
09484 iaxs[callno]->remote_rr.losscnt,
09485 iaxs[callno]->remote_rr.losspct/1000,
09486 iaxs[callno]->remote_rr.dropped,
09487 iaxs[callno]->remote_rr.ooo,
09488 iaxs[callno]->remote_rr.packets);
09489 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",
09490 iaxs[callno]->owner->name,
09491 iaxs[callno]->pingtime,
09492 localjitter,
09493 localdelay,
09494 locallost,
09495 locallosspct,
09496 localdropped,
09497 localooo,
09498 localpackets,
09499 iaxs[callno]->remote_rr.jitter,
09500 iaxs[callno]->remote_rr.delay,
09501 iaxs[callno]->remote_rr.losscnt,
09502 iaxs[callno]->remote_rr.losspct/1000,
09503 iaxs[callno]->remote_rr.dropped,
09504 iaxs[callno]->remote_rr.ooo,
09505 iaxs[callno]->remote_rr.packets);
09506 }
09507 ast_mutex_unlock(&iaxsl[callno]);
09508 }
09509
09510 static int socket_process(struct iax2_thread *thread);
09511
09512
09513
09514
09515 static void handle_deferred_full_frames(struct iax2_thread *thread)
09516 {
09517 struct iax2_pkt_buf *pkt_buf;
09518
09519 ast_mutex_lock(&thread->lock);
09520
09521 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09522 ast_mutex_unlock(&thread->lock);
09523
09524 thread->buf = pkt_buf->buf;
09525 thread->buf_len = pkt_buf->len;
09526 thread->buf_size = pkt_buf->len + 1;
09527
09528 socket_process(thread);
09529
09530 thread->buf = NULL;
09531 ast_free(pkt_buf);
09532
09533 ast_mutex_lock(&thread->lock);
09534 }
09535
09536 ast_mutex_unlock(&thread->lock);
09537 }
09538
09539
09540
09541
09542
09543
09544
09545 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09546 {
09547 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09548 struct ast_iax2_full_hdr *fh, *cur_fh;
09549
09550 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09551 return;
09552
09553 pkt_buf->len = from_here->buf_len;
09554 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09555
09556 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09557 ast_mutex_lock(&to_here->lock);
09558 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09559 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09560 if (fh->oseqno < cur_fh->oseqno) {
09561 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09562 break;
09563 }
09564 }
09565 AST_LIST_TRAVERSE_SAFE_END
09566
09567 if (!cur_pkt_buf)
09568 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09569
09570 ast_mutex_unlock(&to_here->lock);
09571 }
09572
09573 static int socket_read(int *id, int fd, short events, void *cbdata)
09574 {
09575 struct iax2_thread *thread;
09576 socklen_t len;
09577 time_t t;
09578 static time_t last_errtime = 0;
09579 struct ast_iax2_full_hdr *fh;
09580
09581 if (!(thread = find_idle_thread())) {
09582 time(&t);
09583 if (t != last_errtime)
09584 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09585 last_errtime = t;
09586 usleep(1);
09587 return 1;
09588 }
09589
09590 len = sizeof(thread->iosin);
09591 thread->iofd = fd;
09592 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09593 thread->buf_size = sizeof(thread->readbuf);
09594 thread->buf = thread->readbuf;
09595 if (thread->buf_len < 0) {
09596 if (errno != ECONNREFUSED && errno != EAGAIN)
09597 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09598 handle_error();
09599 thread->iostate = IAX_IOSTATE_IDLE;
09600 signal_condition(&thread->lock, &thread->cond);
09601 return 1;
09602 }
09603 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09604 thread->iostate = IAX_IOSTATE_IDLE;
09605 signal_condition(&thread->lock, &thread->cond);
09606 return 1;
09607 }
09608
09609
09610
09611
09612 fh = (struct ast_iax2_full_hdr *) thread->buf;
09613 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09614 struct iax2_thread *cur = NULL;
09615 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09616
09617 AST_LIST_LOCK(&active_list);
09618 AST_LIST_TRAVERSE(&active_list, cur, list) {
09619 if ((cur->ffinfo.callno == callno) &&
09620 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09621 break;
09622 }
09623 if (cur) {
09624
09625
09626 defer_full_frame(thread, cur);
09627 AST_LIST_UNLOCK(&active_list);
09628 thread->iostate = IAX_IOSTATE_IDLE;
09629 signal_condition(&thread->lock, &thread->cond);
09630 return 1;
09631 } else {
09632
09633 thread->ffinfo.callno = callno;
09634 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09635 thread->ffinfo.type = fh->type;
09636 thread->ffinfo.csub = fh->csub;
09637 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09638 }
09639 AST_LIST_UNLOCK(&active_list);
09640 }
09641
09642
09643 thread->iostate = IAX_IOSTATE_READY;
09644 #ifdef DEBUG_SCHED_MULTITHREAD
09645 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09646 #endif
09647 signal_condition(&thread->lock, &thread->cond);
09648
09649 return 1;
09650 }
09651
09652 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09653 struct iax_frame *fr)
09654 {
09655 unsigned char metatype;
09656 struct ast_iax2_meta_trunk_mini *mtm;
09657 struct ast_iax2_meta_trunk_hdr *mth;
09658 struct ast_iax2_meta_trunk_entry *mte;
09659 struct iax2_trunk_peer *tpeer;
09660 unsigned int ts;
09661 void *ptr;
09662 struct timeval rxtrunktime;
09663 struct ast_frame f = { 0, };
09664
09665 if (packet_len < sizeof(*meta)) {
09666 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09667 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09668 return 1;
09669 }
09670
09671 if (meta->metacmd != IAX_META_TRUNK)
09672 return 1;
09673
09674 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09675 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09676 (int) (sizeof(*meta) + sizeof(*mth)));
09677 return 1;
09678 }
09679 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09680 ts = ntohl(mth->ts);
09681 metatype = meta->cmddata;
09682 packet_len -= (sizeof(*meta) + sizeof(*mth));
09683 ptr = mth->data;
09684 tpeer = find_tpeer(sin, sockfd);
09685 if (!tpeer) {
09686 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09687 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09688 return 1;
09689 }
09690 tpeer->trunkact = ast_tvnow();
09691 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09692 tpeer->rxtrunktime = tpeer->trunkact;
09693 rxtrunktime = tpeer->rxtrunktime;
09694 ast_mutex_unlock(&tpeer->lock);
09695 while (packet_len >= sizeof(*mte)) {
09696
09697 unsigned short callno, trunked_ts, len;
09698
09699 if (metatype == IAX_META_TRUNK_MINI) {
09700 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09701 ptr += sizeof(*mtm);
09702 packet_len -= sizeof(*mtm);
09703 len = ntohs(mtm->len);
09704 callno = ntohs(mtm->mini.callno);
09705 trunked_ts = ntohs(mtm->mini.ts);
09706 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09707 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09708 ptr += sizeof(*mte);
09709 packet_len -= sizeof(*mte);
09710 len = ntohs(mte->len);
09711 callno = ntohs(mte->callno);
09712 trunked_ts = 0;
09713 } else {
09714 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09715 break;
09716 }
09717
09718 if (len > packet_len)
09719 break;
09720 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09721 if (!fr->callno)
09722 continue;
09723
09724
09725
09726
09727 memset(&f, 0, sizeof(f));
09728 f.frametype = AST_FRAME_VOICE;
09729 if (!iaxs[fr->callno]) {
09730
09731 } else if (iaxs[fr->callno]->voiceformat == 0) {
09732 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09733 iax2_vnak(fr->callno);
09734 } else {
09735 f.subclass.codec = iaxs[fr->callno]->voiceformat;
09736 f.datalen = len;
09737 if (f.datalen >= 0) {
09738 if (f.datalen)
09739 f.data.ptr = ptr;
09740 else
09741 f.data.ptr = NULL;
09742 if (trunked_ts)
09743 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09744 else
09745 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09746
09747 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09748 struct iax_frame *duped_fr;
09749
09750
09751 f.src = "IAX2";
09752 f.mallocd = 0;
09753 f.offset = 0;
09754 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09755 f.samples = ast_codec_get_samples(&f);
09756 else
09757 f.samples = 0;
09758 fr->outoforder = 0;
09759 iax_frame_wrap(fr, &f);
09760 duped_fr = iaxfrdup2(fr);
09761 if (duped_fr)
09762 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09763 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09764 iaxs[fr->callno]->last = fr->ts;
09765 }
09766 } else {
09767 ast_log(LOG_WARNING, "Datalen < 0?\n");
09768 }
09769 }
09770 ast_mutex_unlock(&iaxsl[fr->callno]);
09771 ptr += len;
09772 packet_len -= len;
09773 }
09774
09775 return 1;
09776 }
09777
09778 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09779 {
09780 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09781 AST_LIST_HEAD(, ast_var_t) *varlist;
09782 struct ast_var_t *var;
09783
09784 if (!variablestore) {
09785 *buf = '\0';
09786 return 0;
09787 }
09788 varlist = variablestore->data;
09789
09790 AST_LIST_LOCK(varlist);
09791 AST_LIST_TRAVERSE(varlist, var, entries) {
09792 if (strcmp(var->name, data) == 0) {
09793 ast_copy_string(buf, var->value, len);
09794 break;
09795 }
09796 }
09797 AST_LIST_UNLOCK(varlist);
09798 return 0;
09799 }
09800
09801 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09802 {
09803 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09804 AST_LIST_HEAD(, ast_var_t) *varlist;
09805 struct ast_var_t *var;
09806
09807 if (!variablestore) {
09808 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09809 if (!variablestore) {
09810 ast_log(LOG_ERROR, "Memory allocation error\n");
09811 return -1;
09812 }
09813 varlist = ast_calloc(1, sizeof(*varlist));
09814 if (!varlist) {
09815 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09816 return -1;
09817 }
09818
09819 AST_LIST_HEAD_INIT(varlist);
09820 variablestore->data = varlist;
09821 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09822 ast_channel_datastore_add(chan, variablestore);
09823 } else
09824 varlist = variablestore->data;
09825
09826 AST_LIST_LOCK(varlist);
09827 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09828 if (strcmp(var->name, data) == 0) {
09829 AST_LIST_REMOVE_CURRENT(entries);
09830 ast_var_delete(var);
09831 break;
09832 }
09833 }
09834 AST_LIST_TRAVERSE_SAFE_END;
09835 var = ast_var_assign(data, value);
09836 if (var)
09837 AST_LIST_INSERT_TAIL(varlist, var, entries);
09838 else
09839 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09840 AST_LIST_UNLOCK(varlist);
09841 return 0;
09842 }
09843
09844 static struct ast_custom_function iaxvar_function = {
09845 .name = "IAXVAR",
09846 .read = acf_iaxvar_read,
09847 .write = acf_iaxvar_write,
09848 };
09849
09850 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
09851 {
09852 iax2_lock_owner(callno);
09853 if (iaxs[callno] && iaxs[callno]->owner) {
09854 if (causecode) {
09855 iaxs[callno]->owner->hangupcause = causecode;
09856 }
09857 ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
09858 ast_channel_unlock(iaxs[callno]->owner);
09859 }
09860 }
09861
09862 static int socket_process(struct iax2_thread *thread)
09863 {
09864 struct sockaddr_in sin;
09865 int res;
09866 int updatehistory=1;
09867 int new = NEW_PREVENT;
09868 int dcallno = 0;
09869 char decrypted = 0;
09870 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09871 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09872 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09873 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09874 struct iax_frame *fr;
09875 struct iax_frame *cur;
09876 struct ast_frame f = { 0, };
09877 struct ast_channel *c = NULL;
09878 struct iax2_dpcache *dp;
09879 struct iax2_peer *peer;
09880 struct iax_ies ies;
09881 struct iax_ie_data ied0, ied1;
09882 format_t format;
09883 int fd;
09884 int exists;
09885 int minivid = 0;
09886 char empty[32]="";
09887 struct iax_frame *duped_fr;
09888 char host_pref_buf[128];
09889 char caller_pref_buf[128];
09890 struct ast_codec_pref pref;
09891 char *using_prefs = "mine";
09892
09893
09894 fr = alloca(sizeof(*fr) + 4096);
09895 memset(fr, 0, sizeof(*fr));
09896 fr->afdatalen = 4096;
09897
09898
09899 res = thread->buf_len;
09900 fd = thread->iofd;
09901 memcpy(&sin, &thread->iosin, sizeof(sin));
09902
09903 if (res < sizeof(*mh)) {
09904 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09905 return 1;
09906 }
09907 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09908 if (res < sizeof(*vh)) {
09909 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));
09910 return 1;
09911 }
09912
09913
09914 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09915 minivid = 1;
09916 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09917 return socket_process_meta(res, meta, &sin, fd, fr);
09918
09919 #ifdef DEBUG_SUPPORT
09920 if (res >= sizeof(*fh))
09921 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09922 #endif
09923 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09924 if (res < sizeof(*fh)) {
09925 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));
09926 return 1;
09927 }
09928
09929
09930 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09931
09932
09933
09934
09935
09936
09937 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09938 ast_mutex_lock(&iaxsl[fr->callno]);
09939 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
09940 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09941 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09942 ast_mutex_unlock(&iaxsl[fr->callno]);
09943 return 1;
09944 }
09945 decrypted = 1;
09946 }
09947 ast_mutex_unlock(&iaxsl[fr->callno]);
09948 }
09949
09950
09951 f.frametype = fh->type;
09952 if (f.frametype == AST_FRAME_VIDEO) {
09953 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09954 } else if (f.frametype == AST_FRAME_VOICE) {
09955 f.subclass.codec = uncompress_subclass(fh->csub);
09956 } else {
09957 f.subclass.integer = uncompress_subclass(fh->csub);
09958 }
09959
09960
09961 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
09962
09963 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09964 return 1;
09965 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
09966
09967 return 1;
09968 }
09969
09970 f.datalen = res - sizeof(*fh);
09971 if (f.datalen) {
09972 if (f.frametype == AST_FRAME_IAX) {
09973 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09974 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09975 ast_variables_destroy(ies.vars);
09976 return 1;
09977 }
09978 f.data.ptr = NULL;
09979 f.datalen = 0;
09980 } else {
09981 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09982 memset(&ies, 0, sizeof(ies));
09983 }
09984 } else {
09985 if (f.frametype == AST_FRAME_IAX)
09986 f.data.ptr = NULL;
09987 else
09988 f.data.ptr = empty;
09989 memset(&ies, 0, sizeof(ies));
09990 }
09991
09992 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
09993
09994 if (handle_call_token(fh, &ies, &sin, fd)) {
09995 ast_variables_destroy(ies.vars);
09996 return 1;
09997 }
09998
09999 if (ies.calltoken && ies.calltokendata) {
10000
10001
10002
10003
10004 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10005 } else {
10006 new = NEW_ALLOW;
10007 }
10008 }
10009 } else {
10010
10011 f.frametype = AST_FRAME_NULL;
10012 f.subclass.integer = 0;
10013 memset(&ies, 0, sizeof(ies));
10014 }
10015
10016 if (!fr->callno) {
10017 int check_dcallno = 0;
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10028 check_dcallno = 1;
10029 }
10030
10031 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10032 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10033 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10034 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10035 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10036 }
10037 ast_variables_destroy(ies.vars);
10038 return 1;
10039 }
10040 }
10041
10042 if (fr->callno > 0)
10043 ast_mutex_lock(&iaxsl[fr->callno]);
10044
10045 if (!fr->callno || !iaxs[fr->callno]) {
10046
10047
10048 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10049
10050 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10051 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10052 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10053 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10054 (f.frametype != AST_FRAME_IAX))
10055 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10056 fd);
10057 }
10058 if (fr->callno > 0)
10059 ast_mutex_unlock(&iaxsl[fr->callno]);
10060 ast_variables_destroy(ies.vars);
10061 return 1;
10062 }
10063 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10064 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10065 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10066 ast_variables_destroy(ies.vars);
10067 ast_mutex_unlock(&iaxsl[fr->callno]);
10068 return 1;
10069 }
10070 decrypted = 1;
10071 }
10072
10073 #ifdef DEBUG_SUPPORT
10074 if (decrypted) {
10075 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10076 }
10077 #endif
10078
10079
10080
10081 iaxs[fr->callno]->frames_received++;
10082
10083 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10084 f.subclass.integer != IAX_COMMAND_TXCNT &&
10085 f.subclass.integer != IAX_COMMAND_TXACC) {
10086 unsigned short new_peercallno;
10087
10088 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10089 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10090 if (iaxs[fr->callno]->peercallno) {
10091 remove_by_peercallno(iaxs[fr->callno]);
10092 }
10093 iaxs[fr->callno]->peercallno = new_peercallno;
10094 store_by_peercallno(iaxs[fr->callno]);
10095 }
10096 }
10097 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10098 if (iaxdebug)
10099 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10100
10101 fr->oseqno = fh->oseqno;
10102 fr->iseqno = fh->iseqno;
10103 fr->ts = ntohl(fh->ts);
10104 #ifdef IAXTESTS
10105 if (test_resync) {
10106 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10107 fr->ts += test_resync;
10108 }
10109 #endif
10110 #if 0
10111 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10112 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10113 (f.subclass == IAX_COMMAND_NEW ||
10114 f.subclass == IAX_COMMAND_AUTHREQ ||
10115 f.subclass == IAX_COMMAND_ACCEPT ||
10116 f.subclass == IAX_COMMAND_REJECT)) ) )
10117 #endif
10118 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10119 updatehistory = 0;
10120 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10121 (iaxs[fr->callno]->iseqno ||
10122 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10123 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10124 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10125 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10126 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10127 (f.frametype != AST_FRAME_IAX))) {
10128 if (
10129 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10130 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10131 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10132 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10133 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10134 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10135 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10136 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10137 (f.frametype != AST_FRAME_IAX)) {
10138
10139 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10140 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10141
10142
10143 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10144
10145 if ((f.frametype != AST_FRAME_IAX) ||
10146 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10147 ast_debug(1, "Acking anyway\n");
10148
10149
10150 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10151 }
10152 } else {
10153
10154 iax2_vnak(fr->callno);
10155 }
10156 ast_variables_destroy(ies.vars);
10157 ast_mutex_unlock(&iaxsl[fr->callno]);
10158 return 1;
10159 }
10160 } else {
10161
10162 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10163 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10164 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10165 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10166 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10167 (f.frametype != AST_FRAME_IAX))
10168 iaxs[fr->callno]->iseqno++;
10169 }
10170
10171 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10172 if (res < thread->buf_size)
10173 thread->buf[res++] = '\0';
10174 else
10175 thread->buf[res - 1] = '\0';
10176 }
10177
10178
10179
10180 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10181 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10182 (f.frametype != AST_FRAME_IAX))) {
10183 unsigned char x;
10184 int call_to_destroy;
10185
10186 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10187 x = fr->iseqno;
10188 else
10189 x = iaxs[fr->callno]->oseqno;
10190 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10191
10192
10193 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10194
10195 if (iaxdebug)
10196 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10197 call_to_destroy = 0;
10198 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10199
10200 if (x == cur->oseqno) {
10201 cur->retries = -1;
10202
10203 if (cur->final)
10204 call_to_destroy = fr->callno;
10205 }
10206 }
10207 if (call_to_destroy) {
10208 if (iaxdebug)
10209 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10210 ast_mutex_lock(&iaxsl[call_to_destroy]);
10211 iax2_destroy(call_to_destroy);
10212 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10213 }
10214 }
10215
10216 if (iaxs[fr->callno])
10217 iaxs[fr->callno]->rseqno = fr->iseqno;
10218 else {
10219
10220 ast_variables_destroy(ies.vars);
10221 ast_mutex_unlock(&iaxsl[fr->callno]);
10222 return 1;
10223 }
10224 } else {
10225 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10226 }
10227 }
10228 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10229 ((f.frametype != AST_FRAME_IAX) ||
10230 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10231 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10232
10233 ast_variables_destroy(ies.vars);
10234 ast_mutex_unlock(&iaxsl[fr->callno]);
10235 return 1;
10236 }
10237
10238
10239
10240
10241 if ((f.frametype == AST_FRAME_VOICE) ||
10242 (f.frametype == AST_FRAME_VIDEO) ||
10243 (f.frametype == AST_FRAME_IAX)) {
10244 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10245 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10246 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10247 ast_variables_destroy(ies.vars);
10248 ast_mutex_unlock(&iaxsl[fr->callno]);
10249 return 1;
10250 }
10251 }
10252
10253 if (ies.vars) {
10254 struct ast_datastore *variablestore = NULL;
10255 struct ast_variable *var, *prev = NULL;
10256 AST_LIST_HEAD(, ast_var_t) *varlist;
10257
10258 iax2_lock_owner(fr->callno);
10259 if (!iaxs[fr->callno]) {
10260 ast_variables_destroy(ies.vars);
10261 ast_mutex_unlock(&iaxsl[fr->callno]);
10262 return 1;
10263 }
10264 if ((c = iaxs[fr->callno]->owner)) {
10265 varlist = ast_calloc(1, sizeof(*varlist));
10266 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10267
10268 if (variablestore && varlist) {
10269 variablestore->data = varlist;
10270 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10271 AST_LIST_HEAD_INIT(varlist);
10272 ast_debug(1, "I can haz IAX vars?\n");
10273 for (var = ies.vars; var; var = var->next) {
10274 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10275 if (prev) {
10276 ast_free(prev);
10277 }
10278 prev = var;
10279 if (!newvar) {
10280
10281 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10282 } else {
10283 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10284 }
10285 }
10286 if (prev) {
10287 ast_free(prev);
10288 }
10289 ies.vars = NULL;
10290 ast_channel_datastore_add(c, variablestore);
10291 } else {
10292 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10293 if (variablestore) {
10294 ast_datastore_free(variablestore);
10295 }
10296 if (varlist) {
10297 ast_free(varlist);
10298 }
10299 }
10300 ast_channel_unlock(c);
10301 } else {
10302
10303
10304 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10305 for (var = ies.vars; var && var->next; var = var->next);
10306 if (var) {
10307 var->next = iaxs[fr->callno]->iaxvars;
10308 iaxs[fr->callno]->iaxvars = ies.vars;
10309 ies.vars = NULL;
10310 }
10311 }
10312 }
10313
10314 if (ies.vars) {
10315 ast_debug(1, "I have IAX variables, but they were not processed\n");
10316 }
10317 }
10318
10319
10320
10321 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10322 send_signaling(iaxs[fr->callno]);
10323 }
10324
10325 if (f.frametype == AST_FRAME_VOICE) {
10326 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10327 iaxs[fr->callno]->voiceformat = f.subclass.codec;
10328 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10329 if (iaxs[fr->callno]->owner) {
10330 iax2_lock_owner(fr->callno);
10331 if (iaxs[fr->callno]) {
10332 if (iaxs[fr->callno]->owner) {
10333 format_t orignative;
10334
10335 orignative = iaxs[fr->callno]->owner->nativeformats;
10336 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10337 if (iaxs[fr->callno]->owner->readformat)
10338 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10339 iaxs[fr->callno]->owner->nativeformats = orignative;
10340 ast_channel_unlock(iaxs[fr->callno]->owner);
10341 }
10342 } else {
10343 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10344
10345 if (ies.vars) {
10346 ast_variables_destroy(ies.vars);
10347 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10348 ies.vars = NULL;
10349 }
10350 ast_mutex_unlock(&iaxsl[fr->callno]);
10351 return 1;
10352 }
10353 }
10354 }
10355 }
10356 if (f.frametype == AST_FRAME_VIDEO) {
10357 if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10358 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10359 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10360 }
10361 }
10362 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10363 if (f.subclass.integer == AST_CONTROL_BUSY) {
10364 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10365 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10366 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10367 }
10368 }
10369 if (f.frametype == AST_FRAME_IAX) {
10370 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10371
10372 if (iaxdebug)
10373 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10374
10375
10376 if (iaxs[fr->callno]->last < fr->ts &&
10377 f.subclass.integer != IAX_COMMAND_ACK &&
10378 f.subclass.integer != IAX_COMMAND_PONG &&
10379 f.subclass.integer != IAX_COMMAND_LAGRP) {
10380 iaxs[fr->callno]->last = fr->ts;
10381 if (iaxdebug)
10382 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10383 }
10384 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10385 if (!iaxs[fr->callno]->first_iax_message) {
10386 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10387 }
10388 switch(f.subclass.integer) {
10389 case IAX_COMMAND_ACK:
10390
10391 break;
10392 case IAX_COMMAND_QUELCH:
10393 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10394
10395 if (iaxs[fr->callno]->owner) {
10396 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10397 "Status: On\r\n"
10398 "Channel: %s\r\n"
10399 "Uniqueid: %s\r\n",
10400 iaxs[fr->callno]->owner->name,
10401 iaxs[fr->callno]->owner->uniqueid);
10402 }
10403
10404 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10405 if (ies.musiconhold) {
10406 iax2_lock_owner(fr->callno);
10407 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10408 break;
10409 }
10410 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10411 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10412
10413
10414
10415
10416
10417 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10418 S_OR(moh_suggest, NULL),
10419 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10420 }
10421 ast_channel_unlock(iaxs[fr->callno]->owner);
10422 }
10423 }
10424 break;
10425 case IAX_COMMAND_UNQUELCH:
10426 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10427 iax2_lock_owner(fr->callno);
10428 if (!iaxs[fr->callno]) {
10429 break;
10430 }
10431
10432 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10433 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10434 "Status: Off\r\n"
10435 "Channel: %s\r\n"
10436 "Uniqueid: %s\r\n",
10437 iaxs[fr->callno]->owner->name,
10438 iaxs[fr->callno]->owner->uniqueid);
10439 }
10440
10441 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10442 if (!iaxs[fr->callno]->owner) {
10443 break;
10444 }
10445 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10446
10447
10448
10449
10450 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10451 }
10452 ast_channel_unlock(iaxs[fr->callno]->owner);
10453 }
10454 break;
10455 case IAX_COMMAND_TXACC:
10456 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10457
10458 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10459
10460 if (cur->transfer) {
10461 cur->retries = -1;
10462 }
10463 }
10464 memset(&ied1, 0, sizeof(ied1));
10465 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10466 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10467 iaxs[fr->callno]->transferring = TRANSFER_READY;
10468 }
10469 break;
10470 case IAX_COMMAND_NEW:
10471
10472 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10473 break;
10474 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10475 ast_mutex_unlock(&iaxsl[fr->callno]);
10476 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10477 ast_mutex_lock(&iaxsl[fr->callno]);
10478 if (!iaxs[fr->callno]) {
10479 break;
10480 }
10481 }
10482
10483 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10484 int new_callno;
10485 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10486 fr->callno = new_callno;
10487 }
10488
10489 if (delayreject)
10490 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10491 if (check_access(fr->callno, &sin, &ies)) {
10492
10493 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10494 if (authdebug)
10495 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);
10496 break;
10497 }
10498 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10499 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10500 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10501 break;
10502 }
10503 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10504 const char *context, *exten, *cid_num;
10505
10506 context = ast_strdupa(iaxs[fr->callno]->context);
10507 exten = ast_strdupa(iaxs[fr->callno]->exten);
10508 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10509
10510
10511 ast_mutex_unlock(&iaxsl[fr->callno]);
10512 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10513 ast_mutex_lock(&iaxsl[fr->callno]);
10514
10515 if (!iaxs[fr->callno]) {
10516 break;
10517 }
10518 } else
10519 exists = 0;
10520
10521 save_osptoken(fr, &ies);
10522 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10523 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10524 memset(&ied0, 0, sizeof(ied0));
10525 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10526 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10527 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10528 if (!iaxs[fr->callno]) {
10529 break;
10530 }
10531 if (authdebug)
10532 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);
10533 } else {
10534
10535
10536 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10537 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10538 using_prefs = "reqonly";
10539 } else {
10540 using_prefs = "disabled";
10541 }
10542 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10543 memset(&pref, 0, sizeof(pref));
10544 strcpy(caller_pref_buf, "disabled");
10545 strcpy(host_pref_buf, "disabled");
10546 } else {
10547 using_prefs = "mine";
10548
10549 if (ies.codec_prefs)
10550 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10551 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10552
10553 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10554 pref = iaxs[fr->callno]->rprefs;
10555 using_prefs = "caller";
10556 } else {
10557 pref = iaxs[fr->callno]->prefs;
10558 }
10559 } else
10560 pref = iaxs[fr->callno]->prefs;
10561
10562 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10563 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10564 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10565 }
10566 if (!format) {
10567 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10568 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10569 if (!format) {
10570 memset(&ied0, 0, sizeof(ied0));
10571 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10572 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10573 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10574 if (!iaxs[fr->callno]) {
10575 break;
10576 }
10577 if (authdebug) {
10578 char tmp[256], tmp2[256], tmp3[256];
10579 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10580 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10581 ast_inet_ntoa(sin.sin_addr),
10582 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10583 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10584 } else {
10585 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10586 ast_inet_ntoa(sin.sin_addr),
10587 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10588 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10589 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10590 }
10591 }
10592 } else {
10593
10594 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10595 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10596 format = 0;
10597 } else {
10598 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10599 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10600 memset(&pref, 0, sizeof(pref));
10601 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10602 strcpy(caller_pref_buf,"disabled");
10603 strcpy(host_pref_buf,"disabled");
10604 } else {
10605 using_prefs = "mine";
10606 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10607
10608 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10609 pref = iaxs[fr->callno]->prefs;
10610 } else {
10611 pref = iaxs[fr->callno]->rprefs;
10612 using_prefs = "caller";
10613 }
10614 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10615 } else
10616 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10617 }
10618 }
10619
10620 if (!format) {
10621 char tmp[256], tmp2[256], tmp3[256];
10622 memset(&ied0, 0, sizeof(ied0));
10623 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10624 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10625 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10626 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10627 if (!iaxs[fr->callno]) {
10628 break;
10629 }
10630 if (authdebug) {
10631 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10632 ast_inet_ntoa(sin.sin_addr),
10633 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10634 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10635 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10636 }
10637 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10638 break;
10639 }
10640 }
10641 }
10642 if (format) {
10643
10644 memset(&ied1, 0, sizeof(ied1));
10645 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10646 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10647 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10648 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10649 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10650 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10651 "%srequested format = %s,\n"
10652 "%srequested prefs = %s,\n"
10653 "%sactual format = %s,\n"
10654 "%shost prefs = %s,\n"
10655 "%spriority = %s\n",
10656 ast_inet_ntoa(sin.sin_addr),
10657 VERBOSE_PREFIX_4,
10658 ast_getformatname(iaxs[fr->callno]->peerformat),
10659 VERBOSE_PREFIX_4,
10660 caller_pref_buf,
10661 VERBOSE_PREFIX_4,
10662 ast_getformatname(format),
10663 VERBOSE_PREFIX_4,
10664 host_pref_buf,
10665 VERBOSE_PREFIX_4,
10666 using_prefs);
10667
10668 iaxs[fr->callno]->chosenformat = format;
10669 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10670 } else {
10671 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10672
10673 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10674 }
10675 }
10676 }
10677 break;
10678 }
10679 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10680 merge_encryption(iaxs[fr->callno],ies.encmethods);
10681 else
10682 iaxs[fr->callno]->encmethods = 0;
10683 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10684 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10685 break;
10686 case IAX_COMMAND_DPREQ:
10687
10688 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10689 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10690 if (iaxcompat) {
10691
10692 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10693 } else {
10694
10695 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10696 }
10697 }
10698 break;
10699 case IAX_COMMAND_HANGUP:
10700 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10701 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10702
10703 if (iaxs[fr->callno]->owner) {
10704 set_hangup_source_and_cause(fr->callno, ies.causecode);
10705 if (!iaxs[fr->callno]) {
10706 break;
10707 }
10708 }
10709
10710
10711 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10712 iax2_destroy(fr->callno);
10713 break;
10714 case IAX_COMMAND_REJECT:
10715
10716 if (iaxs[fr->callno]->owner) {
10717 set_hangup_source_and_cause(fr->callno, ies.causecode);
10718 if (!iaxs[fr->callno]) {
10719 break;
10720 }
10721 }
10722
10723 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10724 if (iaxs[fr->callno]->owner && authdebug)
10725 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10726 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10727 ies.cause ? ies.cause : "<Unknown>");
10728 ast_debug(1, "Immediately destroying %d, having received reject\n",
10729 fr->callno);
10730 }
10731
10732 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10733 fr->ts, NULL, 0, fr->iseqno);
10734 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10735 iaxs[fr->callno]->error = EPERM;
10736 iax2_destroy(fr->callno);
10737 break;
10738 case IAX_COMMAND_TRANSFER:
10739 {
10740 struct ast_channel *bridged_chan;
10741 struct ast_channel *owner;
10742
10743 iax2_lock_owner(fr->callno);
10744 if (!iaxs[fr->callno]) {
10745
10746 break;
10747 }
10748 owner = iaxs[fr->callno]->owner;
10749 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10750 if (bridged_chan && ies.called_number) {
10751 const char *context;
10752
10753 context = ast_strdupa(iaxs[fr->callno]->context);
10754
10755 ast_channel_ref(owner);
10756 ast_channel_ref(bridged_chan);
10757 ast_channel_unlock(owner);
10758 ast_mutex_unlock(&iaxsl[fr->callno]);
10759
10760
10761 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10762 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10763
10764
10765 if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10766 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10767 if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10768 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10769 bridged_chan->name);
10770 }
10771 } else {
10772 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10773 ast_log(LOG_WARNING,
10774 "Async goto of '%s' to '%s@%s' failed\n",
10775 bridged_chan->name, ies.called_number, context);
10776 } else {
10777 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10778 bridged_chan->name, ies.called_number, context);
10779 }
10780 }
10781 ast_channel_unref(owner);
10782 ast_channel_unref(bridged_chan);
10783
10784 ast_mutex_lock(&iaxsl[fr->callno]);
10785 } else {
10786 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10787 if (owner) {
10788 ast_channel_unlock(owner);
10789 }
10790 }
10791
10792 break;
10793 }
10794 case IAX_COMMAND_ACCEPT:
10795
10796 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10797 break;
10798 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10799
10800 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10801 iax2_destroy(fr->callno);
10802 break;
10803 }
10804 if (ies.format) {
10805 iaxs[fr->callno]->peerformat = ies.format;
10806 } else {
10807 if (iaxs[fr->callno]->owner)
10808 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10809 else
10810 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10811 }
10812 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));
10813 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10814 memset(&ied0, 0, sizeof(ied0));
10815 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10816 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10817 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10818 if (!iaxs[fr->callno]) {
10819 break;
10820 }
10821 if (authdebug) {
10822 char tmp1[256], tmp2[256];
10823 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10824 ast_inet_ntoa(sin.sin_addr),
10825 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10826 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10827 }
10828 } else {
10829 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10830 iax2_lock_owner(fr->callno);
10831 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10832
10833 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10834 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10835
10836
10837 if (iaxs[fr->callno]->owner->writeformat)
10838 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10839 if (iaxs[fr->callno]->owner->readformat)
10840 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10841 ast_channel_unlock(iaxs[fr->callno]->owner);
10842 }
10843 }
10844 if (iaxs[fr->callno]) {
10845 AST_LIST_LOCK(&dpcache);
10846 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10847 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10848 iax2_dprequest(dp, fr->callno);
10849 AST_LIST_UNLOCK(&dpcache);
10850 }
10851 break;
10852 case IAX_COMMAND_POKE:
10853
10854 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10855 break;
10856 case IAX_COMMAND_PING:
10857 {
10858 struct iax_ie_data pingied;
10859 construct_rr(iaxs[fr->callno], &pingied);
10860
10861 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10862 }
10863 break;
10864 case IAX_COMMAND_PONG:
10865
10866 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10867
10868 save_rr(fr, &ies);
10869
10870
10871 log_jitterstats(fr->callno);
10872
10873 if (iaxs[fr->callno]->peerpoke) {
10874 peer = iaxs[fr->callno]->peerpoke;
10875 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10876 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10877 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10878 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);
10879 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10880 }
10881 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10882 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10883 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10884 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);
10885 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10886 }
10887 }
10888 peer->lastms = iaxs[fr->callno]->pingtime;
10889 if (peer->smoothing && (peer->lastms > -1))
10890 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10891 else if (peer->smoothing && peer->lastms < 0)
10892 peer->historicms = (0 + peer->historicms) / 2;
10893 else
10894 peer->historicms = iaxs[fr->callno]->pingtime;
10895
10896
10897 if (peer->pokeexpire > -1) {
10898 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10899 peer_unref(peer);
10900 peer->pokeexpire = -1;
10901 }
10902 }
10903
10904 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10905 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10906 else
10907 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10908 if (peer->pokeexpire == -1)
10909 peer_unref(peer);
10910
10911 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10912
10913 iax2_destroy(fr->callno);
10914 peer->callno = 0;
10915 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10916 }
10917 break;
10918 case IAX_COMMAND_LAGRQ:
10919 case IAX_COMMAND_LAGRP:
10920 f.src = "LAGRQ";
10921 f.mallocd = 0;
10922 f.offset = 0;
10923 f.samples = 0;
10924 iax_frame_wrap(fr, &f);
10925 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
10926
10927 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
10928 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10929 } else {
10930
10931 unsigned int ts;
10932
10933 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10934 iaxs[fr->callno]->lag = ts - fr->ts;
10935 if (iaxdebug)
10936 ast_debug(1, "Peer %s lag measured as %dms\n",
10937 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10938 }
10939 break;
10940 case IAX_COMMAND_AUTHREQ:
10941 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10942 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>");
10943 break;
10944 }
10945 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10946 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10947 .subclass.integer = AST_CONTROL_HANGUP,
10948 };
10949 ast_log(LOG_WARNING,
10950 "I don't know how to authenticate %s to %s\n",
10951 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10952 iax2_queue_frame(fr->callno, &hangup_fr);
10953 }
10954 break;
10955 case IAX_COMMAND_AUTHREP:
10956
10957 if (delayreject)
10958 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10959
10960 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10961 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>");
10962 break;
10963 }
10964 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10965 if (authdebug)
10966 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);
10967 memset(&ied0, 0, sizeof(ied0));
10968 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10969 break;
10970 }
10971 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10972
10973 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10974 } else
10975 exists = 0;
10976 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10977 if (authdebug)
10978 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);
10979 memset(&ied0, 0, sizeof(ied0));
10980 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10981 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10982 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10983 if (!iaxs[fr->callno]) {
10984 break;
10985 }
10986 } else {
10987
10988 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10989 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10990 using_prefs = "reqonly";
10991 } else {
10992 using_prefs = "disabled";
10993 }
10994 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10995 memset(&pref, 0, sizeof(pref));
10996 strcpy(caller_pref_buf, "disabled");
10997 strcpy(host_pref_buf, "disabled");
10998 } else {
10999 using_prefs = "mine";
11000 if (ies.codec_prefs)
11001 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11002 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11003 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11004 pref = iaxs[fr->callno]->rprefs;
11005 using_prefs = "caller";
11006 } else {
11007 pref = iaxs[fr->callno]->prefs;
11008 }
11009 } else
11010 pref = iaxs[fr->callno]->prefs;
11011 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11012 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11013 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11014 }
11015 if (!format) {
11016 char tmp1[256], tmp2[256], tmp3[256];
11017 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11018 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11019 ast_getformatname(iaxs[fr->callno]->peerformat),
11020 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11021 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11022 }
11023 if (!format) {
11024 if (authdebug) {
11025 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11026 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11027 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11028 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11029 } else {
11030 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11031 ast_inet_ntoa(sin.sin_addr),
11032 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11033 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11034 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11035 }
11036 }
11037 memset(&ied0, 0, sizeof(ied0));
11038 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11039 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11040 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11041 if (!iaxs[fr->callno]) {
11042 break;
11043 }
11044 } else {
11045
11046 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11047 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11048 format = 0;
11049 } else {
11050 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11051 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11052 memset(&pref, 0, sizeof(pref));
11053 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11054 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11055 strcpy(caller_pref_buf,"disabled");
11056 strcpy(host_pref_buf,"disabled");
11057 } else {
11058 using_prefs = "mine";
11059 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11060
11061 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11062 pref = iaxs[fr->callno]->prefs;
11063 } else {
11064 pref = iaxs[fr->callno]->rprefs;
11065 using_prefs = "caller";
11066 }
11067 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11068 } else
11069 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11070 }
11071 }
11072 if (!format) {
11073 char tmp1[256], tmp2[256], tmp3[256];
11074 ast_log(LOG_ERROR, "No best format in %s???\n",
11075 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11076 if (authdebug) {
11077 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11078 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11079 ast_inet_ntoa(sin.sin_addr),
11080 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11081 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11082 } else {
11083 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11084 ast_inet_ntoa(sin.sin_addr),
11085 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11086 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11087 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11088 }
11089 }
11090 memset(&ied0, 0, sizeof(ied0));
11091 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11092 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11093 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11094 if (!iaxs[fr->callno]) {
11095 break;
11096 }
11097 }
11098 }
11099 }
11100 if (format) {
11101
11102 memset(&ied1, 0, sizeof(ied1));
11103 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11104 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11105 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11106 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11107 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11108 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11109 "%srequested format = %s,\n"
11110 "%srequested prefs = %s,\n"
11111 "%sactual format = %s,\n"
11112 "%shost prefs = %s,\n"
11113 "%spriority = %s\n",
11114 ast_inet_ntoa(sin.sin_addr),
11115 VERBOSE_PREFIX_4,
11116 ast_getformatname(iaxs[fr->callno]->peerformat),
11117 VERBOSE_PREFIX_4,
11118 caller_pref_buf,
11119 VERBOSE_PREFIX_4,
11120 ast_getformatname(format),
11121 VERBOSE_PREFIX_4,
11122 host_pref_buf,
11123 VERBOSE_PREFIX_4,
11124 using_prefs);
11125
11126 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11127 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11128 iax2_destroy(fr->callno);
11129 else if (ies.vars) {
11130 struct ast_datastore *variablestore;
11131 struct ast_variable *var, *prev = NULL;
11132 AST_LIST_HEAD(, ast_var_t) *varlist;
11133 varlist = ast_calloc(1, sizeof(*varlist));
11134 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11135 if (variablestore && varlist) {
11136 variablestore->data = varlist;
11137 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11138 AST_LIST_HEAD_INIT(varlist);
11139 ast_debug(1, "I can haz IAX vars? w00t\n");
11140 for (var = ies.vars; var; var = var->next) {
11141 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11142 if (prev)
11143 ast_free(prev);
11144 prev = var;
11145 if (!newvar) {
11146
11147 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11148 } else {
11149 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11150 }
11151 }
11152 if (prev)
11153 ast_free(prev);
11154 ies.vars = NULL;
11155 ast_channel_datastore_add(c, variablestore);
11156 } else {
11157 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11158 if (variablestore)
11159 ast_datastore_free(variablestore);
11160 if (varlist)
11161 ast_free(varlist);
11162 }
11163 }
11164 } else {
11165 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11166
11167 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11168 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11169 goto immediatedial;
11170 }
11171 }
11172 }
11173 }
11174 break;
11175 case IAX_COMMAND_DIAL:
11176 immediatedial:
11177 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11178 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11179 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11180 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11181 if (authdebug)
11182 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);
11183 memset(&ied0, 0, sizeof(ied0));
11184 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11185 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11186 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11187 if (!iaxs[fr->callno]) {
11188 break;
11189 }
11190 } else {
11191 char tmp[256];
11192 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11193 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11194 ast_inet_ntoa(sin.sin_addr),
11195 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11196 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11197 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11198 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11199 iax2_destroy(fr->callno);
11200 else if (ies.vars) {
11201 struct ast_datastore *variablestore;
11202 struct ast_variable *var, *prev = NULL;
11203 AST_LIST_HEAD(, ast_var_t) *varlist;
11204 varlist = ast_calloc(1, sizeof(*varlist));
11205 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11206 ast_debug(1, "I can haz IAX vars? w00t\n");
11207 if (variablestore && varlist) {
11208 variablestore->data = varlist;
11209 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11210 AST_LIST_HEAD_INIT(varlist);
11211 for (var = ies.vars; var; var = var->next) {
11212 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11213 if (prev)
11214 ast_free(prev);
11215 prev = var;
11216 if (!newvar) {
11217
11218 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11219 } else {
11220 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11221 }
11222 }
11223 if (prev)
11224 ast_free(prev);
11225 ies.vars = NULL;
11226 ast_channel_datastore_add(c, variablestore);
11227 } else {
11228 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11229 if (variablestore)
11230 ast_datastore_free(variablestore);
11231 if (varlist)
11232 ast_free(varlist);
11233 }
11234 }
11235 }
11236 }
11237 break;
11238 case IAX_COMMAND_INVAL:
11239 iaxs[fr->callno]->error = ENOTCONN;
11240 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11241 iax2_destroy(fr->callno);
11242 ast_debug(1, "Destroying call %d\n", fr->callno);
11243 break;
11244 case IAX_COMMAND_VNAK:
11245 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11246
11247 vnak_retransmit(fr->callno, fr->iseqno);
11248 break;
11249 case IAX_COMMAND_REGREQ:
11250 case IAX_COMMAND_REGREL:
11251
11252 if (delayreject)
11253 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11254 if (register_verify(fr->callno, &sin, &ies)) {
11255 if (!iaxs[fr->callno]) {
11256 break;
11257 }
11258
11259 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11260 break;
11261 }
11262 if (!iaxs[fr->callno]) {
11263 break;
11264 }
11265 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11266 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11267
11268 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11269 memset(&sin, 0, sizeof(sin));
11270 sin.sin_family = AF_INET;
11271 }
11272 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11273 ast_log(LOG_WARNING, "Registry error\n");
11274 }
11275 if (!iaxs[fr->callno]) {
11276 break;
11277 }
11278 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11279 ast_mutex_unlock(&iaxsl[fr->callno]);
11280 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11281 ast_mutex_lock(&iaxsl[fr->callno]);
11282 }
11283 break;
11284 }
11285 registry_authrequest(fr->callno);
11286 break;
11287 case IAX_COMMAND_REGACK:
11288 if (iax2_ack_registry(&ies, &sin, fr->callno))
11289 ast_log(LOG_WARNING, "Registration failure\n");
11290
11291 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11292 iax2_destroy(fr->callno);
11293 break;
11294 case IAX_COMMAND_REGREJ:
11295 if (iaxs[fr->callno]->reg) {
11296 if (authdebug) {
11297 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));
11298 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>");
11299 }
11300 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11301 }
11302
11303 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11304 iax2_destroy(fr->callno);
11305 break;
11306 case IAX_COMMAND_REGAUTH:
11307
11308 if (registry_rerequest(&ies, fr->callno, &sin)) {
11309 memset(&ied0, 0, sizeof(ied0));
11310 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11311 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11312 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11313 }
11314 break;
11315 case IAX_COMMAND_TXREJ:
11316 iaxs[fr->callno]->transferring = 0;
11317 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11318 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11319 if (iaxs[fr->callno]->bridgecallno) {
11320 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11321 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11322 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11323 }
11324 }
11325 break;
11326 case IAX_COMMAND_TXREADY:
11327 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11328 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11329 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11330 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11331 else
11332 iaxs[fr->callno]->transferring = TRANSFER_READY;
11333 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11334 if (iaxs[fr->callno]->bridgecallno) {
11335 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11336 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11337
11338 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11339 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11340 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11341
11342 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11343 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11344
11345 memset(&ied0, 0, sizeof(ied0));
11346 memset(&ied1, 0, sizeof(ied1));
11347 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11348 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11349 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11350 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11351 } else {
11352 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11353 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11354
11355 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11356 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11357 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11358 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11359
11360
11361 stop_stuff(fr->callno);
11362 stop_stuff(iaxs[fr->callno]->bridgecallno);
11363
11364 memset(&ied0, 0, sizeof(ied0));
11365 memset(&ied1, 0, sizeof(ied1));
11366 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11367 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11368 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11369 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11370 }
11371
11372 }
11373 }
11374 }
11375 break;
11376 case IAX_COMMAND_TXREQ:
11377 try_transfer(iaxs[fr->callno], &ies);
11378 break;
11379 case IAX_COMMAND_TXCNT:
11380 if (iaxs[fr->callno]->transferring)
11381 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11382 break;
11383 case IAX_COMMAND_TXREL:
11384
11385 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11386 complete_transfer(fr->callno, &ies);
11387 stop_stuff(fr->callno);
11388 break;
11389 case IAX_COMMAND_TXMEDIA:
11390 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11391 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11392
11393 if (cur->transfer) {
11394 cur->retries = -1;
11395 }
11396 }
11397
11398 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11399 }
11400 break;
11401 case IAX_COMMAND_RTKEY:
11402 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11403 ast_log(LOG_WARNING,
11404 "we've been told to rotate our encryption key, "
11405 "but this isn't an encrypted call. bad things will happen.\n"
11406 );
11407 break;
11408 }
11409
11410 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11411
11412 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11413 break;
11414 case IAX_COMMAND_DPREP:
11415 complete_dpreply(iaxs[fr->callno], &ies);
11416 break;
11417 case IAX_COMMAND_UNSUPPORT:
11418 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11419 break;
11420 case IAX_COMMAND_FWDOWNL:
11421
11422 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11423 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11424 break;
11425 }
11426 memset(&ied0, 0, sizeof(ied0));
11427 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11428 if (res < 0)
11429 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11430 else if (res > 0)
11431 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11432 else
11433 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11434 break;
11435 case IAX_COMMAND_CALLTOKEN:
11436 {
11437 struct iax_frame *cur;
11438
11439 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11440 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11441 }
11442 break;
11443 }
11444 default:
11445 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11446 memset(&ied0, 0, sizeof(ied0));
11447 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11448 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11449 }
11450
11451 if (ies.vars) {
11452 ast_variables_destroy(ies.vars);
11453 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11454 ies.vars = NULL;
11455 }
11456
11457
11458 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11459 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11460 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11461 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11462 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11463 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11464 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11465 }
11466 ast_mutex_unlock(&iaxsl[fr->callno]);
11467 return 1;
11468 }
11469
11470 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11471 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11472 } else if (minivid) {
11473 f.frametype = AST_FRAME_VIDEO;
11474 if (iaxs[fr->callno]->videoformat > 0)
11475 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11476 else {
11477 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11478 iax2_vnak(fr->callno);
11479 ast_variables_destroy(ies.vars);
11480 ast_mutex_unlock(&iaxsl[fr->callno]);
11481 return 1;
11482 }
11483 f.datalen = res - sizeof(*vh);
11484 if (f.datalen)
11485 f.data.ptr = thread->buf + sizeof(*vh);
11486 else
11487 f.data.ptr = NULL;
11488 #ifdef IAXTESTS
11489 if (test_resync) {
11490 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11491 } else
11492 #endif
11493 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11494 } else {
11495
11496 f.frametype = AST_FRAME_VOICE;
11497 if (iaxs[fr->callno]->voiceformat > 0)
11498 f.subclass.codec = iaxs[fr->callno]->voiceformat;
11499 else {
11500 ast_debug(1, "Received mini frame before first full voice frame\n");
11501 iax2_vnak(fr->callno);
11502 ast_variables_destroy(ies.vars);
11503 ast_mutex_unlock(&iaxsl[fr->callno]);
11504 return 1;
11505 }
11506 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11507 if (f.datalen < 0) {
11508 ast_log(LOG_WARNING, "Datalen < 0?\n");
11509 ast_variables_destroy(ies.vars);
11510 ast_mutex_unlock(&iaxsl[fr->callno]);
11511 return 1;
11512 }
11513 if (f.datalen)
11514 f.data.ptr = thread->buf + sizeof(*mh);
11515 else
11516 f.data.ptr = NULL;
11517 #ifdef IAXTESTS
11518 if (test_resync) {
11519 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11520 } else
11521 #endif
11522 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11523
11524 }
11525
11526 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11527 ast_variables_destroy(ies.vars);
11528 ast_mutex_unlock(&iaxsl[fr->callno]);
11529 return 1;
11530 }
11531
11532 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11533 struct ast_party_connected_line connected;
11534
11535 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11536 ast_variables_destroy(ies.vars);
11537 ast_mutex_unlock(&iaxsl[fr->callno]);
11538 return 1;
11539 }
11540
11541
11542 ast_party_connected_line_init(&connected);
11543 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11544 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11545
11546 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11547 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11548 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11549 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11550
11551 if (iaxs[fr->callno]->owner) {
11552 ast_set_callerid(iaxs[fr->callno]->owner,
11553 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11554 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11555 NULL);
11556 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11557 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11558 }
11559 }
11560 ast_party_connected_line_free(&connected);
11561 }
11562
11563 f.src = "IAX2";
11564 f.mallocd = 0;
11565 f.offset = 0;
11566 f.len = 0;
11567 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11568 f.samples = ast_codec_get_samples(&f);
11569
11570 if (f.subclass.codec == AST_FORMAT_SLINEAR)
11571 ast_frame_byteswap_be(&f);
11572 } else
11573 f.samples = 0;
11574 iax_frame_wrap(fr, &f);
11575
11576
11577 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11578
11579 fr->outoforder = 0;
11580 } else {
11581 if (iaxdebug && iaxs[fr->callno])
11582 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last);
11583 fr->outoforder = -1;
11584 }
11585 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11586 duped_fr = iaxfrdup2(fr);
11587 if (duped_fr) {
11588 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11589 }
11590 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11591 iaxs[fr->callno]->last = fr->ts;
11592 #if 1
11593 if (iaxdebug)
11594 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11595 #endif
11596 }
11597
11598
11599 ast_variables_destroy(ies.vars);
11600 ast_mutex_unlock(&iaxsl[fr->callno]);
11601 return 1;
11602 }
11603
11604
11605 static void iax2_process_thread_cleanup(void *data)
11606 {
11607 struct iax2_thread *thread = data;
11608 ast_mutex_destroy(&thread->lock);
11609 ast_cond_destroy(&thread->cond);
11610 ast_mutex_destroy(&thread->init_lock);
11611 ast_cond_destroy(&thread->init_cond);
11612 ast_free(thread);
11613 ast_atomic_dec_and_test(&iaxactivethreadcount);
11614 }
11615
11616 static void *iax2_process_thread(void *data)
11617 {
11618 struct iax2_thread *thread = data;
11619 struct timeval wait;
11620 struct timespec ts;
11621 int put_into_idle = 0;
11622 int first_time = 1;
11623 int old_state;
11624
11625 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11626
11627 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11628 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11629
11630 for (;;) {
11631
11632 ast_mutex_lock(&thread->lock);
11633
11634 if (thread->stop) {
11635 ast_mutex_unlock(&thread->lock);
11636 break;
11637 }
11638
11639
11640 if (first_time) {
11641 signal_condition(&thread->init_lock, &thread->init_cond);
11642 first_time = 0;
11643 }
11644
11645
11646 if (put_into_idle) {
11647 insert_idle_thread(thread);
11648 }
11649
11650 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11651 struct iax2_thread *t = NULL;
11652
11653 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11654 ts.tv_sec = wait.tv_sec;
11655 ts.tv_nsec = wait.tv_usec * 1000;
11656 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11657
11658
11659 if (!put_into_idle || thread->stop) {
11660 ast_mutex_unlock(&thread->lock);
11661 break;
11662 }
11663 AST_LIST_LOCK(&dynamic_list);
11664
11665 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11666 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11667 AST_LIST_UNLOCK(&dynamic_list);
11668 if (t) {
11669
11670
11671
11672 ast_mutex_unlock(&thread->lock);
11673 break;
11674 }
11675
11676
11677
11678 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11679 ts.tv_sec = wait.tv_sec;
11680 ts.tv_nsec = wait.tv_usec * 1000;
11681 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11682 ast_mutex_unlock(&thread->lock);
11683 break;
11684 }
11685 }
11686 } else {
11687 ast_cond_wait(&thread->cond, &thread->lock);
11688 }
11689
11690
11691 put_into_idle = 1;
11692
11693 ast_mutex_unlock(&thread->lock);
11694
11695 if (thread->stop) {
11696 break;
11697 }
11698
11699 if (thread->iostate == IAX_IOSTATE_IDLE)
11700 continue;
11701
11702
11703 switch (thread->iostate) {
11704 case IAX_IOSTATE_READY:
11705 thread->actions++;
11706 thread->iostate = IAX_IOSTATE_PROCESSING;
11707 socket_process(thread);
11708 handle_deferred_full_frames(thread);
11709 break;
11710 case IAX_IOSTATE_SCHEDREADY:
11711 thread->actions++;
11712 thread->iostate = IAX_IOSTATE_PROCESSING;
11713 #ifdef SCHED_MULTITHREADED
11714 thread->schedfunc(thread->scheddata);
11715 #endif
11716 default:
11717 break;
11718 }
11719 time(&thread->checktime);
11720 thread->iostate = IAX_IOSTATE_IDLE;
11721 #ifdef DEBUG_SCHED_MULTITHREAD
11722 thread->curfunc[0]='\0';
11723 #endif
11724
11725
11726
11727
11728 AST_LIST_LOCK(&active_list);
11729 AST_LIST_REMOVE(&active_list, thread, list);
11730 AST_LIST_UNLOCK(&active_list);
11731
11732
11733 handle_deferred_full_frames(thread);
11734 }
11735
11736
11737
11738
11739
11740 AST_LIST_LOCK(&idle_list);
11741 AST_LIST_REMOVE(&idle_list, thread, list);
11742 AST_LIST_UNLOCK(&idle_list);
11743
11744 AST_LIST_LOCK(&dynamic_list);
11745 AST_LIST_REMOVE(&dynamic_list, thread, list);
11746 AST_LIST_UNLOCK(&dynamic_list);
11747
11748
11749
11750
11751 pthread_cleanup_pop(1);
11752 return NULL;
11753 }
11754
11755 static int iax2_do_register(struct iax2_registry *reg)
11756 {
11757 struct iax_ie_data ied;
11758 if (iaxdebug)
11759 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11760
11761 if (reg->dnsmgr &&
11762 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
11763
11764 ast_dnsmgr_refresh(reg->dnsmgr);
11765 }
11766
11767
11768
11769
11770
11771 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11772 int callno = reg->callno;
11773 ast_mutex_lock(&iaxsl[callno]);
11774 iax2_destroy(callno);
11775 ast_mutex_unlock(&iaxsl[callno]);
11776 reg->callno = 0;
11777 }
11778 if (!ast_sockaddr_ipv4(®->addr)) {
11779 if (iaxdebug)
11780 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11781
11782 reg->expire = iax2_sched_replace(reg->expire, sched,
11783 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11784 return -1;
11785 }
11786
11787 if (!reg->callno) {
11788 struct sockaddr_in reg_addr;
11789
11790 ast_debug(3, "Allocate call number\n");
11791
11792 ast_sockaddr_to_sin(®->addr, ®_addr);
11793
11794 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
11795 if (reg->callno < 1) {
11796 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11797 return -1;
11798 } else
11799 ast_debug(3, "Registration created on call %d\n", reg->callno);
11800 iaxs[reg->callno]->reg = reg;
11801 ast_mutex_unlock(&iaxsl[reg->callno]);
11802 }
11803
11804 reg->expire = iax2_sched_replace(reg->expire, sched,
11805 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11806
11807 memset(&ied, 0, sizeof(ied));
11808 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11809 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11810 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11811 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11812 reg->regstate = REG_STATE_REGSENT;
11813 return 0;
11814 }
11815
11816 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
11817 {
11818
11819
11820 struct iax_ie_data provdata;
11821 struct iax_ie_data ied;
11822 unsigned int sig;
11823 struct sockaddr_in sin;
11824 int callno;
11825 struct create_addr_info cai;
11826
11827 memset(&cai, 0, sizeof(cai));
11828
11829 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11830
11831 if (iax_provision_build(&provdata, &sig, template, force)) {
11832 ast_debug(1, "No provisioning found for template '%s'\n", template);
11833 return 0;
11834 }
11835
11836 if (end) {
11837 memcpy(&sin, end, sizeof(sin));
11838 cai.sockfd = sockfd;
11839 } else if (create_addr(dest, NULL, &sin, &cai))
11840 return -1;
11841
11842
11843 memset(&ied, 0, sizeof(ied));
11844 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11845
11846 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11847 if (!callno)
11848 return -1;
11849
11850 if (iaxs[callno]) {
11851
11852 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11853 sched, 15000, auto_hangup, (void *)(long)callno);
11854 ast_set_flag64(iaxs[callno], IAX_PROVISION);
11855
11856 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11857 }
11858 ast_mutex_unlock(&iaxsl[callno]);
11859
11860 return 1;
11861 }
11862
11863 static char *papp = "IAX2Provision";
11864
11865
11866
11867
11868 static int iax2_prov_app(struct ast_channel *chan, const char *data)
11869 {
11870 int res;
11871 char *sdata;
11872 char *opts;
11873 int force =0;
11874 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11875 if (ast_strlen_zero(data))
11876 data = "default";
11877 sdata = ast_strdupa(data);
11878 opts = strchr(sdata, '|');
11879 if (opts)
11880 *opts='\0';
11881
11882 if (chan->tech != &iax2_tech) {
11883 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11884 return -1;
11885 }
11886 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11887 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11888 return -1;
11889 }
11890 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11891 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11892 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11893 sdata, res);
11894 return res;
11895 }
11896
11897 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11898 {
11899 int force = 0;
11900 int res;
11901
11902 switch (cmd) {
11903 case CLI_INIT:
11904 e->command = "iax2 provision";
11905 e->usage =
11906 "Usage: iax2 provision <host> <template> [forced]\n"
11907 " Provisions the given peer or IP address using a template\n"
11908 " matching either 'template' or '*' if the template is not\n"
11909 " found. If 'forced' is specified, even empty provisioning\n"
11910 " fields will be provisioned as empty fields.\n";
11911 return NULL;
11912 case CLI_GENERATE:
11913 if (a->pos == 3)
11914 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11915 return NULL;
11916 }
11917
11918 if (a->argc < 4)
11919 return CLI_SHOWUSAGE;
11920 if (a->argc > 4) {
11921 if (!strcasecmp(a->argv[4], "forced"))
11922 force = 1;
11923 else
11924 return CLI_SHOWUSAGE;
11925 }
11926 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11927 if (res < 0)
11928 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11929 else if (res < 1)
11930 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11931 else
11932 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11933 return CLI_SUCCESS;
11934 }
11935
11936 static void __iax2_poke_noanswer(const void *data)
11937 {
11938 struct iax2_peer *peer = (struct iax2_peer *)data;
11939 int callno;
11940
11941 if (peer->lastms > -1) {
11942 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11943 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11944 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11945 }
11946 if ((callno = peer->callno) > 0) {
11947 ast_mutex_lock(&iaxsl[callno]);
11948 iax2_destroy(callno);
11949 ast_mutex_unlock(&iaxsl[callno]);
11950 }
11951 peer->callno = 0;
11952 peer->lastms = -1;
11953
11954 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11955 if (peer->pokeexpire == -1)
11956 peer_unref(peer);
11957 }
11958
11959 static int iax2_poke_noanswer(const void *data)
11960 {
11961 struct iax2_peer *peer = (struct iax2_peer *)data;
11962 peer->pokeexpire = -1;
11963 #ifdef SCHED_MULTITHREADED
11964 if (schedule_action(__iax2_poke_noanswer, data))
11965 #endif
11966 __iax2_poke_noanswer(data);
11967 peer_unref(peer);
11968 return 0;
11969 }
11970
11971 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11972 {
11973 struct iax2_peer *peer = obj;
11974
11975 iax2_poke_peer(peer, 0);
11976
11977 return 0;
11978 }
11979
11980 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11981 {
11982 int callno;
11983 struct sockaddr_in peer_addr;
11984
11985 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
11986
11987
11988 peer->lastms = 0;
11989 peer->historicms = 0;
11990 peer->pokeexpire = -1;
11991 peer->callno = 0;
11992 return 0;
11993 }
11994
11995 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
11996
11997
11998 if ((callno = peer->callno) > 0) {
11999 ast_log(LOG_NOTICE, "Still have a callno...\n");
12000 ast_mutex_lock(&iaxsl[callno]);
12001 iax2_destroy(callno);
12002 ast_mutex_unlock(&iaxsl[callno]);
12003 }
12004 if (heldcall)
12005 ast_mutex_unlock(&iaxsl[heldcall]);
12006 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12007 if (heldcall)
12008 ast_mutex_lock(&iaxsl[heldcall]);
12009 if (peer->callno < 1) {
12010 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12011 return -1;
12012 }
12013
12014
12015 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12016 iaxs[peer->callno]->peerpoke = peer;
12017
12018 if (peer->pokeexpire > -1) {
12019 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
12020 peer->pokeexpire = -1;
12021 peer_unref(peer);
12022 }
12023 }
12024
12025
12026
12027 if (peer->lastms < 0)
12028 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12029 else
12030 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12031
12032 if (peer->pokeexpire == -1)
12033 peer_unref(peer);
12034
12035
12036 ast_mutex_lock(&iaxsl[callno]);
12037 if (iaxs[callno]) {
12038 struct iax_ie_data ied = {
12039 .buf = { 0 },
12040 .pos = 0,
12041 };
12042 add_empty_calltoken_ie(iaxs[callno], &ied);
12043 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12044 }
12045 ast_mutex_unlock(&iaxsl[callno]);
12046
12047 return 0;
12048 }
12049
12050 static void free_context(struct iax2_context *con)
12051 {
12052 struct iax2_context *conl;
12053 while(con) {
12054 conl = con;
12055 con = con->next;
12056 ast_free(conl);
12057 }
12058 }
12059
12060 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
12061 {
12062 int callno;
12063 int res;
12064 format_t fmt, native;
12065 struct sockaddr_in sin;
12066 struct ast_channel *c;
12067 struct parsed_dial_string pds;
12068 struct create_addr_info cai;
12069 char *tmpstr;
12070
12071 memset(&pds, 0, sizeof(pds));
12072 tmpstr = ast_strdupa(data);
12073 parse_dial_string(tmpstr, &pds);
12074
12075 if (ast_strlen_zero(pds.peer)) {
12076 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12077 return NULL;
12078 }
12079
12080 memset(&cai, 0, sizeof(cai));
12081 cai.capability = iax2_capability;
12082
12083 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12084
12085
12086 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12087 *cause = AST_CAUSE_UNREGISTERED;
12088 return NULL;
12089 }
12090
12091 if (pds.port)
12092 sin.sin_port = htons(atoi(pds.port));
12093
12094 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12095 if (callno < 1) {
12096 ast_log(LOG_WARNING, "Unable to create call\n");
12097 *cause = AST_CAUSE_CONGESTION;
12098 return NULL;
12099 }
12100
12101
12102 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12103 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12104 int new_callno;
12105 if ((new_callno = make_trunk(callno, 1)) != -1)
12106 callno = new_callno;
12107 }
12108 iaxs[callno]->maxtime = cai.maxtime;
12109 if (cai.found)
12110 ast_string_field_set(iaxs[callno], host, pds.peer);
12111
12112 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
12113
12114 ast_mutex_unlock(&iaxsl[callno]);
12115
12116 if (c) {
12117
12118 if (c->nativeformats & format)
12119 c->nativeformats &= format;
12120 else {
12121 native = c->nativeformats;
12122 fmt = format;
12123 res = ast_translator_best_choice(&fmt, &native);
12124 if (res < 0) {
12125 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12126 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12127 ast_hangup(c);
12128 return NULL;
12129 }
12130 c->nativeformats = native;
12131 }
12132 c->readformat = ast_best_codec(c->nativeformats);
12133 c->writeformat = c->readformat;
12134 }
12135
12136 return c;
12137 }
12138
12139 static void *network_thread(void *ignore)
12140 {
12141 if (timer) {
12142 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12143 }
12144
12145 for (;;) {
12146 pthread_testcancel();
12147
12148
12149
12150 ast_io_wait(io, 1000);
12151 }
12152
12153 return NULL;
12154 }
12155
12156 static int start_network_thread(void)
12157 {
12158 struct iax2_thread *thread;
12159 int threadcount = 0;
12160 int x;
12161 for (x = 0; x < iaxthreadcount; x++) {
12162 thread = ast_calloc(1, sizeof(*thread));
12163 if (thread) {
12164 thread->type = IAX_THREAD_TYPE_POOL;
12165 thread->threadnum = ++threadcount;
12166 ast_mutex_init(&thread->lock);
12167 ast_cond_init(&thread->cond, NULL);
12168 ast_mutex_init(&thread->init_lock);
12169 ast_cond_init(&thread->init_cond, NULL);
12170 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12171 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12172 ast_mutex_destroy(&thread->lock);
12173 ast_cond_destroy(&thread->cond);
12174 ast_mutex_destroy(&thread->init_lock);
12175 ast_cond_destroy(&thread->init_cond);
12176 ast_free(thread);
12177 thread = NULL;
12178 continue;
12179 }
12180 AST_LIST_LOCK(&idle_list);
12181 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12182 AST_LIST_UNLOCK(&idle_list);
12183 }
12184 }
12185 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12186 ast_verb(2, "%d helper threads started\n", threadcount);
12187 return 0;
12188 }
12189
12190 static struct iax2_context *build_context(const char *context)
12191 {
12192 struct iax2_context *con;
12193
12194 if ((con = ast_calloc(1, sizeof(*con))))
12195 ast_copy_string(con->context, context, sizeof(con->context));
12196
12197 return con;
12198 }
12199
12200 static int get_auth_methods(const char *value)
12201 {
12202 int methods = 0;
12203 if (strstr(value, "rsa"))
12204 methods |= IAX_AUTH_RSA;
12205 if (strstr(value, "md5"))
12206 methods |= IAX_AUTH_MD5;
12207 if (strstr(value, "plaintext"))
12208 methods |= IAX_AUTH_PLAINTEXT;
12209 return methods;
12210 }
12211
12212
12213
12214
12215
12216 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12217 {
12218 int sd;
12219 int res;
12220
12221 sd = socket(AF_INET, SOCK_DGRAM, 0);
12222 if (sd < 0) {
12223 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12224 return -1;
12225 }
12226
12227 res = bind(sd, sa, salen);
12228 if (res < 0) {
12229 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12230 close(sd);
12231 return 1;
12232 }
12233
12234 close(sd);
12235 return 0;
12236 }
12237
12238
12239
12240
12241 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12242 {
12243 struct sockaddr_in sin;
12244 struct ast_sockaddr sin_tmp;
12245 int nonlocal = 1;
12246 int port = IAX_DEFAULT_PORTNO;
12247 int sockfd = defaultsockfd;
12248 char *tmp;
12249 char *addr;
12250 char *portstr;
12251
12252 if (!(tmp = ast_strdupa(srcaddr)))
12253 return -1;
12254
12255 addr = strsep(&tmp, ":");
12256 portstr = tmp;
12257
12258 if (portstr) {
12259 port = atoi(portstr);
12260 if (port < 1)
12261 port = IAX_DEFAULT_PORTNO;
12262 }
12263
12264 sin_tmp.ss.ss_family = AF_INET;
12265 if (!ast_get_ip(&sin_tmp, addr)) {
12266 struct ast_netsock *sock;
12267 int res;
12268
12269 ast_sockaddr_to_sin(&sin_tmp, &sin);
12270 sin.sin_port = 0;
12271 sin.sin_family = AF_INET;
12272 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12273 if (res == 0) {
12274
12275 sin.sin_port = htons(port);
12276 if (!(sock = ast_netsock_find(netsock, &sin)))
12277 sock = ast_netsock_find(outsock, &sin);
12278 if (sock) {
12279 sockfd = ast_netsock_sockfd(sock);
12280 nonlocal = 0;
12281 } else {
12282 unsigned int orig_saddr = sin.sin_addr.s_addr;
12283
12284 sin.sin_addr.s_addr = INADDR_ANY;
12285 if (ast_netsock_find(netsock, &sin)) {
12286 sin.sin_addr.s_addr = orig_saddr;
12287 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12288 if (sock) {
12289 sockfd = ast_netsock_sockfd(sock);
12290 ast_netsock_unref(sock);
12291 nonlocal = 0;
12292 } else {
12293 nonlocal = 2;
12294 }
12295 }
12296 }
12297 }
12298 }
12299
12300 peer->sockfd = sockfd;
12301
12302 if (nonlocal == 1) {
12303 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12304 srcaddr, peer->name);
12305 return -1;
12306 } else if (nonlocal == 2) {
12307 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12308 srcaddr, peer->name);
12309 return -1;
12310 } else {
12311 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12312 return 0;
12313 }
12314 }
12315
12316 static void peer_destructor(void *obj)
12317 {
12318 struct iax2_peer *peer = obj;
12319 int callno = peer->callno;
12320
12321 ast_free_ha(peer->ha);
12322
12323 if (callno > 0) {
12324 ast_mutex_lock(&iaxsl[callno]);
12325 iax2_destroy(callno);
12326 ast_mutex_unlock(&iaxsl[callno]);
12327 }
12328
12329 register_peer_exten(peer, 0);
12330
12331 if (peer->dnsmgr)
12332 ast_dnsmgr_release(peer->dnsmgr);
12333
12334 if (peer->mwi_event_sub)
12335 ast_event_unsubscribe(peer->mwi_event_sub);
12336
12337 ast_string_field_free_memory(peer);
12338 }
12339
12340
12341 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12342 {
12343 struct iax2_peer *peer = NULL;
12344 struct ast_ha *oldha = NULL;
12345 int maskfound = 0;
12346 int found = 0;
12347 int firstpass = 1;
12348 struct iax2_peer tmp_peer = {
12349 .name = name,
12350 };
12351
12352 if (!temponly) {
12353 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12354 if (peer && !ast_test_flag64(peer, IAX_DELME))
12355 firstpass = 0;
12356 }
12357
12358 if (peer) {
12359 found++;
12360 if (firstpass) {
12361 oldha = peer->ha;
12362 peer->ha = NULL;
12363 }
12364 unlink_peer(peer);
12365 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12366 peer->expire = -1;
12367 peer->pokeexpire = -1;
12368 peer->sockfd = defaultsockfd;
12369 peer->addr.ss.ss_family = AF_INET;
12370 if (ast_string_field_init(peer, 32))
12371 peer = peer_unref(peer);
12372 }
12373
12374 if (peer) {
12375 if (firstpass) {
12376 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12377 peer->encmethods = iax2_encryption;
12378 peer->adsi = adsi;
12379 ast_string_field_set(peer,secret,"");
12380 if (!found) {
12381 ast_string_field_set(peer, name, name);
12382 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12383 peer->expiry = min_reg_expire;
12384 }
12385 peer->prefs = prefs;
12386 peer->capability = iax2_capability;
12387 peer->smoothing = 0;
12388 peer->pokefreqok = DEFAULT_FREQ_OK;
12389 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12390 peer->maxcallno = 0;
12391 peercnt_modify(0, 0, &peer->addr);
12392 peer->calltoken_required = CALLTOKEN_DEFAULT;
12393 ast_string_field_set(peer,context,"");
12394 ast_string_field_set(peer,peercontext,"");
12395 ast_clear_flag64(peer, IAX_HASCALLERID);
12396 ast_string_field_set(peer, cid_name, "");
12397 ast_string_field_set(peer, cid_num, "");
12398 ast_string_field_set(peer, mohinterpret, mohinterpret);
12399 ast_string_field_set(peer, mohsuggest, mohsuggest);
12400 }
12401
12402 if (!v) {
12403 v = alt;
12404 alt = NULL;
12405 }
12406 while(v) {
12407 if (!strcasecmp(v->name, "secret")) {
12408 ast_string_field_set(peer, secret, v->value);
12409 } else if (!strcasecmp(v->name, "mailbox")) {
12410 ast_string_field_set(peer, mailbox, v->value);
12411 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12412 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12413 ast_string_field_set(peer, mailbox, name);
12414 }
12415 } else if (!strcasecmp(v->name, "mohinterpret")) {
12416 ast_string_field_set(peer, mohinterpret, v->value);
12417 } else if (!strcasecmp(v->name, "mohsuggest")) {
12418 ast_string_field_set(peer, mohsuggest, v->value);
12419 } else if (!strcasecmp(v->name, "dbsecret")) {
12420 ast_string_field_set(peer, dbsecret, v->value);
12421 } else if (!strcasecmp(v->name, "trunk")) {
12422 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12423 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12424 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12425 ast_clear_flag64(peer, IAX_TRUNK);
12426 }
12427 } else if (!strcasecmp(v->name, "auth")) {
12428 peer->authmethods = get_auth_methods(v->value);
12429 } else if (!strcasecmp(v->name, "encryption")) {
12430 peer->encmethods |= get_encrypt_methods(v->value);
12431 if (!peer->encmethods) {
12432 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12433 }
12434 } else if (!strcasecmp(v->name, "forceencryption")) {
12435 if (ast_false(v->value)) {
12436 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12437 } else {
12438 peer->encmethods |= get_encrypt_methods(v->value);
12439 if (peer->encmethods) {
12440 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12441 }
12442 }
12443 } else if (!strcasecmp(v->name, "transfer")) {
12444 if (!strcasecmp(v->value, "mediaonly")) {
12445 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12446 } else if (ast_true(v->value)) {
12447 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12448 } else
12449 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12450 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12451 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12452 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12453 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12454 } else if (!strcasecmp(v->name, "host")) {
12455 if (!strcasecmp(v->value, "dynamic")) {
12456
12457 ast_set_flag64(peer, IAX_DYNAMIC);
12458 if (!found) {
12459
12460
12461 if (ast_sockaddr_port(&peer->addr)) {
12462 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12463 }
12464 ast_sockaddr_setnull(&peer->addr);
12465 }
12466 } else {
12467
12468 ast_sched_thread_del(sched, peer->expire);
12469 ast_clear_flag64(peer, IAX_DYNAMIC);
12470 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12471 return peer_unref(peer);
12472 if (!ast_sockaddr_port(&peer->addr)) {
12473 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12474 }
12475 }
12476 if (!maskfound)
12477 inet_aton("255.255.255.255", &peer->mask);
12478 } else if (!strcasecmp(v->name, "defaultip")) {
12479 struct ast_sockaddr peer_defaddr_tmp;
12480
12481 peer_defaddr_tmp.ss.ss_family = AF_INET;
12482 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12483 return peer_unref(peer);
12484 }
12485 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12486 &peer->defaddr);
12487 } else if (!strcasecmp(v->name, "sourceaddress")) {
12488 peer_set_srcaddr(peer, v->value);
12489 } else if (!strcasecmp(v->name, "permit") ||
12490 !strcasecmp(v->name, "deny")) {
12491 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12492 } else if (!strcasecmp(v->name, "mask")) {
12493 maskfound++;
12494 inet_aton(v->value, &peer->mask);
12495 } else if (!strcasecmp(v->name, "context")) {
12496 ast_string_field_set(peer, context, v->value);
12497 } else if (!strcasecmp(v->name, "regexten")) {
12498 ast_string_field_set(peer, regexten, v->value);
12499 } else if (!strcasecmp(v->name, "peercontext")) {
12500 ast_string_field_set(peer, peercontext, v->value);
12501 } else if (!strcasecmp(v->name, "port")) {
12502 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12503 peer->defaddr.sin_port = htons(atoi(v->value));
12504 } else {
12505 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12506 }
12507 } else if (!strcasecmp(v->name, "username")) {
12508 ast_string_field_set(peer, username, v->value);
12509 } else if (!strcasecmp(v->name, "allow")) {
12510 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12511 } else if (!strcasecmp(v->name, "disallow")) {
12512 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12513 } else if (!strcasecmp(v->name, "callerid")) {
12514 if (!ast_strlen_zero(v->value)) {
12515 char name2[80];
12516 char num2[80];
12517 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12518 ast_string_field_set(peer, cid_name, name2);
12519 ast_string_field_set(peer, cid_num, num2);
12520 } else {
12521 ast_string_field_set(peer, cid_name, "");
12522 ast_string_field_set(peer, cid_num, "");
12523 }
12524 ast_set_flag64(peer, IAX_HASCALLERID);
12525 } else if (!strcasecmp(v->name, "fullname")) {
12526 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12527 ast_set_flag64(peer, IAX_HASCALLERID);
12528 } else if (!strcasecmp(v->name, "cid_number")) {
12529 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12530 ast_set_flag64(peer, IAX_HASCALLERID);
12531 } else if (!strcasecmp(v->name, "sendani")) {
12532 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12533 } else if (!strcasecmp(v->name, "inkeys")) {
12534 ast_string_field_set(peer, inkeys, v->value);
12535 } else if (!strcasecmp(v->name, "outkey")) {
12536 ast_string_field_set(peer, outkey, v->value);
12537 } else if (!strcasecmp(v->name, "qualify")) {
12538 if (!strcasecmp(v->value, "no")) {
12539 peer->maxms = 0;
12540 } else if (!strcasecmp(v->value, "yes")) {
12541 peer->maxms = DEFAULT_MAXMS;
12542 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12543 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);
12544 peer->maxms = 0;
12545 }
12546 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12547 peer->smoothing = ast_true(v->value);
12548 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12549 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12550 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);
12551 }
12552 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12553 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12554 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);
12555 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12556 } else if (!strcasecmp(v->name, "timezone")) {
12557 ast_string_field_set(peer, zonetag, v->value);
12558 } else if (!strcasecmp(v->name, "adsi")) {
12559 peer->adsi = ast_true(v->value);
12560 } else if (!strcasecmp(v->name, "connectedline")) {
12561 if (ast_true(v->value)) {
12562 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12563 } else if (!strcasecmp(v->value, "send")) {
12564 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12565 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12566 } else if (!strcasecmp(v->value, "receive")) {
12567 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12568 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12569 } else {
12570 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12571 }
12572 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12573 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12574 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12575 } else {
12576 peercnt_modify(1, peer->maxcallno, &peer->addr);
12577 }
12578 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12579
12580 if (ast_false(v->value)) {
12581 peer->calltoken_required = CALLTOKEN_NO;
12582 } else if (!strcasecmp(v->value, "auto")) {
12583 peer->calltoken_required = CALLTOKEN_AUTO;
12584 } else if (ast_true(v->value)) {
12585 peer->calltoken_required = CALLTOKEN_YES;
12586 } else {
12587 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12588 }
12589 }
12590
12591 v = v->next;
12592 if (!v) {
12593 v = alt;
12594 alt = NULL;
12595 }
12596 }
12597 if (!peer->authmethods)
12598 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12599 ast_clear_flag64(peer, IAX_DELME);
12600 }
12601
12602 if (oldha)
12603 ast_free_ha(oldha);
12604
12605 if (!ast_strlen_zero(peer->mailbox)) {
12606 char *mailbox, *context;
12607 context = mailbox = ast_strdupa(peer->mailbox);
12608 strsep(&context, "@");
12609 if (ast_strlen_zero(context))
12610 context = "default";
12611 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12612 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12613 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12614 AST_EVENT_IE_END);
12615 }
12616
12617 return peer;
12618 }
12619
12620 static void user_destructor(void *obj)
12621 {
12622 struct iax2_user *user = obj;
12623
12624 ast_free_ha(user->ha);
12625 free_context(user->contexts);
12626 if(user->vars) {
12627 ast_variables_destroy(user->vars);
12628 user->vars = NULL;
12629 }
12630 ast_string_field_free_memory(user);
12631 }
12632
12633
12634 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12635 {
12636 struct iax2_user *user = NULL;
12637 struct iax2_context *con, *conl = NULL;
12638 struct ast_ha *oldha = NULL;
12639 struct iax2_context *oldcon = NULL;
12640 int format;
12641 int firstpass=1;
12642 int oldcurauthreq = 0;
12643 char *varname = NULL, *varval = NULL;
12644 struct ast_variable *tmpvar = NULL;
12645 struct iax2_user tmp_user = {
12646 .name = name,
12647 };
12648
12649 if (!temponly) {
12650 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12651 if (user && !ast_test_flag64(user, IAX_DELME))
12652 firstpass = 0;
12653 }
12654
12655 if (user) {
12656 if (firstpass) {
12657 oldcurauthreq = user->curauthreq;
12658 oldha = user->ha;
12659 oldcon = user->contexts;
12660 user->ha = NULL;
12661 user->contexts = NULL;
12662 }
12663
12664 ao2_unlink(users, user);
12665 } else {
12666 user = ao2_alloc(sizeof(*user), user_destructor);
12667 }
12668
12669 if (user) {
12670 if (firstpass) {
12671 ast_string_field_free_memory(user);
12672 memset(user, 0, sizeof(struct iax2_user));
12673 if (ast_string_field_init(user, 32)) {
12674 user = user_unref(user);
12675 goto cleanup;
12676 }
12677 user->maxauthreq = maxauthreq;
12678 user->curauthreq = oldcurauthreq;
12679 user->prefs = prefs;
12680 user->capability = iax2_capability;
12681 user->encmethods = iax2_encryption;
12682 user->adsi = adsi;
12683 user->calltoken_required = CALLTOKEN_DEFAULT;
12684 ast_string_field_set(user, name, name);
12685 ast_string_field_set(user, language, language);
12686 ast_copy_flags64(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12687 ast_clear_flag64(user, IAX_HASCALLERID);
12688 ast_string_field_set(user, cid_name, "");
12689 ast_string_field_set(user, cid_num, "");
12690 ast_string_field_set(user, accountcode, accountcode);
12691 ast_string_field_set(user, mohinterpret, mohinterpret);
12692 ast_string_field_set(user, mohsuggest, mohsuggest);
12693 }
12694 if (!v) {
12695 v = alt;
12696 alt = NULL;
12697 }
12698 while(v) {
12699 if (!strcasecmp(v->name, "context")) {
12700 con = build_context(v->value);
12701 if (con) {
12702 if (conl)
12703 conl->next = con;
12704 else
12705 user->contexts = con;
12706 conl = con;
12707 }
12708 } else if (!strcasecmp(v->name, "permit") ||
12709 !strcasecmp(v->name, "deny")) {
12710 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12711 } else if (!strcasecmp(v->name, "setvar")) {
12712 varname = ast_strdupa(v->value);
12713 if (varname && (varval = strchr(varname,'='))) {
12714 *varval = '\0';
12715 varval++;
12716 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12717 tmpvar->next = user->vars;
12718 user->vars = tmpvar;
12719 }
12720 }
12721 } else if (!strcasecmp(v->name, "allow")) {
12722 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12723 } else if (!strcasecmp(v->name, "disallow")) {
12724 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12725 } else if (!strcasecmp(v->name, "trunk")) {
12726 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
12727 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12728 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12729 ast_clear_flag64(user, IAX_TRUNK);
12730 }
12731 } else if (!strcasecmp(v->name, "auth")) {
12732 user->authmethods = get_auth_methods(v->value);
12733 } else if (!strcasecmp(v->name, "encryption")) {
12734 user->encmethods |= get_encrypt_methods(v->value);
12735 if (!user->encmethods) {
12736 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12737 }
12738 } else if (!strcasecmp(v->name, "forceencryption")) {
12739 if (ast_false(v->value)) {
12740 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12741 } else {
12742 user->encmethods |= get_encrypt_methods(v->value);
12743 if (user->encmethods) {
12744 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12745 }
12746 }
12747 } else if (!strcasecmp(v->name, "transfer")) {
12748 if (!strcasecmp(v->value, "mediaonly")) {
12749 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12750 } else if (ast_true(v->value)) {
12751 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12752 } else
12753 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12754 } else if (!strcasecmp(v->name, "codecpriority")) {
12755 if(!strcasecmp(v->value, "caller"))
12756 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12757 else if(!strcasecmp(v->value, "disabled"))
12758 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12759 else if(!strcasecmp(v->value, "reqonly")) {
12760 ast_set_flag64(user, IAX_CODEC_NOCAP);
12761 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12762 }
12763 } else if (!strcasecmp(v->name, "immediate")) {
12764 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12765 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12766 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12767 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12768 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12769 } else if (!strcasecmp(v->name, "dbsecret")) {
12770 ast_string_field_set(user, dbsecret, v->value);
12771 } else if (!strcasecmp(v->name, "secret")) {
12772 if (!ast_strlen_zero(user->secret)) {
12773 char *old = ast_strdupa(user->secret);
12774
12775 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12776 } else
12777 ast_string_field_set(user, secret, v->value);
12778 } else if (!strcasecmp(v->name, "callerid")) {
12779 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12780 char name2[80];
12781 char num2[80];
12782 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12783 ast_string_field_set(user, cid_name, name2);
12784 ast_string_field_set(user, cid_num, num2);
12785 ast_set_flag64(user, IAX_HASCALLERID);
12786 } else {
12787 ast_clear_flag64(user, IAX_HASCALLERID);
12788 ast_string_field_set(user, cid_name, "");
12789 ast_string_field_set(user, cid_num, "");
12790 }
12791 } else if (!strcasecmp(v->name, "fullname")) {
12792 if (!ast_strlen_zero(v->value)) {
12793 ast_string_field_set(user, cid_name, v->value);
12794 ast_set_flag64(user, IAX_HASCALLERID);
12795 } else {
12796 ast_string_field_set(user, cid_name, "");
12797 if (ast_strlen_zero(user->cid_num))
12798 ast_clear_flag64(user, IAX_HASCALLERID);
12799 }
12800 } else if (!strcasecmp(v->name, "cid_number")) {
12801 if (!ast_strlen_zero(v->value)) {
12802 ast_string_field_set(user, cid_num, v->value);
12803 ast_set_flag64(user, IAX_HASCALLERID);
12804 } else {
12805 ast_string_field_set(user, cid_num, "");
12806 if (ast_strlen_zero(user->cid_name))
12807 ast_clear_flag64(user, IAX_HASCALLERID);
12808 }
12809 } else if (!strcasecmp(v->name, "accountcode")) {
12810 ast_string_field_set(user, accountcode, v->value);
12811 } else if (!strcasecmp(v->name, "mohinterpret")) {
12812 ast_string_field_set(user, mohinterpret, v->value);
12813 } else if (!strcasecmp(v->name, "mohsuggest")) {
12814 ast_string_field_set(user, mohsuggest, v->value);
12815 } else if (!strcasecmp(v->name, "parkinglot")) {
12816 ast_string_field_set(user, parkinglot, v->value);
12817 } else if (!strcasecmp(v->name, "language")) {
12818 ast_string_field_set(user, language, v->value);
12819 } else if (!strcasecmp(v->name, "amaflags")) {
12820 format = ast_cdr_amaflags2int(v->value);
12821 if (format < 0) {
12822 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12823 } else {
12824 user->amaflags = format;
12825 }
12826 } else if (!strcasecmp(v->name, "inkeys")) {
12827 ast_string_field_set(user, inkeys, v->value);
12828 } else if (!strcasecmp(v->name, "maxauthreq")) {
12829 user->maxauthreq = atoi(v->value);
12830 if (user->maxauthreq < 0)
12831 user->maxauthreq = 0;
12832 } else if (!strcasecmp(v->name, "adsi")) {
12833 user->adsi = ast_true(v->value);
12834 } else if (!strcasecmp(v->name, "connectedline")) {
12835 if (ast_true(v->value)) {
12836 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12837 } else if (!strcasecmp(v->value, "send")) {
12838 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12839 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12840 } else if (!strcasecmp(v->value, "receive")) {
12841 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12842 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12843 } else {
12844 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12845 }
12846 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12847
12848 if (ast_false(v->value)) {
12849 user->calltoken_required = CALLTOKEN_NO;
12850 } else if (!strcasecmp(v->value, "auto")) {
12851 user->calltoken_required = CALLTOKEN_AUTO;
12852 } else if (ast_true(v->value)) {
12853 user->calltoken_required = CALLTOKEN_YES;
12854 } else {
12855 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12856 }
12857 }
12858
12859 v = v->next;
12860 if (!v) {
12861 v = alt;
12862 alt = NULL;
12863 }
12864 }
12865 if (!user->authmethods) {
12866 if (!ast_strlen_zero(user->secret)) {
12867 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12868 if (!ast_strlen_zero(user->inkeys))
12869 user->authmethods |= IAX_AUTH_RSA;
12870 } else if (!ast_strlen_zero(user->inkeys)) {
12871 user->authmethods = IAX_AUTH_RSA;
12872 } else {
12873 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12874 }
12875 }
12876 ast_clear_flag64(user, IAX_DELME);
12877 }
12878 cleanup:
12879 if (oldha)
12880 ast_free_ha(oldha);
12881 if (oldcon)
12882 free_context(oldcon);
12883 return user;
12884 }
12885
12886 static int peer_delme_cb(void *obj, void *arg, int flags)
12887 {
12888 struct iax2_peer *peer = obj;
12889
12890 ast_set_flag64(peer, IAX_DELME);
12891
12892 return 0;
12893 }
12894
12895 static int user_delme_cb(void *obj, void *arg, int flags)
12896 {
12897 struct iax2_user *user = obj;
12898
12899 ast_set_flag64(user, IAX_DELME);
12900
12901 return 0;
12902 }
12903
12904 static void delete_users(void)
12905 {
12906 struct iax2_registry *reg;
12907
12908 ao2_callback(users, 0, user_delme_cb, NULL);
12909
12910 AST_LIST_LOCK(®istrations);
12911 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12912 if (sched) {
12913 ast_sched_thread_del(sched, reg->expire);
12914 }
12915 if (reg->callno) {
12916 int callno = reg->callno;
12917 ast_mutex_lock(&iaxsl[callno]);
12918 if (iaxs[callno]) {
12919 iaxs[callno]->reg = NULL;
12920 iax2_destroy(callno);
12921 }
12922 ast_mutex_unlock(&iaxsl[callno]);
12923 }
12924 if (reg->dnsmgr)
12925 ast_dnsmgr_release(reg->dnsmgr);
12926 ast_free(reg);
12927 }
12928 AST_LIST_UNLOCK(®istrations);
12929
12930 ao2_callback(peers, 0, peer_delme_cb, NULL);
12931 }
12932
12933 static void prune_users(void)
12934 {
12935 struct iax2_user *user;
12936 struct ao2_iterator i;
12937
12938 i = ao2_iterator_init(users, 0);
12939 while ((user = ao2_iterator_next(&i))) {
12940 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
12941 ao2_unlink(users, user);
12942 }
12943 user_unref(user);
12944 }
12945 ao2_iterator_destroy(&i);
12946 }
12947
12948
12949 static void prune_peers(void)
12950 {
12951 struct iax2_peer *peer;
12952 struct ao2_iterator i;
12953
12954 i = ao2_iterator_init(peers, 0);
12955 while ((peer = ao2_iterator_next(&i))) {
12956 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
12957 unlink_peer(peer);
12958 }
12959 peer_unref(peer);
12960 }
12961 ao2_iterator_destroy(&i);
12962 }
12963
12964 static void set_config_destroy(void)
12965 {
12966 strcpy(accountcode, "");
12967 strcpy(language, "");
12968 strcpy(mohinterpret, "default");
12969 strcpy(mohsuggest, "");
12970 trunkmaxsize = MAX_TRUNKDATA;
12971 amaflags = 0;
12972 delayreject = 0;
12973 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
12974 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12975 delete_users();
12976 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12977 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12978 }
12979
12980
12981 static int set_config(const char *config_file, int reload)
12982 {
12983 struct ast_config *cfg, *ucfg;
12984 format_t capability = iax2_capability;
12985 struct ast_variable *v;
12986 char *cat;
12987 const char *utype;
12988 const char *tosval;
12989 int format;
12990 int portno = IAX_DEFAULT_PORTNO;
12991 int x;
12992 int mtuv;
12993 int subscribe_network_change = 1;
12994 struct iax2_user *user;
12995 struct iax2_peer *peer;
12996 struct ast_netsock *ns;
12997 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12998 #if 0
12999 static unsigned short int last_port=0;
13000 #endif
13001
13002 cfg = ast_config_load(config_file, config_flags);
13003
13004 if (!cfg) {
13005 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13006 return -1;
13007 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13008 ucfg = ast_config_load("users.conf", config_flags);
13009 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13010 return 0;
13011
13012 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13013 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13014 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13015 ast_config_destroy(ucfg);
13016 return 0;
13017 }
13018 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13019 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13020 return 0;
13021 } else {
13022 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13023 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13024 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
13025 ast_config_destroy(cfg);
13026 return 0;
13027 }
13028 }
13029
13030 if (reload) {
13031 set_config_destroy();
13032 }
13033
13034
13035 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13036
13037
13038 memset(&globalflags, 0, sizeof(globalflags));
13039 ast_set_flag64(&globalflags, IAX_RTUPDATE);
13040 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13041
13042 #ifdef SO_NO_CHECK
13043 nochecksums = 0;
13044 #endif
13045
13046 default_parkinglot[0] = '\0';
13047
13048 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13049 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13050 global_max_trunk_mtu = MAX_TRUNK_MTU;
13051 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13052 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13053
13054 maxauthreq = 3;
13055
13056 srvlookup = 0;
13057
13058 v = ast_variable_browse(cfg, "general");
13059
13060
13061 tosval = ast_variable_retrieve(cfg, "general", "tos");
13062 if (tosval) {
13063 if (ast_str2tos(tosval, &qos.tos))
13064 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13065 }
13066
13067 tosval = ast_variable_retrieve(cfg, "general", "cos");
13068 if (tosval) {
13069 if (ast_str2cos(tosval, &qos.cos))
13070 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13071 }
13072 while(v) {
13073 if (!strcasecmp(v->name, "bindport")){
13074 if (reload)
13075 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13076 else
13077 portno = atoi(v->value);
13078 } else if (!strcasecmp(v->name, "pingtime"))
13079 ping_time = atoi(v->value);
13080 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13081 if (reload) {
13082 if (atoi(v->value) != iaxthreadcount)
13083 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13084 } else {
13085 iaxthreadcount = atoi(v->value);
13086 if (iaxthreadcount < 1) {
13087 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13088 iaxthreadcount = 1;
13089 } else if (iaxthreadcount > 256) {
13090 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13091 iaxthreadcount = 256;
13092 }
13093 }
13094 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13095 if (reload) {
13096 AST_LIST_LOCK(&dynamic_list);
13097 iaxmaxthreadcount = atoi(v->value);
13098 AST_LIST_UNLOCK(&dynamic_list);
13099 } else {
13100 iaxmaxthreadcount = atoi(v->value);
13101 if (iaxmaxthreadcount < 0) {
13102 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13103 iaxmaxthreadcount = 0;
13104 } else if (iaxmaxthreadcount > 256) {
13105 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13106 iaxmaxthreadcount = 256;
13107 }
13108 }
13109 } else if (!strcasecmp(v->name, "nochecksums")) {
13110 #ifdef SO_NO_CHECK
13111 if (ast_true(v->value))
13112 nochecksums = 1;
13113 else
13114 nochecksums = 0;
13115 #else
13116 if (ast_true(v->value))
13117 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13118 #endif
13119 }
13120 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13121 maxjitterbuffer = atoi(v->value);
13122 else if (!strcasecmp(v->name, "resyncthreshold"))
13123 resyncthreshold = atoi(v->value);
13124 else if (!strcasecmp(v->name, "maxjitterinterps"))
13125 maxjitterinterps = atoi(v->value);
13126 else if (!strcasecmp(v->name, "jittertargetextra"))
13127 jittertargetextra = atoi(v->value);
13128 else if (!strcasecmp(v->name, "lagrqtime"))
13129 lagrq_time = atoi(v->value);
13130 else if (!strcasecmp(v->name, "maxregexpire"))
13131 max_reg_expire = atoi(v->value);
13132 else if (!strcasecmp(v->name, "minregexpire"))
13133 min_reg_expire = atoi(v->value);
13134 else if (!strcasecmp(v->name, "bindaddr")) {
13135 if (reload) {
13136 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13137 } else {
13138 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13139 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13140 } else {
13141 if (strchr(v->value, ':'))
13142 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13143 else
13144 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13145 if (defaultsockfd < 0)
13146 defaultsockfd = ast_netsock_sockfd(ns);
13147 ast_netsock_unref(ns);
13148 }
13149 }
13150 } else if (!strcasecmp(v->name, "authdebug")) {
13151 authdebug = ast_true(v->value);
13152 } else if (!strcasecmp(v->name, "encryption")) {
13153 iax2_encryption |= get_encrypt_methods(v->value);
13154 if (!iax2_encryption) {
13155 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13156 }
13157 } else if (!strcasecmp(v->name, "forceencryption")) {
13158 if (ast_false(v->value)) {
13159 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13160 } else {
13161 iax2_encryption |= get_encrypt_methods(v->value);
13162 if (iax2_encryption) {
13163 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13164 }
13165 }
13166 } else if (!strcasecmp(v->name, "transfer")) {
13167 if (!strcasecmp(v->value, "mediaonly")) {
13168 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13169 } else if (ast_true(v->value)) {
13170 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13171 } else
13172 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13173 } else if (!strcasecmp(v->name, "codecpriority")) {
13174 if(!strcasecmp(v->value, "caller"))
13175 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13176 else if(!strcasecmp(v->value, "disabled"))
13177 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13178 else if(!strcasecmp(v->value, "reqonly")) {
13179 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13180 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13181 }
13182 } else if (!strcasecmp(v->name, "jitterbuffer"))
13183 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13184 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13185 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13186 else if (!strcasecmp(v->name, "delayreject"))
13187 delayreject = ast_true(v->value);
13188 else if (!strcasecmp(v->name, "allowfwdownload"))
13189 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13190 else if (!strcasecmp(v->name, "rtcachefriends"))
13191 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13192 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13193 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13194 else if (!strcasecmp(v->name, "rtupdate"))
13195 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13196 else if (!strcasecmp(v->name, "rtsavesysname"))
13197 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13198 else if (!strcasecmp(v->name, "trunktimestamps"))
13199 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13200 else if (!strcasecmp(v->name, "rtautoclear")) {
13201 int i = atoi(v->value);
13202 if(i > 0)
13203 global_rtautoclear = i;
13204 else
13205 i = 0;
13206 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13207 } else if (!strcasecmp(v->name, "trunkfreq")) {
13208 trunkfreq = atoi(v->value);
13209 if (trunkfreq < 10)
13210 trunkfreq = 10;
13211 } else if (!strcasecmp(v->name, "trunkmtu")) {
13212 mtuv = atoi(v->value);
13213 if (mtuv == 0 )
13214 global_max_trunk_mtu = 0;
13215 else if (mtuv >= 172 && mtuv < 4000)
13216 global_max_trunk_mtu = mtuv;
13217 else
13218 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13219 mtuv, v->lineno);
13220 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13221 trunkmaxsize = atoi(v->value);
13222 if (trunkmaxsize == 0)
13223 trunkmaxsize = MAX_TRUNKDATA;
13224 } else if (!strcasecmp(v->name, "autokill")) {
13225 if (sscanf(v->value, "%30d", &x) == 1) {
13226 if (x >= 0)
13227 autokill = x;
13228 else
13229 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13230 } else if (ast_true(v->value)) {
13231 autokill = DEFAULT_MAXMS;
13232 } else {
13233 autokill = 0;
13234 }
13235 } else if (!strcasecmp(v->name, "bandwidth")) {
13236 if (!strcasecmp(v->value, "low")) {
13237 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13238 } else if (!strcasecmp(v->value, "medium")) {
13239 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13240 } else if (!strcasecmp(v->value, "high")) {
13241 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13242 } else
13243 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13244 } else if (!strcasecmp(v->name, "allow")) {
13245 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13246 } else if (!strcasecmp(v->name, "disallow")) {
13247 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13248 } else if (!strcasecmp(v->name, "register")) {
13249 iax2_register(v->value, v->lineno);
13250 } else if (!strcasecmp(v->name, "iaxcompat")) {
13251 iaxcompat = ast_true(v->value);
13252 } else if (!strcasecmp(v->name, "regcontext")) {
13253 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13254
13255 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13256 } else if (!strcasecmp(v->name, "tos")) {
13257 if (ast_str2tos(v->value, &qos.tos))
13258 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13259 } else if (!strcasecmp(v->name, "cos")) {
13260 if (ast_str2cos(v->value, &qos.cos))
13261 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13262 } else if (!strcasecmp(v->name, "parkinglot")) {
13263 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13264 } else if (!strcasecmp(v->name, "accountcode")) {
13265 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13266 } else if (!strcasecmp(v->name, "mohinterpret")) {
13267 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13268 } else if (!strcasecmp(v->name, "mohsuggest")) {
13269 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13270 } else if (!strcasecmp(v->name, "amaflags")) {
13271 format = ast_cdr_amaflags2int(v->value);
13272 if (format < 0) {
13273 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13274 } else {
13275 amaflags = format;
13276 }
13277 } else if (!strcasecmp(v->name, "language")) {
13278 ast_copy_string(language, v->value, sizeof(language));
13279 } else if (!strcasecmp(v->name, "maxauthreq")) {
13280 maxauthreq = atoi(v->value);
13281 if (maxauthreq < 0)
13282 maxauthreq = 0;
13283 } else if (!strcasecmp(v->name, "adsi")) {
13284 adsi = ast_true(v->value);
13285 } else if (!strcasecmp(v->name, "srvlookup")) {
13286 srvlookup = ast_true(v->value);
13287 } else if (!strcasecmp(v->name, "connectedline")) {
13288 if (ast_true(v->value)) {
13289 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13290 } else if (!strcasecmp(v->value, "send")) {
13291 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13292 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13293 } else if (!strcasecmp(v->value, "receive")) {
13294 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13295 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13296 } else {
13297 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13298 }
13299 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13300 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13301 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13302 }
13303 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13304 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13305 ast_log(LOG_WARNING, "maxcallnumbers_nonvalidated must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
13306 }
13307 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13308 if (add_calltoken_ignore(v->value)) {
13309 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13310 }
13311 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13312 if (ast_true(v->value)) {
13313 subscribe_network_change = 1;
13314 } else if (ast_false(v->value)) {
13315 subscribe_network_change = 0;
13316 } else {
13317 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13318 }
13319 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13320 if (ast_true(v->value)) {
13321 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13322 } else if (ast_false(v->value)) {
13323 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13324 } else {
13325 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13326 }
13327 }
13328
13329 v = v->next;
13330 }
13331
13332 if (subscribe_network_change) {
13333 network_change_event_subscribe();
13334 } else {
13335 network_change_event_unsubscribe();
13336 }
13337
13338 if (defaultsockfd < 0) {
13339 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13340 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13341 } else {
13342 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13343 defaultsockfd = ast_netsock_sockfd(ns);
13344 ast_netsock_unref(ns);
13345 }
13346 }
13347 if (reload) {
13348 ast_netsock_release(outsock);
13349 outsock = ast_netsock_list_alloc();
13350 if (!outsock) {
13351 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13352 return -1;
13353 }
13354 ast_netsock_init(outsock);
13355 }
13356
13357 if (min_reg_expire > max_reg_expire) {
13358 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13359 min_reg_expire, max_reg_expire, max_reg_expire);
13360 min_reg_expire = max_reg_expire;
13361 }
13362 iax2_capability = capability;
13363
13364 if (ucfg) {
13365 struct ast_variable *gen;
13366 int genhasiax;
13367 int genregisteriax;
13368 const char *hasiax, *registeriax;
13369
13370 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13371 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13372 gen = ast_variable_browse(ucfg, "general");
13373 cat = ast_category_browse(ucfg, NULL);
13374 while (cat) {
13375 if (strcasecmp(cat, "general")) {
13376 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13377 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13378 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13379
13380 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13381 if (user) {
13382 ao2_link(users, user);
13383 user = user_unref(user);
13384 }
13385 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13386 if (peer) {
13387 if (ast_test_flag64(peer, IAX_DYNAMIC))
13388 reg_source_db(peer);
13389 ao2_link(peers, peer);
13390 peer = peer_unref(peer);
13391 }
13392 }
13393 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13394 char tmp[256];
13395 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13396 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13397 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13398 if (!host)
13399 host = ast_variable_retrieve(ucfg, "general", "host");
13400 if (!username)
13401 username = ast_variable_retrieve(ucfg, "general", "username");
13402 if (!secret)
13403 secret = ast_variable_retrieve(ucfg, "general", "secret");
13404 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13405 if (!ast_strlen_zero(secret))
13406 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13407 else
13408 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13409 iax2_register(tmp, 0);
13410 }
13411 }
13412 }
13413 cat = ast_category_browse(ucfg, cat);
13414 }
13415 ast_config_destroy(ucfg);
13416 }
13417
13418 cat = ast_category_browse(cfg, NULL);
13419 while(cat) {
13420 if (strcasecmp(cat, "general")) {
13421 utype = ast_variable_retrieve(cfg, cat, "type");
13422 if (!strcasecmp(cat, "callnumberlimits")) {
13423 build_callno_limits(ast_variable_browse(cfg, cat));
13424 } else if (utype) {
13425 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13426 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13427 if (user) {
13428 ao2_link(users, user);
13429 user = user_unref(user);
13430 }
13431 }
13432 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13433 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13434 if (peer) {
13435 if (ast_test_flag64(peer, IAX_DYNAMIC))
13436 reg_source_db(peer);
13437 ao2_link(peers, peer);
13438 peer = peer_unref(peer);
13439 }
13440 } else if (strcasecmp(utype, "user")) {
13441 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13442 }
13443 } else
13444 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13445 }
13446 cat = ast_category_browse(cfg, cat);
13447 }
13448 ast_config_destroy(cfg);
13449 return 1;
13450 }
13451
13452 static void poke_all_peers(void)
13453 {
13454 struct ao2_iterator i;
13455 struct iax2_peer *peer;
13456
13457 i = ao2_iterator_init(peers, 0);
13458 while ((peer = ao2_iterator_next(&i))) {
13459 iax2_poke_peer(peer, 0);
13460 peer_unref(peer);
13461 }
13462 ao2_iterator_destroy(&i);
13463 }
13464 static int reload_config(void)
13465 {
13466 static const char config[] = "iax.conf";
13467 struct iax2_registry *reg;
13468
13469 if (set_config(config, 1) > 0) {
13470 prune_peers();
13471 prune_users();
13472 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13473 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13474 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13475 trunk_timed = trunk_untimed = 0;
13476 trunk_nmaxmtu = trunk_maxmtu = 0;
13477 memset(&debugaddr, '\0', sizeof(debugaddr));
13478
13479 AST_LIST_LOCK(®istrations);
13480 AST_LIST_TRAVERSE(®istrations, reg, entry)
13481 iax2_do_register(reg);
13482 AST_LIST_UNLOCK(®istrations);
13483
13484
13485 poke_all_peers();
13486 }
13487
13488 reload_firmware(0);
13489 iax_provision_reload(1);
13490 ast_unload_realtime("iaxpeers");
13491
13492 return 0;
13493 }
13494
13495 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13496 {
13497 switch (cmd) {
13498 case CLI_INIT:
13499 e->command = "iax2 reload";
13500 e->usage =
13501 "Usage: iax2 reload\n"
13502 " Reloads IAX configuration from iax.conf\n";
13503 return NULL;
13504 case CLI_GENERATE:
13505 return NULL;
13506 }
13507
13508 reload_config();
13509
13510 return CLI_SUCCESS;
13511 }
13512
13513 static int reload(void)
13514 {
13515 return reload_config();
13516 }
13517
13518 static int cache_get_callno_locked(const char *data)
13519 {
13520 struct sockaddr_in sin;
13521 int x;
13522 int callno;
13523 struct iax_ie_data ied;
13524 struct create_addr_info cai;
13525 struct parsed_dial_string pds;
13526 char *tmpstr;
13527
13528 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13529
13530
13531 if (!ast_mutex_trylock(&iaxsl[x])) {
13532 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13533 return x;
13534 ast_mutex_unlock(&iaxsl[x]);
13535 }
13536 }
13537
13538
13539
13540 memset(&cai, 0, sizeof(cai));
13541 memset(&ied, 0, sizeof(ied));
13542 memset(&pds, 0, sizeof(pds));
13543
13544 tmpstr = ast_strdupa(data);
13545 parse_dial_string(tmpstr, &pds);
13546
13547 if (ast_strlen_zero(pds.peer)) {
13548 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13549 return -1;
13550 }
13551
13552
13553 if (create_addr(pds.peer, NULL, &sin, &cai))
13554 return -1;
13555
13556 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13557 pds.peer, pds.username, pds.password, pds.context);
13558
13559 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13560 if (callno < 1) {
13561 ast_log(LOG_WARNING, "Unable to create call\n");
13562 return -1;
13563 }
13564
13565 ast_string_field_set(iaxs[callno], dproot, data);
13566 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13567
13568 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13569 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13570
13571
13572
13573 if (pds.exten)
13574 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13575 if (pds.username)
13576 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13577 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13578 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13579
13580 if (pds.password)
13581 ast_string_field_set(iaxs[callno], secret, pds.password);
13582 if (pds.key)
13583 ast_string_field_set(iaxs[callno], outkey, pds.key);
13584
13585 add_empty_calltoken_ie(iaxs[callno], &ied);
13586 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13587
13588 return callno;
13589 }
13590
13591 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13592 {
13593 struct iax2_dpcache *dp = NULL;
13594 struct timeval now = ast_tvnow();
13595 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13596 struct ast_channel *c = NULL;
13597 struct ast_frame *f = NULL;
13598
13599 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13600 if (ast_tvcmp(now, dp->expiry) > 0) {
13601 AST_LIST_REMOVE_CURRENT(cache_list);
13602 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13603 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13604 else
13605 ast_free(dp);
13606 continue;
13607 }
13608 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13609 break;
13610 }
13611 AST_LIST_TRAVERSE_SAFE_END;
13612
13613 if (!dp) {
13614
13615
13616 if ((callno = cache_get_callno_locked(data)) < 0) {
13617 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13618 return NULL;
13619 }
13620 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13621 ast_mutex_unlock(&iaxsl[callno]);
13622 return NULL;
13623 }
13624 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13625 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13626 dp->expiry = ast_tvnow();
13627 dp->orig = dp->expiry;
13628
13629 dp->expiry.tv_sec += iaxdefaultdpcache;
13630 dp->flags = CACHE_FLAG_PENDING;
13631 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13632 dp->waiters[x] = -1;
13633
13634 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13635 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13636
13637 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13638 iax2_dprequest(dp, callno);
13639 ast_mutex_unlock(&iaxsl[callno]);
13640 }
13641
13642
13643 if (dp->flags & CACHE_FLAG_PENDING) {
13644
13645
13646 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13647
13648 if (dp->waiters[x] < 0)
13649 break;
13650 }
13651 if (x >= ARRAY_LEN(dp->waiters)) {
13652 ast_log(LOG_WARNING, "No more waiter positions available\n");
13653 return NULL;
13654 }
13655 if (pipe(com)) {
13656 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13657 return NULL;
13658 }
13659 dp->waiters[x] = com[1];
13660
13661 timeout = iaxdefaulttimeout * 1000;
13662
13663 AST_LIST_UNLOCK(&dpcache);
13664
13665 if (chan)
13666 old = ast_channel_defer_dtmf(chan);
13667 doabort = 0;
13668 while(timeout) {
13669 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13670 if (outfd > -1)
13671 break;
13672 if (!c)
13673 continue;
13674 if (!(f = ast_read(c))) {
13675 doabort = 1;
13676 break;
13677 }
13678 ast_frfree(f);
13679 }
13680 if (!timeout) {
13681 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13682 }
13683 AST_LIST_LOCK(&dpcache);
13684 dp->waiters[x] = -1;
13685 close(com[1]);
13686 close(com[0]);
13687 if (doabort) {
13688
13689
13690 if (!old && chan)
13691 ast_channel_undefer_dtmf(chan);
13692 return NULL;
13693 }
13694 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13695
13696 if (dp->flags & CACHE_FLAG_PENDING) {
13697
13698
13699 dp->flags &= ~CACHE_FLAG_PENDING;
13700 dp->flags |= CACHE_FLAG_TIMEOUT;
13701
13702
13703 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13704 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13705 if (dp->waiters[x] > -1) {
13706 if (write(dp->waiters[x], "asdf", 4) < 0) {
13707 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13708 }
13709 }
13710 }
13711 }
13712 }
13713
13714 if (!old && chan)
13715 ast_channel_undefer_dtmf(chan);
13716 }
13717 return dp;
13718 }
13719
13720
13721 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13722 {
13723 int res = 0;
13724 struct iax2_dpcache *dp = NULL;
13725 #if 0
13726 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13727 #endif
13728 if ((priority != 1) && (priority != 2))
13729 return 0;
13730
13731 AST_LIST_LOCK(&dpcache);
13732 if ((dp = find_cache(chan, data, context, exten, priority))) {
13733 if (dp->flags & CACHE_FLAG_EXISTS)
13734 res = 1;
13735 } else {
13736 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13737 }
13738 AST_LIST_UNLOCK(&dpcache);
13739
13740 return res;
13741 }
13742
13743
13744 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13745 {
13746 int res = 0;
13747 struct iax2_dpcache *dp = NULL;
13748 #if 0
13749 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13750 #endif
13751 if ((priority != 1) && (priority != 2))
13752 return 0;
13753
13754 AST_LIST_LOCK(&dpcache);
13755 if ((dp = find_cache(chan, data, context, exten, priority))) {
13756 if (dp->flags & CACHE_FLAG_CANEXIST)
13757 res = 1;
13758 } else {
13759 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13760 }
13761 AST_LIST_UNLOCK(&dpcache);
13762
13763 return res;
13764 }
13765
13766
13767 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13768 {
13769 int res = 0;
13770 struct iax2_dpcache *dp = NULL;
13771 #if 0
13772 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13773 #endif
13774 if ((priority != 1) && (priority != 2))
13775 return 0;
13776
13777 AST_LIST_LOCK(&dpcache);
13778 if ((dp = find_cache(chan, data, context, exten, priority))) {
13779 if (dp->flags & CACHE_FLAG_MATCHMORE)
13780 res = 1;
13781 } else {
13782 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13783 }
13784 AST_LIST_UNLOCK(&dpcache);
13785
13786 return res;
13787 }
13788
13789
13790 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13791 {
13792 char odata[256];
13793 char req[256];
13794 char *ncontext;
13795 struct iax2_dpcache *dp = NULL;
13796 struct ast_app *dial = NULL;
13797 #if 0
13798 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);
13799 #endif
13800 if (priority == 2) {
13801
13802 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13803 if (dialstatus) {
13804 dial = pbx_findapp(dialstatus);
13805 if (dial)
13806 pbx_exec(chan, dial, "");
13807 }
13808 return -1;
13809 } else if (priority != 1)
13810 return -1;
13811
13812 AST_LIST_LOCK(&dpcache);
13813 if ((dp = find_cache(chan, data, context, exten, priority))) {
13814 if (dp->flags & CACHE_FLAG_EXISTS) {
13815 ast_copy_string(odata, data, sizeof(odata));
13816 ncontext = strchr(odata, '/');
13817 if (ncontext) {
13818 *ncontext = '\0';
13819 ncontext++;
13820 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13821 } else {
13822 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13823 }
13824 ast_verb(3, "Executing Dial('%s')\n", req);
13825 } else {
13826 AST_LIST_UNLOCK(&dpcache);
13827 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13828 return -1;
13829 }
13830 }
13831 AST_LIST_UNLOCK(&dpcache);
13832
13833 if ((dial = pbx_findapp("Dial")))
13834 return pbx_exec(chan, dial, req);
13835 else
13836 ast_log(LOG_WARNING, "No dial application registered\n");
13837
13838 return -1;
13839 }
13840
13841 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13842 {
13843 struct iax2_peer *peer;
13844 char *peername, *colname;
13845
13846 peername = ast_strdupa(data);
13847
13848
13849 if (!strcmp(peername,"CURRENTCHANNEL")) {
13850 unsigned short callno;
13851 if (chan->tech != &iax2_tech)
13852 return -1;
13853 callno = PTR_TO_CALLNO(chan->tech_pvt);
13854 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13855 return 0;
13856 }
13857
13858 if ((colname = strchr(peername, ',')))
13859 *colname++ = '\0';
13860 else
13861 colname = "ip";
13862
13863 if (!(peer = find_peer(peername, 1)))
13864 return -1;
13865
13866 if (!strcasecmp(colname, "ip")) {
13867 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13868 } else if (!strcasecmp(colname, "status")) {
13869 peer_status(peer, buf, len);
13870 } else if (!strcasecmp(colname, "mailbox")) {
13871 ast_copy_string(buf, peer->mailbox, len);
13872 } else if (!strcasecmp(colname, "context")) {
13873 ast_copy_string(buf, peer->context, len);
13874 } else if (!strcasecmp(colname, "expire")) {
13875 snprintf(buf, len, "%d", peer->expire);
13876 } else if (!strcasecmp(colname, "dynamic")) {
13877 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13878 } else if (!strcasecmp(colname, "callerid_name")) {
13879 ast_copy_string(buf, peer->cid_name, len);
13880 } else if (!strcasecmp(colname, "callerid_num")) {
13881 ast_copy_string(buf, peer->cid_num, len);
13882 } else if (!strcasecmp(colname, "codecs")) {
13883 ast_getformatname_multiple(buf, len -1, peer->capability);
13884 } else if (!strncasecmp(colname, "codec[", 6)) {
13885 char *codecnum, *ptr;
13886 int codec = 0;
13887
13888 codecnum = strchr(colname, '[');
13889 *codecnum = '\0';
13890 codecnum++;
13891 if ((ptr = strchr(codecnum, ']'))) {
13892 *ptr = '\0';
13893 }
13894 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13895 ast_copy_string(buf, ast_getformatname(codec), len);
13896 } else {
13897 buf[0] = '\0';
13898 }
13899 } else {
13900 buf[0] = '\0';
13901 }
13902
13903 peer_unref(peer);
13904
13905 return 0;
13906 }
13907
13908 static struct ast_custom_function iaxpeer_function = {
13909 .name = "IAXPEER",
13910 .read = function_iaxpeer,
13911 };
13912
13913 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13914 {
13915 struct chan_iax2_pvt *pvt;
13916 unsigned int callno;
13917 int res = 0;
13918
13919 if (!chan || chan->tech != &iax2_tech) {
13920 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13921 return -1;
13922 }
13923
13924 callno = PTR_TO_CALLNO(chan->tech_pvt);
13925 ast_mutex_lock(&iaxsl[callno]);
13926 if (!(pvt = iaxs[callno])) {
13927 ast_mutex_unlock(&iaxsl[callno]);
13928 return -1;
13929 }
13930
13931 if (!strcasecmp(args, "osptoken")) {
13932 ast_copy_string(buf, pvt->osptoken, buflen);
13933 } else if (!strcasecmp(args, "peerip")) {
13934 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13935 } else if (!strcasecmp(args, "peername")) {
13936 ast_copy_string(buf, pvt->username, buflen);
13937 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
13938 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
13939 } else {
13940 res = -1;
13941 }
13942
13943 ast_mutex_unlock(&iaxsl[callno]);
13944
13945 return res;
13946 }
13947
13948
13949 static int iax2_devicestate(void *data)
13950 {
13951 struct parsed_dial_string pds;
13952 char *tmp = ast_strdupa(data);
13953 struct iax2_peer *p;
13954 int res = AST_DEVICE_INVALID;
13955
13956 memset(&pds, 0, sizeof(pds));
13957 parse_dial_string(tmp, &pds);
13958
13959 if (ast_strlen_zero(pds.peer)) {
13960 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13961 return res;
13962 }
13963
13964 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13965
13966
13967 if (!(p = find_peer(pds.peer, 1)))
13968 return res;
13969
13970 res = AST_DEVICE_UNAVAILABLE;
13971 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13972 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13973
13974 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
13975 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13976
13977
13978 if (p->historicms == 0 || p->historicms <= p->maxms)
13979
13980 res = AST_DEVICE_UNKNOWN;
13981 }
13982
13983 peer_unref(p);
13984
13985 return res;
13986 }
13987
13988 static struct ast_switch iax2_switch =
13989 {
13990 name: "IAX2",
13991 description: "IAX Remote Dialplan Switch",
13992 exists: iax2_exists,
13993 canmatch: iax2_canmatch,
13994 exec: iax2_exec,
13995 matchmore: iax2_matchmore,
13996 };
13997
13998
13999
14000
14001
14002
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037
14038
14039
14040
14041
14042
14043
14044
14045
14046
14047
14048
14049
14050
14051
14052
14053
14054
14055
14056
14057
14058
14059
14060
14061
14062
14063
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075
14076
14077
14078
14079
14080
14081
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091
14092
14093
14094
14095
14096
14097
14098
14099
14100
14101
14102 static struct ast_cli_entry cli_iax2[] = {
14103 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14104 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14105 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14106 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14107 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14108 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14109 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14110 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14111 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14112 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14113 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14114 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14115 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14116 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14117 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14118 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14119 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14120 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14121 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14122 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14123 #ifdef IAXTESTS
14124 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14125 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14126 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14127 #endif
14128 };
14129
14130 #ifdef TEST_FRAMEWORK
14131 AST_TEST_DEFINE(test_iax2_peers_get)
14132 {
14133 struct ast_data_query query = {
14134 .path = "/asterisk/channel/iax2/peers",
14135 .search = "peers/peer/name=test_peer_data_provider"
14136 };
14137 struct ast_data *node;
14138 struct iax2_peer *peer;
14139
14140 switch (cmd) {
14141 case TEST_INIT:
14142 info->name = "iax2_peers_get_data_test";
14143 info->category = "/main/data/iax2/peers/";
14144 info->summary = "IAX2 peers data providers unit test";
14145 info->description =
14146 "Tests whether the IAX2 peers data provider implementation works as expected.";
14147 return AST_TEST_NOT_RUN;
14148 case TEST_EXECUTE:
14149 break;
14150 }
14151
14152
14153 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14154 if (!peer) {
14155 return AST_TEST_FAIL;
14156 }
14157 peer->expiry= 1010;
14158 ao2_link(peers, peer);
14159
14160 node = ast_data_get(&query);
14161 if (!node) {
14162 ao2_unlink(peers, peer);
14163 peer_unref(peer);
14164 return AST_TEST_FAIL;
14165 }
14166
14167
14168 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14169 ao2_unlink(peers, peer);
14170 peer_unref(peer);
14171 ast_data_free(node);
14172 return AST_TEST_FAIL;
14173 }
14174
14175 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14176 ao2_unlink(peers, peer);
14177 peer_unref(peer);
14178 ast_data_free(node);
14179 return AST_TEST_FAIL;
14180 }
14181
14182
14183 ast_data_free(node);
14184
14185 ao2_unlink(peers, peer);
14186 peer_unref(peer);
14187
14188 return AST_TEST_PASS;
14189 }
14190
14191 AST_TEST_DEFINE(test_iax2_users_get)
14192 {
14193 struct ast_data_query query = {
14194 .path = "/asterisk/channel/iax2/users",
14195 .search = "users/user/name=test_user_data_provider"
14196 };
14197 struct ast_data *node;
14198 struct iax2_user *user;
14199
14200 switch (cmd) {
14201 case TEST_INIT:
14202 info->name = "iax2_users_get_data_test";
14203 info->category = "/main/data/iax2/users/";
14204 info->summary = "IAX2 users data providers unit test";
14205 info->description =
14206 "Tests whether the IAX2 users data provider implementation works as expected.";
14207 return AST_TEST_NOT_RUN;
14208 case TEST_EXECUTE:
14209 break;
14210 }
14211
14212 user = build_user("test_user_data_provider", NULL, NULL, 0);
14213 if (!user) {
14214 ast_test_status_update(test, "Failed to build a test user\n");
14215 return AST_TEST_FAIL;
14216 }
14217 user->amaflags = 1010;
14218 ao2_link(users, user);
14219
14220 node = ast_data_get(&query);
14221 if (!node) {
14222 ast_test_status_update(test, "The data query to find our test user failed\n");
14223 ao2_unlink(users, user);
14224 user_unref(user);
14225 return AST_TEST_FAIL;
14226 }
14227
14228 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14229 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14230 ao2_unlink(users, user);
14231 user_unref(user);
14232 ast_data_free(node);
14233 return AST_TEST_FAIL;
14234 }
14235
14236 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14237 ast_test_status_update(test, "The amaflags field in our test user was '%d' not the expected value '1010'\n", ast_data_retrieve_int(node, "user/amaflags/value"));
14238 ao2_unlink(users, user);
14239 user_unref(user);
14240 ast_data_free(node);
14241 return AST_TEST_FAIL;
14242 }
14243
14244 ast_data_free(node);
14245
14246 ao2_unlink(users, user);
14247 user_unref(user);
14248
14249 return AST_TEST_PASS;
14250 }
14251 #endif
14252
14253 static void cleanup_thread_list(void *head)
14254 {
14255 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14256 struct iax2_thread_list *list_head = head;
14257 struct iax2_thread *thread;
14258
14259 AST_LIST_LOCK(list_head);
14260 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14261 pthread_t thread_id = thread->threadid;
14262
14263 thread->stop = 1;
14264 signal_condition(&thread->lock, &thread->cond);
14265
14266 AST_LIST_UNLOCK(list_head);
14267 pthread_join(thread_id, NULL);
14268 AST_LIST_LOCK(list_head);
14269 }
14270 AST_LIST_UNLOCK(list_head);
14271 }
14272
14273 static int __unload_module(void)
14274 {
14275 struct ast_context *con;
14276 int x;
14277
14278 network_change_event_unsubscribe();
14279
14280 ast_manager_unregister("IAXpeers");
14281 ast_manager_unregister("IAXpeerlist");
14282 ast_manager_unregister("IAXnetstats");
14283 ast_manager_unregister("IAXregistry");
14284 ast_unregister_application(papp);
14285 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14286 ast_unregister_switch(&iax2_switch);
14287 ast_channel_unregister(&iax2_tech);
14288
14289 if (netthreadid != AST_PTHREADT_NULL) {
14290 pthread_cancel(netthreadid);
14291 pthread_kill(netthreadid, SIGURG);
14292 pthread_join(netthreadid, NULL);
14293 }
14294
14295 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14296 if (iaxs[x]) {
14297 iax2_destroy(x);
14298 }
14299 }
14300
14301
14302 cleanup_thread_list(&idle_list);
14303 cleanup_thread_list(&active_list);
14304 cleanup_thread_list(&dynamic_list);
14305
14306 ast_netsock_release(netsock);
14307 ast_netsock_release(outsock);
14308 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14309 if (iaxs[x]) {
14310 iax2_destroy(x);
14311 }
14312 }
14313 ast_manager_unregister( "IAXpeers" );
14314 ast_manager_unregister( "IAXpeerlist" );
14315 ast_manager_unregister( "IAXnetstats" );
14316 ast_manager_unregister( "IAXregistry" );
14317 ast_unregister_application(papp);
14318 #ifdef TEST_FRAMEWORK
14319 AST_TEST_UNREGISTER(test_iax2_peers_get);
14320 AST_TEST_UNREGISTER(test_iax2_users_get);
14321 #endif
14322 ast_data_unregister(NULL);
14323 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14324 ast_unregister_switch(&iax2_switch);
14325 ast_channel_unregister(&iax2_tech);
14326 delete_users();
14327 iax_provision_unload();
14328 reload_firmware(1);
14329
14330 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14331 ast_mutex_destroy(&iaxsl[x]);
14332 }
14333
14334 ao2_ref(peers, -1);
14335 ao2_ref(users, -1);
14336 ao2_ref(iax_peercallno_pvts, -1);
14337 ao2_ref(iax_transfercallno_pvts, -1);
14338 ao2_ref(peercnts, -1);
14339 ao2_ref(callno_limits, -1);
14340 ao2_ref(calltoken_ignores, -1);
14341 ao2_ref(callno_pool, -1);
14342 ao2_ref(callno_pool_trunk, -1);
14343 if (timer) {
14344 ast_timer_close(timer);
14345 }
14346 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14347 sched = ast_sched_thread_destroy(sched);
14348
14349 con = ast_context_find(regcontext);
14350 if (con)
14351 ast_context_destroy(con, "IAX2");
14352 ast_unload_realtime("iaxpeers");
14353 return 0;
14354 }
14355
14356 static int unload_module(void)
14357 {
14358 ast_custom_function_unregister(&iaxpeer_function);
14359 ast_custom_function_unregister(&iaxvar_function);
14360 return __unload_module();
14361 }
14362
14363 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14364 {
14365 struct iax2_peer *peer = obj;
14366
14367 if (peer->sockfd < 0)
14368 peer->sockfd = defaultsockfd;
14369
14370 return 0;
14371 }
14372
14373 static int pvt_hash_cb(const void *obj, const int flags)
14374 {
14375 const struct chan_iax2_pvt *pvt = obj;
14376
14377 return pvt->peercallno;
14378 }
14379
14380 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14381 {
14382 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14383
14384
14385
14386
14387 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14388 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14389 }
14390
14391 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14392 {
14393 const struct chan_iax2_pvt *pvt = obj;
14394
14395 return pvt->transfercallno;
14396 }
14397
14398 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14399 {
14400 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14401
14402
14403
14404
14405 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14406 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14407 }
14408
14409 static int load_objects(void)
14410 {
14411 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14412 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14413
14414 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14415 goto container_fail;
14416 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14417 goto container_fail;
14418 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14419 goto container_fail;
14420 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14421 goto container_fail;
14422 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14423 goto container_fail;
14424 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14425 goto container_fail;
14426 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14427 goto container_fail;
14428 } else if (create_callno_pools()) {
14429 goto container_fail;
14430 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14431 goto container_fail;
14432 }
14433
14434 return 0;
14435
14436 container_fail:
14437 if (peers) {
14438 ao2_ref(peers, -1);
14439 }
14440 if (users) {
14441 ao2_ref(users, -1);
14442 }
14443 if (iax_peercallno_pvts) {
14444 ao2_ref(iax_peercallno_pvts, -1);
14445 }
14446 if (iax_transfercallno_pvts) {
14447 ao2_ref(iax_transfercallno_pvts, -1);
14448 }
14449 if (peercnts) {
14450 ao2_ref(peercnts, -1);
14451 }
14452 if (callno_limits) {
14453 ao2_ref(callno_limits, -1);
14454 }
14455 if (calltoken_ignores) {
14456 ao2_ref(calltoken_ignores, -1);
14457 }
14458 if (callno_pool) {
14459 ao2_ref(callno_pool, -1);
14460 }
14461 if (callno_pool_trunk) {
14462 ao2_ref(callno_pool_trunk, -1);
14463 }
14464 return AST_MODULE_LOAD_FAILURE;
14465 }
14466
14467
14468 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14469 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14470 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14471 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14472 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14473 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14474 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14475 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14476 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14477 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14478 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14479 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14480 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14481 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14482 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14483 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14484 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14485 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14486 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14487 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14488 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14489 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14490 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14491 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14492 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14493 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14494
14495 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14496
14497 static int peers_data_provider_get(const struct ast_data_search *search,
14498 struct ast_data *data_root)
14499 {
14500 struct ast_data *data_peer;
14501 struct iax2_peer *peer;
14502 struct ao2_iterator i;
14503 char status[20];
14504 struct ast_str *encmethods = ast_str_alloca(256);
14505
14506 i = ao2_iterator_init(peers, 0);
14507 while ((peer = ao2_iterator_next(&i))) {
14508 data_peer = ast_data_add_node(data_root, "peer");
14509 if (!data_peer) {
14510 peer_unref(peer);
14511 continue;
14512 }
14513
14514 ast_data_add_structure(iax2_peer, data_peer, peer);
14515
14516 ast_data_add_codecs(data_peer, "codecs", peer->capability);
14517
14518 peer_status(peer, status, sizeof(status));
14519 ast_data_add_str(data_peer, "status", status);
14520
14521 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14522
14523 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14524
14525 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14526
14527 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14528
14529 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14530
14531 encmethods_to_str(peer->encmethods, encmethods);
14532 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14533
14534 peer_unref(peer);
14535
14536 if (!ast_data_search_match(search, data_peer)) {
14537 ast_data_remove_node(data_root, data_peer);
14538 }
14539 }
14540 ao2_iterator_destroy(&i);
14541
14542 return 0;
14543 }
14544
14545 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14546 MEMBER(iax2_user, name, AST_DATA_STRING) \
14547 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14548 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14549 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14550 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14551 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14552 MEMBER(iax2_user, language, AST_DATA_STRING) \
14553 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14554 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14555 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14556 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14557 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14558
14559 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14560
14561 static int users_data_provider_get(const struct ast_data_search *search,
14562 struct ast_data *data_root)
14563 {
14564 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14565 struct iax2_user *user;
14566 struct ao2_iterator i;
14567 char auth[90];
14568 char *pstr = "";
14569
14570 i = ao2_iterator_init(users, 0);
14571 while ((user = ao2_iterator_next(&i))) {
14572 data_user = ast_data_add_node(data_root, "user");
14573 if (!data_user) {
14574 user_unref(user);
14575 continue;
14576 }
14577
14578 ast_data_add_structure(iax2_user, data_user, user);
14579
14580 ast_data_add_codecs(data_user, "codecs", user->capability);
14581
14582 if (!ast_strlen_zero(user->secret)) {
14583 ast_copy_string(auth, user->secret, sizeof(auth));
14584 } else if (!ast_strlen_zero(user->inkeys)) {
14585 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14586 } else {
14587 ast_copy_string(auth, "no secret", sizeof(auth));
14588 }
14589 ast_data_add_password(data_user, "secret", auth);
14590
14591 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14592
14593
14594 data_authmethods = ast_data_add_node(data_user, "authmethods");
14595 if (!data_authmethods) {
14596 ast_data_remove_node(data_root, data_user);
14597 continue;
14598 }
14599 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14600 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14601 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14602
14603
14604 data_enum_node = ast_data_add_node(data_user, "amaflags");
14605 if (!data_enum_node) {
14606 ast_data_remove_node(data_root, data_user);
14607 continue;
14608 }
14609 ast_data_add_int(data_enum_node, "value", user->amaflags);
14610 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14611
14612 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14613
14614 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14615 pstr = "REQ only";
14616 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14617 pstr = "disabled";
14618 } else {
14619 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14620 }
14621 ast_data_add_str(data_user, "codec-preferences", pstr);
14622
14623 user_unref(user);
14624
14625 if (!ast_data_search_match(search, data_user)) {
14626 ast_data_remove_node(data_root, data_user);
14627 }
14628 }
14629 ao2_iterator_destroy(&i);
14630
14631 return 0;
14632 }
14633
14634 static const struct ast_data_handler peers_data_provider = {
14635 .version = AST_DATA_HANDLER_VERSION,
14636 .get = peers_data_provider_get
14637 };
14638
14639 static const struct ast_data_handler users_data_provider = {
14640 .version = AST_DATA_HANDLER_VERSION,
14641 .get = users_data_provider_get
14642 };
14643
14644 static const struct ast_data_entry iax2_data_providers[] = {
14645 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14646 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14647 };
14648
14649
14650 static int load_module(void)
14651 {
14652 static const char config[] = "iax.conf";
14653 int x = 0;
14654 struct iax2_registry *reg = NULL;
14655
14656 if (load_objects()) {
14657 return AST_MODULE_LOAD_FAILURE;
14658 }
14659
14660 memset(iaxs, 0, sizeof(iaxs));
14661
14662 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14663 ast_mutex_init(&iaxsl[x]);
14664 }
14665
14666 if (!(sched = ast_sched_thread_create())) {
14667 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14668 return AST_MODULE_LOAD_FAILURE;
14669 }
14670
14671 if (!(io = io_context_create())) {
14672 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14673 sched = ast_sched_thread_destroy(sched);
14674 return AST_MODULE_LOAD_FAILURE;
14675 }
14676
14677 if (!(netsock = ast_netsock_list_alloc())) {
14678 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14679 io_context_destroy(io);
14680 sched = ast_sched_thread_destroy(sched);
14681 return AST_MODULE_LOAD_FAILURE;
14682 }
14683 ast_netsock_init(netsock);
14684
14685 outsock = ast_netsock_list_alloc();
14686 if (!outsock) {
14687 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14688 io_context_destroy(io);
14689 sched = ast_sched_thread_destroy(sched);
14690 return AST_MODULE_LOAD_FAILURE;
14691 }
14692 ast_netsock_init(outsock);
14693
14694 randomcalltokendata = ast_random();
14695
14696 iax_set_output(iax_debug_output);
14697 iax_set_error(iax_error_output);
14698 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14699
14700 if ((timer = ast_timer_open())) {
14701 ast_timer_set_rate(timer, trunkfreq);
14702 }
14703
14704 if (set_config(config, 0) == -1) {
14705 if (timer) {
14706 ast_timer_close(timer);
14707 }
14708 return AST_MODULE_LOAD_DECLINE;
14709 }
14710
14711 #ifdef TEST_FRAMEWORK
14712 AST_TEST_REGISTER(test_iax2_peers_get);
14713 AST_TEST_REGISTER(test_iax2_users_get);
14714 #endif
14715
14716
14717 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14718 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14719
14720 ast_register_application_xml(papp, iax2_prov_app);
14721
14722 ast_custom_function_register(&iaxpeer_function);
14723 ast_custom_function_register(&iaxvar_function);
14724
14725 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14726 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14727 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14728 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14729
14730 if (ast_channel_register(&iax2_tech)) {
14731 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14732 __unload_module();
14733 return AST_MODULE_LOAD_FAILURE;
14734 }
14735
14736 if (ast_register_switch(&iax2_switch)) {
14737 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14738 }
14739
14740 if (start_network_thread()) {
14741 ast_log(LOG_ERROR, "Unable to start network thread\n");
14742 __unload_module();
14743 return AST_MODULE_LOAD_FAILURE;
14744 } else {
14745 ast_verb(2, "IAX Ready and Listening\n");
14746 }
14747
14748 AST_LIST_LOCK(®istrations);
14749 AST_LIST_TRAVERSE(®istrations, reg, entry)
14750 iax2_do_register(reg);
14751 AST_LIST_UNLOCK(®istrations);
14752
14753 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14754 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14755
14756
14757 reload_firmware(0);
14758 iax_provision_reload(0);
14759
14760 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14761
14762 network_change_event_subscribe();
14763
14764 return AST_MODULE_LOAD_SUCCESS;
14765 }
14766
14767 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
14768 .load = load_module,
14769 .unload = unload_module,
14770 .reload = reload,
14771 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
14772 .nonoptreq = "res_crypto",
14773 );