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: 352955 $")
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 ao2_ref(peercnt, -1);
02564 found = 1;
02565 break;
02566 } else {
02567 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02568 }
02569 ao2_ref(peercnt, -1);
02570 }
02571 ao2_iterator_destroy(&i);
02572
02573 if (a->argc == 4) {
02574 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02575 "Non-CallToken Validated Callno Used: %d\n",
02576 global_maxcallno_nonval,
02577 total_nonval_callno_used);
02578
02579 ast_cli(a->fd, "Total Available Callno: %d\n"
02580 "Regular Callno Available: %d\n"
02581 "Trunk Callno Available: %d\n",
02582 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02583 ao2_container_count(callno_pool),
02584 ao2_container_count(callno_pool_trunk));
02585 } else if (a->argc == 5 && !found) {
02586 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02587 }
02588
02589
02590 return CLI_SUCCESS;
02591 default:
02592 return NULL;
02593 }
02594 }
02595
02596 static struct callno_entry *get_unused_callno(int trunk, int validated)
02597 {
02598 struct callno_entry *callno_entry = NULL;
02599 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02600 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02601
02602 return NULL;
02603 }
02604
02605
02606
02607 ao2_lock(callno_pool);
02608
02609
02610
02611
02612 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02613 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02614 ao2_unlock(callno_pool);
02615 return NULL;
02616 }
02617
02618
02619
02620 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02621
02622 if (callno_entry) {
02623 callno_entry->validated = validated;
02624 if (!validated) {
02625 total_nonval_callno_used++;
02626 }
02627 }
02628
02629 ao2_unlock(callno_pool);
02630 return callno_entry;
02631 }
02632
02633 static int replace_callno(const void *obj)
02634 {
02635 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02636
02637
02638
02639 ao2_lock(callno_pool);
02640
02641 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02642 total_nonval_callno_used--;
02643 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02644 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02645 }
02646
02647 if (callno_entry->callno < TRUNK_CALL_START) {
02648 ao2_link(callno_pool, callno_entry);
02649 } else {
02650 ao2_link(callno_pool_trunk, callno_entry);
02651 }
02652 ao2_ref(callno_entry, -1);
02653
02654 ao2_unlock(callno_pool);
02655 return 0;
02656 }
02657
02658 static int callno_hash(const void *obj, const int flags)
02659 {
02660 return abs(ast_random());
02661 }
02662
02663 static int create_callno_pools(void)
02664 {
02665 uint16_t i;
02666
02667 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02668 return -1;
02669 }
02670
02671 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02672 return -1;
02673 }
02674
02675
02676 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02677 struct callno_entry *callno_entry;
02678
02679 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02680 return -1;
02681 }
02682
02683 callno_entry->callno = i;
02684
02685 if (i < TRUNK_CALL_START) {
02686 ao2_link(callno_pool, callno_entry);
02687 } else {
02688 ao2_link(callno_pool_trunk, callno_entry);
02689 }
02690
02691 ao2_ref(callno_entry, -1);
02692 }
02693
02694 return 0;
02695 }
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02706 {
02707 int i;
02708 struct peercnt *peercnt;
02709 struct peercnt tmp = {
02710 .addr = sin->sin_addr.s_addr,
02711 };
02712
02713 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02714
02715 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02716 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02717 if (i == -1) {
02718 ao2_ref(peercnt, -1);
02719 }
02720 }
02721
02722 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02723 }
02724
02725
02726
02727
02728
02729
02730
02731
02732 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02733 {
02734 if (frametype != AST_FRAME_IAX) {
02735 return 0;
02736 }
02737 switch (subclass) {
02738 case IAX_COMMAND_NEW:
02739 case IAX_COMMAND_REGREQ:
02740 case IAX_COMMAND_FWDOWNL:
02741 case IAX_COMMAND_REGREL:
02742 return 1;
02743 case IAX_COMMAND_POKE:
02744 if (!inbound) {
02745 return 1;
02746 }
02747 break;
02748 }
02749 return 0;
02750 }
02751
02752
02753
02754
02755 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02756 {
02757 int res = 0;
02758 int x;
02759
02760
02761 int validated = (new > NEW_ALLOW) ? 1 : 0;
02762 char host[80];
02763
02764 if (new <= NEW_ALLOW) {
02765 if (callno) {
02766 struct chan_iax2_pvt *pvt;
02767 struct chan_iax2_pvt tmp_pvt = {
02768 .callno = dcallno,
02769 .peercallno = callno,
02770 .transfercallno = callno,
02771
02772 .frames_received = check_dcallno,
02773 };
02774
02775 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02776
02777 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02778 if (return_locked) {
02779 ast_mutex_lock(&iaxsl[pvt->callno]);
02780 }
02781 res = pvt->callno;
02782 ao2_ref(pvt, -1);
02783 pvt = NULL;
02784 return res;
02785 }
02786
02787 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02788 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02789 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02790 if (return_locked) {
02791 ast_mutex_lock(&iaxsl[pvt->callno]);
02792 }
02793 res = pvt->callno;
02794 ao2_ref(pvt, -1);
02795 pvt = NULL;
02796 return res;
02797 }
02798 }
02799
02800
02801 if (dcallno) {
02802 ast_mutex_lock(&iaxsl[dcallno]);
02803 }
02804 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02805 iaxs[dcallno]->peercallno = callno;
02806 res = dcallno;
02807 store_by_peercallno(iaxs[dcallno]);
02808 if (!res || !return_locked) {
02809 ast_mutex_unlock(&iaxsl[dcallno]);
02810 }
02811 return res;
02812 }
02813 if (dcallno) {
02814 ast_mutex_unlock(&iaxsl[dcallno]);
02815 }
02816 #ifdef IAX_OLD_FIND
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828 for (x = 1; !res && x < maxnontrunkcall; x++) {
02829 ast_mutex_lock(&iaxsl[x]);
02830 if (iaxs[x]) {
02831
02832 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02833 res = x;
02834 }
02835 }
02836 if (!res || !return_locked)
02837 ast_mutex_unlock(&iaxsl[x]);
02838 }
02839 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02840 ast_mutex_lock(&iaxsl[x]);
02841 if (iaxs[x]) {
02842
02843 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02844 res = x;
02845 }
02846 }
02847 if (!res || !return_locked)
02848 ast_mutex_unlock(&iaxsl[x]);
02849 }
02850 #endif
02851 }
02852 if (!res && (new >= NEW_ALLOW)) {
02853 struct callno_entry *callno_entry;
02854
02855
02856
02857
02858
02859
02860 if (!iax2_getpeername(*sin, host, sizeof(host)))
02861 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02862
02863 if (peercnt_add(sin)) {
02864
02865
02866 return 0;
02867 }
02868
02869 if (!(callno_entry = get_unused_callno(0, validated))) {
02870
02871
02872 peercnt_remove_by_addr(sin);
02873 ast_log(LOG_WARNING, "No more space\n");
02874 return 0;
02875 }
02876 x = callno_entry->callno;
02877 ast_mutex_lock(&iaxsl[x]);
02878
02879 iaxs[x] = new_iax(sin, host);
02880 update_max_nontrunk();
02881 if (iaxs[x]) {
02882 if (iaxdebug)
02883 ast_debug(1, "Creating new call structure %d\n", x);
02884 iaxs[x]->callno_entry = callno_entry;
02885 iaxs[x]->sockfd = sockfd;
02886 iaxs[x]->addr.sin_port = sin->sin_port;
02887 iaxs[x]->addr.sin_family = sin->sin_family;
02888 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02889 iaxs[x]->peercallno = callno;
02890 iaxs[x]->callno = x;
02891 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02892 iaxs[x]->expiry = min_reg_expire;
02893 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02894 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02895 iaxs[x]->amaflags = amaflags;
02896 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02897 ast_string_field_set(iaxs[x], accountcode, accountcode);
02898 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02899 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02900 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02901
02902 if (iaxs[x]->peercallno) {
02903 store_by_peercallno(iaxs[x]);
02904 }
02905 } else {
02906 ast_log(LOG_WARNING, "Out of resources\n");
02907 ast_mutex_unlock(&iaxsl[x]);
02908 replace_callno(callno_entry);
02909 return 0;
02910 }
02911 if (!return_locked)
02912 ast_mutex_unlock(&iaxsl[x]);
02913 res = x;
02914 }
02915 return res;
02916 }
02917
02918 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02919 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02920 }
02921
02922 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02923
02924 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02925 }
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937 static int iax2_queue_frame(int callno, struct ast_frame *f)
02938 {
02939 iax2_lock_owner(callno);
02940 if (iaxs[callno] && iaxs[callno]->owner) {
02941 ast_queue_frame(iaxs[callno]->owner, f);
02942 ast_channel_unlock(iaxs[callno]->owner);
02943 }
02944 return 0;
02945 }
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960 static int iax2_queue_hangup(int callno)
02961 {
02962 iax2_lock_owner(callno);
02963 if (iaxs[callno] && iaxs[callno]->owner) {
02964 ast_queue_hangup(iaxs[callno]->owner);
02965 ast_channel_unlock(iaxs[callno]->owner);
02966 }
02967 return 0;
02968 }
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983 static int iax2_queue_control_data(int callno,
02984 enum ast_control_frame_type control, const void *data, size_t datalen)
02985 {
02986 iax2_lock_owner(callno);
02987 if (iaxs[callno] && iaxs[callno]->owner) {
02988 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02989 ast_channel_unlock(iaxs[callno]->owner);
02990 }
02991 return 0;
02992 }
02993 static void destroy_firmware(struct iax_firmware *cur)
02994 {
02995
02996 if (cur->fwh) {
02997 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02998 }
02999 close(cur->fd);
03000 ast_free(cur);
03001 }
03002
03003 static int try_firmware(char *s)
03004 {
03005 struct stat stbuf;
03006 struct iax_firmware *cur = NULL;
03007 int ifd, fd, res, len, chunk;
03008 struct ast_iax2_firmware_header *fwh, fwh2;
03009 struct MD5Context md5;
03010 unsigned char sum[16], buf[1024];
03011 char *s2, *last;
03012
03013 if (!(s2 = alloca(strlen(s) + 100))) {
03014 ast_log(LOG_WARNING, "Alloca failed!\n");
03015 return -1;
03016 }
03017
03018 last = strrchr(s, '/');
03019 if (last)
03020 last++;
03021 else
03022 last = s;
03023
03024 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03025
03026 if ((res = stat(s, &stbuf) < 0)) {
03027 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03028 return -1;
03029 }
03030
03031
03032 if (S_ISDIR(stbuf.st_mode))
03033 return -1;
03034 ifd = open(s, O_RDONLY);
03035 if (ifd < 0) {
03036 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03037 return -1;
03038 }
03039 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03040 if (fd < 0) {
03041 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03042 close(ifd);
03043 return -1;
03044 }
03045
03046 unlink(s2);
03047
03048
03049 len = stbuf.st_size;
03050 while(len) {
03051 chunk = len;
03052 if (chunk > sizeof(buf))
03053 chunk = sizeof(buf);
03054 res = read(ifd, buf, chunk);
03055 if (res != chunk) {
03056 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03057 close(ifd);
03058 close(fd);
03059 return -1;
03060 }
03061 res = write(fd, buf, chunk);
03062 if (res != chunk) {
03063 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03064 close(ifd);
03065 close(fd);
03066 return -1;
03067 }
03068 len -= chunk;
03069 }
03070 close(ifd);
03071
03072 lseek(fd, 0, SEEK_SET);
03073 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03074 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03075 close(fd);
03076 return -1;
03077 }
03078 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03079 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03080 close(fd);
03081 return -1;
03082 }
03083 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03084 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03085 close(fd);
03086 return -1;
03087 }
03088 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03089 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03090 close(fd);
03091 return -1;
03092 }
03093 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
03094 if (fwh == MAP_FAILED) {
03095 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03096 close(fd);
03097 return -1;
03098 }
03099 MD5Init(&md5);
03100 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03101 MD5Final(sum, &md5);
03102 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03103 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03104 munmap((void*)fwh, stbuf.st_size);
03105 close(fd);
03106 return -1;
03107 }
03108
03109 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03110 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03111
03112 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03113
03114 break;
03115
03116
03117 munmap((void*)fwh, stbuf.st_size);
03118 close(fd);
03119 return 0;
03120 }
03121 }
03122
03123 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03124 cur->fd = -1;
03125 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03126 }
03127
03128 if (cur) {
03129 if (cur->fwh)
03130 munmap((void*)cur->fwh, cur->mmaplen);
03131 if (cur->fd > -1)
03132 close(cur->fd);
03133 cur->fwh = fwh;
03134 cur->fd = fd;
03135 cur->mmaplen = stbuf.st_size;
03136 cur->dead = 0;
03137 }
03138
03139 return 0;
03140 }
03141
03142 static int iax_check_version(char *dev)
03143 {
03144 int res = 0;
03145 struct iax_firmware *cur = NULL;
03146
03147 if (ast_strlen_zero(dev))
03148 return 0;
03149
03150 AST_LIST_LOCK(&firmwares);
03151 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03152 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03153 res = ntohs(cur->fwh->version);
03154 break;
03155 }
03156 }
03157 AST_LIST_UNLOCK(&firmwares);
03158
03159 return res;
03160 }
03161
03162 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03163 {
03164 int res = -1;
03165 unsigned int bs = desc & 0xff;
03166 unsigned int start = (desc >> 8) & 0xffffff;
03167 unsigned int bytes;
03168 struct iax_firmware *cur;
03169
03170 if (ast_strlen_zero((char *)dev) || !bs)
03171 return -1;
03172
03173 start *= bs;
03174
03175 AST_LIST_LOCK(&firmwares);
03176 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03177 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03178 continue;
03179 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03180 if (start < ntohl(cur->fwh->datalen)) {
03181 bytes = ntohl(cur->fwh->datalen) - start;
03182 if (bytes > bs)
03183 bytes = bs;
03184 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03185 } else {
03186 bytes = 0;
03187 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03188 }
03189 if (bytes == bs)
03190 res = 0;
03191 else
03192 res = 1;
03193 break;
03194 }
03195 AST_LIST_UNLOCK(&firmwares);
03196
03197 return res;
03198 }
03199
03200
03201 static void reload_firmware(int unload)
03202 {
03203 struct iax_firmware *cur = NULL;
03204 DIR *fwd;
03205 struct dirent *de;
03206 char dir[256], fn[256];
03207
03208 AST_LIST_LOCK(&firmwares);
03209
03210
03211 AST_LIST_TRAVERSE(&firmwares, cur, list)
03212 cur->dead = 1;
03213
03214
03215 if (!unload) {
03216 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03217 fwd = opendir(dir);
03218 if (fwd) {
03219 while((de = readdir(fwd))) {
03220 if (de->d_name[0] != '.') {
03221 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03222 if (!try_firmware(fn)) {
03223 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03224 }
03225 }
03226 }
03227 closedir(fwd);
03228 } else
03229 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03230 }
03231
03232
03233 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03234 if (!cur->dead)
03235 continue;
03236 AST_LIST_REMOVE_CURRENT(list);
03237 destroy_firmware(cur);
03238 }
03239 AST_LIST_TRAVERSE_SAFE_END;
03240
03241 AST_LIST_UNLOCK(&firmwares);
03242 }
03243
03244
03245
03246
03247
03248
03249
03250
03251
03252 static int __do_deliver(void *data)
03253 {
03254
03255
03256 struct iax_frame *fr = data;
03257 fr->retrans = -1;
03258 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03259 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03260 iax2_queue_frame(fr->callno, &fr->af);
03261
03262 iax2_frame_free(fr);
03263
03264 return 0;
03265 }
03266
03267 static int handle_error(void)
03268 {
03269
03270
03271
03272 #if 0
03273 struct sockaddr_in *sin;
03274 int res;
03275 struct msghdr m;
03276 struct sock_extended_err e;
03277 m.msg_name = NULL;
03278 m.msg_namelen = 0;
03279 m.msg_iov = NULL;
03280 m.msg_control = &e;
03281 m.msg_controllen = sizeof(e);
03282 m.msg_flags = 0;
03283 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03284 if (res < 0)
03285 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03286 else {
03287 if (m.msg_controllen) {
03288 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03289 if (sin)
03290 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03291 else
03292 ast_log(LOG_WARNING, "No address detected??\n");
03293 } else {
03294 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03295 }
03296 }
03297 #endif
03298 return 0;
03299 }
03300
03301 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03302 {
03303 int res;
03304 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03305 sizeof(*sin));
03306 if (res < 0) {
03307 ast_debug(1, "Received error: %s\n", strerror(errno));
03308 handle_error();
03309 } else
03310 res = 0;
03311 return res;
03312 }
03313
03314 static int send_packet(struct iax_frame *f)
03315 {
03316 int res;
03317 int callno = f->callno;
03318
03319
03320 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03321 return -1;
03322
03323
03324 if (iaxdebug)
03325 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));
03326
03327 if (f->transfer) {
03328 if (iaxdebug)
03329 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03330 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03331 } else {
03332 if (iaxdebug)
03333 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03334 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03335 }
03336 if (res < 0) {
03337 if (iaxdebug)
03338 ast_debug(1, "Received error: %s\n", strerror(errno));
03339 handle_error();
03340 } else
03341 res = 0;
03342
03343 return res;
03344 }
03345
03346
03347
03348
03349
03350 static int iax2_predestroy(int callno)
03351 {
03352 struct ast_channel *c = NULL;
03353 struct chan_iax2_pvt *pvt = iaxs[callno];
03354
03355 if (!pvt)
03356 return -1;
03357
03358 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03359 iax2_destroy_helper(pvt);
03360 ast_set_flag64(pvt, IAX_ALREADYGONE);
03361 }
03362
03363 if ((c = pvt->owner)) {
03364 c->tech_pvt = NULL;
03365 iax2_queue_hangup(callno);
03366 pvt->owner = NULL;
03367 ast_module_unref(ast_module_info->self);
03368 }
03369
03370 return 0;
03371 }
03372
03373 static void iax2_destroy(int callno)
03374 {
03375 struct chan_iax2_pvt *pvt = NULL;
03376 struct ast_channel *owner = NULL;
03377
03378 retry:
03379 if ((pvt = iaxs[callno])) {
03380 #if 0
03381
03382
03383
03384
03385
03386
03387
03388 iax2_destroy_helper(pvt);
03389 #endif
03390 }
03391
03392 owner = pvt ? pvt->owner : NULL;
03393
03394 if (owner) {
03395 if (ast_channel_trylock(owner)) {
03396 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03397 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03398 goto retry;
03399 }
03400 }
03401
03402 if (!owner) {
03403 iaxs[callno] = NULL;
03404 }
03405
03406 if (pvt) {
03407 if (!owner) {
03408 pvt->owner = NULL;
03409 } else {
03410
03411
03412
03413 ast_queue_hangup(owner);
03414 }
03415
03416 if (pvt->peercallno) {
03417 remove_by_peercallno(pvt);
03418 }
03419
03420 if (pvt->transfercallno) {
03421 remove_by_transfercallno(pvt);
03422 }
03423
03424 if (!owner) {
03425 ao2_ref(pvt, -1);
03426 pvt = NULL;
03427 }
03428 }
03429
03430 if (owner) {
03431 ast_channel_unlock(owner);
03432 }
03433
03434 if (callno & 0x4000) {
03435 update_max_trunk();
03436 }
03437 }
03438
03439 static int update_packet(struct iax_frame *f)
03440 {
03441
03442 struct ast_iax2_full_hdr *fh = f->data;
03443 struct ast_frame af;
03444
03445
03446 if (f->encmethods) {
03447 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03448 }
03449
03450 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03451
03452 f->iseqno = iaxs[f->callno]->iseqno;
03453 fh->iseqno = f->iseqno;
03454
03455
03456 if (f->encmethods) {
03457
03458
03459 build_rand_pad(f->semirand, sizeof(f->semirand));
03460 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03461 }
03462 return 0;
03463 }
03464
03465 static int attempt_transmit(const void *data);
03466 static void __attempt_transmit(const void *data)
03467 {
03468
03469
03470 struct iax_frame *f = (struct iax_frame *)data;
03471 int freeme = 0;
03472 int callno = f->callno;
03473
03474 if (callno)
03475 ast_mutex_lock(&iaxsl[callno]);
03476 if (callno && iaxs[callno]) {
03477 if ((f->retries < 0) ||
03478 (f->retries >= max_retries) ) {
03479
03480 if (f->retries >= max_retries) {
03481 if (f->transfer) {
03482
03483 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03484 } else if (f->final) {
03485 iax2_destroy(callno);
03486 } else {
03487 if (iaxs[callno]->owner)
03488 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);
03489 iaxs[callno]->error = ETIMEDOUT;
03490 if (iaxs[callno]->owner) {
03491 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03492
03493 iax2_queue_frame(callno, &fr);
03494
03495 if (iaxs[callno] && iaxs[callno]->owner)
03496 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03497 } else {
03498 if (iaxs[callno]->reg) {
03499 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03500 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03501 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03502 }
03503 iax2_destroy(callno);
03504 }
03505 }
03506
03507 }
03508 freeme = 1;
03509 } else {
03510
03511 update_packet(f);
03512
03513 send_packet(f);
03514 f->retries++;
03515
03516 f->retrytime *= 10;
03517 if (f->retrytime > MAX_RETRY_TIME)
03518 f->retrytime = MAX_RETRY_TIME;
03519
03520 if (f->transfer && (f->retrytime > 1000))
03521 f->retrytime = 1000;
03522 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03523 }
03524 } else {
03525
03526 f->retries = -1;
03527 freeme = 1;
03528 }
03529
03530 if (freeme) {
03531
03532 AST_LIST_REMOVE(&frame_queue[callno], f, list);
03533 ast_mutex_unlock(&iaxsl[callno]);
03534 f->retrans = -1;
03535
03536 iax2_frame_free(f);
03537 } else if (callno) {
03538 ast_mutex_unlock(&iaxsl[callno]);
03539 }
03540 }
03541
03542 static int attempt_transmit(const void *data)
03543 {
03544 #ifdef SCHED_MULTITHREADED
03545 if (schedule_action(__attempt_transmit, data))
03546 #endif
03547 __attempt_transmit(data);
03548 return 0;
03549 }
03550
03551 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03552 {
03553 struct iax2_peer *peer = NULL;
03554 struct iax2_user *user = NULL;
03555 static const char * const choices[] = { "all", NULL };
03556 char *cmplt;
03557
03558 switch (cmd) {
03559 case CLI_INIT:
03560 e->command = "iax2 prune realtime";
03561 e->usage =
03562 "Usage: iax2 prune realtime [<peername>|all]\n"
03563 " Prunes object(s) from the cache\n";
03564 return NULL;
03565 case CLI_GENERATE:
03566 if (a->pos == 3) {
03567 cmplt = ast_cli_complete(a->word, choices, a->n);
03568 if (!cmplt)
03569 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03570 return cmplt;
03571 }
03572 return NULL;
03573 }
03574 if (a->argc != 4)
03575 return CLI_SHOWUSAGE;
03576 if (!strcmp(a->argv[3], "all")) {
03577 prune_users();
03578 prune_peers();
03579 ast_cli(a->fd, "Cache flushed successfully.\n");
03580 return CLI_SUCCESS;
03581 }
03582 peer = find_peer(a->argv[3], 0);
03583 user = find_user(a->argv[3]);
03584 if (peer || user) {
03585 if (peer) {
03586 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03587 ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03588 expire_registry(peer_ref(peer));
03589 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03590 } else {
03591 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03592 }
03593 peer_unref(peer);
03594 }
03595 if (user) {
03596 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03597 ast_set_flag64(user, IAX_RTAUTOCLEAR);
03598 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03599 } else {
03600 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03601 }
03602 ao2_unlink(users,user);
03603 user_unref(user);
03604 }
03605 } else {
03606 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03607 }
03608
03609 return CLI_SUCCESS;
03610 }
03611
03612 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03613 {
03614 switch (cmd) {
03615 case CLI_INIT:
03616 e->command = "iax2 test losspct";
03617 e->usage =
03618 "Usage: iax2 test losspct <percentage>\n"
03619 " For testing, throws away <percentage> percent of incoming packets\n";
03620 return NULL;
03621 case CLI_GENERATE:
03622 return NULL;
03623 }
03624 if (a->argc != 4)
03625 return CLI_SHOWUSAGE;
03626
03627 test_losspct = atoi(a->argv[3]);
03628
03629 return CLI_SUCCESS;
03630 }
03631
03632 #ifdef IAXTESTS
03633 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03634 {
03635 switch (cmd) {
03636 case CLI_INIT:
03637 e->command = "iax2 test late";
03638 e->usage =
03639 "Usage: iax2 test late <ms>\n"
03640 " For testing, count the next frame as <ms> ms late\n";
03641 return NULL;
03642 case CLI_GENERATE:
03643 return NULL;
03644 }
03645
03646 if (a->argc != 4)
03647 return CLI_SHOWUSAGE;
03648
03649 test_late = atoi(a->argv[3]);
03650
03651 return CLI_SUCCESS;
03652 }
03653
03654 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03655 {
03656 switch (cmd) {
03657 case CLI_INIT:
03658 e->command = "iax2 test resync";
03659 e->usage =
03660 "Usage: iax2 test resync <ms>\n"
03661 " For testing, adjust all future frames by <ms> ms\n";
03662 return NULL;
03663 case CLI_GENERATE:
03664 return NULL;
03665 }
03666
03667 if (a->argc != 4)
03668 return CLI_SHOWUSAGE;
03669
03670 test_resync = atoi(a->argv[3]);
03671
03672 return CLI_SUCCESS;
03673 }
03674
03675 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03676 {
03677 switch (cmd) {
03678 case CLI_INIT:
03679 e->command = "iax2 test jitter";
03680 e->usage =
03681 "Usage: iax2 test jitter <ms> <pct>\n"
03682 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03683 " percentage of packets. If <pct> is not specified, adds\n"
03684 " jitter to all packets.\n";
03685 return NULL;
03686 case CLI_GENERATE:
03687 return NULL;
03688 }
03689
03690 if (a->argc < 4 || a->argc > 5)
03691 return CLI_SHOWUSAGE;
03692
03693 test_jit = atoi(a->argv[3]);
03694 if (a->argc == 5)
03695 test_jitpct = atoi(a->argv[4]);
03696
03697 return CLI_SUCCESS;
03698 }
03699 #endif
03700
03701
03702
03703 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03704 {
03705 int res = 0;
03706 if (peer->maxms) {
03707 if (peer->lastms < 0) {
03708 ast_copy_string(status, "UNREACHABLE", statuslen);
03709 } else if (peer->lastms > peer->maxms) {
03710 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03711 res = 1;
03712 } else if (peer->lastms) {
03713 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03714 res = 1;
03715 } else {
03716 ast_copy_string(status, "UNKNOWN", statuslen);
03717 }
03718 } else {
03719 ast_copy_string(status, "Unmonitored", statuslen);
03720 res = -1;
03721 }
03722 return res;
03723 }
03724
03725
03726 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03727 {
03728 char status[30];
03729 char cbuf[256];
03730 struct iax2_peer *peer;
03731 char codec_buf[512];
03732 struct ast_str *encmethods = ast_str_alloca(256);
03733 int x = 0, codec = 0, load_realtime = 0;
03734
03735 switch (cmd) {
03736 case CLI_INIT:
03737 e->command = "iax2 show peer";
03738 e->usage =
03739 "Usage: iax2 show peer <name>\n"
03740 " Display details on specific IAX peer\n";
03741 return NULL;
03742 case CLI_GENERATE:
03743 if (a->pos == 3)
03744 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03745 return NULL;
03746 }
03747
03748 if (a->argc < 4)
03749 return CLI_SHOWUSAGE;
03750
03751 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03752
03753 peer = find_peer(a->argv[3], load_realtime);
03754 if (peer) {
03755 struct sockaddr_in peer_addr;
03756
03757 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03758
03759 encmethods_to_str(peer->encmethods, encmethods);
03760 ast_cli(a->fd, "\n\n");
03761 ast_cli(a->fd, " * Name : %s\n", peer->name);
03762 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03763 ast_cli(a->fd, " Context : %s\n", peer->context);
03764 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03765 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03766 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03767 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03768 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03769 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03770 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03771 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03772 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03773 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03774 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));
03775 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03776 ast_cli(a->fd, " Username : %s\n", peer->username);
03777 ast_cli(a->fd, " Codecs : ");
03778 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03779 ast_cli(a->fd, "%s\n", codec_buf);
03780
03781 ast_cli(a->fd, " Codec Order : (");
03782 for(x = 0; x < 32 ; x++) {
03783 codec = ast_codec_pref_index(&peer->prefs,x);
03784 if(!codec)
03785 break;
03786 ast_cli(a->fd, "%s", ast_getformatname(codec));
03787 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03788 ast_cli(a->fd, "|");
03789 }
03790
03791 if (!x)
03792 ast_cli(a->fd, "none");
03793 ast_cli(a->fd, ")\n");
03794
03795 ast_cli(a->fd, " Status : ");
03796 peer_status(peer, status, sizeof(status));
03797 ast_cli(a->fd, "%s\n",status);
03798 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");
03799 ast_cli(a->fd, "\n");
03800 peer_unref(peer);
03801 } else {
03802 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03803 ast_cli(a->fd, "\n");
03804 }
03805
03806 return CLI_SUCCESS;
03807 }
03808
03809 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
03810 {
03811 int which = 0;
03812 struct iax2_peer *peer;
03813 char *res = NULL;
03814 int wordlen = strlen(word);
03815 struct ao2_iterator i;
03816
03817 i = ao2_iterator_init(peers, 0);
03818 while ((peer = ao2_iterator_next(&i))) {
03819 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03820 && (!flags || ast_test_flag64(peer, flags))) {
03821 res = ast_strdup(peer->name);
03822 peer_unref(peer);
03823 break;
03824 }
03825 peer_unref(peer);
03826 }
03827 ao2_iterator_destroy(&i);
03828
03829 return res;
03830 }
03831
03832 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03833 {
03834 struct iax_frame *cur;
03835 int cnt = 0, dead = 0, final = 0, i = 0;
03836
03837 switch (cmd) {
03838 case CLI_INIT:
03839 e->command = "iax2 show stats";
03840 e->usage =
03841 "Usage: iax2 show stats\n"
03842 " Display statistics on IAX channel driver.\n";
03843 return NULL;
03844 case CLI_GENERATE:
03845 return NULL;
03846 }
03847
03848 if (a->argc != 3)
03849 return CLI_SHOWUSAGE;
03850
03851 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03852 ast_mutex_lock(&iaxsl[i]);
03853 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03854 if (cur->retries < 0)
03855 dead++;
03856 if (cur->final)
03857 final++;
03858 cnt++;
03859 }
03860 ast_mutex_unlock(&iaxsl[i]);
03861 }
03862
03863 ast_cli(a->fd, " IAX Statistics\n");
03864 ast_cli(a->fd, "---------------------\n");
03865 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03866 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03867 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03868 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03869
03870 trunk_timed = trunk_untimed = 0;
03871 if (trunk_maxmtu > trunk_nmaxmtu)
03872 trunk_nmaxmtu = trunk_maxmtu;
03873
03874 return CLI_SUCCESS;
03875 }
03876
03877
03878 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03879 {
03880 int mtuv;
03881
03882 switch (cmd) {
03883 case CLI_INIT:
03884 e->command = "iax2 set mtu";
03885 e->usage =
03886 "Usage: iax2 set mtu <value>\n"
03887 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03888 " zero to disable. Disabling means that the operating system\n"
03889 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03890 " packet exceeds the UDP payload size. This is substantially\n"
03891 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03892 " greater for G.711 samples.\n";
03893 return NULL;
03894 case CLI_GENERATE:
03895 return NULL;
03896 }
03897
03898 if (a->argc != 4)
03899 return CLI_SHOWUSAGE;
03900 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03901 mtuv = MAX_TRUNK_MTU;
03902 else
03903 mtuv = atoi(a->argv[3]);
03904
03905 if (mtuv == 0) {
03906 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03907 global_max_trunk_mtu = 0;
03908 return CLI_SUCCESS;
03909 }
03910 if (mtuv < 172 || mtuv > 4000) {
03911 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03912 return CLI_SHOWUSAGE;
03913 }
03914 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03915 global_max_trunk_mtu = mtuv;
03916 return CLI_SUCCESS;
03917 }
03918
03919 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03920 {
03921 struct iax2_dpcache *dp = NULL;
03922 char tmp[1024], *pc = NULL;
03923 int s, x, y;
03924 struct timeval now = ast_tvnow();
03925
03926 switch (cmd) {
03927 case CLI_INIT:
03928 e->command = "iax2 show cache";
03929 e->usage =
03930 "Usage: iax2 show cache\n"
03931 " Display currently cached IAX Dialplan results.\n";
03932 return NULL;
03933 case CLI_GENERATE:
03934 return NULL;
03935 }
03936
03937 AST_LIST_LOCK(&dpcache);
03938
03939 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03940
03941 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03942 s = dp->expiry.tv_sec - now.tv_sec;
03943 tmp[0] = '\0';
03944 if (dp->flags & CACHE_FLAG_EXISTS)
03945 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03946 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03947 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03948 if (dp->flags & CACHE_FLAG_CANEXIST)
03949 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03950 if (dp->flags & CACHE_FLAG_PENDING)
03951 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03952 if (dp->flags & CACHE_FLAG_TIMEOUT)
03953 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03954 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03955 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03956 if (dp->flags & CACHE_FLAG_MATCHMORE)
03957 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03958 if (dp->flags & CACHE_FLAG_UNKNOWN)
03959 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03960
03961 if (!ast_strlen_zero(tmp)) {
03962 tmp[strlen(tmp) - 1] = '\0';
03963 } else {
03964 ast_copy_string(tmp, "(none)", sizeof(tmp));
03965 }
03966 y = 0;
03967 pc = strchr(dp->peercontext, '@');
03968 if (!pc) {
03969 pc = dp->peercontext;
03970 } else {
03971 pc++;
03972 }
03973 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03974 if (dp->waiters[x] > -1)
03975 y++;
03976 }
03977 if (s > 0) {
03978 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03979 } else {
03980 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03981 }
03982 }
03983
03984 AST_LIST_UNLOCK(&dpcache);
03985
03986 return CLI_SUCCESS;
03987 }
03988
03989 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03990
03991 static void unwrap_timestamp(struct iax_frame *fr)
03992 {
03993
03994
03995 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03996 const int lower_mask = (1 << ts_shift) - 1;
03997 const int upper_mask = ~lower_mask;
03998 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03999
04000 if ( (fr->ts & upper_mask) == last_upper ) {
04001 const int x = fr->ts - iaxs[fr->callno]->last;
04002 const int threshold = (ts_shift == 15) ? 25000 : 50000;
04003
04004 if (x < -threshold) {
04005
04006
04007
04008
04009 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04010 if (iaxdebug)
04011 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04012 } else if (x > threshold) {
04013
04014
04015
04016
04017 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04018 if (iaxdebug)
04019 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04020 }
04021 }
04022 }
04023
04024 static int get_from_jb(const void *p);
04025
04026 static void update_jbsched(struct chan_iax2_pvt *pvt)
04027 {
04028 int when;
04029
04030 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04031
04032 when = jb_next(pvt->jb) - when;
04033
04034 if (when <= 0) {
04035
04036 when = 1;
04037 }
04038
04039 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
04040 CALLNO_TO_PTR(pvt->callno));
04041 }
04042
04043 static void __get_from_jb(const void *p)
04044 {
04045 int callno = PTR_TO_CALLNO(p);
04046 struct chan_iax2_pvt *pvt = NULL;
04047 struct iax_frame *fr;
04048 jb_frame frame;
04049 int ret;
04050 long ms;
04051 long next;
04052 struct timeval now = ast_tvnow();
04053
04054
04055 ast_mutex_lock(&iaxsl[callno]);
04056 pvt = iaxs[callno];
04057 if (!pvt) {
04058
04059 ast_mutex_unlock(&iaxsl[callno]);
04060 return;
04061 }
04062
04063 pvt->jbid = -1;
04064
04065
04066
04067
04068 now.tv_usec += 1000;
04069
04070 ms = ast_tvdiff_ms(now, pvt->rxcore);
04071
04072 if(ms >= (next = jb_next(pvt->jb))) {
04073 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04074 switch(ret) {
04075 case JB_OK:
04076 fr = frame.data;
04077 __do_deliver(fr);
04078
04079 pvt = iaxs[callno];
04080 break;
04081 case JB_INTERP:
04082 {
04083 struct ast_frame af = { 0, };
04084
04085
04086 af.frametype = AST_FRAME_VOICE;
04087 af.subclass.codec = pvt->voiceformat;
04088 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04089 af.src = "IAX2 JB interpolation";
04090 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04091 af.offset = AST_FRIENDLY_OFFSET;
04092
04093
04094
04095 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04096 iax2_queue_frame(callno, &af);
04097
04098 pvt = iaxs[callno];
04099 }
04100 }
04101 break;
04102 case JB_DROP:
04103 iax2_frame_free(frame.data);
04104 break;
04105 case JB_NOFRAME:
04106 case JB_EMPTY:
04107
04108 break;
04109 default:
04110
04111 break;
04112 }
04113 }
04114 if (pvt)
04115 update_jbsched(pvt);
04116 ast_mutex_unlock(&iaxsl[callno]);
04117 }
04118
04119 static int get_from_jb(const void *data)
04120 {
04121 #ifdef SCHED_MULTITHREADED
04122 if (schedule_action(__get_from_jb, data))
04123 #endif
04124 __get_from_jb(data);
04125 return 0;
04126 }
04127
04128
04129
04130
04131
04132
04133
04134 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
04135 {
04136 int type, len;
04137 int ret;
04138 int needfree = 0;
04139 struct ast_channel *owner = NULL;
04140 struct ast_channel *bridge = NULL;
04141
04142
04143 unwrap_timestamp(fr);
04144
04145
04146 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04147 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04148 else {
04149 #if 0
04150 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04151 #endif
04152 fr->af.delivery = ast_tv(0,0);
04153 }
04154
04155 type = JB_TYPE_CONTROL;
04156 len = 0;
04157
04158 if(fr->af.frametype == AST_FRAME_VOICE) {
04159 type = JB_TYPE_VOICE;
04160 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04161 } else if(fr->af.frametype == AST_FRAME_CNG) {
04162 type = JB_TYPE_SILENCE;
04163 }
04164
04165 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04166 if (tsout)
04167 *tsout = fr->ts;
04168 __do_deliver(fr);
04169 return -1;
04170 }
04171
04172 iax2_lock_owner(fr->callno);
04173 if (!iaxs[fr->callno]) {
04174
04175 iax2_frame_free(fr);
04176 return -1;
04177 }
04178 if ((owner = iaxs[fr->callno]->owner))
04179 bridge = ast_bridged_channel(owner);
04180
04181
04182
04183 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04184 jb_frame frame;
04185
04186 ast_channel_unlock(owner);
04187
04188
04189 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04190 __do_deliver(frame.data);
04191
04192 if (!iaxs[fr->callno])
04193 return -1;
04194 }
04195
04196 jb_reset(iaxs[fr->callno]->jb);
04197
04198 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04199
04200
04201 if (tsout)
04202 *tsout = fr->ts;
04203 __do_deliver(fr);
04204 return -1;
04205 }
04206 if (owner) {
04207 ast_channel_unlock(owner);
04208 }
04209
04210
04211
04212 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04213 calc_rxstamp(iaxs[fr->callno],fr->ts));
04214 if (ret == JB_DROP) {
04215 needfree++;
04216 } else if (ret == JB_SCHED) {
04217 update_jbsched(iaxs[fr->callno]);
04218 }
04219 if (tsout)
04220 *tsout = fr->ts;
04221 if (needfree) {
04222
04223 iax2_frame_free(fr);
04224 return -1;
04225 }
04226 return 0;
04227 }
04228
04229 static int transmit_frame(void *data)
04230 {
04231 struct iax_frame *fr = data;
04232
04233 ast_mutex_lock(&iaxsl[fr->callno]);
04234
04235 fr->sentyet = 1;
04236
04237 if (iaxs[fr->callno]) {
04238 send_packet(fr);
04239 }
04240
04241 if (fr->retries < 0) {
04242 ast_mutex_unlock(&iaxsl[fr->callno]);
04243
04244 iax_frame_free(fr);
04245 } else {
04246
04247 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04248 fr->retries++;
04249 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04250 ast_mutex_unlock(&iaxsl[fr->callno]);
04251 }
04252
04253 return 0;
04254 }
04255
04256 static int iax2_transmit(struct iax_frame *fr)
04257 {
04258 fr->sentyet = 0;
04259
04260 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04261 }
04262
04263 static int iax2_digit_begin(struct ast_channel *c, char digit)
04264 {
04265 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04266 }
04267
04268 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04269 {
04270 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04271 }
04272
04273 static int iax2_sendtext(struct ast_channel *c, const char *text)
04274 {
04275
04276 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04277 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04278 }
04279
04280 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04281 {
04282 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04283 }
04284
04285 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04286 {
04287 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04288 }
04289
04290 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04291 {
04292 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04293 ast_mutex_lock(&iaxsl[callno]);
04294 if (iaxs[callno])
04295 iaxs[callno]->owner = newchan;
04296 else
04297 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04298 ast_mutex_unlock(&iaxsl[callno]);
04299 return 0;
04300 }
04301
04302
04303
04304
04305
04306 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04307 {
04308 struct ast_variable *var = NULL;
04309 struct ast_variable *tmp;
04310 struct iax2_peer *peer=NULL;
04311 time_t regseconds = 0, nowtime;
04312 int dynamic=0;
04313
04314 if (peername) {
04315 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04316 if (!var && sin)
04317 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04318 } else if (sin) {
04319 char porta[25];
04320 sprintf(porta, "%d", ntohs(sin->sin_port));
04321 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04322 if (var) {
04323
04324 for (tmp = var; tmp; tmp = tmp->next) {
04325 if (!strcasecmp(tmp->name, "name"))
04326 peername = tmp->value;
04327 }
04328 }
04329 }
04330 if (!var && peername) {
04331 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04332
04333
04334
04335
04336
04337
04338 if (var && sin) {
04339 for (tmp = var; tmp; tmp = tmp->next) {
04340 if (!strcasecmp(tmp->name, "host")) {
04341 struct ast_hostent ahp;
04342 struct hostent *hp;
04343 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04344
04345 ast_variables_destroy(var);
04346 var = NULL;
04347 }
04348 break;
04349 }
04350 }
04351 }
04352 }
04353 if (!var)
04354 return NULL;
04355
04356 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04357
04358 if (!peer) {
04359 ast_variables_destroy(var);
04360 return NULL;
04361 }
04362
04363 for (tmp = var; tmp; tmp = tmp->next) {
04364
04365 if (!strcasecmp(tmp->name, "type")) {
04366 if (strcasecmp(tmp->value, "friend") &&
04367 strcasecmp(tmp->value, "peer")) {
04368
04369 peer = peer_unref(peer);
04370 break;
04371 }
04372 } else if (!strcasecmp(tmp->name, "regseconds")) {
04373 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04374 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04375 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE);
04376 } else if (!strcasecmp(tmp->name, "port")) {
04377 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04378 } else if (!strcasecmp(tmp->name, "host")) {
04379 if (!strcasecmp(tmp->value, "dynamic"))
04380 dynamic = 1;
04381 }
04382 }
04383
04384 ast_variables_destroy(var);
04385
04386 if (!peer)
04387 return NULL;
04388
04389 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04390 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04391 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04392 if (peer->expire > -1) {
04393 if (!ast_sched_thread_del(sched, peer->expire)) {
04394 peer->expire = -1;
04395 peer_unref(peer);
04396 }
04397 }
04398 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04399 if (peer->expire == -1)
04400 peer_unref(peer);
04401 }
04402 ao2_link(peers, peer);
04403 if (ast_test_flag64(peer, IAX_DYNAMIC))
04404 reg_source_db(peer);
04405 } else {
04406 ast_set_flag64(peer, IAX_TEMPONLY);
04407 }
04408
04409 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04410 time(&nowtime);
04411 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04412 memset(&peer->addr, 0, sizeof(peer->addr));
04413 realtime_update_peer(peer->name, &peer->addr, 0);
04414 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04415 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04416 }
04417 else {
04418 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04419 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04420 }
04421 }
04422
04423 return peer;
04424 }
04425
04426 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04427 {
04428 struct ast_variable *var;
04429 struct ast_variable *tmp;
04430 struct iax2_user *user=NULL;
04431
04432 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04433 if (!var)
04434 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04435 if (!var && sin) {
04436 char porta[6];
04437 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04438 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04439 if (!var)
04440 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04441 }
04442 if (!var) {
04443 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04444
04445
04446
04447
04448
04449
04450 if (var) {
04451 for (tmp = var; tmp; tmp = tmp->next) {
04452 if (!strcasecmp(tmp->name, "host")) {
04453 struct ast_hostent ahp;
04454 struct hostent *hp;
04455 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04456
04457 ast_variables_destroy(var);
04458 var = NULL;
04459 }
04460 break;
04461 }
04462 }
04463 }
04464 }
04465 if (!var)
04466 return NULL;
04467
04468 tmp = var;
04469 while(tmp) {
04470
04471 if (!strcasecmp(tmp->name, "type")) {
04472 if (strcasecmp(tmp->value, "friend") &&
04473 strcasecmp(tmp->value, "user")) {
04474 return NULL;
04475 }
04476 }
04477 tmp = tmp->next;
04478 }
04479
04480 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04481
04482 ast_variables_destroy(var);
04483
04484 if (!user)
04485 return NULL;
04486
04487 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04488 ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04489 ao2_link(users, user);
04490 } else {
04491 ast_set_flag64(user, IAX_TEMPONLY);
04492 }
04493
04494 return user;
04495 }
04496
04497 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
04498 {
04499 char port[10];
04500 char regseconds[20];
04501 const char *sysname = ast_config_AST_SYSTEM_NAME;
04502 char *syslabel = NULL;
04503
04504 if (ast_strlen_zero(sysname))
04505 sysname = NULL;
04506 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04507 syslabel = "regserver";
04508
04509 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04510 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04511 ast_update_realtime("iaxpeers", "name", peername,
04512 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port,
04513 "regseconds", regseconds, syslabel, sysname, SENTINEL);
04514 }
04515
04516 struct create_addr_info {
04517 format_t capability;
04518 uint64_t flags;
04519 int maxtime;
04520 int encmethods;
04521 int found;
04522 int sockfd;
04523 int adsi;
04524 char username[80];
04525 char secret[80];
04526 char outkey[80];
04527 char timezone[80];
04528 char prefs[32];
04529 char cid_num[80];
04530 char cid_name[80];
04531 char context[AST_MAX_CONTEXT];
04532 char peercontext[AST_MAX_CONTEXT];
04533 char mohinterpret[MAX_MUSICCLASS];
04534 char mohsuggest[MAX_MUSICCLASS];
04535 };
04536
04537 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04538 {
04539 struct iax2_peer *peer;
04540 int res = -1;
04541 struct ast_codec_pref ourprefs;
04542 struct sockaddr_in peer_addr;
04543
04544 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04545 cai->sockfd = defaultsockfd;
04546 cai->maxtime = 0;
04547 sin->sin_family = AF_INET;
04548
04549 if (!(peer = find_peer(peername, 1))) {
04550 struct ast_sockaddr sin_tmp;
04551
04552 cai->found = 0;
04553 sin_tmp.ss.ss_family = AF_INET;
04554 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04555 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04556 return -1;
04557 }
04558 ast_sockaddr_to_sin(&sin_tmp, sin);
04559 if (sin->sin_port == 0) {
04560 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04561 }
04562
04563
04564 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04565 if (c)
04566 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04567 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04568 return 0;
04569 }
04570
04571 cai->found = 1;
04572
04573 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04574
04575
04576 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04577 goto return_unref;
04578 }
04579
04580
04581 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04582 goto return_unref;
04583
04584 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04585 cai->maxtime = peer->maxms;
04586 cai->capability = peer->capability;
04587 cai->encmethods = peer->encmethods;
04588 cai->sockfd = peer->sockfd;
04589 cai->adsi = peer->adsi;
04590 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04591
04592 if (c) {
04593 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04594 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04595 }
04596 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04597 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04598 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04599 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04600 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04601 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04602 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04603 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04604 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04605 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04606 if (ast_strlen_zero(peer->dbsecret)) {
04607 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04608 } else {
04609 char *family;
04610 char *key = NULL;
04611
04612 family = ast_strdupa(peer->dbsecret);
04613 key = strchr(family, '/');
04614 if (key)
04615 *key++ = '\0';
04616 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04617 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04618 goto return_unref;
04619 }
04620 }
04621
04622 if (peer_addr.sin_addr.s_addr) {
04623 sin->sin_addr = peer_addr.sin_addr;
04624 sin->sin_port = peer_addr.sin_port;
04625 } else {
04626 sin->sin_addr = peer->defaddr.sin_addr;
04627 sin->sin_port = peer->defaddr.sin_port;
04628 }
04629
04630 res = 0;
04631
04632 return_unref:
04633 peer_unref(peer);
04634
04635 return res;
04636 }
04637
04638 static void __auto_congest(const void *nothing)
04639 {
04640 int callno = PTR_TO_CALLNO(nothing);
04641 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04642 ast_mutex_lock(&iaxsl[callno]);
04643 if (iaxs[callno]) {
04644 iaxs[callno]->initid = -1;
04645 iax2_queue_frame(callno, &f);
04646 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04647 }
04648 ast_mutex_unlock(&iaxsl[callno]);
04649 }
04650
04651 static int auto_congest(const void *data)
04652 {
04653 #ifdef SCHED_MULTITHREADED
04654 if (schedule_action(__auto_congest, data))
04655 #endif
04656 __auto_congest(data);
04657 return 0;
04658 }
04659
04660 static unsigned int iax2_datetime(const char *tz)
04661 {
04662 struct timeval t = ast_tvnow();
04663 struct ast_tm tm;
04664 unsigned int tmp;
04665 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04666 tmp = (tm.tm_sec >> 1) & 0x1f;
04667 tmp |= (tm.tm_min & 0x3f) << 5;
04668 tmp |= (tm.tm_hour & 0x1f) << 11;
04669 tmp |= (tm.tm_mday & 0x1f) << 16;
04670 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04671 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04672 return tmp;
04673 }
04674
04675 struct parsed_dial_string {
04676 char *username;
04677 char *password;
04678 char *key;
04679 char *peer;
04680 char *port;
04681 char *exten;
04682 char *context;
04683 char *options;
04684 };
04685
04686 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04687 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04688 int sockfd, struct iax_ie_data *ied)
04689 {
04690 struct {
04691 struct ast_iax2_full_hdr f;
04692 struct iax_ie_data ied;
04693 } data;
04694 size_t size = sizeof(struct ast_iax2_full_hdr);
04695
04696 if (ied) {
04697 size += ied->pos;
04698 memcpy(&data.ied, ied->buf, ied->pos);
04699 }
04700
04701 data.f.scallno = htons(0x8000 | callno);
04702 data.f.dcallno = htons(dcallno);
04703 data.f.ts = htonl(ts);
04704 data.f.iseqno = seqno;
04705 data.f.oseqno = 0;
04706 data.f.type = AST_FRAME_IAX;
04707 data.f.csub = compress_subclass(command);
04708
04709 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04710 }
04711
04712 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04713 {
04714
04715 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04716 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04717 ied->buf[ied->pos++] = 0;
04718 pvt->calltoken_ie_len = 2;
04719 }
04720 }
04721
04722 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04723 {
04724 struct chan_iax2_pvt *pvt = iaxs[callno];
04725 int frametype = f->af.frametype;
04726 int subclass = f->af.subclass.integer;
04727 struct {
04728 struct ast_iax2_full_hdr fh;
04729 struct iax_ie_data ied;
04730 } data = {
04731 .ied.buf = { 0 },
04732 .ied.pos = 0,
04733 };
04734
04735 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04736
04737 if (!pvt) {
04738 return;
04739 }
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04753 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04754 (f->datalen > sizeof(data))) {
04755
04756 return;
04757 }
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772
04773 memcpy(&data, f->data, f->datalen);
04774 data.ied.pos = ie_data_pos;
04775
04776
04777
04778 data.ied.pos -= pvt->calltoken_ie_len;
04779 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04780
04781
04782 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04783
04784
04785 AST_LIST_REMOVE(&frame_queue[callno], f, list);
04786
04787
04788 iax2_frame_free(f);
04789
04790
04791 pvt->oseqno = 0;
04792 pvt->rseqno = 0;
04793 pvt->iseqno = 0;
04794 pvt->aseqno = 0;
04795 if (pvt->peercallno) {
04796 remove_by_peercallno(pvt);
04797 pvt->peercallno = 0;
04798 }
04799
04800
04801 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04802 }
04803
04804 static void requirecalltoken_mark_auto(const char *name, int subclass)
04805 {
04806 struct iax2_user *user = NULL;
04807 struct iax2_peer *peer = NULL;
04808
04809 if (ast_strlen_zero(name)) {
04810 return;
04811 }
04812
04813 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04814 user->calltoken_required = CALLTOKEN_YES;
04815 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04816 peer->calltoken_required = CALLTOKEN_YES;
04817 }
04818
04819 if (peer) {
04820 peer_unref(peer);
04821 }
04822 if (user) {
04823 user_unref(user);
04824 }
04825 }
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843
04844 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04845 struct sockaddr_in *sin, int fd)
04846 {
04847 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04848 #define CALLTOKEN_IE_FORMAT "%u?%s"
04849 struct ast_str *buf = ast_str_alloca(256);
04850 time_t t = time(NULL);
04851 char hash[41];
04852 int subclass = uncompress_subclass(fh->csub);
04853
04854
04855 if (ies->calltoken && !ies->calltokendata) {
04856 struct iax_ie_data ied = {
04857 .buf = { 0 },
04858 .pos = 0,
04859 };
04860
04861
04862 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04863 ast_sha1_hash(hash, ast_str_buffer(buf));
04864
04865 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04866 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04867 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04868
04869 return 1;
04870
04871
04872 } else if (ies->calltoken && ies->calltokendata) {
04873 char *rec_hash = NULL;
04874 char *rec_ts = NULL;
04875 unsigned int rec_time;
04876
04877
04878 rec_hash = strchr((char *) ies->calltokendata, '?');
04879 if (rec_hash) {
04880 *rec_hash++ = '\0';
04881 rec_ts = (char *) ies->calltokendata;
04882 }
04883
04884
04885 if (!rec_hash || !rec_ts) {
04886 goto reject;
04887 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04888 goto reject;
04889 }
04890
04891
04892 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04893 ast_sha1_hash(hash, ast_str_buffer(buf));
04894
04895
04896 if (strcmp(hash, rec_hash)) {
04897 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04898 goto reject;
04899 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04900 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04901 goto reject;
04902 }
04903
04904
04905
04906 requirecalltoken_mark_auto(ies->username, subclass);
04907 return 0;
04908
04909
04910 } else {
04911 if (calltoken_required(sin, ies->username, subclass)) {
04912 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"));
04913 goto reject;
04914 }
04915 return 0;
04916 }
04917
04918 reject:
04919
04920 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04921 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04922 } else {
04923 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04924 }
04925
04926 return 1;
04927 }
04928
04929
04930
04931
04932
04933
04934
04935
04936
04937
04938
04939
04940
04941
04942
04943
04944
04945
04946
04947 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04948 {
04949 if (ast_strlen_zero(data))
04950 return;
04951
04952 pds->peer = strsep(&data, "/");
04953 pds->exten = strsep(&data, "/");
04954 pds->options = data;
04955
04956 if (pds->exten) {
04957 data = pds->exten;
04958 pds->exten = strsep(&data, "@");
04959 pds->context = data;
04960 }
04961
04962 if (strchr(pds->peer, '@')) {
04963 data = pds->peer;
04964 pds->username = strsep(&data, "@");
04965 pds->peer = data;
04966 }
04967
04968 if (pds->username) {
04969 data = pds->username;
04970 pds->username = strsep(&data, ":");
04971 pds->password = data;
04972 }
04973
04974 data = pds->peer;
04975 pds->peer = strsep(&data, ":");
04976 pds->port = data;
04977
04978
04979
04980
04981 if (pds->password && (pds->password[0] == '[')) {
04982 pds->key = ast_strip_quoted(pds->password, "[", "]");
04983 pds->password = NULL;
04984 }
04985 }
04986
04987 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04988 {
04989 struct sockaddr_in sin;
04990 char *l=NULL, *n=NULL, *tmpstr;
04991 struct iax_ie_data ied;
04992 char *defaultrdest = "s";
04993 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04994 struct parsed_dial_string pds;
04995 struct create_addr_info cai;
04996 struct ast_var_t *var;
04997 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04998 const char* osp_token_ptr;
04999 unsigned int osp_token_length;
05000 unsigned char osp_block_index;
05001 unsigned int osp_block_length;
05002 unsigned char osp_buffer[256];
05003
05004 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05005 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
05006 return -1;
05007 }
05008
05009 memset(&cai, 0, sizeof(cai));
05010 cai.encmethods = iax2_encryption;
05011
05012 memset(&pds, 0, sizeof(pds));
05013 tmpstr = ast_strdupa(dest);
05014 parse_dial_string(tmpstr, &pds);
05015
05016 if (ast_strlen_zero(pds.peer)) {
05017 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05018 return -1;
05019 }
05020 if (!pds.exten) {
05021 pds.exten = defaultrdest;
05022 }
05023 if (create_addr(pds.peer, c, &sin, &cai)) {
05024 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05025 return -1;
05026 }
05027 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05028 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05029 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05030 return -1;
05031 }
05032 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05033 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05034 return -1;
05035 }
05036 if (!pds.username && !ast_strlen_zero(cai.username))
05037 pds.username = cai.username;
05038 if (!pds.password && !ast_strlen_zero(cai.secret))
05039 pds.password = cai.secret;
05040 if (!pds.key && !ast_strlen_zero(cai.outkey))
05041 pds.key = cai.outkey;
05042 if (!pds.context && !ast_strlen_zero(cai.peercontext))
05043 pds.context = cai.peercontext;
05044
05045
05046 ast_copy_string(c->context, cai.context, sizeof(c->context));
05047
05048 if (pds.port)
05049 sin.sin_port = htons(atoi(pds.port));
05050
05051 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05052 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05053
05054
05055 memset(&ied, 0, sizeof(ied));
05056
05057
05058 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05059 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05060 if (pds.options && strchr(pds.options, 'a')) {
05061
05062 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05063 }
05064
05065
05066 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05067
05068 if (l) {
05069 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05070 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05071 ast_party_id_presentation(&c->connected.id));
05072 } else if (n) {
05073 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05074 ast_party_id_presentation(&c->connected.id));
05075 } else {
05076 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05077 }
05078
05079 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05080 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05081
05082 if (n)
05083 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05084 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05085 && c->connected.ani.number.valid
05086 && c->connected.ani.number.str) {
05087 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05088 }
05089
05090 if (!ast_strlen_zero(c->language))
05091 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
05092 if (!ast_strlen_zero(c->dialed.number.str)) {
05093 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05094 }
05095 if (c->redirecting.from.number.valid
05096 && !ast_strlen_zero(c->redirecting.from.number.str)) {
05097 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05098 }
05099
05100 if (pds.context)
05101 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05102
05103 if (pds.username)
05104 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05105
05106 if (cai.encmethods)
05107 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05108
05109 ast_mutex_lock(&iaxsl[callno]);
05110
05111 if (!ast_strlen_zero(c->context))
05112 ast_string_field_set(iaxs[callno], context, c->context);
05113
05114 if (pds.username)
05115 ast_string_field_set(iaxs[callno], username, pds.username);
05116
05117 iaxs[callno]->encmethods = cai.encmethods;
05118
05119 iaxs[callno]->adsi = cai.adsi;
05120
05121 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05122 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05123
05124 if (pds.key)
05125 ast_string_field_set(iaxs[callno], outkey, pds.key);
05126 if (pds.password)
05127 ast_string_field_set(iaxs[callno], secret, pds.password);
05128
05129 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
05130 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
05131 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05132 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05133 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05134 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05135
05136 if (iaxs[callno]->maxtime) {
05137
05138 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05139 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05140 } else if (autokill) {
05141 iaxs[callno]->pingtime = autokill / 2;
05142 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05143 }
05144
05145
05146 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05147 if (!ast_strlen_zero(osp_token_ptr)) {
05148 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05149 osp_block_index = 0;
05150 while (osp_token_length > 0) {
05151 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05152 osp_buffer[0] = osp_block_index;
05153 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05154 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05155 osp_block_index++;
05156 osp_token_ptr += osp_block_length;
05157 osp_token_length -= osp_block_length;
05158 }
05159 } else
05160 ast_log(LOG_WARNING, "OSP token is too long\n");
05161 } else if (iaxdebug)
05162 ast_debug(1, "OSP token is undefined\n");
05163
05164
05165 iaxs[callno]->sockfd = cai.sockfd;
05166
05167
05168 if (variablestore) {
05169 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05170 ast_debug(1, "Found an IAX variable store on this channel\n");
05171 AST_LIST_LOCK(variablelist);
05172 AST_LIST_TRAVERSE(variablelist, var, entries) {
05173 char tmp[256];
05174 int i;
05175 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05176
05177 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05178 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05179 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05180 }
05181 }
05182 AST_LIST_UNLOCK(variablelist);
05183 }
05184
05185
05186 add_empty_calltoken_ie(iaxs[callno], &ied);
05187 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05188
05189 ast_mutex_unlock(&iaxsl[callno]);
05190 ast_setstate(c, AST_STATE_RINGING);
05191
05192 return 0;
05193 }
05194
05195 static int iax2_hangup(struct ast_channel *c)
05196 {
05197 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05198 struct iax_ie_data ied;
05199 int alreadygone;
05200 memset(&ied, 0, sizeof(ied));
05201 ast_mutex_lock(&iaxsl[callno]);
05202 if (callno && iaxs[callno]) {
05203 ast_debug(1, "We're hanging up %s now...\n", c->name);
05204 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05205
05206 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05207 if (!iaxs[callno]->error && !alreadygone) {
05208 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05209 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05210 }
05211 if (!iaxs[callno]) {
05212 ast_mutex_unlock(&iaxsl[callno]);
05213 return 0;
05214 }
05215 }
05216
05217 iax2_predestroy(callno);
05218
05219 if (iaxs[callno] && alreadygone) {
05220 ast_debug(1, "Really destroying %s now...\n", c->name);
05221 iax2_destroy(callno);
05222 } else if (iaxs[callno]) {
05223 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05224 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05225 iax2_destroy(callno);
05226 }
05227 }
05228 } else if (c->tech_pvt) {
05229
05230
05231
05232
05233 c->tech_pvt = NULL;
05234 }
05235 ast_mutex_unlock(&iaxsl[callno]);
05236 ast_verb(3, "Hungup '%s'\n", c->name);
05237 return 0;
05238 }
05239
05240
05241
05242
05243 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05244 {
05245 unsigned short callno = pvt->callno;
05246
05247 if (!pvt->peercallno) {
05248
05249 int count = 10;
05250 while (count-- && pvt && !pvt->peercallno) {
05251 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05252 pvt = iaxs[callno];
05253 }
05254 if (!pvt->peercallno) {
05255 return -1;
05256 }
05257 }
05258
05259 return 0;
05260 }
05261
05262 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05263 {
05264 struct ast_option_header *h;
05265 int res;
05266
05267 switch (option) {
05268 case AST_OPTION_TXGAIN:
05269 case AST_OPTION_RXGAIN:
05270
05271 errno = ENOSYS;
05272 return -1;
05273 case AST_OPTION_OPRMODE:
05274 errno = EINVAL;
05275 return -1;
05276 case AST_OPTION_SECURE_SIGNALING:
05277 case AST_OPTION_SECURE_MEDIA:
05278 {
05279 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05280 ast_mutex_lock(&iaxsl[callno]);
05281 if ((*(int *) data)) {
05282 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05283 } else {
05284 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05285 }
05286 ast_mutex_unlock(&iaxsl[callno]);
05287 return 0;
05288 }
05289
05290
05291
05292
05293 case AST_OPTION_TONE_VERIFY:
05294 case AST_OPTION_TDD:
05295 case AST_OPTION_RELAXDTMF:
05296 case AST_OPTION_AUDIO_MODE:
05297 case AST_OPTION_DIGIT_DETECT:
05298 case AST_OPTION_FAX_DETECT:
05299 {
05300 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05301 struct chan_iax2_pvt *pvt;
05302
05303 ast_mutex_lock(&iaxsl[callno]);
05304 pvt = iaxs[callno];
05305
05306 if (wait_for_peercallno(pvt)) {
05307 ast_mutex_unlock(&iaxsl[callno]);
05308 return -1;
05309 }
05310
05311 ast_mutex_unlock(&iaxsl[callno]);
05312
05313 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05314 return -1;
05315 }
05316
05317 h->flag = AST_OPTION_FLAG_REQUEST;
05318 h->option = htons(option);
05319 memcpy(h->data, data, datalen);
05320 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05321 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05322 datalen + sizeof(*h), -1);
05323 ast_free(h);
05324 return res;
05325 }
05326 default:
05327 return -1;
05328 }
05329
05330
05331 return -1;
05332 }
05333
05334 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
05335 {
05336 switch (option) {
05337 case AST_OPTION_SECURE_SIGNALING:
05338 case AST_OPTION_SECURE_MEDIA:
05339 {
05340 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05341 ast_mutex_lock(&iaxsl[callno]);
05342 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05343 ast_mutex_unlock(&iaxsl[callno]);
05344 return 0;
05345 }
05346 default:
05347 return -1;
05348 }
05349 }
05350
05351 static struct ast_frame *iax2_read(struct ast_channel *c)
05352 {
05353 ast_debug(1, "I should never be called!\n");
05354 return &ast_null_frame;
05355 }
05356
05357 static int iax2_key_rotate(const void *vpvt)
05358 {
05359 int res = 0;
05360 struct chan_iax2_pvt *pvt = (void *) vpvt;
05361 struct MD5Context md5;
05362 char key[17] = "";
05363 struct iax_ie_data ied = {
05364 .pos = 0,
05365 };
05366
05367 ast_mutex_lock(&iaxsl[pvt->callno]);
05368 pvt->keyrotateid =
05369 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05370
05371 snprintf(key, sizeof(key), "%lX", ast_random());
05372
05373 MD5Init(&md5);
05374 MD5Update(&md5, (unsigned char *) key, strlen(key));
05375 MD5Final((unsigned char *) key, &md5);
05376
05377 IAX_DEBUGDIGEST("Sending", key);
05378
05379 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05380
05381 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05382
05383 build_ecx_key((unsigned char *) key, pvt);
05384
05385 ast_mutex_unlock(&iaxsl[pvt->callno]);
05386
05387 return res;
05388 }
05389
05390 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05391 {
05392 int res;
05393 struct iax_ie_data ied0;
05394 struct iax_ie_data ied1;
05395 unsigned int transferid = (unsigned int)ast_random();
05396
05397 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05398 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05399 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05400 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05401 return 0;
05402 }
05403
05404 memset(&ied0, 0, sizeof(ied0));
05405 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05406 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05407 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05408
05409 memset(&ied1, 0, sizeof(ied1));
05410 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05411 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05412 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05413
05414 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05415 if (res)
05416 return -1;
05417 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05418 if (res)
05419 return -1;
05420 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05421 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05422 return 0;
05423 }
05424
05425 static void lock_both(unsigned short callno0, unsigned short callno1)
05426 {
05427 ast_mutex_lock(&iaxsl[callno0]);
05428 while (ast_mutex_trylock(&iaxsl[callno1])) {
05429 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05430 }
05431 }
05432
05433 static void unlock_both(unsigned short callno0, unsigned short callno1)
05434 {
05435 ast_mutex_unlock(&iaxsl[callno1]);
05436 ast_mutex_unlock(&iaxsl[callno0]);
05437 }
05438
05439 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)
05440 {
05441 struct ast_channel *cs[3];
05442 struct ast_channel *who, *other;
05443 int to = -1;
05444 int res = -1;
05445 int transferstarted=0;
05446 struct ast_frame *f;
05447 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05448 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05449 struct timeval waittimer = {0, 0};
05450
05451
05452 if (timeoutms > 0) {
05453 return AST_BRIDGE_FAILED;
05454 }
05455
05456 timeoutms = -1;
05457
05458 lock_both(callno0, callno1);
05459 if (!iaxs[callno0] || !iaxs[callno1]) {
05460 unlock_both(callno0, callno1);
05461 return AST_BRIDGE_FAILED;
05462 }
05463
05464 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05465 iaxs[callno0]->bridgecallno = callno1;
05466 iaxs[callno1]->bridgecallno = callno0;
05467 }
05468 unlock_both(callno0, callno1);
05469
05470
05471 cs[0] = c0;
05472 cs[1] = c1;
05473 for (;;) {
05474
05475 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05476 ast_verb(3, "Can't masquerade, we're different...\n");
05477
05478 if (c0->tech == &iax2_tech) {
05479 ast_mutex_lock(&iaxsl[callno0]);
05480 iaxs[callno0]->bridgecallno = 0;
05481 ast_mutex_unlock(&iaxsl[callno0]);
05482 }
05483 if (c1->tech == &iax2_tech) {
05484 ast_mutex_lock(&iaxsl[callno1]);
05485 iaxs[callno1]->bridgecallno = 0;
05486 ast_mutex_unlock(&iaxsl[callno1]);
05487 }
05488 return AST_BRIDGE_FAILED_NOWARN;
05489 }
05490 if (c0->nativeformats != c1->nativeformats) {
05491 char buf0[256];
05492 char buf1[256];
05493 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05494 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05495 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05496
05497 lock_both(callno0, callno1);
05498 if (iaxs[callno0])
05499 iaxs[callno0]->bridgecallno = 0;
05500 if (iaxs[callno1])
05501 iaxs[callno1]->bridgecallno = 0;
05502 unlock_both(callno0, callno1);
05503 return AST_BRIDGE_FAILED_NOWARN;
05504 }
05505
05506 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05507
05508 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05509 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05510 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05511 transferstarted = 1;
05512 }
05513 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05514
05515 struct timeval now = ast_tvnow();
05516 if (ast_tvzero(waittimer)) {
05517 waittimer = now;
05518 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05519 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05520 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05521 *fo = NULL;
05522 *rc = c0;
05523 res = AST_BRIDGE_COMPLETE;
05524 break;
05525 }
05526 }
05527 to = 1000;
05528 who = ast_waitfor_n(cs, 2, &to);
05529 if (timeoutms > -1) {
05530 timeoutms -= (1000 - to);
05531 if (timeoutms < 0)
05532 timeoutms = 0;
05533 }
05534 if (!who) {
05535 if (!timeoutms) {
05536 res = AST_BRIDGE_RETRY;
05537 break;
05538 }
05539 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05540 res = AST_BRIDGE_FAILED;
05541 break;
05542 }
05543 continue;
05544 }
05545 f = ast_read(who);
05546 if (!f) {
05547 *fo = NULL;
05548 *rc = who;
05549 res = AST_BRIDGE_COMPLETE;
05550 break;
05551 }
05552 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05553 *fo = f;
05554 *rc = who;
05555 res = AST_BRIDGE_COMPLETE;
05556 break;
05557 }
05558 other = (who == c0) ? c1 : c0;
05559 if ((f->frametype == AST_FRAME_VOICE) ||
05560 (f->frametype == AST_FRAME_TEXT) ||
05561 (f->frametype == AST_FRAME_VIDEO) ||
05562 (f->frametype == AST_FRAME_IMAGE) ||
05563 (f->frametype == AST_FRAME_DTMF) ||
05564 (f->frametype == AST_FRAME_CONTROL)) {
05565
05566
05567
05568 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05569 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05570 *rc = who;
05571 *fo = f;
05572 res = AST_BRIDGE_COMPLETE;
05573
05574 break;
05575 }
05576
05577 ast_write(other, f);
05578 }
05579 ast_frfree(f);
05580
05581 cs[2] = cs[0];
05582 cs[0] = cs[1];
05583 cs[1] = cs[2];
05584 }
05585 lock_both(callno0, callno1);
05586 if(iaxs[callno0])
05587 iaxs[callno0]->bridgecallno = 0;
05588 if(iaxs[callno1])
05589 iaxs[callno1]->bridgecallno = 0;
05590 unlock_both(callno0, callno1);
05591 return res;
05592 }
05593
05594 static int iax2_answer(struct ast_channel *c)
05595 {
05596 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05597 ast_debug(1, "Answering IAX2 call\n");
05598 ast_mutex_lock(&iaxsl[callno]);
05599 if (iaxs[callno])
05600 iax2_ami_channelupdate(iaxs[callno]);
05601 ast_mutex_unlock(&iaxsl[callno]);
05602 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05603 }
05604
05605 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05606 {
05607 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05608 struct chan_iax2_pvt *pvt;
05609 int res = 0;
05610
05611 if (iaxdebug)
05612 ast_debug(1, "Indicating condition %d\n", condition);
05613
05614 ast_mutex_lock(&iaxsl[callno]);
05615 pvt = iaxs[callno];
05616
05617 if (wait_for_peercallno(pvt)) {
05618 res = -1;
05619 goto done;
05620 }
05621
05622 switch (condition) {
05623 case AST_CONTROL_HOLD:
05624 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05625 ast_moh_start(c, data, pvt->mohinterpret);
05626 goto done;
05627 }
05628 break;
05629 case AST_CONTROL_UNHOLD:
05630 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05631 ast_moh_stop(c);
05632 goto done;
05633 }
05634 break;
05635 case AST_CONTROL_CONNECTED_LINE:
05636 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05637 goto done;
05638 break;
05639 }
05640
05641 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05642
05643 done:
05644 ast_mutex_unlock(&iaxsl[callno]);
05645
05646 return res;
05647 }
05648
05649 static int iax2_transfer(struct ast_channel *c, const char *dest)
05650 {
05651 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05652 struct iax_ie_data ied = { "", };
05653 char tmp[256], *context;
05654 enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05655 ast_copy_string(tmp, dest, sizeof(tmp));
05656 context = strchr(tmp, '@');
05657 if (context) {
05658 *context = '\0';
05659 context++;
05660 }
05661 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05662 if (context)
05663 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05664 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05665 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05666 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05667 }
05668
05669 static int iax2_getpeertrunk(struct sockaddr_in sin)
05670 {
05671 struct iax2_peer *peer;
05672 int res = 0;
05673 struct ao2_iterator i;
05674
05675 i = ao2_iterator_init(peers, 0);
05676 while ((peer = ao2_iterator_next(&i))) {
05677 struct sockaddr_in peer_addr;
05678
05679 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05680
05681 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05682 (peer_addr.sin_port == sin.sin_port)) {
05683 res = ast_test_flag64(peer, IAX_TRUNK);
05684 peer_unref(peer);
05685 break;
05686 }
05687 peer_unref(peer);
05688 }
05689 ao2_iterator_destroy(&i);
05690
05691 return res;
05692 }
05693
05694
05695 static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
05696 {
05697 struct ast_channel *tmp;
05698 struct chan_iax2_pvt *i;
05699 struct ast_variable *v = NULL;
05700
05701 if (!(i = iaxs[callno])) {
05702 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05703 return NULL;
05704 }
05705
05706
05707 ast_mutex_unlock(&iaxsl[callno]);
05708 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);
05709 ast_mutex_lock(&iaxsl[callno]);
05710 if (i != iaxs[callno]) {
05711 if (tmp) {
05712
05713 ast_mutex_unlock(&iaxsl[callno]);
05714 tmp = ast_channel_release(tmp);
05715 ast_mutex_lock(&iaxsl[callno]);
05716 }
05717 return NULL;
05718 }
05719 iax2_ami_channelupdate(i);
05720 if (!tmp)
05721 return NULL;
05722 tmp->tech = &iax2_tech;
05723
05724 tmp->nativeformats = capability;
05725 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05726 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05727 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05728
05729 if (!ast_strlen_zero(i->parkinglot))
05730 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05731
05732
05733 if (!ast_strlen_zero(i->ani)) {
05734 tmp->caller.ani.number.valid = 1;
05735 tmp->caller.ani.number.str = ast_strdup(i->ani);
05736 } else if (!ast_strlen_zero(i->cid_num)) {
05737 tmp->caller.ani.number.valid = 1;
05738 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05739 }
05740 tmp->dialed.number.str = ast_strdup(i->dnid);
05741 if (!ast_strlen_zero(i->rdnis)) {
05742 tmp->redirecting.from.number.valid = 1;
05743 tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05744 }
05745 tmp->caller.id.name.presentation = i->calling_pres;
05746 tmp->caller.id.number.presentation = i->calling_pres;
05747 tmp->caller.id.number.plan = i->calling_ton;
05748 tmp->dialed.transit_network_select = i->calling_tns;
05749 if (!ast_strlen_zero(i->language))
05750 ast_string_field_set(tmp, language, i->language);
05751 if (!ast_strlen_zero(i->accountcode))
05752 ast_string_field_set(tmp, accountcode, i->accountcode);
05753 if (i->amaflags)
05754 tmp->amaflags = i->amaflags;
05755 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05756 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05757 if (i->adsi)
05758 tmp->adsicpe = i->peeradsicpe;
05759 else
05760 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05761 i->owner = tmp;
05762 i->capability = capability;
05763
05764
05765 if (i->vars) {
05766 for (v = i->vars ; v ; v = v->next)
05767 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05768 }
05769 if (i->iaxvars) {
05770 struct ast_datastore *variablestore;
05771 struct ast_variable *var, *prev = NULL;
05772 AST_LIST_HEAD(, ast_var_t) *varlist;
05773 ast_debug(1, "Loading up the channel with IAXVARs\n");
05774 varlist = ast_calloc(1, sizeof(*varlist));
05775 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05776 if (variablestore && varlist) {
05777 variablestore->data = varlist;
05778 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05779 AST_LIST_HEAD_INIT(varlist);
05780 for (var = i->iaxvars; var; var = var->next) {
05781 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05782 if (prev)
05783 ast_free(prev);
05784 prev = var;
05785 if (!newvar) {
05786
05787 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05788 } else {
05789 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05790 }
05791 }
05792 if (prev)
05793 ast_free(prev);
05794 i->iaxvars = NULL;
05795 ast_channel_datastore_add(i->owner, variablestore);
05796 } else {
05797 if (variablestore) {
05798 ast_datastore_free(variablestore);
05799 }
05800 if (varlist) {
05801 ast_free(varlist);
05802 }
05803 }
05804 }
05805
05806 if (state != AST_STATE_DOWN) {
05807 if (ast_pbx_start(tmp)) {
05808 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05809 ast_hangup(tmp);
05810 i->owner = NULL;
05811 return NULL;
05812 }
05813 }
05814
05815 ast_module_ref(ast_module_info->self);
05816 return tmp;
05817 }
05818
05819 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05820 {
05821 unsigned long int mssincetx;
05822 long int ms, pred;
05823
05824 tpeer->trunkact = *now;
05825 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05826 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05827
05828 tpeer->txtrunktime = *now;
05829 tpeer->lastsent = 999999;
05830 }
05831
05832 tpeer->lasttxtime = *now;
05833
05834
05835 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05836
05837 pred = tpeer->lastsent + sampms;
05838 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05839 ms = pred;
05840
05841
05842 if (ms == tpeer->lastsent)
05843 ms = tpeer->lastsent + 1;
05844 tpeer->lastsent = ms;
05845 return ms;
05846 }
05847
05848 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05849 {
05850 long ms;
05851 if (ast_tvzero(iaxs[callno]->rxcore)) {
05852
05853 iaxs[callno]->rxcore = ast_tvnow();
05854
05855 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05856 }
05857
05858 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05859
05860 return ms + ts;
05861 }
05862
05863 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05864 {
05865 int ms;
05866 int voice = 0;
05867 int genuine = 0;
05868 int adjust;
05869 int rate = ast_format_rate(f->subclass.codec) / 1000;
05870 struct timeval *delivery = NULL;
05871
05872
05873
05874
05875
05876
05877
05878
05879 if (f) {
05880 if (f->frametype == AST_FRAME_VOICE) {
05881 voice = 1;
05882 delivery = &f->delivery;
05883 } else if (f->frametype == AST_FRAME_IAX) {
05884 genuine = 1;
05885 } else if (f->frametype == AST_FRAME_CNG) {
05886 p->notsilenttx = 0;
05887 }
05888 }
05889 if (ast_tvzero(p->offset)) {
05890 p->offset = ast_tvnow();
05891
05892 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05893 }
05894
05895 if (ts)
05896 return ts;
05897
05898 if (delivery && !ast_tvzero(*delivery)) {
05899 ms = ast_tvdiff_ms(*delivery, p->offset);
05900 if (ms < 0) {
05901 ms = 0;
05902 }
05903 if (iaxdebug)
05904 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05905 } else {
05906 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05907 if (ms < 0)
05908 ms = 0;
05909 if (voice) {
05910
05911 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921
05922
05923
05924
05925
05926
05927
05928
05929
05930 adjust = (ms - p->nextpred);
05931 if (adjust < 0)
05932 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05933 else if (adjust > 0)
05934 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05935
05936 if (!p->nextpred) {
05937 p->nextpred = ms;
05938 if (p->nextpred <= p->lastsent)
05939 p->nextpred = p->lastsent + 3;
05940 }
05941 ms = p->nextpred;
05942 } else {
05943
05944
05945
05946
05947
05948
05949
05950
05951
05952 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05953 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05954 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05955
05956 if (f->samples >= rate)
05957 {
05958 int diff = ms % (f->samples / rate);
05959 if (diff)
05960 ms += f->samples/rate - diff;
05961 }
05962
05963 p->nextpred = ms;
05964 p->notsilenttx = 1;
05965 }
05966 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05967
05968
05969
05970
05971
05972
05973
05974
05975 if ( (unsigned int)ms < p->lastsent )
05976 ms = p->lastsent;
05977 } else {
05978
05979
05980 if (genuine) {
05981
05982 if (ms <= p->lastsent)
05983 ms = p->lastsent + 3;
05984 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05985
05986 ms = p->lastsent + 3;
05987 }
05988 }
05989 }
05990 p->lastsent = ms;
05991 if (voice)
05992 p->nextpred = p->nextpred + f->samples / rate;
05993 return ms;
05994 }
05995
05996 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05997 {
05998
05999
06000 int ms;
06001 #ifdef IAXTESTS
06002 int jit;
06003 #endif
06004
06005 if (ast_tvzero(p->rxcore)) {
06006 p->rxcore = ast_tvnow();
06007 if (iaxdebug)
06008 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06009 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06010 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06011 #if 1
06012 if (iaxdebug)
06013 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06014 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06015 #endif
06016 }
06017
06018 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06019 #ifdef IAXTESTS
06020 if (test_jit) {
06021 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06022 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06023 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06024 jit = -jit;
06025 ms += jit;
06026 }
06027 }
06028 if (test_late) {
06029 ms += test_late;
06030 test_late = 0;
06031 }
06032 #endif
06033 return ms;
06034 }
06035
06036 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
06037 {
06038 struct iax2_trunk_peer *tpeer = NULL;
06039
06040
06041 AST_LIST_LOCK(&tpeers);
06042
06043 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06044 if (!inaddrcmp(&tpeer->addr, sin)) {
06045 ast_mutex_lock(&tpeer->lock);
06046 break;
06047 }
06048 }
06049
06050 if (!tpeer) {
06051 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06052 ast_mutex_init(&tpeer->lock);
06053 tpeer->lastsent = 9999;
06054 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06055 tpeer->trunkact = ast_tvnow();
06056 ast_mutex_lock(&tpeer->lock);
06057 tpeer->sockfd = fd;
06058 #ifdef SO_NO_CHECK
06059 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06060 #endif
06061 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06062 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06063 }
06064 }
06065
06066 AST_LIST_UNLOCK(&tpeers);
06067
06068 return tpeer;
06069 }
06070
06071 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
06072 {
06073 struct ast_frame *f;
06074 struct iax2_trunk_peer *tpeer;
06075 void *tmp, *ptr;
06076 struct timeval now;
06077 struct ast_iax2_meta_trunk_entry *met;
06078 struct ast_iax2_meta_trunk_mini *mtm;
06079
06080 f = &fr->af;
06081 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06082 if (tpeer) {
06083 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06084
06085 if (tpeer->trunkdataalloc < trunkmaxsize) {
06086 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06087 ast_mutex_unlock(&tpeer->lock);
06088 return -1;
06089 }
06090
06091 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06092 tpeer->trunkdata = tmp;
06093 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);
06094 } else {
06095 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));
06096 ast_mutex_unlock(&tpeer->lock);
06097 return -1;
06098 }
06099 }
06100
06101
06102 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06103 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06104 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06105 mtm->len = htons(f->datalen);
06106 mtm->mini.callno = htons(pvt->callno);
06107 mtm->mini.ts = htons(0xffff & fr->ts);
06108 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06109 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06110 } else {
06111 met = (struct ast_iax2_meta_trunk_entry *)ptr;
06112
06113 met->callno = htons(pvt->callno);
06114 met->len = htons(f->datalen);
06115
06116 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06117 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06118 }
06119
06120 memcpy(ptr, f->data.ptr, f->datalen);
06121 tpeer->trunkdatalen += f->datalen;
06122
06123 tpeer->calls++;
06124
06125
06126 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
06127 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
06128
06129
06130 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06131 now = ast_tvnow();
06132 send_trunk(tpeer, &now);
06133 trunk_untimed ++;
06134 }
06135
06136 ast_mutex_unlock(&tpeer->lock);
06137 }
06138 return 0;
06139 }
06140
06141
06142
06143 static void build_rand_pad(unsigned char *buf, ssize_t len)
06144 {
06145 long tmp;
06146 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06147 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06148 buf += sizeof(tmp);
06149 len -= sizeof(tmp);
06150 }
06151 }
06152
06153 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06154 {
06155 build_ecx_key(digest, pvt);
06156 ast_aes_set_decrypt_key(digest, &pvt->dcx);
06157 }
06158
06159 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06160 {
06161
06162
06163
06164 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06165 ast_aes_set_encrypt_key(digest, &pvt->ecx);
06166 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06167 }
06168
06169 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
06170 {
06171 #if 0
06172
06173 int x;
06174 if (len % 16)
06175 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06176 for (x=0;x<len;x++)
06177 dst[x] = src[x] ^ 0xff;
06178 #else
06179 unsigned char lastblock[16] = { 0 };
06180 int x;
06181 while(len > 0) {
06182 ast_aes_decrypt(src, dst, dcx);
06183 for (x=0;x<16;x++)
06184 dst[x] ^= lastblock[x];
06185 memcpy(lastblock, src, sizeof(lastblock));
06186 dst += 16;
06187 src += 16;
06188 len -= 16;
06189 }
06190 #endif
06191 }
06192
06193 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
06194 {
06195 #if 0
06196
06197 int x;
06198 if (len % 16)
06199 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06200 for (x=0;x<len;x++)
06201 dst[x] = src[x] ^ 0xff;
06202 #else
06203 unsigned char curblock[16] = { 0 };
06204 int x;
06205 while(len > 0) {
06206 for (x=0;x<16;x++)
06207 curblock[x] ^= src[x];
06208 ast_aes_encrypt(curblock, dst, ecx);
06209 memcpy(curblock, dst, sizeof(curblock));
06210 dst += 16;
06211 src += 16;
06212 len -= 16;
06213 }
06214 #endif
06215 }
06216
06217 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06218 {
06219 int padding;
06220 unsigned char *workspace;
06221
06222 workspace = alloca(*datalen);
06223 memset(f, 0, sizeof(*f));
06224 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06225 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06226 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06227 return -1;
06228
06229 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06230
06231 padding = 16 + (workspace[15] & 0x0f);
06232 if (iaxdebug)
06233 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06234 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06235 return -1;
06236
06237 *datalen -= padding;
06238 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06239 f->frametype = fh->type;
06240 if (f->frametype == AST_FRAME_VIDEO) {
06241 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06242 } else if (f->frametype == AST_FRAME_VOICE) {
06243 f->subclass.codec = uncompress_subclass(fh->csub);
06244 } else {
06245 f->subclass.integer = uncompress_subclass(fh->csub);
06246 }
06247 } else {
06248 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06249 if (iaxdebug)
06250 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06251 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06252 return -1;
06253
06254 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06255 padding = 16 + (workspace[15] & 0x0f);
06256 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06257 return -1;
06258 *datalen -= padding;
06259 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06260 }
06261 return 0;
06262 }
06263
06264 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06265 {
06266 int padding;
06267 unsigned char *workspace;
06268 workspace = alloca(*datalen + 32);
06269 if (!workspace)
06270 return -1;
06271 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06272 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06273 if (iaxdebug)
06274 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06275 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06276 padding = 16 + (padding & 0xf);
06277 memcpy(workspace, poo, padding);
06278 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06279 workspace[15] &= 0xf0;
06280 workspace[15] |= (padding & 0xf);
06281 if (iaxdebug)
06282 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06283 *datalen += padding;
06284 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06285 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06286 memcpy(poo, workspace + *datalen - 32, 32);
06287 } else {
06288 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06289 if (iaxdebug)
06290 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06291 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06292 padding = 16 + (padding & 0xf);
06293 memcpy(workspace, poo, padding);
06294 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06295 workspace[15] &= 0xf0;
06296 workspace[15] |= (padding & 0x0f);
06297 *datalen += padding;
06298 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06299 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06300 memcpy(poo, workspace + *datalen - 32, 32);
06301 }
06302 return 0;
06303 }
06304
06305 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06306 {
06307 int res=-1;
06308 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06309
06310 struct MD5Context md5;
06311 unsigned char digest[16];
06312 char *tmppw, *stringp;
06313
06314 tmppw = ast_strdupa(iaxs[callno]->secret);
06315 stringp = tmppw;
06316 while ((tmppw = strsep(&stringp, ";"))) {
06317 MD5Init(&md5);
06318 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06319 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06320 MD5Final(digest, &md5);
06321 build_encryption_keys(digest, iaxs[callno]);
06322 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06323 if (!res) {
06324 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06325 break;
06326 }
06327 }
06328 } else
06329 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06330 return res;
06331 }
06332
06333 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06334 {
06335
06336
06337
06338 struct ast_iax2_full_hdr *fh;
06339 struct ast_iax2_mini_hdr *mh;
06340 struct ast_iax2_video_hdr *vh;
06341 struct {
06342 struct iax_frame fr2;
06343 unsigned char buffer[4096];
06344 } frb;
06345 struct iax_frame *fr;
06346 int res;
06347 int sendmini=0;
06348 unsigned int lastsent;
06349 unsigned int fts;
06350
06351 frb.fr2.afdatalen = sizeof(frb.buffer);
06352
06353 if (!pvt) {
06354 ast_log(LOG_WARNING, "No private structure for packet?\n");
06355 return -1;
06356 }
06357
06358 lastsent = pvt->lastsent;
06359
06360
06361 fts = calc_timestamp(pvt, ts, f);
06362
06363
06364
06365
06366 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06367 return 0;
06368 #if 0
06369 ast_log(LOG_NOTICE,
06370 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06371 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06372 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06373 pvt->keyrotateid != -1 ? "" : "no "
06374 );
06375 #endif
06376 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06377 iax2_key_rotate(pvt);
06378 }
06379
06380 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
06381 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06382 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06383 &&
06384 (f->frametype == AST_FRAME_VOICE)
06385 &&
06386 (f->subclass.codec == pvt->svoiceformat)
06387 ) {
06388
06389 now = 1;
06390
06391 sendmini = 1;
06392 }
06393 if ( f->frametype == AST_FRAME_VIDEO ) {
06394
06395
06396
06397
06398
06399 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06400 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06401 ) {
06402 now = 1;
06403 sendmini = 1;
06404 } else {
06405 now = 0;
06406 sendmini = 0;
06407 }
06408 pvt->lastvsent = fts;
06409 }
06410 if (f->frametype == AST_FRAME_IAX) {
06411
06412 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06413 if (!pvt->first_iax_message) {
06414 pvt->first_iax_message = pvt->last_iax_message;
06415 }
06416 }
06417
06418 if (now) {
06419 fr = &frb.fr2;
06420 } else
06421 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));
06422 if (!fr) {
06423 ast_log(LOG_WARNING, "Out of memory\n");
06424 return -1;
06425 }
06426
06427 iax_frame_wrap(fr, f);
06428
06429 fr->ts = fts;
06430 fr->callno = pvt->callno;
06431 fr->transfer = transfer;
06432 fr->final = final;
06433 fr->encmethods = 0;
06434 if (!sendmini) {
06435
06436 if (seqno > -1)
06437 fr->oseqno = seqno;
06438 else
06439 fr->oseqno = pvt->oseqno++;
06440 fr->iseqno = pvt->iseqno;
06441 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06442 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06443 fh->ts = htonl(fr->ts);
06444 fh->oseqno = fr->oseqno;
06445 if (transfer) {
06446 fh->iseqno = 0;
06447 } else
06448 fh->iseqno = fr->iseqno;
06449
06450 if (!transfer)
06451 pvt->aseqno = fr->iseqno;
06452 fh->type = fr->af.frametype & 0xFF;
06453
06454 if (fr->af.frametype == AST_FRAME_VIDEO) {
06455 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06456 } else if (fr->af.frametype == AST_FRAME_VOICE) {
06457 fh->csub = compress_subclass(fr->af.subclass.codec);
06458 } else {
06459 fh->csub = compress_subclass(fr->af.subclass.integer);
06460 }
06461
06462 if (transfer) {
06463 fr->dcallno = pvt->transfercallno;
06464 } else
06465 fr->dcallno = pvt->peercallno;
06466 fh->dcallno = htons(fr->dcallno);
06467 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06468 fr->data = fh;
06469 fr->retries = 0;
06470
06471 fr->retrytime = pvt->pingtime * 2;
06472 if (fr->retrytime < MIN_RETRY_TIME)
06473 fr->retrytime = MIN_RETRY_TIME;
06474 if (fr->retrytime > MAX_RETRY_TIME)
06475 fr->retrytime = MAX_RETRY_TIME;
06476
06477 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06478 fr->retries = -1;
06479 else if (f->frametype == AST_FRAME_VOICE)
06480 pvt->svoiceformat = f->subclass.codec;
06481 else if (f->frametype == AST_FRAME_VIDEO)
06482 pvt->svideoformat = f->subclass.codec & ~0x1LL;
06483 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06484 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06485 if (fr->transfer)
06486 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06487 else
06488 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06489 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06490 fr->encmethods = pvt->encmethods;
06491 fr->ecx = pvt->ecx;
06492 fr->mydcx = pvt->mydcx;
06493 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06494 } else
06495 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06496 }
06497
06498 if (now) {
06499 res = send_packet(fr);
06500 } else
06501 res = iax2_transmit(fr);
06502 } else {
06503 if (ast_test_flag64(pvt, IAX_TRUNK)) {
06504 iax2_trunk_queue(pvt, fr);
06505 res = 0;
06506 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06507
06508 fr->oseqno = -1;
06509 fr->iseqno = -1;
06510 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06511 vh->zeros = 0;
06512 vh->callno = htons(0x8000 | fr->callno);
06513 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06514 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06515 fr->data = vh;
06516 fr->retries = -1;
06517 res = send_packet(fr);
06518 } else {
06519
06520 fr->oseqno = -1;
06521 fr->iseqno = -1;
06522
06523 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06524 mh->callno = htons(fr->callno);
06525 mh->ts = htons(fr->ts & 0xFFFF);
06526 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06527 fr->data = mh;
06528 fr->retries = -1;
06529 if (pvt->transferring == TRANSFER_MEDIAPASS)
06530 fr->transfer = 1;
06531 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06532 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06533 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06534 } else
06535 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06536 }
06537 res = send_packet(fr);
06538 }
06539 }
06540 return res;
06541 }
06542
06543 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06544 {
06545 regex_t regexbuf;
06546 int havepattern = 0;
06547
06548 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06549 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06550
06551 struct iax2_user *user = NULL;
06552 char auth[90];
06553 char *pstr = "";
06554 struct ao2_iterator i;
06555
06556 switch (cmd) {
06557 case CLI_INIT:
06558 e->command = "iax2 show users [like]";
06559 e->usage =
06560 "Usage: iax2 show users [like <pattern>]\n"
06561 " Lists all known IAX2 users.\n"
06562 " Optional regular expression pattern is used to filter the user list.\n";
06563 return NULL;
06564 case CLI_GENERATE:
06565 return NULL;
06566 }
06567
06568 switch (a->argc) {
06569 case 5:
06570 if (!strcasecmp(a->argv[3], "like")) {
06571 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06572 return CLI_SHOWUSAGE;
06573 havepattern = 1;
06574 } else
06575 return CLI_SHOWUSAGE;
06576 case 3:
06577 break;
06578 default:
06579 return CLI_SHOWUSAGE;
06580 }
06581
06582 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06583 i = ao2_iterator_init(users, 0);
06584 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
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_unref(peer)) {
06673 char nm[20];
06674 char status[20];
06675 int retstatus;
06676 struct sockaddr_in peer_addr;
06677
06678 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06679
06680 if (registeredonly && !peer_addr.sin_addr.s_addr) {
06681 continue;
06682 }
06683 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
06684 continue;
06685 }
06686
06687 if (!ast_strlen_zero(peer->username))
06688 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06689 else
06690 ast_copy_string(name, peer->name, sizeof(name));
06691
06692 encmethods_to_str(peer->encmethods, encmethods);
06693 retstatus = peer_status(peer, status, sizeof(status));
06694 if (retstatus > 0)
06695 online_peers++;
06696 else if (!retstatus)
06697 offline_peers++;
06698 else
06699 unmonitored_peers++;
06700
06701 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06702
06703 if (s) {
06704 astman_append(s,
06705 "Event: PeerEntry\r\n%s"
06706 "Channeltype: IAX2\r\n"
06707 "ObjectName: %s\r\n"
06708 "ChanObjectType: peer\r\n"
06709 "IPaddress: %s\r\n"
06710 "IPport: %d\r\n"
06711 "Dynamic: %s\r\n"
06712 "Trunk: %s\r\n"
06713 "Encryption: %s\r\n"
06714 "Status: %s\r\n\r\n",
06715 idtext,
06716 name,
06717 ast_sockaddr_stringify_addr(&peer->addr),
06718 ast_sockaddr_port(&peer->addr),
06719 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06720 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06721 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06722 status);
06723 } else {
06724 ast_cli(fd, FORMAT, name,
06725 ast_sockaddr_stringify_addr(&peer->addr),
06726 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06727 nm,
06728 ast_sockaddr_port(&peer->addr),
06729 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
06730 peer->encmethods ? "(E)" : " ",
06731 status);
06732 }
06733 total_peers++;
06734 }
06735 ao2_iterator_destroy(&i);
06736
06737 if (!s)
06738 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06739 total_peers, online_peers, offline_peers, unmonitored_peers);
06740
06741 if (havepattern)
06742 regfree(®exbuf);
06743
06744 if (total)
06745 *total = total_peers;
06746
06747 return RESULT_SUCCESS;
06748 #undef FORMAT
06749 #undef FORMAT2
06750 }
06751
06752 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06753 {
06754 struct iax2_thread *thread = NULL;
06755 time_t t;
06756 int threadcount = 0, dynamiccount = 0;
06757 char type;
06758
06759 switch (cmd) {
06760 case CLI_INIT:
06761 e->command = "iax2 show threads";
06762 e->usage =
06763 "Usage: iax2 show threads\n"
06764 " Lists status of IAX helper threads\n";
06765 return NULL;
06766 case CLI_GENERATE:
06767 return NULL;
06768 }
06769 if (a->argc != 3)
06770 return CLI_SHOWUSAGE;
06771
06772 ast_cli(a->fd, "IAX2 Thread Information\n");
06773 time(&t);
06774 ast_cli(a->fd, "Idle Threads:\n");
06775 AST_LIST_LOCK(&idle_list);
06776 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06777 #ifdef DEBUG_SCHED_MULTITHREAD
06778 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06779 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06780 #else
06781 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06782 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06783 #endif
06784 threadcount++;
06785 }
06786 AST_LIST_UNLOCK(&idle_list);
06787 ast_cli(a->fd, "Active Threads:\n");
06788 AST_LIST_LOCK(&active_list);
06789 AST_LIST_TRAVERSE(&active_list, thread, list) {
06790 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06791 type = 'D';
06792 else
06793 type = 'P';
06794 #ifdef DEBUG_SCHED_MULTITHREAD
06795 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06796 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06797 #else
06798 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06799 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06800 #endif
06801 threadcount++;
06802 }
06803 AST_LIST_UNLOCK(&active_list);
06804 ast_cli(a->fd, "Dynamic Threads:\n");
06805 AST_LIST_LOCK(&dynamic_list);
06806 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06807 #ifdef DEBUG_SCHED_MULTITHREAD
06808 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06809 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06810 #else
06811 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06812 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06813 #endif
06814 dynamiccount++;
06815 }
06816 AST_LIST_UNLOCK(&dynamic_list);
06817 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06818 return CLI_SUCCESS;
06819 }
06820
06821 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06822 {
06823 struct iax2_peer *p;
06824
06825 switch (cmd) {
06826 case CLI_INIT:
06827 e->command = "iax2 unregister";
06828 e->usage =
06829 "Usage: iax2 unregister <peername>\n"
06830 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06831 return NULL;
06832 case CLI_GENERATE:
06833 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06834 }
06835
06836 if (a->argc != 3)
06837 return CLI_SHOWUSAGE;
06838
06839 p = find_peer(a->argv[2], 1);
06840 if (p) {
06841 if (p->expire > 0) {
06842 struct iax2_peer tmp_peer = {
06843 .name = a->argv[2],
06844 };
06845 struct iax2_peer *peer;
06846
06847 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06848 if (peer) {
06849 expire_registry(peer_ref(peer));
06850 peer_unref(peer);
06851 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06852 } else {
06853 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06854 }
06855 } else {
06856 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06857 }
06858 } else {
06859 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06860 }
06861 return CLI_SUCCESS;
06862 }
06863
06864 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06865 {
06866 int which = 0;
06867 struct iax2_peer *p = NULL;
06868 char *res = NULL;
06869 int wordlen = strlen(word);
06870
06871
06872 if (pos == 2) {
06873 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06874 while ((p = ao2_iterator_next(&i))) {
06875 if (!strncasecmp(p->name, word, wordlen) &&
06876 ++which > state && p->expire > 0) {
06877 res = ast_strdup(p->name);
06878 peer_unref(p);
06879 break;
06880 }
06881 peer_unref(p);
06882 }
06883 ao2_iterator_destroy(&i);
06884 }
06885
06886 return res;
06887 }
06888
06889 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06890 {
06891 switch (cmd) {
06892 case CLI_INIT:
06893 e->command = "iax2 show peers";
06894 e->usage =
06895 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06896 " Lists all known IAX2 peers.\n"
06897 " Optional 'registered' argument lists only peers with known addresses.\n"
06898 " Optional regular expression pattern is used to filter the peer list.\n";
06899 return NULL;
06900 case CLI_GENERATE:
06901 return NULL;
06902 }
06903
06904 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06905 case RESULT_SHOWUSAGE:
06906 return CLI_SHOWUSAGE;
06907 case RESULT_FAILURE:
06908 return CLI_FAILURE;
06909 default:
06910 return CLI_SUCCESS;
06911 }
06912 }
06913
06914 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06915 {
06916 ast_cli_netstats(s, -1, 0);
06917 astman_append(s, "\r\n");
06918 return RESULT_SUCCESS;
06919 }
06920
06921 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06922 {
06923 struct iax_firmware *cur = NULL;
06924
06925 switch (cmd) {
06926 case CLI_INIT:
06927 e->command = "iax2 show firmware";
06928 e->usage =
06929 "Usage: iax2 show firmware\n"
06930 " Lists all known IAX firmware images.\n";
06931 return NULL;
06932 case CLI_GENERATE:
06933 return NULL;
06934 }
06935
06936 if (a->argc != 3 && a->argc != 4)
06937 return CLI_SHOWUSAGE;
06938
06939 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06940 AST_LIST_LOCK(&firmwares);
06941 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06942 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06943 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06944 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06945 }
06946 }
06947 AST_LIST_UNLOCK(&firmwares);
06948
06949 return CLI_SUCCESS;
06950 }
06951
06952
06953 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06954 {
06955 static const char * const a[] = { "iax2", "show", "peers" };
06956 const char *id = astman_get_header(m,"ActionID");
06957 char idtext[256] = "";
06958 int total = 0;
06959
06960 if (!ast_strlen_zero(id))
06961 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06962
06963 astman_send_listack(s, m, "Peer status list will follow", "start");
06964
06965 __iax2_show_peers(-1, &total, s, 3, a);
06966
06967 astman_append(s,
06968 "Event: PeerlistComplete\r\n"
06969 "EventList: Complete\r\n"
06970 "ListItems: %d\r\n"
06971 "%s"
06972 "\r\n", total, idtext);
06973 return 0;
06974 }
06975
06976
06977 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06978 {
06979 struct iax2_peer *peer = NULL;
06980 int peer_count = 0;
06981 char nm[20];
06982 char status[20];
06983 const char *id = astman_get_header(m,"ActionID");
06984 char idtext[256] = "";
06985 struct ast_str *encmethods = ast_str_alloca(256);
06986 struct ao2_iterator i;
06987
06988 if (!ast_strlen_zero(id))
06989 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06990
06991 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06992
06993
06994 i = ao2_iterator_init(peers, 0);
06995 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) {
06996 encmethods_to_str(peer->encmethods, encmethods);
06997 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06998 if (!ast_strlen_zero(peer->username)) {
06999 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
07000 } else {
07001 astman_append(s, "ObjectName: %s\r\n", peer->name);
07002 }
07003 astman_append(s, "ChanObjectType: peer\r\n");
07004 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07005 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07006 astman_append(s, "Mask: %s\r\n", nm);
07007 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07008 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07009 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07010 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07011 peer_status(peer, status, sizeof(status));
07012 astman_append(s, "Status: %s\r\n\r\n", status);
07013 peer_count++;
07014 }
07015 ao2_iterator_destroy(&i);
07016
07017 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07018 return RESULT_SUCCESS;
07019 }
07020
07021
07022 static char *regstate2str(int regstate)
07023 {
07024 switch(regstate) {
07025 case REG_STATE_UNREGISTERED:
07026 return "Unregistered";
07027 case REG_STATE_REGSENT:
07028 return "Request Sent";
07029 case REG_STATE_AUTHSENT:
07030 return "Auth. Sent";
07031 case REG_STATE_REGISTERED:
07032 return "Registered";
07033 case REG_STATE_REJECTED:
07034 return "Rejected";
07035 case REG_STATE_TIMEOUT:
07036 return "Timeout";
07037 case REG_STATE_NOAUTH:
07038 return "No Authentication";
07039 default:
07040 return "Unknown";
07041 }
07042 }
07043
07044 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07045 {
07046 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
07047 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
07048 struct iax2_registry *reg = NULL;
07049 char host[80];
07050 char perceived[80];
07051 int counter = 0;
07052
07053 switch (cmd) {
07054 case CLI_INIT:
07055 e->command = "iax2 show registry";
07056 e->usage =
07057 "Usage: iax2 show registry\n"
07058 " Lists all registration requests and status.\n";
07059 return NULL;
07060 case CLI_GENERATE:
07061 return NULL;
07062 }
07063 if (a->argc != 3)
07064 return CLI_SHOWUSAGE;
07065 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07066 AST_LIST_LOCK(®istrations);
07067 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07068 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07069 if (reg->us.sin_addr.s_addr)
07070 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07071 else
07072 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07073 ast_cli(a->fd, FORMAT, host,
07074 (reg->dnsmgr) ? "Y" : "N",
07075 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07076 counter++;
07077 }
07078 AST_LIST_UNLOCK(®istrations);
07079 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07080 return CLI_SUCCESS;
07081 #undef FORMAT
07082 #undef FORMAT2
07083 }
07084
07085 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
07086 {
07087 const char *id = astman_get_header(m, "ActionID");
07088 struct iax2_registry *reg = NULL;
07089 char idtext[256] = "";
07090 char host[80] = "";
07091 char perceived[80] = "";
07092 int total = 0;
07093
07094 if (!ast_strlen_zero(id))
07095 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07096
07097 astman_send_listack(s, m, "Registrations will follow", "start");
07098
07099 AST_LIST_LOCK(®istrations);
07100 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07101 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07102
07103 if (reg->us.sin_addr.s_addr) {
07104 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07105 } else {
07106 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07107 }
07108
07109 astman_append(s,
07110 "Event: RegistryEntry\r\n"
07111 "%s"
07112 "Host: %s\r\n"
07113 "DNSmanager: %s\r\n"
07114 "Username: %s\r\n"
07115 "Perceived: %s\r\n"
07116 "Refresh: %d\r\n"
07117 "State: %s\r\n"
07118 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
07119 reg->refresh, regstate2str(reg->regstate));
07120
07121 total++;
07122 }
07123 AST_LIST_UNLOCK(®istrations);
07124
07125 astman_append(s,
07126 "Event: RegistrationsComplete\r\n"
07127 "EventList: Complete\r\n"
07128 "ListItems: %d\r\n"
07129 "%s"
07130 "\r\n", total, idtext);
07131
07132 return 0;
07133 }
07134
07135 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07136 {
07137 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
07138 #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"
07139 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
07140 int x;
07141 int numchans = 0;
07142 char first_message[10] = { 0, };
07143 char last_message[10] = { 0, };
07144
07145 switch (cmd) {
07146 case CLI_INIT:
07147 e->command = "iax2 show channels";
07148 e->usage =
07149 "Usage: iax2 show channels\n"
07150 " Lists all currently active IAX channels.\n";
07151 return NULL;
07152 case CLI_GENERATE:
07153 return NULL;
07154 }
07155
07156 if (a->argc != 3)
07157 return CLI_SHOWUSAGE;
07158 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07159 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07160 ast_mutex_lock(&iaxsl[x]);
07161 if (iaxs[x]) {
07162 int lag, jitter, localdelay;
07163 jb_info jbinfo;
07164 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07165 jb_getinfo(iaxs[x]->jb, &jbinfo);
07166 jitter = jbinfo.jitter;
07167 localdelay = jbinfo.current - jbinfo.min;
07168 } else {
07169 jitter = -1;
07170 localdelay = 0;
07171 }
07172
07173 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07174 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07175 lag = iaxs[x]->remote_rr.delay;
07176 ast_cli(a->fd, FORMAT,
07177 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07178 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07179 S_OR(iaxs[x]->username, "(None)"),
07180 iaxs[x]->callno, iaxs[x]->peercallno,
07181 iaxs[x]->oseqno, iaxs[x]->iseqno,
07182 lag,
07183 jitter,
07184 localdelay,
07185 ast_getformatname(iaxs[x]->voiceformat),
07186 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07187 first_message,
07188 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07189 last_message);
07190 numchans++;
07191 }
07192 ast_mutex_unlock(&iaxsl[x]);
07193 }
07194 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07195 return CLI_SUCCESS;
07196 #undef FORMAT
07197 #undef FORMAT2
07198 #undef FORMATB
07199 }
07200
07201 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07202 {
07203 int x;
07204 int numchans = 0;
07205 char first_message[10] = { 0, };
07206 char last_message[10] = { 0, };
07207 #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"
07208 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07209 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07210 ast_mutex_lock(&iaxsl[x]);
07211 if (iaxs[x]) {
07212 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07213 jb_info jbinfo;
07214 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07215 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07216
07217 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07218 jb_getinfo(iaxs[x]->jb, &jbinfo);
07219 localjitter = jbinfo.jitter;
07220 localdelay = jbinfo.current - jbinfo.min;
07221 locallost = jbinfo.frames_lost;
07222 locallosspct = jbinfo.losspct/1000;
07223 localdropped = jbinfo.frames_dropped;
07224 localooo = jbinfo.frames_ooo;
07225 } else {
07226 localjitter = -1;
07227 localdelay = 0;
07228 locallost = -1;
07229 locallosspct = -1;
07230 localdropped = 0;
07231 localooo = -1;
07232 }
07233 if (s)
07234 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07235 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07236 iaxs[x]->pingtime,
07237 localjitter,
07238 localdelay,
07239 locallost,
07240 locallosspct,
07241 localdropped,
07242 localooo,
07243 iaxs[x]->frames_received/1000,
07244 iaxs[x]->remote_rr.jitter,
07245 iaxs[x]->remote_rr.delay,
07246 iaxs[x]->remote_rr.losscnt,
07247 iaxs[x]->remote_rr.losspct,
07248 iaxs[x]->remote_rr.dropped,
07249 iaxs[x]->remote_rr.ooo,
07250 iaxs[x]->remote_rr.packets/1000,
07251 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07252 first_message,
07253 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07254 last_message);
07255 else
07256 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07257 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07258 iaxs[x]->pingtime,
07259 localjitter,
07260 localdelay,
07261 locallost,
07262 locallosspct,
07263 localdropped,
07264 localooo,
07265 iaxs[x]->frames_received/1000,
07266 iaxs[x]->remote_rr.jitter,
07267 iaxs[x]->remote_rr.delay,
07268 iaxs[x]->remote_rr.losscnt,
07269 iaxs[x]->remote_rr.losspct,
07270 iaxs[x]->remote_rr.dropped,
07271 iaxs[x]->remote_rr.ooo,
07272 iaxs[x]->remote_rr.packets/1000,
07273 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07274 first_message,
07275 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07276 last_message);
07277 numchans++;
07278 }
07279 ast_mutex_unlock(&iaxsl[x]);
07280 }
07281
07282 return numchans;
07283 }
07284
07285 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07286 {
07287 int numchans = 0;
07288
07289 switch (cmd) {
07290 case CLI_INIT:
07291 e->command = "iax2 show netstats";
07292 e->usage =
07293 "Usage: iax2 show netstats\n"
07294 " Lists network status for all currently active IAX channels.\n";
07295 return NULL;
07296 case CLI_GENERATE:
07297 return NULL;
07298 }
07299 if (a->argc != 3)
07300 return CLI_SHOWUSAGE;
07301 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07302 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07303 numchans = ast_cli_netstats(NULL, a->fd, 1);
07304 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07305 return CLI_SUCCESS;
07306 }
07307
07308 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07309 {
07310 switch (cmd) {
07311 case CLI_INIT:
07312 e->command = "iax2 set debug {on|off|peer}";
07313 e->usage =
07314 "Usage: iax2 set debug {on|off|peer peername}\n"
07315 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07316 return NULL;
07317 case CLI_GENERATE:
07318 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07319 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07320 return NULL;
07321 }
07322
07323 if (a->argc < e->args || a->argc > e->args + 1)
07324 return CLI_SHOWUSAGE;
07325
07326 if (!strcasecmp(a->argv[3], "peer")) {
07327 struct iax2_peer *peer;
07328 struct sockaddr_in peer_addr;
07329
07330
07331 if (a->argc != e->args + 1)
07332 return CLI_SHOWUSAGE;
07333
07334 peer = find_peer(a->argv[4], 1);
07335
07336 if (!peer) {
07337 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07338 return CLI_FAILURE;
07339 }
07340
07341 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07342
07343 debugaddr.sin_addr = peer_addr.sin_addr;
07344 debugaddr.sin_port = peer_addr.sin_port;
07345
07346 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07347 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07348
07349 ao2_ref(peer, -1);
07350 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07351 iaxdebug = 1;
07352 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07353 } else {
07354 iaxdebug = 0;
07355 memset(&debugaddr, 0, sizeof(debugaddr));
07356 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07357 }
07358 return CLI_SUCCESS;
07359 }
07360
07361 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07362 {
07363 switch (cmd) {
07364 case CLI_INIT:
07365 e->command = "iax2 set debug trunk {on|off}";
07366 e->usage =
07367 "Usage: iax2 set debug trunk {on|off}\n"
07368 " Enables/Disables debugging of IAX trunking\n";
07369 return NULL;
07370 case CLI_GENERATE:
07371 return NULL;
07372 }
07373
07374 if (a->argc != e->args)
07375 return CLI_SHOWUSAGE;
07376
07377 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07378 iaxtrunkdebug = 1;
07379 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07380 } else {
07381 iaxtrunkdebug = 0;
07382 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07383 }
07384 return CLI_SUCCESS;
07385 }
07386
07387 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07388 {
07389 switch (cmd) {
07390 case CLI_INIT:
07391 e->command = "iax2 set debug jb {on|off}";
07392 e->usage =
07393 "Usage: iax2 set debug jb {on|off}\n"
07394 " Enables/Disables jitterbuffer debugging information\n";
07395 return NULL;
07396 case CLI_GENERATE:
07397 return NULL;
07398 }
07399
07400 if (a->argc != e->args)
07401 return CLI_SHOWUSAGE;
07402
07403 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07404 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07405 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07406 } else {
07407 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07408 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07409 }
07410 return CLI_SUCCESS;
07411 }
07412
07413 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07414 {
07415 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07416 int res = -1;
07417 ast_mutex_lock(&iaxsl[callno]);
07418 if (iaxs[callno]) {
07419
07420 if (!iaxs[callno]->error) {
07421 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07422 res = 0;
07423
07424 else if (f->frametype == AST_FRAME_NULL)
07425 res = 0;
07426 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07427 res = 0;
07428 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07429 res = 0;
07430 else
07431
07432 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07433 } else {
07434 ast_debug(1, "Write error: %s\n", strerror(errno));
07435 }
07436 }
07437
07438 ast_mutex_unlock(&iaxsl[callno]);
07439 return res;
07440 }
07441
07442 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07443 int now, int transfer, int final)
07444 {
07445 struct ast_frame f = { 0, };
07446 int res = 0;
07447
07448 f.frametype = type;
07449 f.subclass.integer = command;
07450 f.datalen = datalen;
07451 f.src = __FUNCTION__;
07452 f.data.ptr = (void *) data;
07453
07454 if ((res = queue_signalling(i, &f)) <= 0) {
07455 return res;
07456 }
07457
07458 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07459 }
07460
07461 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07462 {
07463 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07464 }
07465
07466 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07467 {
07468 int res;
07469 ast_mutex_lock(&iaxsl[callno]);
07470 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07471 ast_mutex_unlock(&iaxsl[callno]);
07472 return res;
07473 }
07474
07475
07476
07477
07478
07479
07480 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)
07481 {
07482 int call_num = i->callno;
07483
07484 iax2_predestroy(i->callno);
07485 if (!iaxs[call_num])
07486 return -1;
07487 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07488 }
07489
07490 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)
07491 {
07492 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07493 }
07494
07495 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07496 {
07497 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07498 }
07499
07500 static int apply_context(struct iax2_context *con, const char *context)
07501 {
07502 while(con) {
07503 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07504 return -1;
07505 con = con->next;
07506 }
07507 return 0;
07508 }
07509
07510
07511 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07512 {
07513
07514 int res = -1;
07515 int version = 2;
07516 struct iax2_user *user = NULL, *best = NULL;
07517 int bestscore = 0;
07518 int gotcapability = 0;
07519 struct ast_variable *v = NULL, *tmpvar = NULL;
07520 struct ao2_iterator i;
07521 struct ast_sockaddr addr;
07522
07523 if (!iaxs[callno])
07524 return res;
07525 if (ies->called_number)
07526 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07527 if (ies->calling_number) {
07528 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07529 ast_shrink_phone_number(ies->calling_number);
07530 }
07531 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07532 }
07533 if (ies->calling_name)
07534 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07535 if (ies->calling_ani)
07536 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07537 if (ies->dnid)
07538 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07539 if (ies->rdnis)
07540 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07541 if (ies->called_context)
07542 ast_string_field_set(iaxs[callno], context, ies->called_context);
07543 if (ies->language)
07544 ast_string_field_set(iaxs[callno], language, ies->language);
07545 if (ies->username)
07546 ast_string_field_set(iaxs[callno], username, ies->username);
07547 if (ies->calling_ton > -1)
07548 iaxs[callno]->calling_ton = ies->calling_ton;
07549 if (ies->calling_tns > -1)
07550 iaxs[callno]->calling_tns = ies->calling_tns;
07551 if (ies->calling_pres > -1)
07552 iaxs[callno]->calling_pres = ies->calling_pres;
07553 if (ies->format)
07554 iaxs[callno]->peerformat = ies->format;
07555 if (ies->adsicpe)
07556 iaxs[callno]->peeradsicpe = ies->adsicpe;
07557 if (ies->capability) {
07558 gotcapability = 1;
07559 iaxs[callno]->peercapability = ies->capability;
07560 }
07561 if (ies->version)
07562 version = ies->version;
07563
07564
07565 if (ies->codec_prefs) {
07566 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07567 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07568 }
07569
07570 if (!gotcapability)
07571 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07572 if (version > IAX_PROTO_VERSION) {
07573 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07574 ast_inet_ntoa(sin->sin_addr), version);
07575 return res;
07576 }
07577
07578 ast_sockaddr_from_sin(&addr, sin);
07579 i = ao2_iterator_init(users, 0);
07580 while ((user = ao2_iterator_next(&i))) {
07581 if ((ast_strlen_zero(iaxs[callno]->username) ||
07582 !strcmp(iaxs[callno]->username, user->name))
07583 && ast_apply_ha(user->ha, &addr)
07584 && (ast_strlen_zero(iaxs[callno]->context) ||
07585 apply_context(user->contexts, iaxs[callno]->context))) {
07586 if (!ast_strlen_zero(iaxs[callno]->username)) {
07587
07588 if (best)
07589 user_unref(best);
07590 best = user;
07591 break;
07592 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07593
07594 if (user->ha) {
07595
07596 if (bestscore < 4) {
07597 bestscore = 4;
07598 if (best)
07599 user_unref(best);
07600 best = user;
07601 continue;
07602 }
07603 } else {
07604
07605 if (bestscore < 3) {
07606 bestscore = 3;
07607 if (best)
07608 user_unref(best);
07609 best = user;
07610 continue;
07611 }
07612 }
07613 } else {
07614 if (user->ha) {
07615
07616 if (bestscore < 2) {
07617 bestscore = 2;
07618 if (best)
07619 user_unref(best);
07620 best = user;
07621 continue;
07622 }
07623 } else {
07624
07625 if (bestscore < 1) {
07626 bestscore = 1;
07627 if (best)
07628 user_unref(best);
07629 best = user;
07630 continue;
07631 }
07632 }
07633 }
07634 }
07635 user_unref(user);
07636 }
07637 ao2_iterator_destroy(&i);
07638 user = best;
07639 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07640 user = realtime_user(iaxs[callno]->username, sin);
07641 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07642 !apply_context(user->contexts, iaxs[callno]->context)) {
07643 user = user_unref(user);
07644 }
07645 }
07646 if (user) {
07647
07648
07649 for (v = user->vars ; v ; v = v->next) {
07650 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07651 tmpvar->next = iaxs[callno]->vars;
07652 iaxs[callno]->vars = tmpvar;
07653 }
07654 }
07655
07656 if (user->maxauthreq > 0)
07657 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07658 iaxs[callno]->prefs = user->prefs;
07659 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07660 iaxs[callno]->encmethods = user->encmethods;
07661
07662 if (ast_strlen_zero(iaxs[callno]->username))
07663 ast_string_field_set(iaxs[callno], username, user->name);
07664
07665 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07666 iaxs[callno]->capability = user->capability;
07667
07668 if (ast_strlen_zero(iaxs[callno]->context)) {
07669 if (user->contexts)
07670 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07671 else
07672 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07673 }
07674
07675 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07676
07677 iaxs[callno]->authmethods = user->authmethods;
07678 iaxs[callno]->adsi = user->adsi;
07679
07680 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07681 iaxs[callno]->calling_tns = 0;
07682 iaxs[callno]->calling_ton = 0;
07683 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07684 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07685 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07686 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07687 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07688 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07689 }
07690 if (!ast_strlen_zero(user->accountcode))
07691 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07692 if (!ast_strlen_zero(user->mohinterpret))
07693 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07694 if (!ast_strlen_zero(user->mohsuggest))
07695 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07696 if (!ast_strlen_zero(user->parkinglot))
07697 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07698 if (user->amaflags)
07699 iaxs[callno]->amaflags = user->amaflags;
07700 if (!ast_strlen_zero(user->language))
07701 ast_string_field_set(iaxs[callno], language, user->language);
07702 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07703
07704 if (!ast_strlen_zero(user->dbsecret)) {
07705 char *family, *key=NULL;
07706 char buf[80];
07707 family = ast_strdupa(user->dbsecret);
07708 key = strchr(family, '/');
07709 if (key) {
07710 *key = '\0';
07711 key++;
07712 }
07713 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07714 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07715 else
07716 ast_string_field_set(iaxs[callno], secret, buf);
07717 } else
07718 ast_string_field_set(iaxs[callno], secret, user->secret);
07719 res = 0;
07720 user = user_unref(user);
07721 } else {
07722
07723
07724
07725
07726 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07727 ast_string_field_set(iaxs[callno], secret, "badsecret");
07728 iaxs[callno]->authrej = 1;
07729 if (!ast_strlen_zero(iaxs[callno]->username)) {
07730
07731 res = 0;
07732 }
07733 }
07734 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07735 return res;
07736 }
07737
07738 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07739 {
07740 struct ast_iax2_full_hdr fh;
07741 fh.scallno = htons(src | IAX_FLAG_FULL);
07742 fh.dcallno = htons(dst);
07743 fh.ts = 0;
07744 fh.oseqno = 0;
07745 fh.iseqno = 0;
07746 fh.type = AST_FRAME_IAX;
07747 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07748 iax_outputframe(NULL, &fh, 0, sin, 0);
07749 #if 0
07750 if (option_debug)
07751 #endif
07752 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07753 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07754 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07755 }
07756
07757 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07758 {
07759
07760 p->encmethods &= enc;
07761 if (p->encmethods) {
07762 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07763 p->keyrotateid = -2;
07764 }
07765 if (p->encmethods & IAX_ENCRYPT_AES128)
07766 p->encmethods = IAX_ENCRYPT_AES128;
07767 else
07768 p->encmethods = 0;
07769 }
07770 }
07771
07772
07773
07774
07775
07776
07777
07778 static int authenticate_request(int call_num)
07779 {
07780 struct iax_ie_data ied;
07781 int res = -1, authreq_restrict = 0;
07782 char challenge[10];
07783 struct chan_iax2_pvt *p = iaxs[call_num];
07784
07785 memset(&ied, 0, sizeof(ied));
07786
07787
07788 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07789 struct iax2_user *user, tmp_user = {
07790 .name = p->username,
07791 };
07792
07793 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07794 if (user) {
07795 if (user->curauthreq == user->maxauthreq)
07796 authreq_restrict = 1;
07797 else
07798 user->curauthreq++;
07799 user = user_unref(user);
07800 }
07801 }
07802
07803
07804 if (authreq_restrict) {
07805 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07806 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07807 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07808 return 0;
07809 }
07810
07811 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07812 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07813 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07814 ast_string_field_set(p, challenge, challenge);
07815
07816 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07817 }
07818 if (p->encmethods)
07819 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07820
07821 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07822
07823 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07824
07825 if (p->encmethods)
07826 ast_set_flag64(p, IAX_ENCRYPTED);
07827
07828 return res;
07829 }
07830
07831 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07832 {
07833 char requeststr[256];
07834 char md5secret[256] = "";
07835 char secret[256] = "";
07836 char rsasecret[256] = "";
07837 int res = -1;
07838 int x;
07839 struct iax2_user *user, tmp_user = {
07840 .name = p->username,
07841 };
07842
07843 if (p->authrej) {
07844 return res;
07845 }
07846 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07847 if (user) {
07848 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07849 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07850 ast_clear_flag64(p, IAX_MAXAUTHREQ);
07851 }
07852 ast_string_field_set(p, host, user->name);
07853 user = user_unref(user);
07854 }
07855 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07856 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07857 return res;
07858 }
07859 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07860 return res;
07861 if (ies->password)
07862 ast_copy_string(secret, ies->password, sizeof(secret));
07863 if (ies->md5_result)
07864 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07865 if (ies->rsa_result)
07866 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07867 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07868 struct ast_key *key;
07869 char *keyn;
07870 char tmpkey[256];
07871 char *stringp=NULL;
07872 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07873 stringp=tmpkey;
07874 keyn = strsep(&stringp, ":");
07875 while(keyn) {
07876 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07877 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07878 res = 0;
07879 break;
07880 } else if (!key)
07881 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07882 keyn = strsep(&stringp, ":");
07883 }
07884 } else if (p->authmethods & IAX_AUTH_MD5) {
07885 struct MD5Context md5;
07886 unsigned char digest[16];
07887 char *tmppw, *stringp;
07888
07889 tmppw = ast_strdupa(p->secret);
07890 stringp = tmppw;
07891 while((tmppw = strsep(&stringp, ";"))) {
07892 MD5Init(&md5);
07893 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07894 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07895 MD5Final(digest, &md5);
07896
07897 for (x=0;x<16;x++)
07898 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07899 if (!strcasecmp(requeststr, md5secret)) {
07900 res = 0;
07901 break;
07902 }
07903 }
07904 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07905 if (!strcmp(secret, p->secret))
07906 res = 0;
07907 }
07908 return res;
07909 }
07910
07911
07912 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07913 {
07914 char requeststr[256] = "";
07915 char peer[256] = "";
07916 char md5secret[256] = "";
07917 char rsasecret[256] = "";
07918 char secret[256] = "";
07919 struct iax2_peer *p = NULL;
07920 struct ast_key *key;
07921 char *keyn;
07922 int x;
07923 int expire = 0;
07924 int res = -1;
07925 struct ast_sockaddr addr;
07926
07927 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07928
07929 if (ies->username)
07930 ast_copy_string(peer, ies->username, sizeof(peer));
07931 if (ies->password)
07932 ast_copy_string(secret, ies->password, sizeof(secret));
07933 if (ies->md5_result)
07934 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07935 if (ies->rsa_result)
07936 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07937 if (ies->refresh)
07938 expire = ies->refresh;
07939
07940 if (ast_strlen_zero(peer)) {
07941 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07942 return -1;
07943 }
07944
07945
07946 ast_mutex_unlock(&iaxsl[callno]);
07947 p = find_peer(peer, 1);
07948 ast_mutex_lock(&iaxsl[callno]);
07949 if (!p || !iaxs[callno]) {
07950 if (iaxs[callno]) {
07951 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07952
07953 ast_string_field_set(iaxs[callno], secret, "badsecret");
07954
07955
07956
07957
07958
07959
07960
07961
07962
07963 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07964 !(!ast_strlen_zero(secret) && plaintext)) {
07965
07966 res = 0;
07967 }
07968 }
07969 if (authdebug && !p)
07970 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07971 goto return_unref;
07972 }
07973
07974 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
07975 if (authdebug)
07976 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07977 goto return_unref;
07978 }
07979
07980 ast_sockaddr_from_sin(&addr, sin);
07981 if (!ast_apply_ha(p->ha, &addr)) {
07982 if (authdebug)
07983 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07984 goto return_unref;
07985 }
07986 ast_string_field_set(iaxs[callno], secret, p->secret);
07987 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07988
07989 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07990 if (!ast_strlen_zero(p->inkeys)) {
07991 char tmpkeys[256];
07992 char *stringp=NULL;
07993 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07994 stringp=tmpkeys;
07995 keyn = strsep(&stringp, ":");
07996 while(keyn) {
07997 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07998 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07999 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08000 break;
08001 } else if (!key)
08002 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08003 keyn = strsep(&stringp, ":");
08004 }
08005 if (!keyn) {
08006 if (authdebug)
08007 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08008 goto return_unref;
08009 }
08010 } else {
08011 if (authdebug)
08012 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08013 goto return_unref;
08014 }
08015 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08016 struct MD5Context md5;
08017 unsigned char digest[16];
08018 char *tmppw, *stringp;
08019
08020 tmppw = ast_strdupa(p->secret);
08021 stringp = tmppw;
08022 while((tmppw = strsep(&stringp, ";"))) {
08023 MD5Init(&md5);
08024 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08025 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08026 MD5Final(digest, &md5);
08027 for (x=0;x<16;x++)
08028 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08029 if (!strcasecmp(requeststr, md5secret))
08030 break;
08031 }
08032 if (tmppw) {
08033 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08034 } else {
08035 if (authdebug)
08036 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08037 goto return_unref;
08038 }
08039 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08040
08041 if (strcmp(secret, p->secret)) {
08042 if (authdebug)
08043 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08044 goto return_unref;
08045 } else
08046 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08047 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08048
08049 goto return_unref;
08050 }
08051 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08052
08053
08054 res = 0;
08055
08056 return_unref:
08057 if (iaxs[callno]) {
08058 ast_string_field_set(iaxs[callno], peer, peer);
08059
08060
08061 if (expire && (expire < iaxs[callno]->expiry)) {
08062 iaxs[callno]->expiry = expire;
08063 }
08064 }
08065
08066 if (p) {
08067 peer_unref(p);
08068 }
08069 return res;
08070 }
08071
08072 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)
08073 {
08074 int res = -1;
08075 int x;
08076 if (!ast_strlen_zero(keyn)) {
08077 if (!(authmethods & IAX_AUTH_RSA)) {
08078 if (ast_strlen_zero(secret))
08079 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));
08080 } else if (ast_strlen_zero(challenge)) {
08081 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08082 } else {
08083 char sig[256];
08084 struct ast_key *key;
08085 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08086 if (!key) {
08087 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08088 } else {
08089 if (ast_sign(key, (char*)challenge, sig)) {
08090 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08091 res = -1;
08092 } else {
08093 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08094 res = 0;
08095 }
08096 }
08097 }
08098 }
08099
08100 if (res && !ast_strlen_zero(secret)) {
08101 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08102 struct MD5Context md5;
08103 unsigned char digest[16];
08104 char digres[128];
08105 MD5Init(&md5);
08106 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08107 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08108 MD5Final(digest, &md5);
08109
08110 for (x=0;x<16;x++)
08111 sprintf(digres + (x << 1), "%2.2x", digest[x]);
08112 if (pvt) {
08113 build_encryption_keys(digest, pvt);
08114 }
08115 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08116 res = 0;
08117 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08118 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08119 res = 0;
08120 } else
08121 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08122 }
08123 return res;
08124 }
08125
08126
08127
08128
08129
08130 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08131 {
08132 struct iax2_peer *peer = NULL;
08133
08134 int res = -1;
08135 int authmethods = 0;
08136 struct iax_ie_data ied;
08137 uint16_t callno = p->callno;
08138
08139 memset(&ied, 0, sizeof(ied));
08140
08141 if (ies->username)
08142 ast_string_field_set(p, username, ies->username);
08143 if (ies->challenge)
08144 ast_string_field_set(p, challenge, ies->challenge);
08145 if (ies->authmethods)
08146 authmethods = ies->authmethods;
08147 if (authmethods & IAX_AUTH_MD5)
08148 merge_encryption(p, ies->encmethods);
08149 else
08150 p->encmethods = 0;
08151
08152
08153 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08154
08155 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08156 } else {
08157 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08158 while ((peer = ao2_iterator_next(&i))) {
08159 struct sockaddr_in peer_addr;
08160
08161 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08162
08163 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08164
08165 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08166
08167 && (!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)))
08168
08169 ) {
08170 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08171 if (!res) {
08172 peer_unref(peer);
08173 break;
08174 }
08175 }
08176 peer_unref(peer);
08177 }
08178 ao2_iterator_destroy(&i);
08179 if (!peer) {
08180
08181
08182 const char *peer_name = ast_strdupa(p->peer);
08183 ast_mutex_unlock(&iaxsl[callno]);
08184 if ((peer = realtime_peer(peer_name, NULL))) {
08185 ast_mutex_lock(&iaxsl[callno]);
08186 if (!(p = iaxs[callno])) {
08187 peer_unref(peer);
08188 return -1;
08189 }
08190 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08191 peer_unref(peer);
08192 }
08193 if (!peer) {
08194 ast_mutex_lock(&iaxsl[callno]);
08195 if (!(p = iaxs[callno]))
08196 return -1;
08197 }
08198 }
08199 }
08200
08201 if (ies->encmethods) {
08202 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08203 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08204 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08205 return -1;
08206 }
08207 if (!res) {
08208 struct ast_datastore *variablestore;
08209 struct ast_variable *var, *prev = NULL;
08210 AST_LIST_HEAD(, ast_var_t) *varlist;
08211 varlist = ast_calloc(1, sizeof(*varlist));
08212 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08213 if (variablestore && varlist && p->owner) {
08214 variablestore->data = varlist;
08215 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08216 AST_LIST_HEAD_INIT(varlist);
08217 for (var = ies->vars; var; var = var->next) {
08218 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08219 if (prev)
08220 ast_free(prev);
08221 prev = var;
08222 if (!newvar) {
08223
08224 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08225 } else {
08226 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08227 }
08228 }
08229 if (prev)
08230 ast_free(prev);
08231 ies->vars = NULL;
08232 ast_channel_datastore_add(p->owner, variablestore);
08233 } else {
08234 if (p->owner)
08235 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08236 if (variablestore)
08237 ast_datastore_free(variablestore);
08238 if (varlist)
08239 ast_free(varlist);
08240 }
08241 }
08242
08243 if (!res)
08244 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08245 return res;
08246 }
08247
08248 static int iax2_do_register(struct iax2_registry *reg);
08249
08250 static void __iax2_do_register_s(const void *data)
08251 {
08252 struct iax2_registry *reg = (struct iax2_registry *)data;
08253 reg->expire = -1;
08254 iax2_do_register(reg);
08255 }
08256
08257 static int iax2_do_register_s(const void *data)
08258 {
08259 #ifdef SCHED_MULTITHREADED
08260 if (schedule_action(__iax2_do_register_s, data))
08261 #endif
08262 __iax2_do_register_s(data);
08263 return 0;
08264 }
08265
08266 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08267 {
08268 int newcall = 0;
08269 char newip[256];
08270 struct iax_ie_data ied;
08271 struct sockaddr_in new;
08272
08273
08274 memset(&ied, 0, sizeof(ied));
08275 if (ies->apparent_addr)
08276 memmove(&new, ies->apparent_addr, sizeof(new));
08277 if (ies->callno)
08278 newcall = ies->callno;
08279 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08280 ast_log(LOG_WARNING, "Invalid transfer request\n");
08281 return -1;
08282 }
08283 pvt->transfercallno = newcall;
08284 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08285 inet_aton(newip, &pvt->transfer.sin_addr);
08286 pvt->transfer.sin_family = AF_INET;
08287 pvt->transferid = ies->transferid;
08288
08289
08290 if (pvt->transferring == TRANSFER_NONE) {
08291 store_by_transfercallno(pvt);
08292 }
08293 pvt->transferring = TRANSFER_BEGIN;
08294
08295 if (ies->transferid)
08296 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08297 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08298 return 0;
08299 }
08300
08301 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08302 {
08303 char exten[256] = "";
08304 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08305 struct iax2_dpcache *dp = NULL;
08306
08307 if (ies->called_number)
08308 ast_copy_string(exten, ies->called_number, sizeof(exten));
08309
08310 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08311 status = CACHE_FLAG_EXISTS;
08312 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08313 status = CACHE_FLAG_CANEXIST;
08314 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08315 status = CACHE_FLAG_NONEXISTENT;
08316
08317 if (ies->refresh)
08318 expiry = ies->refresh;
08319 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08320 matchmore = CACHE_FLAG_MATCHMORE;
08321
08322 AST_LIST_LOCK(&dpcache);
08323 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08324 if (strcmp(dp->exten, exten))
08325 continue;
08326 AST_LIST_REMOVE_CURRENT(peer_list);
08327 dp->callno = 0;
08328 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08329 if (dp->flags & CACHE_FLAG_PENDING) {
08330 dp->flags &= ~CACHE_FLAG_PENDING;
08331 dp->flags |= status;
08332 dp->flags |= matchmore;
08333 }
08334
08335 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08336 if (dp->waiters[x] > -1) {
08337 if (write(dp->waiters[x], "asdf", 4) < 0) {
08338 }
08339 }
08340 }
08341 }
08342 AST_LIST_TRAVERSE_SAFE_END;
08343 AST_LIST_UNLOCK(&dpcache);
08344
08345 return 0;
08346 }
08347
08348 static int complete_transfer(int callno, struct iax_ies *ies)
08349 {
08350 int peercallno = 0;
08351 struct chan_iax2_pvt *pvt = iaxs[callno];
08352 struct iax_frame *cur;
08353 jb_frame frame;
08354
08355 if (ies->callno)
08356 peercallno = ies->callno;
08357
08358 if (peercallno < 1) {
08359 ast_log(LOG_WARNING, "Invalid transfer request\n");
08360 return -1;
08361 }
08362 remove_by_transfercallno(pvt);
08363
08364
08365
08366 peercnt_remove_by_addr(&pvt->addr);
08367 peercnt_add(&pvt->transfer);
08368
08369 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08370 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08371
08372 pvt->oseqno = 0;
08373 pvt->rseqno = 0;
08374 pvt->iseqno = 0;
08375 pvt->aseqno = 0;
08376
08377 if (pvt->peercallno) {
08378 remove_by_peercallno(pvt);
08379 }
08380 pvt->peercallno = peercallno;
08381
08382 store_by_peercallno(pvt);
08383 pvt->transferring = TRANSFER_NONE;
08384 pvt->svoiceformat = -1;
08385 pvt->voiceformat = 0;
08386 pvt->svideoformat = -1;
08387 pvt->videoformat = 0;
08388 pvt->transfercallno = 0;
08389 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08390 memset(&pvt->offset, 0, sizeof(pvt->offset));
08391
08392 while(jb_getall(pvt->jb,&frame) == JB_OK)
08393 iax2_frame_free(frame.data);
08394 jb_reset(pvt->jb);
08395 pvt->lag = 0;
08396 pvt->last = 0;
08397 pvt->lastsent = 0;
08398 pvt->nextpred = 0;
08399 pvt->pingtime = DEFAULT_RETRY_TIME;
08400 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08401
08402
08403
08404 cur->retries = -1;
08405 }
08406 return 0;
08407 }
08408
08409
08410 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08411 {
08412 struct iax2_registry *reg;
08413
08414 char peer[256] = "";
08415 char msgstatus[60];
08416 int refresh = 60;
08417 char ourip[256] = "<Unspecified>";
08418 struct sockaddr_in oldus;
08419 struct sockaddr_in us;
08420 int oldmsgs;
08421 struct sockaddr_in reg_addr;
08422
08423 memset(&us, 0, sizeof(us));
08424 if (ies->apparent_addr) {
08425 memmove(&us, ies->apparent_addr, sizeof(us));
08426 }
08427 if (ies->username) {
08428 ast_copy_string(peer, ies->username, sizeof(peer));
08429 }
08430 if (ies->refresh) {
08431 refresh = ies->refresh;
08432 }
08433 if (ies->calling_number) {
08434
08435 }
08436 reg = iaxs[callno]->reg;
08437 if (!reg) {
08438 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08439 return -1;
08440 }
08441 memcpy(&oldus, ®->us, sizeof(oldus));
08442 oldmsgs = reg->messages;
08443 ast_sockaddr_to_sin(®->addr, ®_addr);
08444 if (inaddrcmp(®_addr, sin)) {
08445 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08446 return -1;
08447 }
08448 memcpy(®->us, &us, sizeof(reg->us));
08449 if (ies->msgcount >= 0) {
08450 reg->messages = ies->msgcount & 0xffff;
08451 }
08452
08453
08454
08455 reg->refresh = refresh;
08456 reg->expire = iax2_sched_replace(reg->expire, sched,
08457 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08458 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08459 if (reg->messages > 255) {
08460 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08461 } else if (reg->messages > 1) {
08462 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages);
08463 } else if (reg->messages > 0) {
08464 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus));
08465 } else {
08466 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus));
08467 }
08468 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08469 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08470 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08471 }
08472 reg->regstate = REG_STATE_REGISTERED;
08473 return 0;
08474 }
08475
08476 static int iax2_append_register(const char *hostname, const char *username,
08477 const char *secret, const char *porta)
08478 {
08479 struct iax2_registry *reg;
08480
08481 if (!(reg = ast_calloc(1, sizeof(*reg))))
08482 return -1;
08483
08484 reg->addr.ss.ss_family = AF_INET;
08485 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08486 ast_free(reg);
08487 return -1;
08488 }
08489
08490 ast_copy_string(reg->username, username, sizeof(reg->username));
08491
08492 if (secret)
08493 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08494
08495 reg->expire = -1;
08496 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08497 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08498
08499 AST_LIST_LOCK(®istrations);
08500 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08501 AST_LIST_UNLOCK(®istrations);
08502
08503 return 0;
08504 }
08505
08506 static int iax2_register(const char *value, int lineno)
08507 {
08508 char copy[256];
08509 char *username, *hostname, *secret;
08510 char *porta;
08511 char *stringp=NULL;
08512
08513 if (!value)
08514 return -1;
08515
08516 ast_copy_string(copy, value, sizeof(copy));
08517 stringp = copy;
08518 username = strsep(&stringp, "@");
08519 hostname = strsep(&stringp, "@");
08520
08521 if (!hostname) {
08522 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08523 return -1;
08524 }
08525
08526 stringp = username;
08527 username = strsep(&stringp, ":");
08528 secret = strsep(&stringp, ":");
08529 stringp = hostname;
08530 hostname = strsep(&stringp, ":");
08531 porta = strsep(&stringp, ":");
08532
08533 if (porta && !atoi(porta)) {
08534 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08535 return -1;
08536 }
08537
08538 return iax2_append_register(hostname, username, secret, porta);
08539 }
08540
08541
08542 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08543 {
08544 char multi[256];
08545 char *stringp, *ext;
08546 if (!ast_strlen_zero(regcontext)) {
08547 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08548 stringp = multi;
08549 while((ext = strsep(&stringp, "&"))) {
08550 if (onoff) {
08551 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08552 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08553 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08554 } else
08555 ast_context_remove_extension(regcontext, ext, 1, NULL);
08556 }
08557 }
08558 }
08559 static void prune_peers(void);
08560
08561 static void unlink_peer(struct iax2_peer *peer)
08562 {
08563 if (peer->expire > -1) {
08564 if (!ast_sched_thread_del(sched, peer->expire)) {
08565 peer->expire = -1;
08566 peer_unref(peer);
08567 }
08568 }
08569
08570 if (peer->pokeexpire > -1) {
08571 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08572 peer->pokeexpire = -1;
08573 peer_unref(peer);
08574 }
08575 }
08576
08577 ao2_unlink(peers, peer);
08578 }
08579
08580 static void __expire_registry(const void *data)
08581 {
08582 struct iax2_peer *peer = (struct iax2_peer *) data;
08583
08584 if (!peer)
08585 return;
08586 if (peer->expire == -1) {
08587
08588 return;
08589 }
08590
08591 peer->expire = -1;
08592
08593 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08594 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08595 realtime_update_peer(peer->name, &peer->addr, 0);
08596 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08597
08598 peercnt_modify(0, 0, &peer->addr);
08599
08600 memset(&peer->addr, 0, sizeof(peer->addr));
08601
08602 peer->expiry = min_reg_expire;
08603 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08604 ast_db_del("IAX/Registry", peer->name);
08605 register_peer_exten(peer, 0);
08606 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08607 if (iax2_regfunk)
08608 iax2_regfunk(peer->name, 0);
08609
08610 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08611 unlink_peer(peer);
08612
08613 peer_unref(peer);
08614 }
08615
08616 static int expire_registry(const void *data)
08617 {
08618 #ifdef SCHED_MULTITHREADED
08619 if (schedule_action(__expire_registry, data))
08620 #endif
08621 __expire_registry(data);
08622 return 0;
08623 }
08624
08625 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08626
08627 static void reg_source_db(struct iax2_peer *p)
08628 {
08629 char data[80];
08630 char *expiry;
08631
08632 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08633 return;
08634 }
08635
08636 expiry = strrchr(data, ':');
08637 if (!expiry) {
08638 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08639 }
08640 *expiry++ = '\0';
08641
08642 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08643 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08644 return;
08645 }
08646
08647 p->expiry = atoi(expiry);
08648
08649 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08650 ast_sockaddr_stringify(&p->addr), p->expiry);
08651
08652 iax2_poke_peer(p, 0);
08653 if (p->expire > -1) {
08654 if (!ast_sched_thread_del(sched, p->expire)) {
08655 p->expire = -1;
08656 peer_unref(p);
08657 }
08658 }
08659
08660 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08661
08662 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08663 if (p->expire == -1) {
08664 peer_unref(p);
08665 }
08666
08667 if (iax2_regfunk) {
08668 iax2_regfunk(p->name, 1);
08669 }
08670
08671 register_peer_exten(p, 1);
08672 }
08673
08674
08675
08676
08677
08678
08679
08680 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08681 {
08682
08683 struct iax_ie_data ied = {
08684 .pos = 0,
08685 };
08686 struct iax2_peer *p;
08687 int msgcount;
08688 char data[80];
08689 int version;
08690 const char *peer_name;
08691 int res = -1;
08692 struct ast_sockaddr sockaddr;
08693
08694 ast_sockaddr_from_sin(&sockaddr, sin);
08695
08696 peer_name = ast_strdupa(iaxs[callno]->peer);
08697
08698
08699 ast_mutex_unlock(&iaxsl[callno]);
08700 if (!(p = find_peer(peer_name, 1))) {
08701 ast_mutex_lock(&iaxsl[callno]);
08702 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08703 return -1;
08704 }
08705 ast_mutex_lock(&iaxsl[callno]);
08706 if (!iaxs[callno])
08707 goto return_unref;
08708
08709 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08710 if (sin->sin_addr.s_addr) {
08711 time_t nowtime;
08712 time(&nowtime);
08713 realtime_update_peer(peer_name, &sockaddr, nowtime);
08714 } else {
08715 realtime_update_peer(peer_name, &sockaddr, 0);
08716 }
08717 }
08718
08719 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08720 if (iax2_regfunk) {
08721 iax2_regfunk(p->name, 1);
08722 }
08723
08724
08725 peercnt_modify(0, 0, &p->addr);
08726
08727
08728 ast_sockaddr_from_sin(&p->addr, sin);
08729
08730 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08731 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08732 ast_db_put("IAX/Registry", p->name, data);
08733 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08734 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08735 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08736 register_peer_exten(p, 1);
08737 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08738 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08739 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08740 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08741 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08742 register_peer_exten(p, 0);
08743 ast_db_del("IAX/Registry", p->name);
08744 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08745 }
08746
08747
08748 iax2_poke_peer(p, callno);
08749 }
08750
08751
08752 if (p->maxcallno) {
08753 peercnt_modify(1, p->maxcallno, &p->addr);
08754 }
08755
08756
08757 if (!iaxs[callno]) {
08758 res = -1;
08759 goto return_unref;
08760 }
08761
08762
08763 p->sockfd = fd;
08764
08765 if (p->expire > -1) {
08766 if (!ast_sched_thread_del(sched, p->expire)) {
08767 p->expire = -1;
08768 peer_unref(p);
08769 }
08770 }
08771
08772 if (!refresh)
08773 refresh = min_reg_expire;
08774 if (refresh > max_reg_expire) {
08775 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08776 p->name, max_reg_expire, refresh);
08777 p->expiry = max_reg_expire;
08778 } else if (refresh < min_reg_expire) {
08779 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08780 p->name, min_reg_expire, refresh);
08781 p->expiry = min_reg_expire;
08782 } else {
08783 p->expiry = refresh;
08784 }
08785 if (p->expiry && sin->sin_addr.s_addr) {
08786 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08787 if (p->expire == -1)
08788 peer_unref(p);
08789 }
08790 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08791 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08792 if (sin->sin_addr.s_addr) {
08793 struct sockaddr_in peer_addr;
08794
08795 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08796
08797 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08798 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08799 if (!ast_strlen_zero(p->mailbox)) {
08800 struct ast_event *event;
08801 int new, old;
08802 char *mailbox, *context;
08803
08804 context = mailbox = ast_strdupa(p->mailbox);
08805 strsep(&context, "@");
08806 if (ast_strlen_zero(context))
08807 context = "default";
08808
08809 event = ast_event_get_cached(AST_EVENT_MWI,
08810 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08811 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08812 AST_EVENT_IE_END);
08813 if (event) {
08814 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08815 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08816 ast_event_destroy(event);
08817 } else {
08818 ast_app_inboxcount(p->mailbox, &new, &old);
08819 }
08820
08821 if (new > 255) {
08822 new = 255;
08823 }
08824 if (old > 255) {
08825 old = 255;
08826 }
08827 msgcount = (old << 8) | new;
08828
08829 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08830 }
08831 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08832 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08833 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08834 }
08835 }
08836 version = iax_check_version(devtype);
08837 if (version)
08838 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08839
08840 res = 0;
08841
08842 return_unref:
08843 peer_unref(p);
08844
08845 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08846 }
08847
08848 static int registry_authrequest(int callno)
08849 {
08850 struct iax_ie_data ied;
08851 struct iax2_peer *p;
08852 char challenge[10];
08853 const char *peer_name;
08854 int sentauthmethod;
08855
08856 peer_name = ast_strdupa(iaxs[callno]->peer);
08857
08858
08859 ast_mutex_unlock(&iaxsl[callno]);
08860 if ((p = find_peer(peer_name, 1))) {
08861 last_authmethod = p->authmethods;
08862 }
08863
08864 ast_mutex_lock(&iaxsl[callno]);
08865 if (!iaxs[callno])
08866 goto return_unref;
08867
08868 memset(&ied, 0, sizeof(ied));
08869
08870
08871
08872
08873
08874
08875 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08876 if (!p) {
08877 iaxs[callno]->authmethods = sentauthmethod;
08878 }
08879 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08880 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08881
08882 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08883 ast_string_field_set(iaxs[callno], challenge, challenge);
08884 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08885 }
08886 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08887
08888 return_unref:
08889 if (p) {
08890 peer_unref(p);
08891 }
08892
08893 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08894 }
08895
08896 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08897 {
08898 struct iax2_registry *reg;
08899
08900 struct iax_ie_data ied;
08901 char peer[256] = "";
08902 char challenge[256] = "";
08903 int res;
08904 int authmethods = 0;
08905 if (ies->authmethods)
08906 authmethods = ies->authmethods;
08907 if (ies->username)
08908 ast_copy_string(peer, ies->username, sizeof(peer));
08909 if (ies->challenge)
08910 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08911 memset(&ied, 0, sizeof(ied));
08912 reg = iaxs[callno]->reg;
08913 if (reg) {
08914 struct sockaddr_in reg_addr;
08915
08916 ast_sockaddr_to_sin(®->addr, ®_addr);
08917
08918 if (inaddrcmp(®_addr, sin)) {
08919 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08920 return -1;
08921 }
08922 if (ast_strlen_zero(reg->secret)) {
08923 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08924 reg->regstate = REG_STATE_NOAUTH;
08925 return -1;
08926 }
08927 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08928 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08929 if (reg->secret[0] == '[') {
08930 char tmpkey[256];
08931 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08932 tmpkey[strlen(tmpkey) - 1] = '\0';
08933 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08934 } else
08935 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08936 if (!res) {
08937 reg->regstate = REG_STATE_AUTHSENT;
08938 add_empty_calltoken_ie(iaxs[callno], &ied);
08939 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08940 } else
08941 return -1;
08942 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08943 } else
08944 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08945 return -1;
08946 }
08947
08948 static void stop_stuff(int callno)
08949 {
08950 iax2_destroy_helper(iaxs[callno]);
08951 }
08952
08953 static void __auth_reject(const void *nothing)
08954 {
08955
08956 int callno = (int)(long)(nothing);
08957 struct iax_ie_data ied;
08958 ast_mutex_lock(&iaxsl[callno]);
08959 if (iaxs[callno]) {
08960 memset(&ied, 0, sizeof(ied));
08961 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08962 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08963 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08964 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08965 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08966 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08967 }
08968 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08969 }
08970 ast_mutex_unlock(&iaxsl[callno]);
08971 }
08972
08973 static int auth_reject(const void *data)
08974 {
08975 int callno = (int)(long)(data);
08976 ast_mutex_lock(&iaxsl[callno]);
08977 if (iaxs[callno])
08978 iaxs[callno]->authid = -1;
08979 ast_mutex_unlock(&iaxsl[callno]);
08980 #ifdef SCHED_MULTITHREADED
08981 if (schedule_action(__auth_reject, data))
08982 #endif
08983 __auth_reject(data);
08984 return 0;
08985 }
08986
08987 static int auth_fail(int callno, int failcode)
08988 {
08989
08990
08991 if (iaxs[callno]) {
08992 iaxs[callno]->authfail = failcode;
08993 if (delayreject) {
08994 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08995 sched, 1000, auth_reject, (void *)(long)callno);
08996 } else
08997 auth_reject((void *)(long)callno);
08998 }
08999 return 0;
09000 }
09001
09002 static void __auto_hangup(const void *nothing)
09003 {
09004
09005 int callno = (int)(long)(nothing);
09006 struct iax_ie_data ied;
09007 ast_mutex_lock(&iaxsl[callno]);
09008 if (iaxs[callno]) {
09009 memset(&ied, 0, sizeof(ied));
09010 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09011 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09012 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09013 }
09014 ast_mutex_unlock(&iaxsl[callno]);
09015 }
09016
09017 static int auto_hangup(const void *data)
09018 {
09019 int callno = (int)(long)(data);
09020 ast_mutex_lock(&iaxsl[callno]);
09021 if (iaxs[callno]) {
09022 iaxs[callno]->autoid = -1;
09023 }
09024 ast_mutex_unlock(&iaxsl[callno]);
09025 #ifdef SCHED_MULTITHREADED
09026 if (schedule_action(__auto_hangup, data))
09027 #endif
09028 __auto_hangup(data);
09029 return 0;
09030 }
09031
09032 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09033 {
09034 struct iax_ie_data ied;
09035
09036 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09037 sched, 30000, auto_hangup, (void *)(long)callno);
09038 memset(&ied, 0, sizeof(ied));
09039 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09040 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09041 dp->flags |= CACHE_FLAG_TRANSMITTED;
09042 }
09043
09044 static int iax2_vnak(int callno)
09045 {
09046 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09047 }
09048
09049 static void vnak_retransmit(int callno, int last)
09050 {
09051 struct iax_frame *f;
09052
09053 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09054
09055 if (((unsigned char) (f->oseqno - last) < 128) &&
09056 (f->retries >= 0)) {
09057 send_packet(f);
09058 }
09059 }
09060 }
09061
09062 static void __iax2_poke_peer_s(const void *data)
09063 {
09064 struct iax2_peer *peer = (struct iax2_peer *)data;
09065 iax2_poke_peer(peer, 0);
09066 peer_unref(peer);
09067 }
09068
09069 static int iax2_poke_peer_s(const void *data)
09070 {
09071 struct iax2_peer *peer = (struct iax2_peer *)data;
09072 peer->pokeexpire = -1;
09073 #ifdef SCHED_MULTITHREADED
09074 if (schedule_action(__iax2_poke_peer_s, data))
09075 #endif
09076 __iax2_poke_peer_s(data);
09077 return 0;
09078 }
09079
09080 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09081 {
09082 int res = 0;
09083 struct iax_frame *fr;
09084 struct ast_iax2_meta_hdr *meta;
09085 struct ast_iax2_meta_trunk_hdr *mth;
09086 int calls = 0;
09087
09088
09089 fr = (struct iax_frame *)tpeer->trunkdata;
09090
09091 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09092 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09093 if (tpeer->trunkdatalen) {
09094
09095 meta->zeros = 0;
09096 meta->metacmd = IAX_META_TRUNK;
09097 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09098 meta->cmddata = IAX_META_TRUNK_MINI;
09099 else
09100 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09101 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09102
09103 fr->direction = DIRECTION_OUTGRESS;
09104 fr->retrans = -1;
09105 fr->transfer = 0;
09106
09107 fr->data = fr->afdata;
09108 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09109 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09110 calls = tpeer->calls;
09111 #if 0
09112 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));
09113 #endif
09114
09115 tpeer->trunkdatalen = 0;
09116 tpeer->calls = 0;
09117 }
09118 if (res < 0)
09119 return res;
09120 return calls;
09121 }
09122
09123 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09124 {
09125
09126 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09127 return 1;
09128 return 0;
09129 }
09130
09131 static int timing_read(int *id, int fd, short events, void *cbdata)
09132 {
09133 int res, processed = 0, totalcalls = 0;
09134 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09135 struct timeval now = ast_tvnow();
09136
09137 if (iaxtrunkdebug)
09138 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09139
09140 if (timer) {
09141 ast_timer_ack(timer, 1);
09142 }
09143
09144
09145 AST_LIST_LOCK(&tpeers);
09146 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09147 processed++;
09148 res = 0;
09149 ast_mutex_lock(&tpeer->lock);
09150
09151
09152 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09153
09154
09155 AST_LIST_REMOVE_CURRENT(list);
09156 drop = tpeer;
09157 } else {
09158 res = send_trunk(tpeer, &now);
09159 trunk_timed++;
09160 if (iaxtrunkdebug)
09161 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);
09162 }
09163 totalcalls += res;
09164 res = 0;
09165 ast_mutex_unlock(&tpeer->lock);
09166 }
09167 AST_LIST_TRAVERSE_SAFE_END;
09168 AST_LIST_UNLOCK(&tpeers);
09169
09170 if (drop) {
09171 ast_mutex_lock(&drop->lock);
09172
09173
09174 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09175 if (drop->trunkdata) {
09176 ast_free(drop->trunkdata);
09177 drop->trunkdata = NULL;
09178 }
09179 ast_mutex_unlock(&drop->lock);
09180 ast_mutex_destroy(&drop->lock);
09181 ast_free(drop);
09182
09183 }
09184
09185 if (iaxtrunkdebug)
09186 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09187 iaxtrunkdebug = 0;
09188
09189 return 1;
09190 }
09191
09192 struct dpreq_data {
09193 int callno;
09194 char context[AST_MAX_EXTENSION];
09195 char callednum[AST_MAX_EXTENSION];
09196 char *callerid;
09197 };
09198
09199 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09200 {
09201 unsigned short dpstatus = 0;
09202 struct iax_ie_data ied1;
09203 int mm;
09204
09205 memset(&ied1, 0, sizeof(ied1));
09206 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09207
09208 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09209 dpstatus = IAX_DPSTATUS_EXISTS;
09210 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09211 dpstatus = IAX_DPSTATUS_CANEXIST;
09212 } else {
09213 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09214 }
09215 if (ast_ignore_pattern(context, callednum))
09216 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09217 if (mm)
09218 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09219 if (!skiplock)
09220 ast_mutex_lock(&iaxsl[callno]);
09221 if (iaxs[callno]) {
09222 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09223 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09224 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09225 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09226 }
09227 if (!skiplock)
09228 ast_mutex_unlock(&iaxsl[callno]);
09229 }
09230
09231 static void *dp_lookup_thread(void *data)
09232 {
09233
09234 struct dpreq_data *dpr = data;
09235 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09236 if (dpr->callerid)
09237 ast_free(dpr->callerid);
09238 ast_free(dpr);
09239 return NULL;
09240 }
09241
09242 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09243 {
09244 pthread_t newthread;
09245 struct dpreq_data *dpr;
09246
09247 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09248 return;
09249
09250 dpr->callno = callno;
09251 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09252 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09253 if (callerid)
09254 dpr->callerid = ast_strdup(callerid);
09255 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09256 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09257 }
09258 }
09259
09260 struct iax_dual {
09261 struct ast_channel *chan1;
09262 struct ast_channel *chan2;
09263 char *park_exten;
09264 char *park_context;
09265 };
09266
09267 static void *iax_park_thread(void *stuff)
09268 {
09269 struct iax_dual *d;
09270 int res;
09271 int ext = 0;
09272
09273 d = stuff;
09274
09275 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n",
09276 d->chan2->name, d->chan1->name);
09277
09278 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext);
09279 if (res) {
09280
09281 ast_hangup(d->chan1);
09282 } else {
09283 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09284 }
09285 ast_hangup(d->chan2);
09286
09287 ast_free(d->park_exten);
09288 ast_free(d->park_context);
09289 ast_free(d);
09290 return NULL;
09291 }
09292
09293
09294 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context)
09295 {
09296 struct iax_dual *d;
09297 struct ast_channel *chan1m, *chan2m;
09298 pthread_t th;
09299
09300 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09301 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09302 d = ast_calloc(1, sizeof(*d));
09303 if (!chan1m || !chan2m || !d) {
09304 if (chan1m) {
09305 ast_hangup(chan1m);
09306 }
09307 if (chan2m) {
09308 ast_hangup(chan2m);
09309 }
09310 ast_free(d);
09311 return -1;
09312 }
09313 d->park_exten = ast_strdup(park_exten);
09314 d->park_context = ast_strdup(park_context);
09315 if (!d->park_exten || !d->park_context) {
09316 ast_hangup(chan1m);
09317 ast_hangup(chan2m);
09318 ast_free(d->park_exten);
09319 ast_free(d->park_context);
09320 ast_free(d);
09321 return -1;
09322 }
09323
09324
09325 chan1m->readformat = chan1->readformat;
09326 chan1m->writeformat = chan1->writeformat;
09327
09328
09329 if (ast_channel_masquerade(chan1m, chan1)) {
09330 ast_hangup(chan1m);
09331 ast_hangup(chan2m);
09332 ast_free(d->park_exten);
09333 ast_free(d->park_context);
09334 ast_free(d);
09335 return -1;
09336 }
09337
09338
09339 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09340 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09341 chan1m->priority = chan1->priority;
09342
09343 ast_do_masquerade(chan1m);
09344
09345
09346
09347
09348
09349 chan2m->readformat = chan2->readformat;
09350 chan2m->writeformat = chan2->writeformat;
09351 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot);
09352
09353
09354 if (ast_channel_masquerade(chan2m, chan2)) {
09355 ast_hangup(chan1m);
09356 ast_hangup(chan2m);
09357 ast_free(d->park_exten);
09358 ast_free(d->park_context);
09359 ast_free(d);
09360 return -1;
09361 }
09362
09363
09364 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09365 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09366 chan2m->priority = chan2->priority;
09367
09368 ast_do_masquerade(chan2m);
09369
09370 d->chan1 = chan1m;
09371 d->chan2 = chan2m;
09372 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) {
09373
09374 ast_hangup(chan1m);
09375 ast_hangup(chan2m);
09376 ast_free(d->park_exten);
09377 ast_free(d->park_context);
09378 ast_free(d);
09379 return -1;
09380 }
09381 return 0;
09382 }
09383
09384 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09385 {
09386 unsigned int ourver;
09387 char rsi[80];
09388 snprintf(rsi, sizeof(rsi), "si-%s", si);
09389 if (iax_provision_version(&ourver, rsi, 1))
09390 return 0;
09391 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09392 if (ourver != ver)
09393 iax2_provision(sin, sockfd, NULL, rsi, 1);
09394 return 0;
09395 }
09396
09397 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09398 {
09399 jb_info stats;
09400 jb_getinfo(pvt->jb, &stats);
09401
09402 memset(iep, 0, sizeof(*iep));
09403
09404 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09405 if(stats.frames_in == 0) stats.frames_in = 1;
09406 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09407 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09408 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09409 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09410 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09411 }
09412
09413 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09414 {
09415 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09416 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09417 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09418 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09419 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09420 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09421 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09422 }
09423
09424 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09425 {
09426 int i;
09427 unsigned int length, offset = 0;
09428 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09429
09430 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09431 length = ies->ospblocklength[i];
09432 if (length != 0) {
09433 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09434
09435 offset = 0;
09436 break;
09437 } else {
09438 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09439 offset += length;
09440 }
09441 } else {
09442 break;
09443 }
09444 }
09445 *(full_osptoken + offset) = '\0';
09446 if (strlen(full_osptoken) != offset) {
09447
09448 *full_osptoken = '\0';
09449 }
09450
09451 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09452 }
09453
09454 static void log_jitterstats(unsigned short callno)
09455 {
09456 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09457 jb_info jbinfo;
09458
09459 ast_mutex_lock(&iaxsl[callno]);
09460 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09461 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09462 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09463 localjitter = jbinfo.jitter;
09464 localdelay = jbinfo.current - jbinfo.min;
09465 locallost = jbinfo.frames_lost;
09466 locallosspct = jbinfo.losspct/1000;
09467 localdropped = jbinfo.frames_dropped;
09468 localooo = jbinfo.frames_ooo;
09469 localpackets = jbinfo.frames_in;
09470 }
09471 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",
09472 iaxs[callno]->owner->name,
09473 iaxs[callno]->pingtime,
09474 localjitter,
09475 localdelay,
09476 locallost,
09477 locallosspct,
09478 localdropped,
09479 localooo,
09480 localpackets,
09481 iaxs[callno]->remote_rr.jitter,
09482 iaxs[callno]->remote_rr.delay,
09483 iaxs[callno]->remote_rr.losscnt,
09484 iaxs[callno]->remote_rr.losspct/1000,
09485 iaxs[callno]->remote_rr.dropped,
09486 iaxs[callno]->remote_rr.ooo,
09487 iaxs[callno]->remote_rr.packets);
09488 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",
09489 iaxs[callno]->owner->name,
09490 iaxs[callno]->pingtime,
09491 localjitter,
09492 localdelay,
09493 locallost,
09494 locallosspct,
09495 localdropped,
09496 localooo,
09497 localpackets,
09498 iaxs[callno]->remote_rr.jitter,
09499 iaxs[callno]->remote_rr.delay,
09500 iaxs[callno]->remote_rr.losscnt,
09501 iaxs[callno]->remote_rr.losspct/1000,
09502 iaxs[callno]->remote_rr.dropped,
09503 iaxs[callno]->remote_rr.ooo,
09504 iaxs[callno]->remote_rr.packets);
09505 }
09506 ast_mutex_unlock(&iaxsl[callno]);
09507 }
09508
09509 static int socket_process(struct iax2_thread *thread);
09510
09511
09512
09513
09514 static void handle_deferred_full_frames(struct iax2_thread *thread)
09515 {
09516 struct iax2_pkt_buf *pkt_buf;
09517
09518 ast_mutex_lock(&thread->lock);
09519
09520 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09521 ast_mutex_unlock(&thread->lock);
09522
09523 thread->buf = pkt_buf->buf;
09524 thread->buf_len = pkt_buf->len;
09525 thread->buf_size = pkt_buf->len + 1;
09526
09527 socket_process(thread);
09528
09529 thread->buf = NULL;
09530 ast_free(pkt_buf);
09531
09532 ast_mutex_lock(&thread->lock);
09533 }
09534
09535 ast_mutex_unlock(&thread->lock);
09536 }
09537
09538
09539
09540
09541
09542
09543
09544 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09545 {
09546 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09547 struct ast_iax2_full_hdr *fh, *cur_fh;
09548
09549 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09550 return;
09551
09552 pkt_buf->len = from_here->buf_len;
09553 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09554
09555 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09556 ast_mutex_lock(&to_here->lock);
09557 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09558 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09559 if (fh->oseqno < cur_fh->oseqno) {
09560 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09561 break;
09562 }
09563 }
09564 AST_LIST_TRAVERSE_SAFE_END
09565
09566 if (!cur_pkt_buf)
09567 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09568
09569 ast_mutex_unlock(&to_here->lock);
09570 }
09571
09572 static int socket_read(int *id, int fd, short events, void *cbdata)
09573 {
09574 struct iax2_thread *thread;
09575 socklen_t len;
09576 time_t t;
09577 static time_t last_errtime = 0;
09578 struct ast_iax2_full_hdr *fh;
09579
09580 if (!(thread = find_idle_thread())) {
09581 time(&t);
09582 if (t != last_errtime)
09583 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09584 last_errtime = t;
09585 usleep(1);
09586 return 1;
09587 }
09588
09589 len = sizeof(thread->iosin);
09590 thread->iofd = fd;
09591 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09592 thread->buf_size = sizeof(thread->readbuf);
09593 thread->buf = thread->readbuf;
09594 if (thread->buf_len < 0) {
09595 if (errno != ECONNREFUSED && errno != EAGAIN)
09596 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09597 handle_error();
09598 thread->iostate = IAX_IOSTATE_IDLE;
09599 signal_condition(&thread->lock, &thread->cond);
09600 return 1;
09601 }
09602 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09603 thread->iostate = IAX_IOSTATE_IDLE;
09604 signal_condition(&thread->lock, &thread->cond);
09605 return 1;
09606 }
09607
09608
09609
09610
09611 fh = (struct ast_iax2_full_hdr *) thread->buf;
09612 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09613 struct iax2_thread *cur = NULL;
09614 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09615
09616 AST_LIST_LOCK(&active_list);
09617 AST_LIST_TRAVERSE(&active_list, cur, list) {
09618 if ((cur->ffinfo.callno == callno) &&
09619 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09620 break;
09621 }
09622 if (cur) {
09623
09624
09625 defer_full_frame(thread, cur);
09626 AST_LIST_UNLOCK(&active_list);
09627 thread->iostate = IAX_IOSTATE_IDLE;
09628 signal_condition(&thread->lock, &thread->cond);
09629 return 1;
09630 } else {
09631
09632 thread->ffinfo.callno = callno;
09633 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09634 thread->ffinfo.type = fh->type;
09635 thread->ffinfo.csub = fh->csub;
09636 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09637 }
09638 AST_LIST_UNLOCK(&active_list);
09639 }
09640
09641
09642 thread->iostate = IAX_IOSTATE_READY;
09643 #ifdef DEBUG_SCHED_MULTITHREAD
09644 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09645 #endif
09646 signal_condition(&thread->lock, &thread->cond);
09647
09648 return 1;
09649 }
09650
09651 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09652 struct iax_frame *fr)
09653 {
09654 unsigned char metatype;
09655 struct ast_iax2_meta_trunk_mini *mtm;
09656 struct ast_iax2_meta_trunk_hdr *mth;
09657 struct ast_iax2_meta_trunk_entry *mte;
09658 struct iax2_trunk_peer *tpeer;
09659 unsigned int ts;
09660 void *ptr;
09661 struct timeval rxtrunktime;
09662 struct ast_frame f = { 0, };
09663
09664 if (packet_len < sizeof(*meta)) {
09665 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09666 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09667 return 1;
09668 }
09669
09670 if (meta->metacmd != IAX_META_TRUNK)
09671 return 1;
09672
09673 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09674 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09675 (int) (sizeof(*meta) + sizeof(*mth)));
09676 return 1;
09677 }
09678 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09679 ts = ntohl(mth->ts);
09680 metatype = meta->cmddata;
09681 packet_len -= (sizeof(*meta) + sizeof(*mth));
09682 ptr = mth->data;
09683 tpeer = find_tpeer(sin, sockfd);
09684 if (!tpeer) {
09685 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09686 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09687 return 1;
09688 }
09689 tpeer->trunkact = ast_tvnow();
09690 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09691 tpeer->rxtrunktime = tpeer->trunkact;
09692 rxtrunktime = tpeer->rxtrunktime;
09693 ast_mutex_unlock(&tpeer->lock);
09694 while (packet_len >= sizeof(*mte)) {
09695
09696 unsigned short callno, trunked_ts, len;
09697
09698 if (metatype == IAX_META_TRUNK_MINI) {
09699 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09700 ptr += sizeof(*mtm);
09701 packet_len -= sizeof(*mtm);
09702 len = ntohs(mtm->len);
09703 callno = ntohs(mtm->mini.callno);
09704 trunked_ts = ntohs(mtm->mini.ts);
09705 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09706 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09707 ptr += sizeof(*mte);
09708 packet_len -= sizeof(*mte);
09709 len = ntohs(mte->len);
09710 callno = ntohs(mte->callno);
09711 trunked_ts = 0;
09712 } else {
09713 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09714 break;
09715 }
09716
09717 if (len > packet_len)
09718 break;
09719 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09720 if (!fr->callno)
09721 continue;
09722
09723
09724
09725
09726 memset(&f, 0, sizeof(f));
09727 f.frametype = AST_FRAME_VOICE;
09728 if (!iaxs[fr->callno]) {
09729
09730 } else if (iaxs[fr->callno]->voiceformat == 0) {
09731 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09732 iax2_vnak(fr->callno);
09733 } else {
09734 f.subclass.codec = iaxs[fr->callno]->voiceformat;
09735 f.datalen = len;
09736 if (f.datalen >= 0) {
09737 if (f.datalen)
09738 f.data.ptr = ptr;
09739 else
09740 f.data.ptr = NULL;
09741 if (trunked_ts)
09742 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09743 else
09744 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09745
09746 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09747 struct iax_frame *duped_fr;
09748
09749
09750 f.src = "IAX2";
09751 f.mallocd = 0;
09752 f.offset = 0;
09753 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09754 f.samples = ast_codec_get_samples(&f);
09755 else
09756 f.samples = 0;
09757 fr->outoforder = 0;
09758 iax_frame_wrap(fr, &f);
09759 duped_fr = iaxfrdup2(fr);
09760 if (duped_fr)
09761 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09762 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09763 iaxs[fr->callno]->last = fr->ts;
09764 }
09765 } else {
09766 ast_log(LOG_WARNING, "Datalen < 0?\n");
09767 }
09768 }
09769 ast_mutex_unlock(&iaxsl[fr->callno]);
09770 ptr += len;
09771 packet_len -= len;
09772 }
09773
09774 return 1;
09775 }
09776
09777 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09778 {
09779 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09780 AST_LIST_HEAD(, ast_var_t) *varlist;
09781 struct ast_var_t *var;
09782
09783 if (!variablestore) {
09784 *buf = '\0';
09785 return 0;
09786 }
09787 varlist = variablestore->data;
09788
09789 AST_LIST_LOCK(varlist);
09790 AST_LIST_TRAVERSE(varlist, var, entries) {
09791 if (strcmp(var->name, data) == 0) {
09792 ast_copy_string(buf, var->value, len);
09793 break;
09794 }
09795 }
09796 AST_LIST_UNLOCK(varlist);
09797 return 0;
09798 }
09799
09800 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09801 {
09802 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09803 AST_LIST_HEAD(, ast_var_t) *varlist;
09804 struct ast_var_t *var;
09805
09806 if (!variablestore) {
09807 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09808 if (!variablestore) {
09809 ast_log(LOG_ERROR, "Memory allocation error\n");
09810 return -1;
09811 }
09812 varlist = ast_calloc(1, sizeof(*varlist));
09813 if (!varlist) {
09814 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09815 return -1;
09816 }
09817
09818 AST_LIST_HEAD_INIT(varlist);
09819 variablestore->data = varlist;
09820 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09821 ast_channel_datastore_add(chan, variablestore);
09822 } else
09823 varlist = variablestore->data;
09824
09825 AST_LIST_LOCK(varlist);
09826 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09827 if (strcmp(var->name, data) == 0) {
09828 AST_LIST_REMOVE_CURRENT(entries);
09829 ast_var_delete(var);
09830 break;
09831 }
09832 }
09833 AST_LIST_TRAVERSE_SAFE_END;
09834 var = ast_var_assign(data, value);
09835 if (var)
09836 AST_LIST_INSERT_TAIL(varlist, var, entries);
09837 else
09838 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09839 AST_LIST_UNLOCK(varlist);
09840 return 0;
09841 }
09842
09843 static struct ast_custom_function iaxvar_function = {
09844 .name = "IAXVAR",
09845 .read = acf_iaxvar_read,
09846 .write = acf_iaxvar_write,
09847 };
09848
09849 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
09850 {
09851 iax2_lock_owner(callno);
09852 if (iaxs[callno] && iaxs[callno]->owner) {
09853 if (causecode) {
09854 iaxs[callno]->owner->hangupcause = causecode;
09855 }
09856 ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
09857 ast_channel_unlock(iaxs[callno]->owner);
09858 }
09859 }
09860
09861 static int socket_process(struct iax2_thread *thread)
09862 {
09863 struct sockaddr_in sin;
09864 int res;
09865 int updatehistory=1;
09866 int new = NEW_PREVENT;
09867 int dcallno = 0;
09868 char decrypted = 0;
09869 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09870 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09871 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09872 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09873 struct iax_frame *fr;
09874 struct iax_frame *cur;
09875 struct ast_frame f = { 0, };
09876 struct ast_channel *c = NULL;
09877 struct iax2_dpcache *dp;
09878 struct iax2_peer *peer;
09879 struct iax_ies ies;
09880 struct iax_ie_data ied0, ied1;
09881 format_t format;
09882 int fd;
09883 int exists;
09884 int minivid = 0;
09885 char empty[32]="";
09886 struct iax_frame *duped_fr;
09887 char host_pref_buf[128];
09888 char caller_pref_buf[128];
09889 struct ast_codec_pref pref;
09890 char *using_prefs = "mine";
09891
09892
09893 fr = alloca(sizeof(*fr) + 4096);
09894 memset(fr, 0, sizeof(*fr));
09895 fr->afdatalen = 4096;
09896
09897
09898 res = thread->buf_len;
09899 fd = thread->iofd;
09900 memcpy(&sin, &thread->iosin, sizeof(sin));
09901
09902 if (res < sizeof(*mh)) {
09903 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09904 return 1;
09905 }
09906 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09907 if (res < sizeof(*vh)) {
09908 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));
09909 return 1;
09910 }
09911
09912
09913 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09914 minivid = 1;
09915 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09916 return socket_process_meta(res, meta, &sin, fd, fr);
09917
09918 #ifdef DEBUG_SUPPORT
09919 if (res >= sizeof(*fh))
09920 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09921 #endif
09922 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09923 if (res < sizeof(*fh)) {
09924 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));
09925 return 1;
09926 }
09927
09928
09929 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09930
09931
09932
09933
09934
09935
09936 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09937 ast_mutex_lock(&iaxsl[fr->callno]);
09938 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
09939 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09940 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09941 ast_mutex_unlock(&iaxsl[fr->callno]);
09942 return 1;
09943 }
09944 decrypted = 1;
09945 }
09946 ast_mutex_unlock(&iaxsl[fr->callno]);
09947 }
09948
09949
09950 f.frametype = fh->type;
09951 if (f.frametype == AST_FRAME_VIDEO) {
09952 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09953 } else if (f.frametype == AST_FRAME_VOICE) {
09954 f.subclass.codec = uncompress_subclass(fh->csub);
09955 } else {
09956 f.subclass.integer = uncompress_subclass(fh->csub);
09957 }
09958
09959
09960 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
09961
09962 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09963 return 1;
09964 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
09965
09966 return 1;
09967 }
09968
09969 f.datalen = res - sizeof(*fh);
09970 if (f.datalen) {
09971 if (f.frametype == AST_FRAME_IAX) {
09972 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09973 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09974 ast_variables_destroy(ies.vars);
09975 return 1;
09976 }
09977 f.data.ptr = NULL;
09978 f.datalen = 0;
09979 } else {
09980 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09981 memset(&ies, 0, sizeof(ies));
09982 }
09983 } else {
09984 if (f.frametype == AST_FRAME_IAX)
09985 f.data.ptr = NULL;
09986 else
09987 f.data.ptr = empty;
09988 memset(&ies, 0, sizeof(ies));
09989 }
09990
09991 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
09992
09993 if (handle_call_token(fh, &ies, &sin, fd)) {
09994 ast_variables_destroy(ies.vars);
09995 return 1;
09996 }
09997
09998 if (ies.calltoken && ies.calltokendata) {
09999
10000
10001
10002
10003 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
10004 } else {
10005 new = NEW_ALLOW;
10006 }
10007 }
10008 } else {
10009
10010 f.frametype = AST_FRAME_NULL;
10011 f.subclass.integer = 0;
10012 memset(&ies, 0, sizeof(ies));
10013 }
10014
10015 if (!fr->callno) {
10016 int check_dcallno = 0;
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
10027 check_dcallno = 1;
10028 }
10029
10030 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
10031 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
10032 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10033 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
10034 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
10035 }
10036 ast_variables_destroy(ies.vars);
10037 return 1;
10038 }
10039 }
10040
10041 if (fr->callno > 0)
10042 ast_mutex_lock(&iaxsl[fr->callno]);
10043
10044 if (!fr->callno || !iaxs[fr->callno]) {
10045
10046
10047 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10048
10049 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
10050 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10051 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10052 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
10053 (f.frametype != AST_FRAME_IAX))
10054 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
10055 fd);
10056 }
10057 if (fr->callno > 0)
10058 ast_mutex_unlock(&iaxsl[fr->callno]);
10059 ast_variables_destroy(ies.vars);
10060 return 1;
10061 }
10062 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10063 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10064 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10065 ast_variables_destroy(ies.vars);
10066 ast_mutex_unlock(&iaxsl[fr->callno]);
10067 return 1;
10068 }
10069 decrypted = 1;
10070 }
10071
10072 #ifdef DEBUG_SUPPORT
10073 if (decrypted) {
10074 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10075 }
10076 #endif
10077
10078
10079
10080 iaxs[fr->callno]->frames_received++;
10081
10082 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10083 f.subclass.integer != IAX_COMMAND_TXCNT &&
10084 f.subclass.integer != IAX_COMMAND_TXACC) {
10085 unsigned short new_peercallno;
10086
10087 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10088 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10089 if (iaxs[fr->callno]->peercallno) {
10090 remove_by_peercallno(iaxs[fr->callno]);
10091 }
10092 iaxs[fr->callno]->peercallno = new_peercallno;
10093 store_by_peercallno(iaxs[fr->callno]);
10094 }
10095 }
10096 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10097 if (iaxdebug)
10098 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10099
10100 fr->oseqno = fh->oseqno;
10101 fr->iseqno = fh->iseqno;
10102 fr->ts = ntohl(fh->ts);
10103 #ifdef IAXTESTS
10104 if (test_resync) {
10105 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10106 fr->ts += test_resync;
10107 }
10108 #endif
10109 #if 0
10110 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10111 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10112 (f.subclass == IAX_COMMAND_NEW ||
10113 f.subclass == IAX_COMMAND_AUTHREQ ||
10114 f.subclass == IAX_COMMAND_ACCEPT ||
10115 f.subclass == IAX_COMMAND_REJECT)) ) )
10116 #endif
10117 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10118 updatehistory = 0;
10119 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10120 (iaxs[fr->callno]->iseqno ||
10121 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10122 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10123 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10124 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10125 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10126 (f.frametype != AST_FRAME_IAX))) {
10127 if (
10128 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10129 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10130 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10131 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10132 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10133 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10134 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10135 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10136 (f.frametype != AST_FRAME_IAX)) {
10137
10138 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10139 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10140
10141
10142 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10143
10144 if ((f.frametype != AST_FRAME_IAX) ||
10145 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10146 ast_debug(1, "Acking anyway\n");
10147
10148
10149 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10150 }
10151 } else {
10152
10153 iax2_vnak(fr->callno);
10154 }
10155 ast_variables_destroy(ies.vars);
10156 ast_mutex_unlock(&iaxsl[fr->callno]);
10157 return 1;
10158 }
10159 } else {
10160
10161 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10162 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10163 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10164 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10165 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10166 (f.frametype != AST_FRAME_IAX))
10167 iaxs[fr->callno]->iseqno++;
10168 }
10169
10170 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10171 if (res < thread->buf_size)
10172 thread->buf[res++] = '\0';
10173 else
10174 thread->buf[res - 1] = '\0';
10175 }
10176
10177
10178
10179 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10180 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10181 (f.frametype != AST_FRAME_IAX))) {
10182 unsigned char x;
10183 int call_to_destroy;
10184
10185 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10186 x = fr->iseqno;
10187 else
10188 x = iaxs[fr->callno]->oseqno;
10189 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10190
10191
10192 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10193
10194 if (iaxdebug)
10195 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10196 call_to_destroy = 0;
10197 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10198
10199 if (x == cur->oseqno) {
10200 cur->retries = -1;
10201
10202 if (cur->final)
10203 call_to_destroy = fr->callno;
10204 }
10205 }
10206 if (call_to_destroy) {
10207 if (iaxdebug)
10208 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10209 ast_mutex_lock(&iaxsl[call_to_destroy]);
10210 iax2_destroy(call_to_destroy);
10211 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10212 }
10213 }
10214
10215 if (iaxs[fr->callno])
10216 iaxs[fr->callno]->rseqno = fr->iseqno;
10217 else {
10218
10219 ast_variables_destroy(ies.vars);
10220 ast_mutex_unlock(&iaxsl[fr->callno]);
10221 return 1;
10222 }
10223 } else {
10224 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10225 }
10226 }
10227 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10228 ((f.frametype != AST_FRAME_IAX) ||
10229 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10230 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10231
10232 ast_variables_destroy(ies.vars);
10233 ast_mutex_unlock(&iaxsl[fr->callno]);
10234 return 1;
10235 }
10236
10237
10238
10239
10240 if ((f.frametype == AST_FRAME_VOICE) ||
10241 (f.frametype == AST_FRAME_VIDEO) ||
10242 (f.frametype == AST_FRAME_IAX)) {
10243 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10244 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10245 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10246 ast_variables_destroy(ies.vars);
10247 ast_mutex_unlock(&iaxsl[fr->callno]);
10248 return 1;
10249 }
10250 }
10251
10252 if (ies.vars) {
10253 struct ast_datastore *variablestore = NULL;
10254 struct ast_variable *var, *prev = NULL;
10255 AST_LIST_HEAD(, ast_var_t) *varlist;
10256
10257 iax2_lock_owner(fr->callno);
10258 if (!iaxs[fr->callno]) {
10259 ast_variables_destroy(ies.vars);
10260 ast_mutex_unlock(&iaxsl[fr->callno]);
10261 return 1;
10262 }
10263 if ((c = iaxs[fr->callno]->owner)) {
10264 varlist = ast_calloc(1, sizeof(*varlist));
10265 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10266
10267 if (variablestore && varlist) {
10268 variablestore->data = varlist;
10269 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10270 AST_LIST_HEAD_INIT(varlist);
10271 ast_debug(1, "I can haz IAX vars?\n");
10272 for (var = ies.vars; var; var = var->next) {
10273 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10274 if (prev) {
10275 ast_free(prev);
10276 }
10277 prev = var;
10278 if (!newvar) {
10279
10280 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10281 } else {
10282 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10283 }
10284 }
10285 if (prev) {
10286 ast_free(prev);
10287 }
10288 ies.vars = NULL;
10289 ast_channel_datastore_add(c, variablestore);
10290 } else {
10291 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10292 if (variablestore) {
10293 ast_datastore_free(variablestore);
10294 }
10295 if (varlist) {
10296 ast_free(varlist);
10297 }
10298 }
10299 ast_channel_unlock(c);
10300 } else {
10301
10302
10303 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10304 for (var = ies.vars; var && var->next; var = var->next);
10305 if (var) {
10306 var->next = iaxs[fr->callno]->iaxvars;
10307 iaxs[fr->callno]->iaxvars = ies.vars;
10308 ies.vars = NULL;
10309 }
10310 }
10311 }
10312
10313 if (ies.vars) {
10314 ast_debug(1, "I have IAX variables, but they were not processed\n");
10315 }
10316 }
10317
10318
10319
10320 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10321 send_signaling(iaxs[fr->callno]);
10322 }
10323
10324 if (f.frametype == AST_FRAME_VOICE) {
10325 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10326 iaxs[fr->callno]->voiceformat = f.subclass.codec;
10327 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10328 if (iaxs[fr->callno]->owner) {
10329 iax2_lock_owner(fr->callno);
10330 if (iaxs[fr->callno]) {
10331 if (iaxs[fr->callno]->owner) {
10332 format_t orignative;
10333
10334 orignative = iaxs[fr->callno]->owner->nativeformats;
10335 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10336 if (iaxs[fr->callno]->owner->readformat)
10337 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10338 iaxs[fr->callno]->owner->nativeformats = orignative;
10339 ast_channel_unlock(iaxs[fr->callno]->owner);
10340 }
10341 } else {
10342 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10343
10344 if (ies.vars) {
10345 ast_variables_destroy(ies.vars);
10346 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10347 ies.vars = NULL;
10348 }
10349 ast_mutex_unlock(&iaxsl[fr->callno]);
10350 return 1;
10351 }
10352 }
10353 }
10354 }
10355 if (f.frametype == AST_FRAME_VIDEO) {
10356 if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10357 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10358 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10359 }
10360 }
10361 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10362 if (f.subclass.integer == AST_CONTROL_BUSY) {
10363 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10364 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10365 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10366 }
10367 }
10368 if (f.frametype == AST_FRAME_IAX) {
10369 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10370
10371 if (iaxdebug)
10372 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10373
10374
10375 if (iaxs[fr->callno]->last < fr->ts &&
10376 f.subclass.integer != IAX_COMMAND_ACK &&
10377 f.subclass.integer != IAX_COMMAND_PONG &&
10378 f.subclass.integer != IAX_COMMAND_LAGRP) {
10379 iaxs[fr->callno]->last = fr->ts;
10380 if (iaxdebug)
10381 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10382 }
10383 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10384 if (!iaxs[fr->callno]->first_iax_message) {
10385 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10386 }
10387 switch(f.subclass.integer) {
10388 case IAX_COMMAND_ACK:
10389
10390 break;
10391 case IAX_COMMAND_QUELCH:
10392 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10393
10394 if (iaxs[fr->callno]->owner) {
10395 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10396 "Status: On\r\n"
10397 "Channel: %s\r\n"
10398 "Uniqueid: %s\r\n",
10399 iaxs[fr->callno]->owner->name,
10400 iaxs[fr->callno]->owner->uniqueid);
10401 }
10402
10403 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10404 if (ies.musiconhold) {
10405 iax2_lock_owner(fr->callno);
10406 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10407 break;
10408 }
10409 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10410 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10411
10412
10413
10414
10415
10416 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10417 S_OR(moh_suggest, NULL),
10418 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10419 }
10420 ast_channel_unlock(iaxs[fr->callno]->owner);
10421 }
10422 }
10423 break;
10424 case IAX_COMMAND_UNQUELCH:
10425 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10426 iax2_lock_owner(fr->callno);
10427 if (!iaxs[fr->callno]) {
10428 break;
10429 }
10430
10431 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10432 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10433 "Status: Off\r\n"
10434 "Channel: %s\r\n"
10435 "Uniqueid: %s\r\n",
10436 iaxs[fr->callno]->owner->name,
10437 iaxs[fr->callno]->owner->uniqueid);
10438 }
10439
10440 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10441 if (!iaxs[fr->callno]->owner) {
10442 break;
10443 }
10444 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10445
10446
10447
10448
10449 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10450 }
10451 ast_channel_unlock(iaxs[fr->callno]->owner);
10452 }
10453 break;
10454 case IAX_COMMAND_TXACC:
10455 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10456
10457 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10458
10459 if (cur->transfer) {
10460 cur->retries = -1;
10461 }
10462 }
10463 memset(&ied1, 0, sizeof(ied1));
10464 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10465 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10466 iaxs[fr->callno]->transferring = TRANSFER_READY;
10467 }
10468 break;
10469 case IAX_COMMAND_NEW:
10470
10471 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10472 break;
10473 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10474 ast_mutex_unlock(&iaxsl[fr->callno]);
10475 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10476 ast_mutex_lock(&iaxsl[fr->callno]);
10477 if (!iaxs[fr->callno]) {
10478 break;
10479 }
10480 }
10481
10482 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10483 int new_callno;
10484 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10485 fr->callno = new_callno;
10486 }
10487
10488 if (delayreject)
10489 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10490 if (check_access(fr->callno, &sin, &ies)) {
10491
10492 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10493 if (authdebug)
10494 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);
10495 break;
10496 }
10497 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10498 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10499 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10500 break;
10501 }
10502 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10503 const char *context, *exten, *cid_num;
10504
10505 context = ast_strdupa(iaxs[fr->callno]->context);
10506 exten = ast_strdupa(iaxs[fr->callno]->exten);
10507 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10508
10509
10510 ast_mutex_unlock(&iaxsl[fr->callno]);
10511 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10512 ast_mutex_lock(&iaxsl[fr->callno]);
10513
10514 if (!iaxs[fr->callno]) {
10515 break;
10516 }
10517 } else
10518 exists = 0;
10519
10520 save_osptoken(fr, &ies);
10521 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10522 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10523 memset(&ied0, 0, sizeof(ied0));
10524 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10525 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10526 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10527 if (!iaxs[fr->callno]) {
10528 break;
10529 }
10530 if (authdebug)
10531 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);
10532 } else {
10533
10534
10535 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10536 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10537 using_prefs = "reqonly";
10538 } else {
10539 using_prefs = "disabled";
10540 }
10541 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10542 memset(&pref, 0, sizeof(pref));
10543 strcpy(caller_pref_buf, "disabled");
10544 strcpy(host_pref_buf, "disabled");
10545 } else {
10546 using_prefs = "mine";
10547
10548 if (ies.codec_prefs)
10549 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10550 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10551
10552 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10553 pref = iaxs[fr->callno]->rprefs;
10554 using_prefs = "caller";
10555 } else {
10556 pref = iaxs[fr->callno]->prefs;
10557 }
10558 } else
10559 pref = iaxs[fr->callno]->prefs;
10560
10561 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10562 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10563 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10564 }
10565 if (!format) {
10566 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10567 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10568 if (!format) {
10569 memset(&ied0, 0, sizeof(ied0));
10570 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10571 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10572 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10573 if (!iaxs[fr->callno]) {
10574 break;
10575 }
10576 if (authdebug) {
10577 char tmp[256], tmp2[256], tmp3[256];
10578 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10579 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10580 ast_inet_ntoa(sin.sin_addr),
10581 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10582 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10583 } else {
10584 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10585 ast_inet_ntoa(sin.sin_addr),
10586 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10587 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10588 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10589 }
10590 }
10591 } else {
10592
10593 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10594 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10595 format = 0;
10596 } else {
10597 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10598 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10599 memset(&pref, 0, sizeof(pref));
10600 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10601 strcpy(caller_pref_buf,"disabled");
10602 strcpy(host_pref_buf,"disabled");
10603 } else {
10604 using_prefs = "mine";
10605 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10606
10607 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10608 pref = iaxs[fr->callno]->prefs;
10609 } else {
10610 pref = iaxs[fr->callno]->rprefs;
10611 using_prefs = "caller";
10612 }
10613 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10614 } else
10615 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10616 }
10617 }
10618
10619 if (!format) {
10620 char tmp[256], tmp2[256], tmp3[256];
10621 memset(&ied0, 0, sizeof(ied0));
10622 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10623 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10624 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10625 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10626 if (!iaxs[fr->callno]) {
10627 break;
10628 }
10629 if (authdebug) {
10630 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10631 ast_inet_ntoa(sin.sin_addr),
10632 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10633 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10634 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10635 }
10636 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10637 break;
10638 }
10639 }
10640 }
10641 if (format) {
10642
10643 memset(&ied1, 0, sizeof(ied1));
10644 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10645 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10646 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10647 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10648 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10649 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10650 "%srequested format = %s,\n"
10651 "%srequested prefs = %s,\n"
10652 "%sactual format = %s,\n"
10653 "%shost prefs = %s,\n"
10654 "%spriority = %s\n",
10655 ast_inet_ntoa(sin.sin_addr),
10656 VERBOSE_PREFIX_4,
10657 ast_getformatname(iaxs[fr->callno]->peerformat),
10658 VERBOSE_PREFIX_4,
10659 caller_pref_buf,
10660 VERBOSE_PREFIX_4,
10661 ast_getformatname(format),
10662 VERBOSE_PREFIX_4,
10663 host_pref_buf,
10664 VERBOSE_PREFIX_4,
10665 using_prefs);
10666
10667 iaxs[fr->callno]->chosenformat = format;
10668 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10669 } else {
10670 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10671
10672 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10673 }
10674 }
10675 }
10676 break;
10677 }
10678 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10679 merge_encryption(iaxs[fr->callno],ies.encmethods);
10680 else
10681 iaxs[fr->callno]->encmethods = 0;
10682 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10683 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10684 break;
10685 case IAX_COMMAND_DPREQ:
10686
10687 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10688 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10689 if (iaxcompat) {
10690
10691 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10692 } else {
10693
10694 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10695 }
10696 }
10697 break;
10698 case IAX_COMMAND_HANGUP:
10699 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10700 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10701
10702 if (iaxs[fr->callno]->owner) {
10703 set_hangup_source_and_cause(fr->callno, ies.causecode);
10704 if (!iaxs[fr->callno]) {
10705 break;
10706 }
10707 }
10708
10709
10710 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10711 iax2_destroy(fr->callno);
10712 break;
10713 case IAX_COMMAND_REJECT:
10714
10715 if (iaxs[fr->callno]->owner) {
10716 set_hangup_source_and_cause(fr->callno, ies.causecode);
10717 if (!iaxs[fr->callno]) {
10718 break;
10719 }
10720 }
10721
10722 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10723 if (iaxs[fr->callno]->owner && authdebug)
10724 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10725 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10726 ies.cause ? ies.cause : "<Unknown>");
10727 ast_debug(1, "Immediately destroying %d, having received reject\n",
10728 fr->callno);
10729 }
10730
10731 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10732 fr->ts, NULL, 0, fr->iseqno);
10733 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10734 iaxs[fr->callno]->error = EPERM;
10735 iax2_destroy(fr->callno);
10736 break;
10737 case IAX_COMMAND_TRANSFER:
10738 {
10739 struct ast_channel *bridged_chan;
10740 struct ast_channel *owner;
10741
10742 iax2_lock_owner(fr->callno);
10743 if (!iaxs[fr->callno]) {
10744
10745 break;
10746 }
10747 owner = iaxs[fr->callno]->owner;
10748 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10749 if (bridged_chan && ies.called_number) {
10750 const char *context;
10751
10752 context = ast_strdupa(iaxs[fr->callno]->context);
10753
10754 ast_channel_ref(owner);
10755 ast_channel_ref(bridged_chan);
10756 ast_channel_unlock(owner);
10757 ast_mutex_unlock(&iaxsl[fr->callno]);
10758
10759
10760 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10761 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10762
10763
10764 if (ast_parking_ext_valid(ies.called_number, owner, context)) {
10765 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10766 if (iax_park(bridged_chan, owner, ies.called_number, context)) {
10767 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10768 bridged_chan->name);
10769 }
10770 } else {
10771 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) {
10772 ast_log(LOG_WARNING,
10773 "Async goto of '%s' to '%s@%s' failed\n",
10774 bridged_chan->name, ies.called_number, context);
10775 } else {
10776 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10777 bridged_chan->name, ies.called_number, context);
10778 }
10779 }
10780 ast_channel_unref(owner);
10781 ast_channel_unref(bridged_chan);
10782
10783 ast_mutex_lock(&iaxsl[fr->callno]);
10784 } else {
10785 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10786 if (owner) {
10787 ast_channel_unlock(owner);
10788 }
10789 }
10790
10791 break;
10792 }
10793 case IAX_COMMAND_ACCEPT:
10794
10795 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10796 break;
10797 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10798
10799 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10800 iax2_destroy(fr->callno);
10801 break;
10802 }
10803 if (ies.format) {
10804 iaxs[fr->callno]->peerformat = ies.format;
10805 } else {
10806 if (iaxs[fr->callno]->owner)
10807 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10808 else
10809 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10810 }
10811 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));
10812 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10813 memset(&ied0, 0, sizeof(ied0));
10814 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10815 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10816 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10817 if (!iaxs[fr->callno]) {
10818 break;
10819 }
10820 if (authdebug) {
10821 char tmp1[256], tmp2[256];
10822 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10823 ast_inet_ntoa(sin.sin_addr),
10824 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10825 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10826 }
10827 } else {
10828 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10829 iax2_lock_owner(fr->callno);
10830 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10831
10832 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10833 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10834
10835
10836 if (iaxs[fr->callno]->owner->writeformat)
10837 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10838 if (iaxs[fr->callno]->owner->readformat)
10839 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10840 ast_channel_unlock(iaxs[fr->callno]->owner);
10841 }
10842 }
10843 if (iaxs[fr->callno]) {
10844 AST_LIST_LOCK(&dpcache);
10845 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10846 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10847 iax2_dprequest(dp, fr->callno);
10848 AST_LIST_UNLOCK(&dpcache);
10849 }
10850 break;
10851 case IAX_COMMAND_POKE:
10852
10853 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10854 break;
10855 case IAX_COMMAND_PING:
10856 {
10857 struct iax_ie_data pingied;
10858 construct_rr(iaxs[fr->callno], &pingied);
10859
10860 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10861 }
10862 break;
10863 case IAX_COMMAND_PONG:
10864
10865 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10866
10867 save_rr(fr, &ies);
10868
10869
10870 log_jitterstats(fr->callno);
10871
10872 if (iaxs[fr->callno]->peerpoke) {
10873 peer = iaxs[fr->callno]->peerpoke;
10874 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10875 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10876 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10877 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);
10878 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10879 }
10880 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10881 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10882 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10883 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);
10884 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10885 }
10886 }
10887 peer->lastms = iaxs[fr->callno]->pingtime;
10888 if (peer->smoothing && (peer->lastms > -1))
10889 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10890 else if (peer->smoothing && peer->lastms < 0)
10891 peer->historicms = (0 + peer->historicms) / 2;
10892 else
10893 peer->historicms = iaxs[fr->callno]->pingtime;
10894
10895
10896 if (peer->pokeexpire > -1) {
10897 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10898 peer_unref(peer);
10899 peer->pokeexpire = -1;
10900 }
10901 }
10902
10903 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10904 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10905 else
10906 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10907 if (peer->pokeexpire == -1)
10908 peer_unref(peer);
10909
10910 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10911
10912 iax2_destroy(fr->callno);
10913 peer->callno = 0;
10914 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10915 }
10916 break;
10917 case IAX_COMMAND_LAGRQ:
10918 case IAX_COMMAND_LAGRP:
10919 f.src = "LAGRQ";
10920 f.mallocd = 0;
10921 f.offset = 0;
10922 f.samples = 0;
10923 iax_frame_wrap(fr, &f);
10924 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
10925
10926 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
10927 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10928 } else {
10929
10930 unsigned int ts;
10931
10932 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10933 iaxs[fr->callno]->lag = ts - fr->ts;
10934 if (iaxdebug)
10935 ast_debug(1, "Peer %s lag measured as %dms\n",
10936 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10937 }
10938 break;
10939 case IAX_COMMAND_AUTHREQ:
10940 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10941 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>");
10942 break;
10943 }
10944 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10945 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10946 .subclass.integer = AST_CONTROL_HANGUP,
10947 };
10948 ast_log(LOG_WARNING,
10949 "I don't know how to authenticate %s to %s\n",
10950 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10951 iax2_queue_frame(fr->callno, &hangup_fr);
10952 }
10953 break;
10954 case IAX_COMMAND_AUTHREP:
10955
10956 if (delayreject)
10957 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10958
10959 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10960 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>");
10961 break;
10962 }
10963 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10964 if (authdebug)
10965 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);
10966 memset(&ied0, 0, sizeof(ied0));
10967 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10968 break;
10969 }
10970 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10971
10972 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10973 } else
10974 exists = 0;
10975 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10976 if (authdebug)
10977 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);
10978 memset(&ied0, 0, sizeof(ied0));
10979 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10980 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10981 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10982 if (!iaxs[fr->callno]) {
10983 break;
10984 }
10985 } else {
10986
10987 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10988 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10989 using_prefs = "reqonly";
10990 } else {
10991 using_prefs = "disabled";
10992 }
10993 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10994 memset(&pref, 0, sizeof(pref));
10995 strcpy(caller_pref_buf, "disabled");
10996 strcpy(host_pref_buf, "disabled");
10997 } else {
10998 using_prefs = "mine";
10999 if (ies.codec_prefs)
11000 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
11001 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11002 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11003 pref = iaxs[fr->callno]->rprefs;
11004 using_prefs = "caller";
11005 } else {
11006 pref = iaxs[fr->callno]->prefs;
11007 }
11008 } else
11009 pref = iaxs[fr->callno]->prefs;
11010 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
11011 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
11012 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
11013 }
11014 if (!format) {
11015 char tmp1[256], tmp2[256], tmp3[256];
11016 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11017 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
11018 ast_getformatname(iaxs[fr->callno]->peerformat),
11019 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
11020 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
11021 }
11022 if (!format) {
11023 if (authdebug) {
11024 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11025 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
11026 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11027 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11028 } else {
11029 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11030 ast_inet_ntoa(sin.sin_addr),
11031 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11032 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11033 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11034 }
11035 }
11036 memset(&ied0, 0, sizeof(ied0));
11037 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11038 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11039 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11040 if (!iaxs[fr->callno]) {
11041 break;
11042 }
11043 } else {
11044
11045 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11046 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
11047 format = 0;
11048 } else {
11049 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
11050 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
11051 memset(&pref, 0, sizeof(pref));
11052 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
11053 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11054 strcpy(caller_pref_buf,"disabled");
11055 strcpy(host_pref_buf,"disabled");
11056 } else {
11057 using_prefs = "mine";
11058 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
11059
11060 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11061 pref = iaxs[fr->callno]->prefs;
11062 } else {
11063 pref = iaxs[fr->callno]->rprefs;
11064 using_prefs = "caller";
11065 }
11066 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11067 } else
11068 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11069 }
11070 }
11071 if (!format) {
11072 char tmp1[256], tmp2[256], tmp3[256];
11073 ast_log(LOG_ERROR, "No best format in %s???\n",
11074 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11075 if (authdebug) {
11076 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11077 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11078 ast_inet_ntoa(sin.sin_addr),
11079 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11080 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11081 } else {
11082 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11083 ast_inet_ntoa(sin.sin_addr),
11084 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11085 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11086 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11087 }
11088 }
11089 memset(&ied0, 0, sizeof(ied0));
11090 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11091 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11092 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11093 if (!iaxs[fr->callno]) {
11094 break;
11095 }
11096 }
11097 }
11098 }
11099 if (format) {
11100
11101 memset(&ied1, 0, sizeof(ied1));
11102 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11103 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11104 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11105 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11106 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11107 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11108 "%srequested format = %s,\n"
11109 "%srequested prefs = %s,\n"
11110 "%sactual format = %s,\n"
11111 "%shost prefs = %s,\n"
11112 "%spriority = %s\n",
11113 ast_inet_ntoa(sin.sin_addr),
11114 VERBOSE_PREFIX_4,
11115 ast_getformatname(iaxs[fr->callno]->peerformat),
11116 VERBOSE_PREFIX_4,
11117 caller_pref_buf,
11118 VERBOSE_PREFIX_4,
11119 ast_getformatname(format),
11120 VERBOSE_PREFIX_4,
11121 host_pref_buf,
11122 VERBOSE_PREFIX_4,
11123 using_prefs);
11124
11125 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11126 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11127 iax2_destroy(fr->callno);
11128 else if (ies.vars) {
11129 struct ast_datastore *variablestore;
11130 struct ast_variable *var, *prev = NULL;
11131 AST_LIST_HEAD(, ast_var_t) *varlist;
11132 varlist = ast_calloc(1, sizeof(*varlist));
11133 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11134 if (variablestore && varlist) {
11135 variablestore->data = varlist;
11136 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11137 AST_LIST_HEAD_INIT(varlist);
11138 ast_debug(1, "I can haz IAX vars? w00t\n");
11139 for (var = ies.vars; var; var = var->next) {
11140 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11141 if (prev)
11142 ast_free(prev);
11143 prev = var;
11144 if (!newvar) {
11145
11146 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11147 } else {
11148 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11149 }
11150 }
11151 if (prev)
11152 ast_free(prev);
11153 ies.vars = NULL;
11154 ast_channel_datastore_add(c, variablestore);
11155 } else {
11156 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11157 if (variablestore)
11158 ast_datastore_free(variablestore);
11159 if (varlist)
11160 ast_free(varlist);
11161 }
11162 }
11163 } else {
11164 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11165
11166 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11167 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11168 goto immediatedial;
11169 }
11170 }
11171 }
11172 }
11173 break;
11174 case IAX_COMMAND_DIAL:
11175 immediatedial:
11176 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11177 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11178 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11179 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11180 if (authdebug)
11181 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);
11182 memset(&ied0, 0, sizeof(ied0));
11183 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11184 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11185 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11186 if (!iaxs[fr->callno]) {
11187 break;
11188 }
11189 } else {
11190 char tmp[256];
11191 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11192 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11193 ast_inet_ntoa(sin.sin_addr),
11194 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11195 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11196 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11197 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11198 iax2_destroy(fr->callno);
11199 else if (ies.vars) {
11200 struct ast_datastore *variablestore;
11201 struct ast_variable *var, *prev = NULL;
11202 AST_LIST_HEAD(, ast_var_t) *varlist;
11203 varlist = ast_calloc(1, sizeof(*varlist));
11204 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11205 ast_debug(1, "I can haz IAX vars? w00t\n");
11206 if (variablestore && varlist) {
11207 variablestore->data = varlist;
11208 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11209 AST_LIST_HEAD_INIT(varlist);
11210 for (var = ies.vars; var; var = var->next) {
11211 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11212 if (prev)
11213 ast_free(prev);
11214 prev = var;
11215 if (!newvar) {
11216
11217 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11218 } else {
11219 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11220 }
11221 }
11222 if (prev)
11223 ast_free(prev);
11224 ies.vars = NULL;
11225 ast_channel_datastore_add(c, variablestore);
11226 } else {
11227 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11228 if (variablestore)
11229 ast_datastore_free(variablestore);
11230 if (varlist)
11231 ast_free(varlist);
11232 }
11233 }
11234 }
11235 }
11236 break;
11237 case IAX_COMMAND_INVAL:
11238 iaxs[fr->callno]->error = ENOTCONN;
11239 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11240 iax2_destroy(fr->callno);
11241 ast_debug(1, "Destroying call %d\n", fr->callno);
11242 break;
11243 case IAX_COMMAND_VNAK:
11244 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11245
11246 vnak_retransmit(fr->callno, fr->iseqno);
11247 break;
11248 case IAX_COMMAND_REGREQ:
11249 case IAX_COMMAND_REGREL:
11250
11251 if (delayreject)
11252 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11253 if (register_verify(fr->callno, &sin, &ies)) {
11254 if (!iaxs[fr->callno]) {
11255 break;
11256 }
11257
11258 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11259 break;
11260 }
11261 if (!iaxs[fr->callno]) {
11262 break;
11263 }
11264 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11265 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11266
11267 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11268 memset(&sin, 0, sizeof(sin));
11269 sin.sin_family = AF_INET;
11270 }
11271 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11272 ast_log(LOG_WARNING, "Registry error\n");
11273 }
11274 if (!iaxs[fr->callno]) {
11275 break;
11276 }
11277 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11278 ast_mutex_unlock(&iaxsl[fr->callno]);
11279 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11280 ast_mutex_lock(&iaxsl[fr->callno]);
11281 }
11282 break;
11283 }
11284 registry_authrequest(fr->callno);
11285 break;
11286 case IAX_COMMAND_REGACK:
11287 if (iax2_ack_registry(&ies, &sin, fr->callno))
11288 ast_log(LOG_WARNING, "Registration failure\n");
11289
11290 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11291 iax2_destroy(fr->callno);
11292 break;
11293 case IAX_COMMAND_REGREJ:
11294 if (iaxs[fr->callno]->reg) {
11295 if (authdebug) {
11296 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));
11297 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>");
11298 }
11299 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11300 }
11301
11302 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11303 iax2_destroy(fr->callno);
11304 break;
11305 case IAX_COMMAND_REGAUTH:
11306
11307 if (registry_rerequest(&ies, fr->callno, &sin)) {
11308 memset(&ied0, 0, sizeof(ied0));
11309 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11310 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11311 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11312 }
11313 break;
11314 case IAX_COMMAND_TXREJ:
11315 iaxs[fr->callno]->transferring = 0;
11316 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11317 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11318 if (iaxs[fr->callno]->bridgecallno) {
11319 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11320 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11321 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11322 }
11323 }
11324 break;
11325 case IAX_COMMAND_TXREADY:
11326 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11327 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11328 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11329 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11330 else
11331 iaxs[fr->callno]->transferring = TRANSFER_READY;
11332 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11333 if (iaxs[fr->callno]->bridgecallno) {
11334 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11335 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11336
11337 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11338 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11339 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11340
11341 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11342 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11343
11344 memset(&ied0, 0, sizeof(ied0));
11345 memset(&ied1, 0, sizeof(ied1));
11346 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11347 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11348 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11349 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11350 } else {
11351 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11352 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11353
11354 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11355 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11356 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11357 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11358
11359
11360 stop_stuff(fr->callno);
11361 stop_stuff(iaxs[fr->callno]->bridgecallno);
11362
11363 memset(&ied0, 0, sizeof(ied0));
11364 memset(&ied1, 0, sizeof(ied1));
11365 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11366 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11367 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11368 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11369 }
11370
11371 }
11372 }
11373 }
11374 break;
11375 case IAX_COMMAND_TXREQ:
11376 try_transfer(iaxs[fr->callno], &ies);
11377 break;
11378 case IAX_COMMAND_TXCNT:
11379 if (iaxs[fr->callno]->transferring)
11380 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11381 break;
11382 case IAX_COMMAND_TXREL:
11383
11384 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11385 complete_transfer(fr->callno, &ies);
11386 stop_stuff(fr->callno);
11387 break;
11388 case IAX_COMMAND_TXMEDIA:
11389 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11390 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11391
11392 if (cur->transfer) {
11393 cur->retries = -1;
11394 }
11395 }
11396
11397 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11398 }
11399 break;
11400 case IAX_COMMAND_RTKEY:
11401 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11402 ast_log(LOG_WARNING,
11403 "we've been told to rotate our encryption key, "
11404 "but this isn't an encrypted call. bad things will happen.\n"
11405 );
11406 break;
11407 }
11408
11409 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11410
11411 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11412 break;
11413 case IAX_COMMAND_DPREP:
11414 complete_dpreply(iaxs[fr->callno], &ies);
11415 break;
11416 case IAX_COMMAND_UNSUPPORT:
11417 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11418 break;
11419 case IAX_COMMAND_FWDOWNL:
11420
11421 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11422 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11423 break;
11424 }
11425 memset(&ied0, 0, sizeof(ied0));
11426 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11427 if (res < 0)
11428 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11429 else if (res > 0)
11430 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11431 else
11432 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11433 break;
11434 case IAX_COMMAND_CALLTOKEN:
11435 {
11436 struct iax_frame *cur;
11437
11438 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11439 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11440 }
11441 break;
11442 }
11443 default:
11444 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11445 memset(&ied0, 0, sizeof(ied0));
11446 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11447 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11448 }
11449
11450 if (ies.vars) {
11451 ast_variables_destroy(ies.vars);
11452 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11453 ies.vars = NULL;
11454 }
11455
11456
11457 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11458 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11459 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11460 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11461 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11462 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11463 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11464 }
11465 ast_mutex_unlock(&iaxsl[fr->callno]);
11466 return 1;
11467 }
11468
11469 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11470 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11471 } else if (minivid) {
11472 f.frametype = AST_FRAME_VIDEO;
11473 if (iaxs[fr->callno]->videoformat > 0)
11474 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11475 else {
11476 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11477 iax2_vnak(fr->callno);
11478 ast_variables_destroy(ies.vars);
11479 ast_mutex_unlock(&iaxsl[fr->callno]);
11480 return 1;
11481 }
11482 f.datalen = res - sizeof(*vh);
11483 if (f.datalen)
11484 f.data.ptr = thread->buf + sizeof(*vh);
11485 else
11486 f.data.ptr = NULL;
11487 #ifdef IAXTESTS
11488 if (test_resync) {
11489 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11490 } else
11491 #endif
11492 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11493 } else {
11494
11495 f.frametype = AST_FRAME_VOICE;
11496 if (iaxs[fr->callno]->voiceformat > 0)
11497 f.subclass.codec = iaxs[fr->callno]->voiceformat;
11498 else {
11499 ast_debug(1, "Received mini frame before first full voice frame\n");
11500 iax2_vnak(fr->callno);
11501 ast_variables_destroy(ies.vars);
11502 ast_mutex_unlock(&iaxsl[fr->callno]);
11503 return 1;
11504 }
11505 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11506 if (f.datalen < 0) {
11507 ast_log(LOG_WARNING, "Datalen < 0?\n");
11508 ast_variables_destroy(ies.vars);
11509 ast_mutex_unlock(&iaxsl[fr->callno]);
11510 return 1;
11511 }
11512 if (f.datalen)
11513 f.data.ptr = thread->buf + sizeof(*mh);
11514 else
11515 f.data.ptr = NULL;
11516 #ifdef IAXTESTS
11517 if (test_resync) {
11518 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11519 } else
11520 #endif
11521 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11522
11523 }
11524
11525 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11526 ast_variables_destroy(ies.vars);
11527 ast_mutex_unlock(&iaxsl[fr->callno]);
11528 return 1;
11529 }
11530
11531 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11532 struct ast_party_connected_line connected;
11533
11534 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11535 ast_variables_destroy(ies.vars);
11536 ast_mutex_unlock(&iaxsl[fr->callno]);
11537 return 1;
11538 }
11539
11540
11541 ast_party_connected_line_init(&connected);
11542 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11543 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11544
11545 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11546 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11547 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11548 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11549
11550 if (iaxs[fr->callno]->owner) {
11551 ast_set_callerid(iaxs[fr->callno]->owner,
11552 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11553 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11554 NULL);
11555 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11556 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11557 }
11558 }
11559 ast_party_connected_line_free(&connected);
11560 }
11561
11562 f.src = "IAX2";
11563 f.mallocd = 0;
11564 f.offset = 0;
11565 f.len = 0;
11566 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11567 f.samples = ast_codec_get_samples(&f);
11568
11569 if (f.subclass.codec == AST_FORMAT_SLINEAR)
11570 ast_frame_byteswap_be(&f);
11571 } else
11572 f.samples = 0;
11573 iax_frame_wrap(fr, &f);
11574
11575
11576 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11577
11578 fr->outoforder = 0;
11579 } else {
11580 if (iaxdebug && iaxs[fr->callno])
11581 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);
11582 fr->outoforder = -1;
11583 }
11584 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11585 duped_fr = iaxfrdup2(fr);
11586 if (duped_fr) {
11587 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11588 }
11589 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11590 iaxs[fr->callno]->last = fr->ts;
11591 #if 1
11592 if (iaxdebug)
11593 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11594 #endif
11595 }
11596
11597
11598 ast_variables_destroy(ies.vars);
11599 ast_mutex_unlock(&iaxsl[fr->callno]);
11600 return 1;
11601 }
11602
11603
11604 static void iax2_process_thread_cleanup(void *data)
11605 {
11606 struct iax2_thread *thread = data;
11607 ast_mutex_destroy(&thread->lock);
11608 ast_cond_destroy(&thread->cond);
11609 ast_mutex_destroy(&thread->init_lock);
11610 ast_cond_destroy(&thread->init_cond);
11611 ast_free(thread);
11612 ast_atomic_dec_and_test(&iaxactivethreadcount);
11613 }
11614
11615 static void *iax2_process_thread(void *data)
11616 {
11617 struct iax2_thread *thread = data;
11618 struct timeval wait;
11619 struct timespec ts;
11620 int put_into_idle = 0;
11621 int first_time = 1;
11622 int old_state;
11623
11624 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11625
11626 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11627 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11628
11629 for (;;) {
11630
11631 ast_mutex_lock(&thread->lock);
11632
11633 if (thread->stop) {
11634 ast_mutex_unlock(&thread->lock);
11635 break;
11636 }
11637
11638
11639 if (first_time) {
11640 signal_condition(&thread->init_lock, &thread->init_cond);
11641 first_time = 0;
11642 }
11643
11644
11645 if (put_into_idle) {
11646 insert_idle_thread(thread);
11647 }
11648
11649 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11650 struct iax2_thread *t = NULL;
11651
11652 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11653 ts.tv_sec = wait.tv_sec;
11654 ts.tv_nsec = wait.tv_usec * 1000;
11655 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11656
11657
11658 if (!put_into_idle || thread->stop) {
11659 ast_mutex_unlock(&thread->lock);
11660 break;
11661 }
11662 AST_LIST_LOCK(&dynamic_list);
11663
11664 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11665 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11666 AST_LIST_UNLOCK(&dynamic_list);
11667 if (t) {
11668
11669
11670
11671 ast_mutex_unlock(&thread->lock);
11672 break;
11673 }
11674
11675
11676
11677 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11678 ts.tv_sec = wait.tv_sec;
11679 ts.tv_nsec = wait.tv_usec * 1000;
11680 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11681 ast_mutex_unlock(&thread->lock);
11682 break;
11683 }
11684 }
11685 } else {
11686 ast_cond_wait(&thread->cond, &thread->lock);
11687 }
11688
11689
11690 put_into_idle = 1;
11691
11692 ast_mutex_unlock(&thread->lock);
11693
11694 if (thread->stop) {
11695 break;
11696 }
11697
11698 if (thread->iostate == IAX_IOSTATE_IDLE)
11699 continue;
11700
11701
11702 switch (thread->iostate) {
11703 case IAX_IOSTATE_READY:
11704 thread->actions++;
11705 thread->iostate = IAX_IOSTATE_PROCESSING;
11706 socket_process(thread);
11707 handle_deferred_full_frames(thread);
11708 break;
11709 case IAX_IOSTATE_SCHEDREADY:
11710 thread->actions++;
11711 thread->iostate = IAX_IOSTATE_PROCESSING;
11712 #ifdef SCHED_MULTITHREADED
11713 thread->schedfunc(thread->scheddata);
11714 #endif
11715 default:
11716 break;
11717 }
11718 time(&thread->checktime);
11719 thread->iostate = IAX_IOSTATE_IDLE;
11720 #ifdef DEBUG_SCHED_MULTITHREAD
11721 thread->curfunc[0]='\0';
11722 #endif
11723
11724
11725
11726
11727 AST_LIST_LOCK(&active_list);
11728 AST_LIST_REMOVE(&active_list, thread, list);
11729 AST_LIST_UNLOCK(&active_list);
11730
11731
11732 handle_deferred_full_frames(thread);
11733 }
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 if (!thread->stop) {
11749
11750 pthread_detach(pthread_self());
11751 }
11752
11753
11754
11755
11756 pthread_cleanup_pop(1);
11757 return NULL;
11758 }
11759
11760 static int iax2_do_register(struct iax2_registry *reg)
11761 {
11762 struct iax_ie_data ied;
11763 if (iaxdebug)
11764 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11765
11766 if (reg->dnsmgr &&
11767 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
11768
11769 ast_dnsmgr_refresh(reg->dnsmgr);
11770 }
11771
11772
11773
11774
11775
11776 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11777 int callno = reg->callno;
11778 ast_mutex_lock(&iaxsl[callno]);
11779 iax2_destroy(callno);
11780 ast_mutex_unlock(&iaxsl[callno]);
11781 reg->callno = 0;
11782 }
11783 if (!ast_sockaddr_ipv4(®->addr)) {
11784 if (iaxdebug)
11785 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11786
11787 reg->expire = iax2_sched_replace(reg->expire, sched,
11788 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11789 return -1;
11790 }
11791
11792 if (!reg->callno) {
11793 struct sockaddr_in reg_addr;
11794
11795 ast_debug(3, "Allocate call number\n");
11796
11797 ast_sockaddr_to_sin(®->addr, ®_addr);
11798
11799 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
11800 if (reg->callno < 1) {
11801 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11802 return -1;
11803 } else
11804 ast_debug(3, "Registration created on call %d\n", reg->callno);
11805 iaxs[reg->callno]->reg = reg;
11806 ast_mutex_unlock(&iaxsl[reg->callno]);
11807 }
11808
11809 reg->expire = iax2_sched_replace(reg->expire, sched,
11810 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11811
11812 memset(&ied, 0, sizeof(ied));
11813 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11814 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11815 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11816 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11817 reg->regstate = REG_STATE_REGSENT;
11818 return 0;
11819 }
11820
11821 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
11822 {
11823
11824
11825 struct iax_ie_data provdata;
11826 struct iax_ie_data ied;
11827 unsigned int sig;
11828 struct sockaddr_in sin;
11829 int callno;
11830 struct create_addr_info cai;
11831
11832 memset(&cai, 0, sizeof(cai));
11833
11834 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11835
11836 if (iax_provision_build(&provdata, &sig, template, force)) {
11837 ast_debug(1, "No provisioning found for template '%s'\n", template);
11838 return 0;
11839 }
11840
11841 if (end) {
11842 memcpy(&sin, end, sizeof(sin));
11843 cai.sockfd = sockfd;
11844 } else if (create_addr(dest, NULL, &sin, &cai))
11845 return -1;
11846
11847
11848 memset(&ied, 0, sizeof(ied));
11849 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11850
11851 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11852 if (!callno)
11853 return -1;
11854
11855 if (iaxs[callno]) {
11856
11857 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11858 sched, 15000, auto_hangup, (void *)(long)callno);
11859 ast_set_flag64(iaxs[callno], IAX_PROVISION);
11860
11861 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11862 }
11863 ast_mutex_unlock(&iaxsl[callno]);
11864
11865 return 1;
11866 }
11867
11868 static char *papp = "IAX2Provision";
11869
11870
11871
11872
11873 static int iax2_prov_app(struct ast_channel *chan, const char *data)
11874 {
11875 int res;
11876 char *sdata;
11877 char *opts;
11878 int force =0;
11879 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11880 if (ast_strlen_zero(data))
11881 data = "default";
11882 sdata = ast_strdupa(data);
11883 opts = strchr(sdata, '|');
11884 if (opts)
11885 *opts='\0';
11886
11887 if (chan->tech != &iax2_tech) {
11888 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11889 return -1;
11890 }
11891 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11892 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11893 return -1;
11894 }
11895 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11896 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11897 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11898 sdata, res);
11899 return res;
11900 }
11901
11902 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11903 {
11904 int force = 0;
11905 int res;
11906
11907 switch (cmd) {
11908 case CLI_INIT:
11909 e->command = "iax2 provision";
11910 e->usage =
11911 "Usage: iax2 provision <host> <template> [forced]\n"
11912 " Provisions the given peer or IP address using a template\n"
11913 " matching either 'template' or '*' if the template is not\n"
11914 " found. If 'forced' is specified, even empty provisioning\n"
11915 " fields will be provisioned as empty fields.\n";
11916 return NULL;
11917 case CLI_GENERATE:
11918 if (a->pos == 3)
11919 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11920 return NULL;
11921 }
11922
11923 if (a->argc < 4)
11924 return CLI_SHOWUSAGE;
11925 if (a->argc > 4) {
11926 if (!strcasecmp(a->argv[4], "forced"))
11927 force = 1;
11928 else
11929 return CLI_SHOWUSAGE;
11930 }
11931 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11932 if (res < 0)
11933 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11934 else if (res < 1)
11935 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11936 else
11937 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11938 return CLI_SUCCESS;
11939 }
11940
11941 static void __iax2_poke_noanswer(const void *data)
11942 {
11943 struct iax2_peer *peer = (struct iax2_peer *)data;
11944 int callno;
11945
11946 if (peer->lastms > -1) {
11947 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11948 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11949 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11950 }
11951 if ((callno = peer->callno) > 0) {
11952 ast_mutex_lock(&iaxsl[callno]);
11953 iax2_destroy(callno);
11954 ast_mutex_unlock(&iaxsl[callno]);
11955 }
11956 peer->callno = 0;
11957 peer->lastms = -1;
11958
11959 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11960 if (peer->pokeexpire == -1)
11961 peer_unref(peer);
11962 }
11963
11964 static int iax2_poke_noanswer(const void *data)
11965 {
11966 struct iax2_peer *peer = (struct iax2_peer *)data;
11967 peer->pokeexpire = -1;
11968 #ifdef SCHED_MULTITHREADED
11969 if (schedule_action(__iax2_poke_noanswer, data))
11970 #endif
11971 __iax2_poke_noanswer(data);
11972 peer_unref(peer);
11973 return 0;
11974 }
11975
11976 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11977 {
11978 struct iax2_peer *peer = obj;
11979
11980 iax2_poke_peer(peer, 0);
11981
11982 return 0;
11983 }
11984
11985 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11986 {
11987 int callno;
11988 struct sockaddr_in peer_addr;
11989
11990 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
11991
11992
11993 peer->lastms = 0;
11994 peer->historicms = 0;
11995 peer->pokeexpire = -1;
11996 peer->callno = 0;
11997 return 0;
11998 }
11999
12000 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
12001
12002
12003 if ((callno = peer->callno) > 0) {
12004 ast_log(LOG_NOTICE, "Still have a callno...\n");
12005 ast_mutex_lock(&iaxsl[callno]);
12006 iax2_destroy(callno);
12007 ast_mutex_unlock(&iaxsl[callno]);
12008 }
12009 if (heldcall)
12010 ast_mutex_unlock(&iaxsl[heldcall]);
12011 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
12012 if (heldcall)
12013 ast_mutex_lock(&iaxsl[heldcall]);
12014 if (peer->callno < 1) {
12015 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
12016 return -1;
12017 }
12018
12019
12020 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
12021 iaxs[peer->callno]->peerpoke = peer;
12022
12023 if (peer->pokeexpire > -1) {
12024 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
12025 peer->pokeexpire = -1;
12026 peer_unref(peer);
12027 }
12028 }
12029
12030
12031
12032 if (peer->lastms < 0)
12033 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
12034 else
12035 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
12036
12037 if (peer->pokeexpire == -1)
12038 peer_unref(peer);
12039
12040
12041 ast_mutex_lock(&iaxsl[callno]);
12042 if (iaxs[callno]) {
12043 struct iax_ie_data ied = {
12044 .buf = { 0 },
12045 .pos = 0,
12046 };
12047 add_empty_calltoken_ie(iaxs[callno], &ied);
12048 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
12049 }
12050 ast_mutex_unlock(&iaxsl[callno]);
12051
12052 return 0;
12053 }
12054
12055 static void free_context(struct iax2_context *con)
12056 {
12057 struct iax2_context *conl;
12058 while(con) {
12059 conl = con;
12060 con = con->next;
12061 ast_free(conl);
12062 }
12063 }
12064
12065 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
12066 {
12067 int callno;
12068 int res;
12069 format_t fmt, native;
12070 struct sockaddr_in sin;
12071 struct ast_channel *c;
12072 struct parsed_dial_string pds;
12073 struct create_addr_info cai;
12074 char *tmpstr;
12075
12076 memset(&pds, 0, sizeof(pds));
12077 tmpstr = ast_strdupa(data);
12078 parse_dial_string(tmpstr, &pds);
12079
12080 if (ast_strlen_zero(pds.peer)) {
12081 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12082 return NULL;
12083 }
12084
12085 memset(&cai, 0, sizeof(cai));
12086 cai.capability = iax2_capability;
12087
12088 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12089
12090
12091 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12092 *cause = AST_CAUSE_UNREGISTERED;
12093 return NULL;
12094 }
12095
12096 if (pds.port)
12097 sin.sin_port = htons(atoi(pds.port));
12098
12099 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12100 if (callno < 1) {
12101 ast_log(LOG_WARNING, "Unable to create call\n");
12102 *cause = AST_CAUSE_CONGESTION;
12103 return NULL;
12104 }
12105
12106
12107 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12108 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12109 int new_callno;
12110 if ((new_callno = make_trunk(callno, 1)) != -1)
12111 callno = new_callno;
12112 }
12113 iaxs[callno]->maxtime = cai.maxtime;
12114 if (cai.found)
12115 ast_string_field_set(iaxs[callno], host, pds.peer);
12116
12117 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
12118
12119 ast_mutex_unlock(&iaxsl[callno]);
12120
12121 if (c) {
12122
12123 if (c->nativeformats & format)
12124 c->nativeformats &= format;
12125 else {
12126 native = c->nativeformats;
12127 fmt = format;
12128 res = ast_translator_best_choice(&fmt, &native);
12129 if (res < 0) {
12130 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12131 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12132 ast_hangup(c);
12133 return NULL;
12134 }
12135 c->nativeformats = native;
12136 }
12137 c->readformat = ast_best_codec(c->nativeformats);
12138 c->writeformat = c->readformat;
12139 }
12140
12141 return c;
12142 }
12143
12144 static void *network_thread(void *ignore)
12145 {
12146 if (timer) {
12147 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12148 }
12149
12150 for (;;) {
12151 pthread_testcancel();
12152
12153
12154
12155 ast_io_wait(io, 1000);
12156 }
12157
12158 return NULL;
12159 }
12160
12161 static int start_network_thread(void)
12162 {
12163 struct iax2_thread *thread;
12164 int threadcount = 0;
12165 int x;
12166 for (x = 0; x < iaxthreadcount; x++) {
12167 thread = ast_calloc(1, sizeof(*thread));
12168 if (thread) {
12169 thread->type = IAX_THREAD_TYPE_POOL;
12170 thread->threadnum = ++threadcount;
12171 ast_mutex_init(&thread->lock);
12172 ast_cond_init(&thread->cond, NULL);
12173 ast_mutex_init(&thread->init_lock);
12174 ast_cond_init(&thread->init_cond, NULL);
12175 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12176 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12177 ast_mutex_destroy(&thread->lock);
12178 ast_cond_destroy(&thread->cond);
12179 ast_mutex_destroy(&thread->init_lock);
12180 ast_cond_destroy(&thread->init_cond);
12181 ast_free(thread);
12182 thread = NULL;
12183 continue;
12184 }
12185 AST_LIST_LOCK(&idle_list);
12186 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12187 AST_LIST_UNLOCK(&idle_list);
12188 }
12189 }
12190 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12191 ast_verb(2, "%d helper threads started\n", threadcount);
12192 return 0;
12193 }
12194
12195 static struct iax2_context *build_context(const char *context)
12196 {
12197 struct iax2_context *con;
12198
12199 if ((con = ast_calloc(1, sizeof(*con))))
12200 ast_copy_string(con->context, context, sizeof(con->context));
12201
12202 return con;
12203 }
12204
12205 static int get_auth_methods(const char *value)
12206 {
12207 int methods = 0;
12208 if (strstr(value, "rsa"))
12209 methods |= IAX_AUTH_RSA;
12210 if (strstr(value, "md5"))
12211 methods |= IAX_AUTH_MD5;
12212 if (strstr(value, "plaintext"))
12213 methods |= IAX_AUTH_PLAINTEXT;
12214 return methods;
12215 }
12216
12217
12218
12219
12220
12221 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12222 {
12223 int sd;
12224 int res;
12225
12226 sd = socket(AF_INET, SOCK_DGRAM, 0);
12227 if (sd < 0) {
12228 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12229 return -1;
12230 }
12231
12232 res = bind(sd, sa, salen);
12233 if (res < 0) {
12234 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12235 close(sd);
12236 return 1;
12237 }
12238
12239 close(sd);
12240 return 0;
12241 }
12242
12243
12244
12245
12246 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12247 {
12248 struct sockaddr_in sin;
12249 struct ast_sockaddr sin_tmp;
12250 int nonlocal = 1;
12251 int port = IAX_DEFAULT_PORTNO;
12252 int sockfd = defaultsockfd;
12253 char *tmp;
12254 char *addr;
12255 char *portstr;
12256
12257 if (!(tmp = ast_strdupa(srcaddr)))
12258 return -1;
12259
12260 addr = strsep(&tmp, ":");
12261 portstr = tmp;
12262
12263 if (portstr) {
12264 port = atoi(portstr);
12265 if (port < 1)
12266 port = IAX_DEFAULT_PORTNO;
12267 }
12268
12269 sin_tmp.ss.ss_family = AF_INET;
12270 if (!ast_get_ip(&sin_tmp, addr)) {
12271 struct ast_netsock *sock;
12272 int res;
12273
12274 ast_sockaddr_to_sin(&sin_tmp, &sin);
12275 sin.sin_port = 0;
12276 sin.sin_family = AF_INET;
12277 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12278 if (res == 0) {
12279
12280 sin.sin_port = htons(port);
12281 if (!(sock = ast_netsock_find(netsock, &sin)))
12282 sock = ast_netsock_find(outsock, &sin);
12283 if (sock) {
12284 sockfd = ast_netsock_sockfd(sock);
12285 nonlocal = 0;
12286 } else {
12287 unsigned int orig_saddr = sin.sin_addr.s_addr;
12288
12289 sin.sin_addr.s_addr = INADDR_ANY;
12290 if (ast_netsock_find(netsock, &sin)) {
12291 sin.sin_addr.s_addr = orig_saddr;
12292 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12293 if (sock) {
12294 sockfd = ast_netsock_sockfd(sock);
12295 ast_netsock_unref(sock);
12296 nonlocal = 0;
12297 } else {
12298 nonlocal = 2;
12299 }
12300 }
12301 }
12302 }
12303 }
12304
12305 peer->sockfd = sockfd;
12306
12307 if (nonlocal == 1) {
12308 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12309 srcaddr, peer->name);
12310 return -1;
12311 } else if (nonlocal == 2) {
12312 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12313 srcaddr, peer->name);
12314 return -1;
12315 } else {
12316 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12317 return 0;
12318 }
12319 }
12320
12321 static void peer_destructor(void *obj)
12322 {
12323 struct iax2_peer *peer = obj;
12324 int callno = peer->callno;
12325
12326 ast_free_ha(peer->ha);
12327
12328 if (callno > 0) {
12329 ast_mutex_lock(&iaxsl[callno]);
12330 iax2_destroy(callno);
12331 ast_mutex_unlock(&iaxsl[callno]);
12332 }
12333
12334 register_peer_exten(peer, 0);
12335
12336 if (peer->dnsmgr)
12337 ast_dnsmgr_release(peer->dnsmgr);
12338
12339 if (peer->mwi_event_sub)
12340 ast_event_unsubscribe(peer->mwi_event_sub);
12341
12342 ast_string_field_free_memory(peer);
12343 }
12344
12345
12346 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12347 {
12348 struct iax2_peer *peer = NULL;
12349 struct ast_ha *oldha = NULL;
12350 int maskfound = 0;
12351 int found = 0;
12352 int firstpass = 1;
12353 struct iax2_peer tmp_peer = {
12354 .name = name,
12355 };
12356
12357 if (!temponly) {
12358 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12359 if (peer && !ast_test_flag64(peer, IAX_DELME))
12360 firstpass = 0;
12361 }
12362
12363 if (peer) {
12364 found++;
12365 if (firstpass) {
12366 oldha = peer->ha;
12367 peer->ha = NULL;
12368 }
12369 unlink_peer(peer);
12370 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12371 peer->expire = -1;
12372 peer->pokeexpire = -1;
12373 peer->sockfd = defaultsockfd;
12374 peer->addr.ss.ss_family = AF_INET;
12375 if (ast_string_field_init(peer, 32))
12376 peer = peer_unref(peer);
12377 }
12378
12379 if (peer) {
12380 if (firstpass) {
12381 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12382 peer->encmethods = iax2_encryption;
12383 peer->adsi = adsi;
12384 ast_string_field_set(peer,secret,"");
12385 if (!found) {
12386 ast_string_field_set(peer, name, name);
12387 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12388 peer->expiry = min_reg_expire;
12389 }
12390 peer->prefs = prefs;
12391 peer->capability = iax2_capability;
12392 peer->smoothing = 0;
12393 peer->pokefreqok = DEFAULT_FREQ_OK;
12394 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12395 peer->maxcallno = 0;
12396 peercnt_modify(0, 0, &peer->addr);
12397 peer->calltoken_required = CALLTOKEN_DEFAULT;
12398 ast_string_field_set(peer,context,"");
12399 ast_string_field_set(peer,peercontext,"");
12400 ast_clear_flag64(peer, IAX_HASCALLERID);
12401 ast_string_field_set(peer, cid_name, "");
12402 ast_string_field_set(peer, cid_num, "");
12403 ast_string_field_set(peer, mohinterpret, mohinterpret);
12404 ast_string_field_set(peer, mohsuggest, mohsuggest);
12405 }
12406
12407 if (!v) {
12408 v = alt;
12409 alt = NULL;
12410 }
12411 while(v) {
12412 if (!strcasecmp(v->name, "secret")) {
12413 ast_string_field_set(peer, secret, v->value);
12414 } else if (!strcasecmp(v->name, "mailbox")) {
12415 ast_string_field_set(peer, mailbox, v->value);
12416 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12417 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12418 ast_string_field_set(peer, mailbox, name);
12419 }
12420 } else if (!strcasecmp(v->name, "mohinterpret")) {
12421 ast_string_field_set(peer, mohinterpret, v->value);
12422 } else if (!strcasecmp(v->name, "mohsuggest")) {
12423 ast_string_field_set(peer, mohsuggest, v->value);
12424 } else if (!strcasecmp(v->name, "dbsecret")) {
12425 ast_string_field_set(peer, dbsecret, v->value);
12426 } else if (!strcasecmp(v->name, "trunk")) {
12427 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12428 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12429 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12430 ast_clear_flag64(peer, IAX_TRUNK);
12431 }
12432 } else if (!strcasecmp(v->name, "auth")) {
12433 peer->authmethods = get_auth_methods(v->value);
12434 } else if (!strcasecmp(v->name, "encryption")) {
12435 peer->encmethods |= get_encrypt_methods(v->value);
12436 if (!peer->encmethods) {
12437 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12438 }
12439 } else if (!strcasecmp(v->name, "forceencryption")) {
12440 if (ast_false(v->value)) {
12441 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12442 } else {
12443 peer->encmethods |= get_encrypt_methods(v->value);
12444 if (peer->encmethods) {
12445 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12446 }
12447 }
12448 } else if (!strcasecmp(v->name, "transfer")) {
12449 if (!strcasecmp(v->value, "mediaonly")) {
12450 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12451 } else if (ast_true(v->value)) {
12452 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12453 } else
12454 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12455 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12456 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12457 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12458 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12459 } else if (!strcasecmp(v->name, "host")) {
12460 if (!strcasecmp(v->value, "dynamic")) {
12461
12462 ast_set_flag64(peer, IAX_DYNAMIC);
12463 if (!found) {
12464
12465
12466 if (ast_sockaddr_port(&peer->addr)) {
12467 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12468 }
12469 ast_sockaddr_setnull(&peer->addr);
12470 }
12471 } else {
12472
12473 ast_sched_thread_del(sched, peer->expire);
12474 ast_clear_flag64(peer, IAX_DYNAMIC);
12475 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12476 return peer_unref(peer);
12477 if (!ast_sockaddr_port(&peer->addr)) {
12478 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12479 }
12480 }
12481 if (!maskfound)
12482 inet_aton("255.255.255.255", &peer->mask);
12483 } else if (!strcasecmp(v->name, "defaultip")) {
12484 struct ast_sockaddr peer_defaddr_tmp;
12485
12486 peer_defaddr_tmp.ss.ss_family = AF_INET;
12487 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12488 return peer_unref(peer);
12489 }
12490 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12491 &peer->defaddr);
12492 } else if (!strcasecmp(v->name, "sourceaddress")) {
12493 peer_set_srcaddr(peer, v->value);
12494 } else if (!strcasecmp(v->name, "permit") ||
12495 !strcasecmp(v->name, "deny")) {
12496 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12497 } else if (!strcasecmp(v->name, "mask")) {
12498 maskfound++;
12499 inet_aton(v->value, &peer->mask);
12500 } else if (!strcasecmp(v->name, "context")) {
12501 ast_string_field_set(peer, context, v->value);
12502 } else if (!strcasecmp(v->name, "regexten")) {
12503 ast_string_field_set(peer, regexten, v->value);
12504 } else if (!strcasecmp(v->name, "peercontext")) {
12505 ast_string_field_set(peer, peercontext, v->value);
12506 } else if (!strcasecmp(v->name, "port")) {
12507 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12508 peer->defaddr.sin_port = htons(atoi(v->value));
12509 } else {
12510 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12511 }
12512 } else if (!strcasecmp(v->name, "username")) {
12513 ast_string_field_set(peer, username, v->value);
12514 } else if (!strcasecmp(v->name, "allow")) {
12515 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12516 } else if (!strcasecmp(v->name, "disallow")) {
12517 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12518 } else if (!strcasecmp(v->name, "callerid")) {
12519 if (!ast_strlen_zero(v->value)) {
12520 char name2[80];
12521 char num2[80];
12522 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12523 ast_string_field_set(peer, cid_name, name2);
12524 ast_string_field_set(peer, cid_num, num2);
12525 } else {
12526 ast_string_field_set(peer, cid_name, "");
12527 ast_string_field_set(peer, cid_num, "");
12528 }
12529 ast_set_flag64(peer, IAX_HASCALLERID);
12530 } else if (!strcasecmp(v->name, "fullname")) {
12531 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12532 ast_set_flag64(peer, IAX_HASCALLERID);
12533 } else if (!strcasecmp(v->name, "cid_number")) {
12534 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12535 ast_set_flag64(peer, IAX_HASCALLERID);
12536 } else if (!strcasecmp(v->name, "sendani")) {
12537 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12538 } else if (!strcasecmp(v->name, "inkeys")) {
12539 ast_string_field_set(peer, inkeys, v->value);
12540 } else if (!strcasecmp(v->name, "outkey")) {
12541 ast_string_field_set(peer, outkey, v->value);
12542 } else if (!strcasecmp(v->name, "qualify")) {
12543 if (!strcasecmp(v->value, "no")) {
12544 peer->maxms = 0;
12545 } else if (!strcasecmp(v->value, "yes")) {
12546 peer->maxms = DEFAULT_MAXMS;
12547 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12548 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);
12549 peer->maxms = 0;
12550 }
12551 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12552 peer->smoothing = ast_true(v->value);
12553 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12554 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12555 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);
12556 }
12557 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12558 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12559 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);
12560 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12561 } else if (!strcasecmp(v->name, "timezone")) {
12562 ast_string_field_set(peer, zonetag, v->value);
12563 } else if (!strcasecmp(v->name, "adsi")) {
12564 peer->adsi = ast_true(v->value);
12565 } else if (!strcasecmp(v->name, "connectedline")) {
12566 if (ast_true(v->value)) {
12567 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12568 } else if (!strcasecmp(v->value, "send")) {
12569 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12570 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12571 } else if (!strcasecmp(v->value, "receive")) {
12572 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12573 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12574 } else {
12575 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12576 }
12577 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12578 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12579 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12580 } else {
12581 peercnt_modify(1, peer->maxcallno, &peer->addr);
12582 }
12583 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12584
12585 if (ast_false(v->value)) {
12586 peer->calltoken_required = CALLTOKEN_NO;
12587 } else if (!strcasecmp(v->value, "auto")) {
12588 peer->calltoken_required = CALLTOKEN_AUTO;
12589 } else if (ast_true(v->value)) {
12590 peer->calltoken_required = CALLTOKEN_YES;
12591 } else {
12592 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12593 }
12594 }
12595
12596 v = v->next;
12597 if (!v) {
12598 v = alt;
12599 alt = NULL;
12600 }
12601 }
12602 if (!peer->authmethods)
12603 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12604 ast_clear_flag64(peer, IAX_DELME);
12605 }
12606
12607 if (oldha)
12608 ast_free_ha(oldha);
12609
12610 if (!ast_strlen_zero(peer->mailbox)) {
12611 char *mailbox, *context;
12612 context = mailbox = ast_strdupa(peer->mailbox);
12613 strsep(&context, "@");
12614 if (ast_strlen_zero(context))
12615 context = "default";
12616 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12617 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12618 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12619 AST_EVENT_IE_END);
12620 }
12621
12622 return peer;
12623 }
12624
12625 static void user_destructor(void *obj)
12626 {
12627 struct iax2_user *user = obj;
12628
12629 ast_free_ha(user->ha);
12630 free_context(user->contexts);
12631 if(user->vars) {
12632 ast_variables_destroy(user->vars);
12633 user->vars = NULL;
12634 }
12635 ast_string_field_free_memory(user);
12636 }
12637
12638
12639 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12640 {
12641 struct iax2_user *user = NULL;
12642 struct iax2_context *con, *conl = NULL;
12643 struct ast_ha *oldha = NULL;
12644 struct iax2_context *oldcon = NULL;
12645 int format;
12646 int firstpass=1;
12647 int oldcurauthreq = 0;
12648 char *varname = NULL, *varval = NULL;
12649 struct ast_variable *tmpvar = NULL;
12650 struct iax2_user tmp_user = {
12651 .name = name,
12652 };
12653
12654 if (!temponly) {
12655 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12656 if (user && !ast_test_flag64(user, IAX_DELME))
12657 firstpass = 0;
12658 }
12659
12660 if (user) {
12661 if (firstpass) {
12662 oldcurauthreq = user->curauthreq;
12663 oldha = user->ha;
12664 oldcon = user->contexts;
12665 user->ha = NULL;
12666 user->contexts = NULL;
12667 }
12668
12669 ao2_unlink(users, user);
12670 } else {
12671 user = ao2_alloc(sizeof(*user), user_destructor);
12672 }
12673
12674 if (user) {
12675 if (firstpass) {
12676 ast_string_field_free_memory(user);
12677 memset(user, 0, sizeof(struct iax2_user));
12678 if (ast_string_field_init(user, 32)) {
12679 user = user_unref(user);
12680 goto cleanup;
12681 }
12682 user->maxauthreq = maxauthreq;
12683 user->curauthreq = oldcurauthreq;
12684 user->prefs = prefs;
12685 user->capability = iax2_capability;
12686 user->encmethods = iax2_encryption;
12687 user->adsi = adsi;
12688 user->calltoken_required = CALLTOKEN_DEFAULT;
12689 ast_string_field_set(user, name, name);
12690 ast_string_field_set(user, language, language);
12691 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);
12692 ast_clear_flag64(user, IAX_HASCALLERID);
12693 ast_string_field_set(user, cid_name, "");
12694 ast_string_field_set(user, cid_num, "");
12695 ast_string_field_set(user, accountcode, accountcode);
12696 ast_string_field_set(user, mohinterpret, mohinterpret);
12697 ast_string_field_set(user, mohsuggest, mohsuggest);
12698 }
12699 if (!v) {
12700 v = alt;
12701 alt = NULL;
12702 }
12703 while(v) {
12704 if (!strcasecmp(v->name, "context")) {
12705 con = build_context(v->value);
12706 if (con) {
12707 if (conl)
12708 conl->next = con;
12709 else
12710 user->contexts = con;
12711 conl = con;
12712 }
12713 } else if (!strcasecmp(v->name, "permit") ||
12714 !strcasecmp(v->name, "deny")) {
12715 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12716 } else if (!strcasecmp(v->name, "setvar")) {
12717 varname = ast_strdupa(v->value);
12718 if (varname && (varval = strchr(varname,'='))) {
12719 *varval = '\0';
12720 varval++;
12721 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12722 tmpvar->next = user->vars;
12723 user->vars = tmpvar;
12724 }
12725 }
12726 } else if (!strcasecmp(v->name, "allow")) {
12727 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12728 } else if (!strcasecmp(v->name, "disallow")) {
12729 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12730 } else if (!strcasecmp(v->name, "trunk")) {
12731 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
12732 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12733 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12734 ast_clear_flag64(user, IAX_TRUNK);
12735 }
12736 } else if (!strcasecmp(v->name, "auth")) {
12737 user->authmethods = get_auth_methods(v->value);
12738 } else if (!strcasecmp(v->name, "encryption")) {
12739 user->encmethods |= get_encrypt_methods(v->value);
12740 if (!user->encmethods) {
12741 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12742 }
12743 } else if (!strcasecmp(v->name, "forceencryption")) {
12744 if (ast_false(v->value)) {
12745 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12746 } else {
12747 user->encmethods |= get_encrypt_methods(v->value);
12748 if (user->encmethods) {
12749 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12750 }
12751 }
12752 } else if (!strcasecmp(v->name, "transfer")) {
12753 if (!strcasecmp(v->value, "mediaonly")) {
12754 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12755 } else if (ast_true(v->value)) {
12756 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12757 } else
12758 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12759 } else if (!strcasecmp(v->name, "codecpriority")) {
12760 if(!strcasecmp(v->value, "caller"))
12761 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12762 else if(!strcasecmp(v->value, "disabled"))
12763 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12764 else if(!strcasecmp(v->value, "reqonly")) {
12765 ast_set_flag64(user, IAX_CODEC_NOCAP);
12766 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12767 }
12768 } else if (!strcasecmp(v->name, "immediate")) {
12769 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12770 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12771 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12772 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12773 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12774 } else if (!strcasecmp(v->name, "dbsecret")) {
12775 ast_string_field_set(user, dbsecret, v->value);
12776 } else if (!strcasecmp(v->name, "secret")) {
12777 if (!ast_strlen_zero(user->secret)) {
12778 char *old = ast_strdupa(user->secret);
12779
12780 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12781 } else
12782 ast_string_field_set(user, secret, v->value);
12783 } else if (!strcasecmp(v->name, "callerid")) {
12784 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12785 char name2[80];
12786 char num2[80];
12787 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12788 ast_string_field_set(user, cid_name, name2);
12789 ast_string_field_set(user, cid_num, num2);
12790 ast_set_flag64(user, IAX_HASCALLERID);
12791 } else {
12792 ast_clear_flag64(user, IAX_HASCALLERID);
12793 ast_string_field_set(user, cid_name, "");
12794 ast_string_field_set(user, cid_num, "");
12795 }
12796 } else if (!strcasecmp(v->name, "fullname")) {
12797 if (!ast_strlen_zero(v->value)) {
12798 ast_string_field_set(user, cid_name, v->value);
12799 ast_set_flag64(user, IAX_HASCALLERID);
12800 } else {
12801 ast_string_field_set(user, cid_name, "");
12802 if (ast_strlen_zero(user->cid_num))
12803 ast_clear_flag64(user, IAX_HASCALLERID);
12804 }
12805 } else if (!strcasecmp(v->name, "cid_number")) {
12806 if (!ast_strlen_zero(v->value)) {
12807 ast_string_field_set(user, cid_num, v->value);
12808 ast_set_flag64(user, IAX_HASCALLERID);
12809 } else {
12810 ast_string_field_set(user, cid_num, "");
12811 if (ast_strlen_zero(user->cid_name))
12812 ast_clear_flag64(user, IAX_HASCALLERID);
12813 }
12814 } else if (!strcasecmp(v->name, "accountcode")) {
12815 ast_string_field_set(user, accountcode, v->value);
12816 } else if (!strcasecmp(v->name, "mohinterpret")) {
12817 ast_string_field_set(user, mohinterpret, v->value);
12818 } else if (!strcasecmp(v->name, "mohsuggest")) {
12819 ast_string_field_set(user, mohsuggest, v->value);
12820 } else if (!strcasecmp(v->name, "parkinglot")) {
12821 ast_string_field_set(user, parkinglot, v->value);
12822 } else if (!strcasecmp(v->name, "language")) {
12823 ast_string_field_set(user, language, v->value);
12824 } else if (!strcasecmp(v->name, "amaflags")) {
12825 format = ast_cdr_amaflags2int(v->value);
12826 if (format < 0) {
12827 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12828 } else {
12829 user->amaflags = format;
12830 }
12831 } else if (!strcasecmp(v->name, "inkeys")) {
12832 ast_string_field_set(user, inkeys, v->value);
12833 } else if (!strcasecmp(v->name, "maxauthreq")) {
12834 user->maxauthreq = atoi(v->value);
12835 if (user->maxauthreq < 0)
12836 user->maxauthreq = 0;
12837 } else if (!strcasecmp(v->name, "adsi")) {
12838 user->adsi = ast_true(v->value);
12839 } else if (!strcasecmp(v->name, "connectedline")) {
12840 if (ast_true(v->value)) {
12841 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12842 } else if (!strcasecmp(v->value, "send")) {
12843 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12844 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12845 } else if (!strcasecmp(v->value, "receive")) {
12846 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12847 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12848 } else {
12849 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12850 }
12851 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12852
12853 if (ast_false(v->value)) {
12854 user->calltoken_required = CALLTOKEN_NO;
12855 } else if (!strcasecmp(v->value, "auto")) {
12856 user->calltoken_required = CALLTOKEN_AUTO;
12857 } else if (ast_true(v->value)) {
12858 user->calltoken_required = CALLTOKEN_YES;
12859 } else {
12860 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12861 }
12862 }
12863
12864 v = v->next;
12865 if (!v) {
12866 v = alt;
12867 alt = NULL;
12868 }
12869 }
12870 if (!user->authmethods) {
12871 if (!ast_strlen_zero(user->secret)) {
12872 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12873 if (!ast_strlen_zero(user->inkeys))
12874 user->authmethods |= IAX_AUTH_RSA;
12875 } else if (!ast_strlen_zero(user->inkeys)) {
12876 user->authmethods = IAX_AUTH_RSA;
12877 } else {
12878 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12879 }
12880 }
12881 ast_clear_flag64(user, IAX_DELME);
12882 }
12883 cleanup:
12884 if (oldha)
12885 ast_free_ha(oldha);
12886 if (oldcon)
12887 free_context(oldcon);
12888 return user;
12889 }
12890
12891 static int peer_delme_cb(void *obj, void *arg, int flags)
12892 {
12893 struct iax2_peer *peer = obj;
12894
12895 ast_set_flag64(peer, IAX_DELME);
12896
12897 return 0;
12898 }
12899
12900 static int user_delme_cb(void *obj, void *arg, int flags)
12901 {
12902 struct iax2_user *user = obj;
12903
12904 ast_set_flag64(user, IAX_DELME);
12905
12906 return 0;
12907 }
12908
12909 static void delete_users(void)
12910 {
12911 struct iax2_registry *reg;
12912
12913 ao2_callback(users, 0, user_delme_cb, NULL);
12914
12915 AST_LIST_LOCK(®istrations);
12916 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12917 if (sched) {
12918 ast_sched_thread_del(sched, reg->expire);
12919 }
12920 if (reg->callno) {
12921 int callno = reg->callno;
12922 ast_mutex_lock(&iaxsl[callno]);
12923 if (iaxs[callno]) {
12924 iaxs[callno]->reg = NULL;
12925 iax2_destroy(callno);
12926 }
12927 ast_mutex_unlock(&iaxsl[callno]);
12928 }
12929 if (reg->dnsmgr)
12930 ast_dnsmgr_release(reg->dnsmgr);
12931 ast_free(reg);
12932 }
12933 AST_LIST_UNLOCK(®istrations);
12934
12935 ao2_callback(peers, 0, peer_delme_cb, NULL);
12936 }
12937
12938 static void prune_users(void)
12939 {
12940 struct iax2_user *user;
12941 struct ao2_iterator i;
12942
12943 i = ao2_iterator_init(users, 0);
12944 while ((user = ao2_iterator_next(&i))) {
12945 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
12946 ao2_unlink(users, user);
12947 }
12948 user_unref(user);
12949 }
12950 ao2_iterator_destroy(&i);
12951 }
12952
12953
12954 static void prune_peers(void)
12955 {
12956 struct iax2_peer *peer;
12957 struct ao2_iterator i;
12958
12959 i = ao2_iterator_init(peers, 0);
12960 while ((peer = ao2_iterator_next(&i))) {
12961 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
12962 unlink_peer(peer);
12963 }
12964 peer_unref(peer);
12965 }
12966 ao2_iterator_destroy(&i);
12967 }
12968
12969 static void set_config_destroy(void)
12970 {
12971 strcpy(accountcode, "");
12972 strcpy(language, "");
12973 strcpy(mohinterpret, "default");
12974 strcpy(mohsuggest, "");
12975 trunkmaxsize = MAX_TRUNKDATA;
12976 amaflags = 0;
12977 delayreject = 0;
12978 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
12979 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12980 delete_users();
12981 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12982 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12983 }
12984
12985
12986 static int set_config(const char *config_file, int reload)
12987 {
12988 struct ast_config *cfg, *ucfg;
12989 format_t capability = iax2_capability;
12990 struct ast_variable *v;
12991 char *cat;
12992 const char *utype;
12993 const char *tosval;
12994 int format;
12995 int portno = IAX_DEFAULT_PORTNO;
12996 int x;
12997 int mtuv;
12998 int subscribe_network_change = 1;
12999 struct iax2_user *user;
13000 struct iax2_peer *peer;
13001 struct ast_netsock *ns;
13002 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
13003 #if 0
13004 static unsigned short int last_port=0;
13005 #endif
13006
13007 cfg = ast_config_load(config_file, config_flags);
13008
13009 if (!cfg) {
13010 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
13011 return -1;
13012 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
13013 ucfg = ast_config_load("users.conf", config_flags);
13014 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
13015 return 0;
13016
13017 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13018 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
13019 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13020 ast_config_destroy(ucfg);
13021 return 0;
13022 }
13023 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
13024 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
13025 return 0;
13026 } else {
13027 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
13028 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
13029 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
13030 ast_config_destroy(cfg);
13031 return 0;
13032 }
13033 }
13034
13035 if (reload) {
13036 set_config_destroy();
13037 }
13038
13039
13040 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
13041
13042
13043 memset(&globalflags, 0, sizeof(globalflags));
13044 ast_set_flag64(&globalflags, IAX_RTUPDATE);
13045 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13046
13047 #ifdef SO_NO_CHECK
13048 nochecksums = 0;
13049 #endif
13050
13051 default_parkinglot[0] = '\0';
13052
13053 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13054 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
13055 global_max_trunk_mtu = MAX_TRUNK_MTU;
13056 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
13057 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
13058
13059 maxauthreq = 3;
13060
13061 srvlookup = 0;
13062
13063 v = ast_variable_browse(cfg, "general");
13064
13065
13066 tosval = ast_variable_retrieve(cfg, "general", "tos");
13067 if (tosval) {
13068 if (ast_str2tos(tosval, &qos.tos))
13069 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13070 }
13071
13072 tosval = ast_variable_retrieve(cfg, "general", "cos");
13073 if (tosval) {
13074 if (ast_str2cos(tosval, &qos.cos))
13075 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13076 }
13077 while(v) {
13078 if (!strcasecmp(v->name, "bindport")){
13079 if (reload)
13080 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13081 else
13082 portno = atoi(v->value);
13083 } else if (!strcasecmp(v->name, "pingtime"))
13084 ping_time = atoi(v->value);
13085 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13086 if (reload) {
13087 if (atoi(v->value) != iaxthreadcount)
13088 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13089 } else {
13090 iaxthreadcount = atoi(v->value);
13091 if (iaxthreadcount < 1) {
13092 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13093 iaxthreadcount = 1;
13094 } else if (iaxthreadcount > 256) {
13095 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13096 iaxthreadcount = 256;
13097 }
13098 }
13099 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13100 if (reload) {
13101 AST_LIST_LOCK(&dynamic_list);
13102 iaxmaxthreadcount = atoi(v->value);
13103 AST_LIST_UNLOCK(&dynamic_list);
13104 } else {
13105 iaxmaxthreadcount = atoi(v->value);
13106 if (iaxmaxthreadcount < 0) {
13107 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13108 iaxmaxthreadcount = 0;
13109 } else if (iaxmaxthreadcount > 256) {
13110 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13111 iaxmaxthreadcount = 256;
13112 }
13113 }
13114 } else if (!strcasecmp(v->name, "nochecksums")) {
13115 #ifdef SO_NO_CHECK
13116 if (ast_true(v->value))
13117 nochecksums = 1;
13118 else
13119 nochecksums = 0;
13120 #else
13121 if (ast_true(v->value))
13122 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13123 #endif
13124 }
13125 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13126 maxjitterbuffer = atoi(v->value);
13127 else if (!strcasecmp(v->name, "resyncthreshold"))
13128 resyncthreshold = atoi(v->value);
13129 else if (!strcasecmp(v->name, "maxjitterinterps"))
13130 maxjitterinterps = atoi(v->value);
13131 else if (!strcasecmp(v->name, "jittertargetextra"))
13132 jittertargetextra = atoi(v->value);
13133 else if (!strcasecmp(v->name, "lagrqtime"))
13134 lagrq_time = atoi(v->value);
13135 else if (!strcasecmp(v->name, "maxregexpire"))
13136 max_reg_expire = atoi(v->value);
13137 else if (!strcasecmp(v->name, "minregexpire"))
13138 min_reg_expire = atoi(v->value);
13139 else if (!strcasecmp(v->name, "bindaddr")) {
13140 if (reload) {
13141 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13142 } else {
13143 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13144 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13145 } else {
13146 if (strchr(v->value, ':'))
13147 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13148 else
13149 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13150 if (defaultsockfd < 0)
13151 defaultsockfd = ast_netsock_sockfd(ns);
13152 ast_netsock_unref(ns);
13153 }
13154 }
13155 } else if (!strcasecmp(v->name, "authdebug")) {
13156 authdebug = ast_true(v->value);
13157 } else if (!strcasecmp(v->name, "encryption")) {
13158 iax2_encryption |= get_encrypt_methods(v->value);
13159 if (!iax2_encryption) {
13160 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13161 }
13162 } else if (!strcasecmp(v->name, "forceencryption")) {
13163 if (ast_false(v->value)) {
13164 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13165 } else {
13166 iax2_encryption |= get_encrypt_methods(v->value);
13167 if (iax2_encryption) {
13168 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13169 }
13170 }
13171 } else if (!strcasecmp(v->name, "transfer")) {
13172 if (!strcasecmp(v->value, "mediaonly")) {
13173 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13174 } else if (ast_true(v->value)) {
13175 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13176 } else
13177 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13178 } else if (!strcasecmp(v->name, "codecpriority")) {
13179 if(!strcasecmp(v->value, "caller"))
13180 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13181 else if(!strcasecmp(v->value, "disabled"))
13182 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13183 else if(!strcasecmp(v->value, "reqonly")) {
13184 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13185 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13186 }
13187 } else if (!strcasecmp(v->name, "jitterbuffer"))
13188 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13189 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13190 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13191 else if (!strcasecmp(v->name, "delayreject"))
13192 delayreject = ast_true(v->value);
13193 else if (!strcasecmp(v->name, "allowfwdownload"))
13194 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13195 else if (!strcasecmp(v->name, "rtcachefriends"))
13196 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13197 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13198 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13199 else if (!strcasecmp(v->name, "rtupdate"))
13200 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13201 else if (!strcasecmp(v->name, "rtsavesysname"))
13202 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13203 else if (!strcasecmp(v->name, "trunktimestamps"))
13204 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13205 else if (!strcasecmp(v->name, "rtautoclear")) {
13206 int i = atoi(v->value);
13207 if(i > 0)
13208 global_rtautoclear = i;
13209 else
13210 i = 0;
13211 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13212 } else if (!strcasecmp(v->name, "trunkfreq")) {
13213 trunkfreq = atoi(v->value);
13214 if (trunkfreq < 10)
13215 trunkfreq = 10;
13216 } else if (!strcasecmp(v->name, "trunkmtu")) {
13217 mtuv = atoi(v->value);
13218 if (mtuv == 0 )
13219 global_max_trunk_mtu = 0;
13220 else if (mtuv >= 172 && mtuv < 4000)
13221 global_max_trunk_mtu = mtuv;
13222 else
13223 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13224 mtuv, v->lineno);
13225 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13226 trunkmaxsize = atoi(v->value);
13227 if (trunkmaxsize == 0)
13228 trunkmaxsize = MAX_TRUNKDATA;
13229 } else if (!strcasecmp(v->name, "autokill")) {
13230 if (sscanf(v->value, "%30d", &x) == 1) {
13231 if (x >= 0)
13232 autokill = x;
13233 else
13234 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13235 } else if (ast_true(v->value)) {
13236 autokill = DEFAULT_MAXMS;
13237 } else {
13238 autokill = 0;
13239 }
13240 } else if (!strcasecmp(v->name, "bandwidth")) {
13241 if (!strcasecmp(v->value, "low")) {
13242 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13243 } else if (!strcasecmp(v->value, "medium")) {
13244 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13245 } else if (!strcasecmp(v->value, "high")) {
13246 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13247 } else
13248 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13249 } else if (!strcasecmp(v->name, "allow")) {
13250 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13251 } else if (!strcasecmp(v->name, "disallow")) {
13252 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13253 } else if (!strcasecmp(v->name, "register")) {
13254 iax2_register(v->value, v->lineno);
13255 } else if (!strcasecmp(v->name, "iaxcompat")) {
13256 iaxcompat = ast_true(v->value);
13257 } else if (!strcasecmp(v->name, "regcontext")) {
13258 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13259
13260 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13261 } else if (!strcasecmp(v->name, "tos")) {
13262 if (ast_str2tos(v->value, &qos.tos))
13263 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13264 } else if (!strcasecmp(v->name, "cos")) {
13265 if (ast_str2cos(v->value, &qos.cos))
13266 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13267 } else if (!strcasecmp(v->name, "parkinglot")) {
13268 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13269 } else if (!strcasecmp(v->name, "accountcode")) {
13270 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13271 } else if (!strcasecmp(v->name, "mohinterpret")) {
13272 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13273 } else if (!strcasecmp(v->name, "mohsuggest")) {
13274 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13275 } else if (!strcasecmp(v->name, "amaflags")) {
13276 format = ast_cdr_amaflags2int(v->value);
13277 if (format < 0) {
13278 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13279 } else {
13280 amaflags = format;
13281 }
13282 } else if (!strcasecmp(v->name, "language")) {
13283 ast_copy_string(language, v->value, sizeof(language));
13284 } else if (!strcasecmp(v->name, "maxauthreq")) {
13285 maxauthreq = atoi(v->value);
13286 if (maxauthreq < 0)
13287 maxauthreq = 0;
13288 } else if (!strcasecmp(v->name, "adsi")) {
13289 adsi = ast_true(v->value);
13290 } else if (!strcasecmp(v->name, "srvlookup")) {
13291 srvlookup = ast_true(v->value);
13292 } else if (!strcasecmp(v->name, "connectedline")) {
13293 if (ast_true(v->value)) {
13294 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13295 } else if (!strcasecmp(v->value, "send")) {
13296 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13297 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13298 } else if (!strcasecmp(v->value, "receive")) {
13299 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13300 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13301 } else {
13302 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13303 }
13304 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13305 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13306 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13307 }
13308 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13309 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13310 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);
13311 }
13312 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13313 if (add_calltoken_ignore(v->value)) {
13314 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13315 }
13316 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13317 if (ast_true(v->value)) {
13318 subscribe_network_change = 1;
13319 } else if (ast_false(v->value)) {
13320 subscribe_network_change = 0;
13321 } else {
13322 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13323 }
13324 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13325 if (ast_true(v->value)) {
13326 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13327 } else if (ast_false(v->value)) {
13328 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13329 } else {
13330 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13331 }
13332 }
13333
13334 v = v->next;
13335 }
13336
13337 if (subscribe_network_change) {
13338 network_change_event_subscribe();
13339 } else {
13340 network_change_event_unsubscribe();
13341 }
13342
13343 if (defaultsockfd < 0) {
13344 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13345 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13346 } else {
13347 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13348 defaultsockfd = ast_netsock_sockfd(ns);
13349 ast_netsock_unref(ns);
13350 }
13351 }
13352 if (reload) {
13353 ast_netsock_release(outsock);
13354 outsock = ast_netsock_list_alloc();
13355 if (!outsock) {
13356 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13357 return -1;
13358 }
13359 ast_netsock_init(outsock);
13360 }
13361
13362 if (min_reg_expire > max_reg_expire) {
13363 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13364 min_reg_expire, max_reg_expire, max_reg_expire);
13365 min_reg_expire = max_reg_expire;
13366 }
13367 iax2_capability = capability;
13368
13369 if (ucfg) {
13370 struct ast_variable *gen;
13371 int genhasiax;
13372 int genregisteriax;
13373 const char *hasiax, *registeriax;
13374
13375 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13376 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13377 gen = ast_variable_browse(ucfg, "general");
13378 cat = ast_category_browse(ucfg, NULL);
13379 while (cat) {
13380 if (strcasecmp(cat, "general")) {
13381 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13382 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13383 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13384
13385 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13386 if (user) {
13387 ao2_link(users, user);
13388 user = user_unref(user);
13389 }
13390 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13391 if (peer) {
13392 if (ast_test_flag64(peer, IAX_DYNAMIC))
13393 reg_source_db(peer);
13394 ao2_link(peers, peer);
13395 peer = peer_unref(peer);
13396 }
13397 }
13398 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13399 char tmp[256];
13400 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13401 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13402 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13403 if (!host)
13404 host = ast_variable_retrieve(ucfg, "general", "host");
13405 if (!username)
13406 username = ast_variable_retrieve(ucfg, "general", "username");
13407 if (!secret)
13408 secret = ast_variable_retrieve(ucfg, "general", "secret");
13409 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13410 if (!ast_strlen_zero(secret))
13411 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13412 else
13413 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13414 iax2_register(tmp, 0);
13415 }
13416 }
13417 }
13418 cat = ast_category_browse(ucfg, cat);
13419 }
13420 ast_config_destroy(ucfg);
13421 }
13422
13423 cat = ast_category_browse(cfg, NULL);
13424 while(cat) {
13425 if (strcasecmp(cat, "general")) {
13426 utype = ast_variable_retrieve(cfg, cat, "type");
13427 if (!strcasecmp(cat, "callnumberlimits")) {
13428 build_callno_limits(ast_variable_browse(cfg, cat));
13429 } else if (utype) {
13430 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13431 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13432 if (user) {
13433 ao2_link(users, user);
13434 user = user_unref(user);
13435 }
13436 }
13437 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13438 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13439 if (peer) {
13440 if (ast_test_flag64(peer, IAX_DYNAMIC))
13441 reg_source_db(peer);
13442 ao2_link(peers, peer);
13443 peer = peer_unref(peer);
13444 }
13445 } else if (strcasecmp(utype, "user")) {
13446 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13447 }
13448 } else
13449 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13450 }
13451 cat = ast_category_browse(cfg, cat);
13452 }
13453 ast_config_destroy(cfg);
13454 return 1;
13455 }
13456
13457 static void poke_all_peers(void)
13458 {
13459 struct ao2_iterator i;
13460 struct iax2_peer *peer;
13461
13462 i = ao2_iterator_init(peers, 0);
13463 while ((peer = ao2_iterator_next(&i))) {
13464 iax2_poke_peer(peer, 0);
13465 peer_unref(peer);
13466 }
13467 ao2_iterator_destroy(&i);
13468 }
13469 static int reload_config(void)
13470 {
13471 static const char config[] = "iax.conf";
13472 struct iax2_registry *reg;
13473
13474 if (set_config(config, 1) > 0) {
13475 prune_peers();
13476 prune_users();
13477 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13478 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13479 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13480 trunk_timed = trunk_untimed = 0;
13481 trunk_nmaxmtu = trunk_maxmtu = 0;
13482 memset(&debugaddr, '\0', sizeof(debugaddr));
13483
13484 AST_LIST_LOCK(®istrations);
13485 AST_LIST_TRAVERSE(®istrations, reg, entry)
13486 iax2_do_register(reg);
13487 AST_LIST_UNLOCK(®istrations);
13488
13489
13490 poke_all_peers();
13491 }
13492
13493 reload_firmware(0);
13494 iax_provision_reload(1);
13495 ast_unload_realtime("iaxpeers");
13496
13497 return 0;
13498 }
13499
13500 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13501 {
13502 switch (cmd) {
13503 case CLI_INIT:
13504 e->command = "iax2 reload";
13505 e->usage =
13506 "Usage: iax2 reload\n"
13507 " Reloads IAX configuration from iax.conf\n";
13508 return NULL;
13509 case CLI_GENERATE:
13510 return NULL;
13511 }
13512
13513 reload_config();
13514
13515 return CLI_SUCCESS;
13516 }
13517
13518 static int reload(void)
13519 {
13520 return reload_config();
13521 }
13522
13523 static int cache_get_callno_locked(const char *data)
13524 {
13525 struct sockaddr_in sin;
13526 int x;
13527 int callno;
13528 struct iax_ie_data ied;
13529 struct create_addr_info cai;
13530 struct parsed_dial_string pds;
13531 char *tmpstr;
13532
13533 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13534
13535
13536 if (!ast_mutex_trylock(&iaxsl[x])) {
13537 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13538 return x;
13539 ast_mutex_unlock(&iaxsl[x]);
13540 }
13541 }
13542
13543
13544
13545 memset(&cai, 0, sizeof(cai));
13546 memset(&ied, 0, sizeof(ied));
13547 memset(&pds, 0, sizeof(pds));
13548
13549 tmpstr = ast_strdupa(data);
13550 parse_dial_string(tmpstr, &pds);
13551
13552 if (ast_strlen_zero(pds.peer)) {
13553 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13554 return -1;
13555 }
13556
13557
13558 if (create_addr(pds.peer, NULL, &sin, &cai))
13559 return -1;
13560
13561 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13562 pds.peer, pds.username, pds.password, pds.context);
13563
13564 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13565 if (callno < 1) {
13566 ast_log(LOG_WARNING, "Unable to create call\n");
13567 return -1;
13568 }
13569
13570 ast_string_field_set(iaxs[callno], dproot, data);
13571 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13572
13573 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13574 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13575
13576
13577
13578 if (pds.exten)
13579 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13580 if (pds.username)
13581 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13582 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13583 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13584
13585 if (pds.password)
13586 ast_string_field_set(iaxs[callno], secret, pds.password);
13587 if (pds.key)
13588 ast_string_field_set(iaxs[callno], outkey, pds.key);
13589
13590 add_empty_calltoken_ie(iaxs[callno], &ied);
13591 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13592
13593 return callno;
13594 }
13595
13596 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13597 {
13598 struct iax2_dpcache *dp = NULL;
13599 struct timeval now = ast_tvnow();
13600 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13601 struct ast_channel *c = NULL;
13602 struct ast_frame *f = NULL;
13603
13604 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13605 if (ast_tvcmp(now, dp->expiry) > 0) {
13606 AST_LIST_REMOVE_CURRENT(cache_list);
13607 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13608 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13609 else
13610 ast_free(dp);
13611 continue;
13612 }
13613 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13614 break;
13615 }
13616 AST_LIST_TRAVERSE_SAFE_END;
13617
13618 if (!dp) {
13619
13620
13621 if ((callno = cache_get_callno_locked(data)) < 0) {
13622 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13623 return NULL;
13624 }
13625 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13626 ast_mutex_unlock(&iaxsl[callno]);
13627 return NULL;
13628 }
13629 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13630 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13631 dp->expiry = ast_tvnow();
13632 dp->orig = dp->expiry;
13633
13634 dp->expiry.tv_sec += iaxdefaultdpcache;
13635 dp->flags = CACHE_FLAG_PENDING;
13636 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13637 dp->waiters[x] = -1;
13638
13639 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13640 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13641
13642 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13643 iax2_dprequest(dp, callno);
13644 ast_mutex_unlock(&iaxsl[callno]);
13645 }
13646
13647
13648 if (dp->flags & CACHE_FLAG_PENDING) {
13649
13650
13651 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13652
13653 if (dp->waiters[x] < 0)
13654 break;
13655 }
13656 if (x >= ARRAY_LEN(dp->waiters)) {
13657 ast_log(LOG_WARNING, "No more waiter positions available\n");
13658 return NULL;
13659 }
13660 if (pipe(com)) {
13661 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13662 return NULL;
13663 }
13664 dp->waiters[x] = com[1];
13665
13666 timeout = iaxdefaulttimeout * 1000;
13667
13668 AST_LIST_UNLOCK(&dpcache);
13669
13670 if (chan)
13671 old = ast_channel_defer_dtmf(chan);
13672 doabort = 0;
13673 while(timeout) {
13674 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13675 if (outfd > -1)
13676 break;
13677 if (!c)
13678 continue;
13679 if (!(f = ast_read(c))) {
13680 doabort = 1;
13681 break;
13682 }
13683 ast_frfree(f);
13684 }
13685 if (!timeout) {
13686 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13687 }
13688 AST_LIST_LOCK(&dpcache);
13689 dp->waiters[x] = -1;
13690 close(com[1]);
13691 close(com[0]);
13692 if (doabort) {
13693
13694
13695 if (!old && chan)
13696 ast_channel_undefer_dtmf(chan);
13697 return NULL;
13698 }
13699 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13700
13701 if (dp->flags & CACHE_FLAG_PENDING) {
13702
13703
13704 dp->flags &= ~CACHE_FLAG_PENDING;
13705 dp->flags |= CACHE_FLAG_TIMEOUT;
13706
13707
13708 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13709 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13710 if (dp->waiters[x] > -1) {
13711 if (write(dp->waiters[x], "asdf", 4) < 0) {
13712 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13713 }
13714 }
13715 }
13716 }
13717 }
13718
13719 if (!old && chan)
13720 ast_channel_undefer_dtmf(chan);
13721 }
13722 return dp;
13723 }
13724
13725
13726 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13727 {
13728 int res = 0;
13729 struct iax2_dpcache *dp = NULL;
13730 #if 0
13731 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13732 #endif
13733 if ((priority != 1) && (priority != 2))
13734 return 0;
13735
13736 AST_LIST_LOCK(&dpcache);
13737 if ((dp = find_cache(chan, data, context, exten, priority))) {
13738 if (dp->flags & CACHE_FLAG_EXISTS)
13739 res = 1;
13740 } else {
13741 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13742 }
13743 AST_LIST_UNLOCK(&dpcache);
13744
13745 return res;
13746 }
13747
13748
13749 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13750 {
13751 int res = 0;
13752 struct iax2_dpcache *dp = NULL;
13753 #if 0
13754 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13755 #endif
13756 if ((priority != 1) && (priority != 2))
13757 return 0;
13758
13759 AST_LIST_LOCK(&dpcache);
13760 if ((dp = find_cache(chan, data, context, exten, priority))) {
13761 if (dp->flags & CACHE_FLAG_CANEXIST)
13762 res = 1;
13763 } else {
13764 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13765 }
13766 AST_LIST_UNLOCK(&dpcache);
13767
13768 return res;
13769 }
13770
13771
13772 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13773 {
13774 int res = 0;
13775 struct iax2_dpcache *dp = NULL;
13776 #if 0
13777 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13778 #endif
13779 if ((priority != 1) && (priority != 2))
13780 return 0;
13781
13782 AST_LIST_LOCK(&dpcache);
13783 if ((dp = find_cache(chan, data, context, exten, priority))) {
13784 if (dp->flags & CACHE_FLAG_MATCHMORE)
13785 res = 1;
13786 } else {
13787 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13788 }
13789 AST_LIST_UNLOCK(&dpcache);
13790
13791 return res;
13792 }
13793
13794
13795 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13796 {
13797 char odata[256];
13798 char req[256];
13799 char *ncontext;
13800 struct iax2_dpcache *dp = NULL;
13801 struct ast_app *dial = NULL;
13802 #if 0
13803 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);
13804 #endif
13805 if (priority == 2) {
13806
13807 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13808 if (dialstatus) {
13809 dial = pbx_findapp(dialstatus);
13810 if (dial)
13811 pbx_exec(chan, dial, "");
13812 }
13813 return -1;
13814 } else if (priority != 1)
13815 return -1;
13816
13817 AST_LIST_LOCK(&dpcache);
13818 if ((dp = find_cache(chan, data, context, exten, priority))) {
13819 if (dp->flags & CACHE_FLAG_EXISTS) {
13820 ast_copy_string(odata, data, sizeof(odata));
13821 ncontext = strchr(odata, '/');
13822 if (ncontext) {
13823 *ncontext = '\0';
13824 ncontext++;
13825 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13826 } else {
13827 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13828 }
13829 ast_verb(3, "Executing Dial('%s')\n", req);
13830 } else {
13831 AST_LIST_UNLOCK(&dpcache);
13832 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13833 return -1;
13834 }
13835 }
13836 AST_LIST_UNLOCK(&dpcache);
13837
13838 if ((dial = pbx_findapp("Dial")))
13839 return pbx_exec(chan, dial, req);
13840 else
13841 ast_log(LOG_WARNING, "No dial application registered\n");
13842
13843 return -1;
13844 }
13845
13846 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13847 {
13848 struct iax2_peer *peer;
13849 char *peername, *colname;
13850
13851 peername = ast_strdupa(data);
13852
13853
13854 if (!strcmp(peername,"CURRENTCHANNEL")) {
13855 unsigned short callno;
13856 if (chan->tech != &iax2_tech)
13857 return -1;
13858 callno = PTR_TO_CALLNO(chan->tech_pvt);
13859 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13860 return 0;
13861 }
13862
13863 if ((colname = strchr(peername, ',')))
13864 *colname++ = '\0';
13865 else
13866 colname = "ip";
13867
13868 if (!(peer = find_peer(peername, 1)))
13869 return -1;
13870
13871 if (!strcasecmp(colname, "ip")) {
13872 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13873 } else if (!strcasecmp(colname, "status")) {
13874 peer_status(peer, buf, len);
13875 } else if (!strcasecmp(colname, "mailbox")) {
13876 ast_copy_string(buf, peer->mailbox, len);
13877 } else if (!strcasecmp(colname, "context")) {
13878 ast_copy_string(buf, peer->context, len);
13879 } else if (!strcasecmp(colname, "expire")) {
13880 snprintf(buf, len, "%d", peer->expire);
13881 } else if (!strcasecmp(colname, "dynamic")) {
13882 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13883 } else if (!strcasecmp(colname, "callerid_name")) {
13884 ast_copy_string(buf, peer->cid_name, len);
13885 } else if (!strcasecmp(colname, "callerid_num")) {
13886 ast_copy_string(buf, peer->cid_num, len);
13887 } else if (!strcasecmp(colname, "codecs")) {
13888 ast_getformatname_multiple(buf, len -1, peer->capability);
13889 } else if (!strncasecmp(colname, "codec[", 6)) {
13890 char *codecnum, *ptr;
13891 int codec = 0;
13892
13893 codecnum = strchr(colname, '[');
13894 *codecnum = '\0';
13895 codecnum++;
13896 if ((ptr = strchr(codecnum, ']'))) {
13897 *ptr = '\0';
13898 }
13899 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13900 ast_copy_string(buf, ast_getformatname(codec), len);
13901 } else {
13902 buf[0] = '\0';
13903 }
13904 } else {
13905 buf[0] = '\0';
13906 }
13907
13908 peer_unref(peer);
13909
13910 return 0;
13911 }
13912
13913 static struct ast_custom_function iaxpeer_function = {
13914 .name = "IAXPEER",
13915 .read = function_iaxpeer,
13916 };
13917
13918 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13919 {
13920 struct chan_iax2_pvt *pvt;
13921 unsigned int callno;
13922 int res = 0;
13923
13924 if (!chan || chan->tech != &iax2_tech) {
13925 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13926 return -1;
13927 }
13928
13929 callno = PTR_TO_CALLNO(chan->tech_pvt);
13930 ast_mutex_lock(&iaxsl[callno]);
13931 if (!(pvt = iaxs[callno])) {
13932 ast_mutex_unlock(&iaxsl[callno]);
13933 return -1;
13934 }
13935
13936 if (!strcasecmp(args, "osptoken")) {
13937 ast_copy_string(buf, pvt->osptoken, buflen);
13938 } else if (!strcasecmp(args, "peerip")) {
13939 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13940 } else if (!strcasecmp(args, "peername")) {
13941 ast_copy_string(buf, pvt->username, buflen);
13942 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
13943 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
13944 } else {
13945 res = -1;
13946 }
13947
13948 ast_mutex_unlock(&iaxsl[callno]);
13949
13950 return res;
13951 }
13952
13953
13954 static int iax2_devicestate(void *data)
13955 {
13956 struct parsed_dial_string pds;
13957 char *tmp = ast_strdupa(data);
13958 struct iax2_peer *p;
13959 int res = AST_DEVICE_INVALID;
13960
13961 memset(&pds, 0, sizeof(pds));
13962 parse_dial_string(tmp, &pds);
13963
13964 if (ast_strlen_zero(pds.peer)) {
13965 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13966 return res;
13967 }
13968
13969 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13970
13971
13972 if (!(p = find_peer(pds.peer, 1)))
13973 return res;
13974
13975 res = AST_DEVICE_UNAVAILABLE;
13976 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13977 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13978
13979 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
13980 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13981
13982
13983 if (p->historicms == 0 || p->historicms <= p->maxms)
13984
13985 res = AST_DEVICE_UNKNOWN;
13986 }
13987
13988 peer_unref(p);
13989
13990 return res;
13991 }
13992
13993 static struct ast_switch iax2_switch =
13994 {
13995 name: "IAX2",
13996 description: "IAX Remote Dialplan Switch",
13997 exists: iax2_exists,
13998 canmatch: iax2_canmatch,
13999 exec: iax2_exec,
14000 matchmore: iax2_matchmore,
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
14103
14104
14105
14106
14107 static struct ast_cli_entry cli_iax2[] = {
14108 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14109 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14110 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14111 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14112 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14113 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14114 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14115 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14116 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14117 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14118 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14119 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14120 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14121 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14122 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14123 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14124 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14125 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14126 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14127 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14128 #ifdef IAXTESTS
14129 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14130 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14131 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14132 #endif
14133 };
14134
14135 #ifdef TEST_FRAMEWORK
14136 AST_TEST_DEFINE(test_iax2_peers_get)
14137 {
14138 struct ast_data_query query = {
14139 .path = "/asterisk/channel/iax2/peers",
14140 .search = "peers/peer/name=test_peer_data_provider"
14141 };
14142 struct ast_data *node;
14143 struct iax2_peer *peer;
14144
14145 switch (cmd) {
14146 case TEST_INIT:
14147 info->name = "iax2_peers_get_data_test";
14148 info->category = "/main/data/iax2/peers/";
14149 info->summary = "IAX2 peers data providers unit test";
14150 info->description =
14151 "Tests whether the IAX2 peers data provider implementation works as expected.";
14152 return AST_TEST_NOT_RUN;
14153 case TEST_EXECUTE:
14154 break;
14155 }
14156
14157
14158 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14159 if (!peer) {
14160 return AST_TEST_FAIL;
14161 }
14162 peer->expiry= 1010;
14163 ao2_link(peers, peer);
14164
14165 node = ast_data_get(&query);
14166 if (!node) {
14167 ao2_unlink(peers, peer);
14168 peer_unref(peer);
14169 return AST_TEST_FAIL;
14170 }
14171
14172
14173 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14174 ao2_unlink(peers, peer);
14175 peer_unref(peer);
14176 ast_data_free(node);
14177 return AST_TEST_FAIL;
14178 }
14179
14180 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14181 ao2_unlink(peers, peer);
14182 peer_unref(peer);
14183 ast_data_free(node);
14184 return AST_TEST_FAIL;
14185 }
14186
14187
14188 ast_data_free(node);
14189
14190 ao2_unlink(peers, peer);
14191 peer_unref(peer);
14192
14193 return AST_TEST_PASS;
14194 }
14195
14196 AST_TEST_DEFINE(test_iax2_users_get)
14197 {
14198 struct ast_data_query query = {
14199 .path = "/asterisk/channel/iax2/users",
14200 .search = "users/user/name=test_user_data_provider"
14201 };
14202 struct ast_data *node;
14203 struct iax2_user *user;
14204
14205 switch (cmd) {
14206 case TEST_INIT:
14207 info->name = "iax2_users_get_data_test";
14208 info->category = "/main/data/iax2/users/";
14209 info->summary = "IAX2 users data providers unit test";
14210 info->description =
14211 "Tests whether the IAX2 users data provider implementation works as expected.";
14212 return AST_TEST_NOT_RUN;
14213 case TEST_EXECUTE:
14214 break;
14215 }
14216
14217 user = build_user("test_user_data_provider", NULL, NULL, 0);
14218 if (!user) {
14219 ast_test_status_update(test, "Failed to build a test user\n");
14220 return AST_TEST_FAIL;
14221 }
14222 user->amaflags = 1010;
14223 ao2_link(users, user);
14224
14225 node = ast_data_get(&query);
14226 if (!node) {
14227 ast_test_status_update(test, "The data query to find our test user failed\n");
14228 ao2_unlink(users, user);
14229 user_unref(user);
14230 return AST_TEST_FAIL;
14231 }
14232
14233 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14234 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14235 ao2_unlink(users, user);
14236 user_unref(user);
14237 ast_data_free(node);
14238 return AST_TEST_FAIL;
14239 }
14240
14241 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14242 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"));
14243 ao2_unlink(users, user);
14244 user_unref(user);
14245 ast_data_free(node);
14246 return AST_TEST_FAIL;
14247 }
14248
14249 ast_data_free(node);
14250
14251 ao2_unlink(users, user);
14252 user_unref(user);
14253
14254 return AST_TEST_PASS;
14255 }
14256 #endif
14257
14258 static void cleanup_thread_list(void *head)
14259 {
14260 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14261 struct iax2_thread_list *list_head = head;
14262 struct iax2_thread *thread;
14263
14264 AST_LIST_LOCK(list_head);
14265 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14266 pthread_t thread_id = thread->threadid;
14267
14268 thread->stop = 1;
14269 signal_condition(&thread->lock, &thread->cond);
14270
14271 AST_LIST_UNLOCK(list_head);
14272 pthread_join(thread_id, NULL);
14273 AST_LIST_LOCK(list_head);
14274 }
14275 AST_LIST_UNLOCK(list_head);
14276 }
14277
14278 static int __unload_module(void)
14279 {
14280 struct ast_context *con;
14281 int x;
14282
14283 network_change_event_unsubscribe();
14284
14285 ast_manager_unregister("IAXpeers");
14286 ast_manager_unregister("IAXpeerlist");
14287 ast_manager_unregister("IAXnetstats");
14288 ast_manager_unregister("IAXregistry");
14289 ast_unregister_application(papp);
14290 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14291 ast_unregister_switch(&iax2_switch);
14292 ast_channel_unregister(&iax2_tech);
14293
14294 if (netthreadid != AST_PTHREADT_NULL) {
14295 pthread_cancel(netthreadid);
14296 pthread_kill(netthreadid, SIGURG);
14297 pthread_join(netthreadid, NULL);
14298 }
14299
14300 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14301 if (iaxs[x]) {
14302 iax2_destroy(x);
14303 }
14304 }
14305
14306
14307 cleanup_thread_list(&idle_list);
14308 cleanup_thread_list(&active_list);
14309 cleanup_thread_list(&dynamic_list);
14310
14311 ast_netsock_release(netsock);
14312 ast_netsock_release(outsock);
14313 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14314 if (iaxs[x]) {
14315 iax2_destroy(x);
14316 }
14317 }
14318 ast_manager_unregister( "IAXpeers" );
14319 ast_manager_unregister( "IAXpeerlist" );
14320 ast_manager_unregister( "IAXnetstats" );
14321 ast_manager_unregister( "IAXregistry" );
14322 ast_unregister_application(papp);
14323 #ifdef TEST_FRAMEWORK
14324 AST_TEST_UNREGISTER(test_iax2_peers_get);
14325 AST_TEST_UNREGISTER(test_iax2_users_get);
14326 #endif
14327 ast_data_unregister(NULL);
14328 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14329 ast_unregister_switch(&iax2_switch);
14330 ast_channel_unregister(&iax2_tech);
14331 delete_users();
14332 iax_provision_unload();
14333 reload_firmware(1);
14334
14335 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14336 ast_mutex_destroy(&iaxsl[x]);
14337 }
14338
14339 ao2_ref(peers, -1);
14340 ao2_ref(users, -1);
14341 ao2_ref(iax_peercallno_pvts, -1);
14342 ao2_ref(iax_transfercallno_pvts, -1);
14343 ao2_ref(peercnts, -1);
14344 ao2_ref(callno_limits, -1);
14345 ao2_ref(calltoken_ignores, -1);
14346 ao2_ref(callno_pool, -1);
14347 ao2_ref(callno_pool_trunk, -1);
14348 if (timer) {
14349 ast_timer_close(timer);
14350 }
14351 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14352 sched = ast_sched_thread_destroy(sched);
14353
14354 con = ast_context_find(regcontext);
14355 if (con)
14356 ast_context_destroy(con, "IAX2");
14357 ast_unload_realtime("iaxpeers");
14358 return 0;
14359 }
14360
14361 static int unload_module(void)
14362 {
14363 ast_custom_function_unregister(&iaxpeer_function);
14364 ast_custom_function_unregister(&iaxvar_function);
14365 return __unload_module();
14366 }
14367
14368 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14369 {
14370 struct iax2_peer *peer = obj;
14371
14372 if (peer->sockfd < 0)
14373 peer->sockfd = defaultsockfd;
14374
14375 return 0;
14376 }
14377
14378 static int pvt_hash_cb(const void *obj, const int flags)
14379 {
14380 const struct chan_iax2_pvt *pvt = obj;
14381
14382 return pvt->peercallno;
14383 }
14384
14385 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14386 {
14387 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14388
14389
14390
14391
14392 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14393 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14394 }
14395
14396 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14397 {
14398 const struct chan_iax2_pvt *pvt = obj;
14399
14400 return pvt->transfercallno;
14401 }
14402
14403 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14404 {
14405 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14406
14407
14408
14409
14410 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14411 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14412 }
14413
14414 static int load_objects(void)
14415 {
14416 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14417 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14418
14419 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14420 goto container_fail;
14421 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14422 goto container_fail;
14423 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14424 goto container_fail;
14425 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14426 goto container_fail;
14427 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14428 goto container_fail;
14429 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14430 goto container_fail;
14431 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14432 goto container_fail;
14433 } else if (create_callno_pools()) {
14434 goto container_fail;
14435 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14436 goto container_fail;
14437 }
14438
14439 return 0;
14440
14441 container_fail:
14442 if (peers) {
14443 ao2_ref(peers, -1);
14444 }
14445 if (users) {
14446 ao2_ref(users, -1);
14447 }
14448 if (iax_peercallno_pvts) {
14449 ao2_ref(iax_peercallno_pvts, -1);
14450 }
14451 if (iax_transfercallno_pvts) {
14452 ao2_ref(iax_transfercallno_pvts, -1);
14453 }
14454 if (peercnts) {
14455 ao2_ref(peercnts, -1);
14456 }
14457 if (callno_limits) {
14458 ao2_ref(callno_limits, -1);
14459 }
14460 if (calltoken_ignores) {
14461 ao2_ref(calltoken_ignores, -1);
14462 }
14463 if (callno_pool) {
14464 ao2_ref(callno_pool, -1);
14465 }
14466 if (callno_pool_trunk) {
14467 ao2_ref(callno_pool_trunk, -1);
14468 }
14469 return AST_MODULE_LOAD_FAILURE;
14470 }
14471
14472
14473 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14474 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14475 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14476 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14477 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14478 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14479 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14480 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14481 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14482 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14483 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14484 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14485 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14486 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14487 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14488 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14489 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14490 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14491 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14492 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14493 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14494 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14495 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14496 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14497 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14498 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14499
14500 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14501
14502 static int peers_data_provider_get(const struct ast_data_search *search,
14503 struct ast_data *data_root)
14504 {
14505 struct ast_data *data_peer;
14506 struct iax2_peer *peer;
14507 struct ao2_iterator i;
14508 char status[20];
14509 struct ast_str *encmethods = ast_str_alloca(256);
14510
14511 i = ao2_iterator_init(peers, 0);
14512 while ((peer = ao2_iterator_next(&i))) {
14513 data_peer = ast_data_add_node(data_root, "peer");
14514 if (!data_peer) {
14515 peer_unref(peer);
14516 continue;
14517 }
14518
14519 ast_data_add_structure(iax2_peer, data_peer, peer);
14520
14521 ast_data_add_codecs(data_peer, "codecs", peer->capability);
14522
14523 peer_status(peer, status, sizeof(status));
14524 ast_data_add_str(data_peer, "status", status);
14525
14526 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14527
14528 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14529
14530 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14531
14532 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14533
14534 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14535
14536 encmethods_to_str(peer->encmethods, encmethods);
14537 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14538
14539 peer_unref(peer);
14540
14541 if (!ast_data_search_match(search, data_peer)) {
14542 ast_data_remove_node(data_root, data_peer);
14543 }
14544 }
14545 ao2_iterator_destroy(&i);
14546
14547 return 0;
14548 }
14549
14550 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14551 MEMBER(iax2_user, name, AST_DATA_STRING) \
14552 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14553 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14554 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14555 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14556 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14557 MEMBER(iax2_user, language, AST_DATA_STRING) \
14558 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14559 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14560 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14561 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14562 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14563
14564 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14565
14566 static int users_data_provider_get(const struct ast_data_search *search,
14567 struct ast_data *data_root)
14568 {
14569 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14570 struct iax2_user *user;
14571 struct ao2_iterator i;
14572 char auth[90];
14573 char *pstr = "";
14574
14575 i = ao2_iterator_init(users, 0);
14576 for (; (user = ao2_iterator_next(&i)); user_unref(user)) {
14577 data_user = ast_data_add_node(data_root, "user");
14578 if (!data_user) {
14579 continue;
14580 }
14581
14582 ast_data_add_structure(iax2_user, data_user, user);
14583
14584 ast_data_add_codecs(data_user, "codecs", user->capability);
14585
14586 if (!ast_strlen_zero(user->secret)) {
14587 ast_copy_string(auth, user->secret, sizeof(auth));
14588 } else if (!ast_strlen_zero(user->inkeys)) {
14589 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14590 } else {
14591 ast_copy_string(auth, "no secret", sizeof(auth));
14592 }
14593 ast_data_add_password(data_user, "secret", auth);
14594
14595 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14596
14597
14598 data_authmethods = ast_data_add_node(data_user, "authmethods");
14599 if (!data_authmethods) {
14600 ast_data_remove_node(data_root, data_user);
14601 continue;
14602 }
14603 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14604 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14605 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14606
14607
14608 data_enum_node = ast_data_add_node(data_user, "amaflags");
14609 if (!data_enum_node) {
14610 ast_data_remove_node(data_root, data_user);
14611 continue;
14612 }
14613 ast_data_add_int(data_enum_node, "value", user->amaflags);
14614 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14615
14616 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14617
14618 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14619 pstr = "REQ only";
14620 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14621 pstr = "disabled";
14622 } else {
14623 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14624 }
14625 ast_data_add_str(data_user, "codec-preferences", pstr);
14626
14627 if (!ast_data_search_match(search, data_user)) {
14628 ast_data_remove_node(data_root, data_user);
14629 }
14630 }
14631 ao2_iterator_destroy(&i);
14632
14633 return 0;
14634 }
14635
14636 static const struct ast_data_handler peers_data_provider = {
14637 .version = AST_DATA_HANDLER_VERSION,
14638 .get = peers_data_provider_get
14639 };
14640
14641 static const struct ast_data_handler users_data_provider = {
14642 .version = AST_DATA_HANDLER_VERSION,
14643 .get = users_data_provider_get
14644 };
14645
14646 static const struct ast_data_entry iax2_data_providers[] = {
14647 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14648 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14649 };
14650
14651
14652 static int load_module(void)
14653 {
14654 static const char config[] = "iax.conf";
14655 int x = 0;
14656 struct iax2_registry *reg = NULL;
14657
14658 if (load_objects()) {
14659 return AST_MODULE_LOAD_FAILURE;
14660 }
14661
14662 memset(iaxs, 0, sizeof(iaxs));
14663
14664 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14665 ast_mutex_init(&iaxsl[x]);
14666 }
14667
14668 if (!(sched = ast_sched_thread_create())) {
14669 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14670 return AST_MODULE_LOAD_FAILURE;
14671 }
14672
14673 if (!(io = io_context_create())) {
14674 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14675 sched = ast_sched_thread_destroy(sched);
14676 return AST_MODULE_LOAD_FAILURE;
14677 }
14678
14679 if (!(netsock = ast_netsock_list_alloc())) {
14680 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14681 io_context_destroy(io);
14682 sched = ast_sched_thread_destroy(sched);
14683 return AST_MODULE_LOAD_FAILURE;
14684 }
14685 ast_netsock_init(netsock);
14686
14687 outsock = ast_netsock_list_alloc();
14688 if (!outsock) {
14689 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14690 io_context_destroy(io);
14691 sched = ast_sched_thread_destroy(sched);
14692 return AST_MODULE_LOAD_FAILURE;
14693 }
14694 ast_netsock_init(outsock);
14695
14696 randomcalltokendata = ast_random();
14697
14698 iax_set_output(iax_debug_output);
14699 iax_set_error(iax_error_output);
14700 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14701
14702 if ((timer = ast_timer_open())) {
14703 ast_timer_set_rate(timer, trunkfreq);
14704 }
14705
14706 if (set_config(config, 0) == -1) {
14707 if (timer) {
14708 ast_timer_close(timer);
14709 }
14710 return AST_MODULE_LOAD_DECLINE;
14711 }
14712
14713 #ifdef TEST_FRAMEWORK
14714 AST_TEST_REGISTER(test_iax2_peers_get);
14715 AST_TEST_REGISTER(test_iax2_users_get);
14716 #endif
14717
14718
14719 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14720 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14721
14722 ast_register_application_xml(papp, iax2_prov_app);
14723
14724 ast_custom_function_register(&iaxpeer_function);
14725 ast_custom_function_register(&iaxvar_function);
14726
14727 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14728 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14729 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14730 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14731
14732 if (ast_channel_register(&iax2_tech)) {
14733 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14734 __unload_module();
14735 return AST_MODULE_LOAD_FAILURE;
14736 }
14737
14738 if (ast_register_switch(&iax2_switch)) {
14739 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14740 }
14741
14742 if (start_network_thread()) {
14743 ast_log(LOG_ERROR, "Unable to start network thread\n");
14744 __unload_module();
14745 return AST_MODULE_LOAD_FAILURE;
14746 } else {
14747 ast_verb(2, "IAX Ready and Listening\n");
14748 }
14749
14750 AST_LIST_LOCK(®istrations);
14751 AST_LIST_TRAVERSE(®istrations, reg, entry)
14752 iax2_do_register(reg);
14753 AST_LIST_UNLOCK(®istrations);
14754
14755 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14756 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14757
14758
14759 reload_firmware(0);
14760 iax_provision_reload(0);
14761
14762 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14763
14764 network_change_event_subscribe();
14765
14766 return AST_MODULE_LOAD_SUCCESS;
14767 }
14768
14769 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
14770 .load = load_module,
14771 .unload = unload_module,
14772 .reload = reload,
14773 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
14774 .nonoptreq = "res_crypto",
14775 );