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: 331248 $")
00042
00043 #include <sys/mman.h>
00044 #include <dirent.h>
00045 #include <sys/socket.h>
00046 #include <netinet/in.h>
00047 #include <arpa/inet.h>
00048 #include <netinet/in_systm.h>
00049 #include <netinet/ip.h>
00050 #include <sys/time.h>
00051 #include <sys/signal.h>
00052 #include <signal.h>
00053 #include <strings.h>
00054 #include <netdb.h>
00055 #include <fcntl.h>
00056 #include <sys/stat.h>
00057 #include <regex.h>
00058
00059 #include "asterisk/paths.h"
00060
00061 #include "asterisk/lock.h"
00062 #include "asterisk/frame.h"
00063 #include "asterisk/channel.h"
00064 #include "asterisk/module.h"
00065 #include "asterisk/pbx.h"
00066 #include "asterisk/sched.h"
00067 #include "asterisk/io.h"
00068 #include "asterisk/config.h"
00069 #include "asterisk/cli.h"
00070 #include "asterisk/translate.h"
00071 #include "asterisk/md5.h"
00072 #include "asterisk/cdr.h"
00073 #include "asterisk/crypto.h"
00074 #include "asterisk/acl.h"
00075 #include "asterisk/manager.h"
00076 #include "asterisk/callerid.h"
00077 #include "asterisk/app.h"
00078 #include "asterisk/astdb.h"
00079 #include "asterisk/musiconhold.h"
00080 #include "asterisk/features.h"
00081 #include "asterisk/utils.h"
00082 #include "asterisk/causes.h"
00083 #include "asterisk/localtime.h"
00084 #include "asterisk/dnsmgr.h"
00085 #include "asterisk/devicestate.h"
00086 #include "asterisk/netsock.h"
00087 #include "asterisk/stringfields.h"
00088 #include "asterisk/linkedlists.h"
00089 #include "asterisk/event.h"
00090 #include "asterisk/astobj2.h"
00091 #include "asterisk/timing.h"
00092 #include "asterisk/taskprocessor.h"
00093 #include "asterisk/test.h"
00094 #include "asterisk/data.h"
00095 #include "asterisk/netsock2.h"
00096
00097 #include "iax2.h"
00098 #include "iax2-parser.h"
00099 #include "iax2-provision.h"
00100 #include "jitterbuf.h"
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 #define SCHED_MULTITHREADED
00228
00229
00230
00231 #define DEBUG_SCHED_MULTITHREAD
00232
00233
00234 #ifdef SO_NO_CHECK
00235 static int nochecksums = 0;
00236 #endif
00237
00238 #define PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a))
00239 #define CALLNO_TO_PTR(a) ((void *)(unsigned long)(a))
00240
00241 #define DEFAULT_THREAD_COUNT 10
00242 #define DEFAULT_MAX_THREAD_COUNT 100
00243 #define DEFAULT_RETRY_TIME 1000
00244 #define MEMORY_SIZE 100
00245 #define DEFAULT_DROP 3
00246
00247 #define DEBUG_SUPPORT
00248
00249 #define MIN_REUSE_TIME 60
00250
00251
00252 #define GAMMA (0.01)
00253
00254 static struct ast_codec_pref prefs;
00255
00256 static const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)";
00257
00258
00259
00260
00261 #define MAX_TRUNK_MTU 1240
00262
00263 static int global_max_trunk_mtu;
00264 static int trunk_timed, trunk_untimed, trunk_maxmtu, trunk_nmaxmtu ;
00265
00266 #define DEFAULT_CONTEXT "default"
00267
00268 static char default_parkinglot[AST_MAX_CONTEXT];
00269
00270 static char language[MAX_LANGUAGE] = "";
00271 static char regcontext[AST_MAX_CONTEXT] = "";
00272
00273 static struct ast_event_sub *network_change_event_subscription;
00274 static int network_change_event_sched_id = -1;
00275
00276 static int maxauthreq = 3;
00277 static int max_retries = 4;
00278 static int ping_time = 21;
00279 static int lagrq_time = 10;
00280 static int maxjitterbuffer=1000;
00281 static int resyncthreshold=1000;
00282 static int maxjitterinterps=10;
00283 static int jittertargetextra = 40;
00284
00285 #define MAX_TRUNKDATA 640 * 200
00286
00287 static int trunkfreq = 20;
00288 static int trunkmaxsize = MAX_TRUNKDATA;
00289
00290 static int authdebug = 1;
00291 static int autokill = 0;
00292 static int iaxcompat = 0;
00293 static int last_authmethod = 0;
00294
00295 static int iaxdefaultdpcache=10 * 60;
00296
00297 static int iaxdefaulttimeout = 5;
00298
00299 static struct {
00300 unsigned int tos;
00301 unsigned int cos;
00302 } qos = { 0, 0 };
00303
00304 static int min_reg_expire;
00305 static int max_reg_expire;
00306
00307 static int srvlookup = 0;
00308
00309 static struct ast_timer *timer;
00310
00311 static struct ast_netsock_list *netsock;
00312 static struct ast_netsock_list *outsock;
00313 static int defaultsockfd = -1;
00314
00315 static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
00316
00317
00318 #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF
00319
00320 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
00321 ~AST_FORMAT_SLINEAR & \
00322 ~AST_FORMAT_SLINEAR16 & \
00323 ~AST_FORMAT_SIREN7 & \
00324 ~AST_FORMAT_SIREN14 & \
00325 ~AST_FORMAT_G719 & \
00326 ~AST_FORMAT_ULAW & \
00327 ~AST_FORMAT_ALAW & \
00328 ~AST_FORMAT_G722)
00329
00330 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
00331 ~AST_FORMAT_G726 & \
00332 ~AST_FORMAT_G726_AAL2 & \
00333 ~AST_FORMAT_ADPCM)
00334
00335 #define IAX_CAPABILITY_LOWFREE (IAX_CAPABILITY_LOWBANDWIDTH & \
00336 ~AST_FORMAT_G723_1)
00337
00338
00339 #define DEFAULT_MAXMS 2000
00340 #define DEFAULT_FREQ_OK 60 * 1000
00341 #define DEFAULT_FREQ_NOTOK 10 * 1000
00342
00343
00344 #define IAX_CALLENCRYPTED(pvt) \
00345 (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED))
00346
00347 #define IAX_DEBUGDIGEST(msg, key) do { \
00348 int idx; \
00349 char digest[33] = ""; \
00350 \
00351 if (!iaxdebug) \
00352 break; \
00353 \
00354 for (idx = 0; idx < 16; idx++) \
00355 sprintf(digest + (idx << 1), "%2.2x", (unsigned char) key[idx]); \
00356 \
00357 ast_log(LOG_NOTICE, msg " IAX_COMMAND_RTKEY to rotate key to '%s'\n", digest); \
00358 } while(0)
00359
00360 static struct io_context *io;
00361 static struct ast_sched_thread *sched;
00362
00363 #define DONT_RESCHEDULE -2
00364
00365 static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
00366
00367 static int iaxdebug = 0;
00368
00369 static int iaxtrunkdebug = 0;
00370
00371 static int test_losspct = 0;
00372 #ifdef IAXTESTS
00373 static int test_late = 0;
00374 static int test_resync = 0;
00375 static int test_jit = 0;
00376 static int test_jitpct = 0;
00377 #endif
00378
00379 static char accountcode[AST_MAX_ACCOUNT_CODE];
00380 static char mohinterpret[MAX_MUSICCLASS];
00381 static char mohsuggest[MAX_MUSICCLASS];
00382 static int amaflags = 0;
00383 static int adsi = 0;
00384 static int delayreject = 0;
00385 static int iax2_encryption = 0;
00386
00387 static struct ast_flags64 globalflags = { 0 };
00388
00389 static pthread_t netthreadid = AST_PTHREADT_NULL;
00390
00391 enum iax2_state {
00392 IAX_STATE_STARTED = (1 << 0),
00393 IAX_STATE_AUTHENTICATED = (1 << 1),
00394 IAX_STATE_TBD = (1 << 2),
00395 };
00396
00397 struct iax2_context {
00398 char context[AST_MAX_CONTEXT];
00399 struct iax2_context *next;
00400 };
00401
00402
00403 #define IAX_HASCALLERID (uint64_t)(1 << 0)
00404 #define IAX_DELME (uint64_t)(1 << 1)
00405 #define IAX_TEMPONLY (uint64_t)(1 << 2)
00406 #define IAX_TRUNK (uint64_t)(1 << 3)
00407 #define IAX_NOTRANSFER (uint64_t)(1 << 4)
00408 #define IAX_USEJITTERBUF (uint64_t)(1 << 5)
00409 #define IAX_DYNAMIC (uint64_t)(1 << 6)
00410 #define IAX_SENDANI (uint64_t)(1 << 7)
00411 #define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8)
00412 #define IAX_ALREADYGONE (uint64_t)(1 << 9)
00413 #define IAX_PROVISION (uint64_t)(1 << 10)
00414 #define IAX_QUELCH (uint64_t)(1 << 11)
00415 #define IAX_ENCRYPTED (uint64_t)(1 << 12)
00416 #define IAX_KEYPOPULATED (uint64_t)(1 << 13)
00417 #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14)
00418 #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15)
00419 #define IAX_CODEC_NOCAP (uint64_t)(1 << 16)
00420 #define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17)
00421 #define IAX_RTUPDATE (uint64_t)(1 << 18)
00422 #define IAX_RTAUTOCLEAR (uint64_t)(1 << 19)
00423 #define IAX_FORCEJITTERBUF (uint64_t)(1 << 20)
00424 #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21)
00425 #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22)
00426 #define IAX_TRANSFERMEDIA (uint64_t)(1 << 23)
00427 #define IAX_MAXAUTHREQ (uint64_t)(1 << 24)
00428 #define IAX_DELAYPBXSTART (uint64_t)(1 << 25)
00429 #define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26)
00430 #define IAX_IMMEDIATE (uint64_t)(1 << 27)
00431 #define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28)
00432 #define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29)
00433 #define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30)
00434 #define IAX_SHRINKCALLERID (uint64_t)(1 << 31)
00435 static int global_rtautoclear = 120;
00436
00437 static int reload_config(void);
00438
00439
00440
00441
00442 enum calltoken_peer_enum {
00443
00444 CALLTOKEN_DEFAULT = 0,
00445
00446 CALLTOKEN_YES = 1,
00447
00448
00449 CALLTOKEN_AUTO = 2,
00450
00451 CALLTOKEN_NO = 3,
00452 };
00453
00454 struct iax2_user {
00455 AST_DECLARE_STRING_FIELDS(
00456 AST_STRING_FIELD(name);
00457 AST_STRING_FIELD(secret);
00458 AST_STRING_FIELD(dbsecret);
00459 AST_STRING_FIELD(accountcode);
00460 AST_STRING_FIELD(mohinterpret);
00461 AST_STRING_FIELD(mohsuggest);
00462 AST_STRING_FIELD(inkeys);
00463 AST_STRING_FIELD(language);
00464 AST_STRING_FIELD(cid_num);
00465 AST_STRING_FIELD(cid_name);
00466 AST_STRING_FIELD(parkinglot);
00467 );
00468
00469 int authmethods;
00470 int encmethods;
00471 int amaflags;
00472 int adsi;
00473 uint64_t flags;
00474 format_t capability;
00475 int maxauthreq;
00476 int curauthreq;
00477 struct ast_codec_pref prefs;
00478 struct ast_ha *ha;
00479 struct iax2_context *contexts;
00480 struct ast_variable *vars;
00481 enum calltoken_peer_enum calltoken_required;
00482 };
00483
00484 struct iax2_peer {
00485 AST_DECLARE_STRING_FIELDS(
00486 AST_STRING_FIELD(name);
00487 AST_STRING_FIELD(username);
00488 AST_STRING_FIELD(secret);
00489 AST_STRING_FIELD(dbsecret);
00490 AST_STRING_FIELD(outkey);
00491
00492 AST_STRING_FIELD(regexten);
00493 AST_STRING_FIELD(context);
00494 AST_STRING_FIELD(peercontext);
00495 AST_STRING_FIELD(mailbox);
00496 AST_STRING_FIELD(mohinterpret);
00497 AST_STRING_FIELD(mohsuggest);
00498 AST_STRING_FIELD(inkeys);
00499
00500 AST_STRING_FIELD(cid_num);
00501 AST_STRING_FIELD(cid_name);
00502 AST_STRING_FIELD(zonetag);
00503 AST_STRING_FIELD(parkinglot);
00504 );
00505 struct ast_codec_pref prefs;
00506 struct ast_dnsmgr_entry *dnsmgr;
00507 struct ast_sockaddr addr;
00508 int formats;
00509 int sockfd;
00510 struct in_addr mask;
00511 int adsi;
00512 uint64_t flags;
00513
00514
00515 struct sockaddr_in defaddr;
00516 int authmethods;
00517 int encmethods;
00518
00519 int expire;
00520 int expiry;
00521 format_t capability;
00522
00523
00524 int callno;
00525 int pokeexpire;
00526 int lastms;
00527 int maxms;
00528
00529 int pokefreqok;
00530 int pokefreqnotok;
00531 int historicms;
00532 int smoothing;
00533 uint16_t maxcallno;
00534
00535 struct ast_event_sub *mwi_event_sub;
00536
00537 struct ast_ha *ha;
00538 enum calltoken_peer_enum calltoken_required;
00539 };
00540
00541 #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr))
00542
00543 struct iax2_trunk_peer {
00544 ast_mutex_t lock;
00545 int sockfd;
00546 struct sockaddr_in addr;
00547 struct timeval txtrunktime;
00548 struct timeval rxtrunktime;
00549 struct timeval lasttxtime;
00550 struct timeval trunkact;
00551 unsigned int lastsent;
00552
00553 unsigned char *trunkdata;
00554 unsigned int trunkdatalen;
00555 unsigned int trunkdataalloc;
00556 int trunkmaxmtu;
00557 int trunkerror;
00558 int calls;
00559 AST_LIST_ENTRY(iax2_trunk_peer) list;
00560 };
00561
00562 static AST_LIST_HEAD_STATIC(tpeers, iax2_trunk_peer);
00563
00564 struct iax_firmware {
00565 AST_LIST_ENTRY(iax_firmware) list;
00566 int fd;
00567 int mmaplen;
00568 int dead;
00569 struct ast_iax2_firmware_header *fwh;
00570 unsigned char *buf;
00571 };
00572
00573 enum iax_reg_state {
00574 REG_STATE_UNREGISTERED = 0,
00575 REG_STATE_REGSENT,
00576 REG_STATE_AUTHSENT,
00577 REG_STATE_REGISTERED,
00578 REG_STATE_REJECTED,
00579 REG_STATE_TIMEOUT,
00580 REG_STATE_NOAUTH
00581 };
00582
00583 enum iax_transfer_state {
00584 TRANSFER_NONE = 0,
00585 TRANSFER_BEGIN,
00586 TRANSFER_READY,
00587 TRANSFER_RELEASED,
00588 TRANSFER_PASSTHROUGH,
00589 TRANSFER_MBEGIN,
00590 TRANSFER_MREADY,
00591 TRANSFER_MRELEASED,
00592 TRANSFER_MPASSTHROUGH,
00593 TRANSFER_MEDIA,
00594 TRANSFER_MEDIAPASS
00595 };
00596
00597 struct iax2_registry {
00598 struct ast_sockaddr addr;
00599 char username[80];
00600 char secret[80];
00601 int expire;
00602 int refresh;
00603 enum iax_reg_state regstate;
00604 int messages;
00605 int callno;
00606 struct sockaddr_in us;
00607 struct ast_dnsmgr_entry *dnsmgr;
00608 AST_LIST_ENTRY(iax2_registry) entry;
00609 };
00610
00611 static AST_LIST_HEAD_STATIC(registrations, iax2_registry);
00612
00613
00614 #define MIN_RETRY_TIME 100
00615 #define MAX_RETRY_TIME 10000
00616
00617 #define MAX_JITTER_BUFFER 50
00618 #define MIN_JITTER_BUFFER 10
00619
00620 #define DEFAULT_TRUNKDATA 640 * 10
00621
00622 #define MAX_TIMESTAMP_SKEW 160
00623
00624
00625 #define TS_GAP_FOR_JB_RESYNC 5000
00626
00627
00628 #define MARK_IAX_SUBCLASS_TX 0x8000
00629
00630 static int iaxthreadcount = DEFAULT_THREAD_COUNT;
00631 static int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT;
00632 static int iaxdynamicthreadcount = 0;
00633 static int iaxdynamicthreadnum = 0;
00634 static int iaxactivethreadcount = 0;
00635
00636 struct iax_rr {
00637 int jitter;
00638 int losspct;
00639 int losscnt;
00640 int packets;
00641 int delay;
00642 int dropped;
00643 int ooo;
00644 };
00645
00646 struct iax2_pvt_ref;
00647
00648 struct chan_iax2_pvt {
00649
00650 int sockfd;
00651
00652 format_t voiceformat;
00653
00654 format_t videoformat;
00655
00656 format_t svoiceformat;
00657
00658 format_t svideoformat;
00659
00660 format_t capability;
00661
00662 unsigned int last;
00663
00664 unsigned int lastsent;
00665
00666 unsigned int lastvsent;
00667
00668 unsigned int nextpred;
00669
00670 int first_iax_message;
00671
00672 int last_iax_message;
00673
00674 unsigned int notsilenttx:1;
00675
00676 unsigned int pingtime;
00677
00678 int maxtime;
00679
00680 struct sockaddr_in addr;
00681
00682 struct ast_codec_pref prefs;
00683
00684 struct ast_codec_pref rprefs;
00685
00686 unsigned short callno;
00687
00688 struct callno_entry *callno_entry;
00689
00690 unsigned short peercallno;
00691
00692
00693
00694 format_t chosenformat;
00695
00696 format_t peerformat;
00697
00698 format_t peercapability;
00699
00700 struct timeval offset;
00701
00702 struct timeval rxcore;
00703
00704 jitterbuf *jb;
00705
00706 int jbid;
00707
00708 int lag;
00709
00710 int error;
00711
00712 struct ast_channel *owner;
00713
00714 struct ast_flags state;
00715
00716 int expiry;
00717
00718 unsigned char oseqno;
00719
00720 unsigned char rseqno;
00721
00722 unsigned char iseqno;
00723
00724 unsigned char aseqno;
00725
00726 AST_DECLARE_STRING_FIELDS(
00727
00728 AST_STRING_FIELD(peer);
00729
00730 AST_STRING_FIELD(context);
00731
00732 AST_STRING_FIELD(cid_num);
00733 AST_STRING_FIELD(cid_name);
00734
00735 AST_STRING_FIELD(ani);
00736
00737 AST_STRING_FIELD(dnid);
00738
00739 AST_STRING_FIELD(rdnis);
00740
00741 AST_STRING_FIELD(exten);
00742
00743 AST_STRING_FIELD(username);
00744
00745 AST_STRING_FIELD(secret);
00746
00747 AST_STRING_FIELD(challenge);
00748
00749 AST_STRING_FIELD(inkeys);
00750
00751 AST_STRING_FIELD(outkey);
00752
00753 AST_STRING_FIELD(language);
00754
00755 AST_STRING_FIELD(host);
00756
00757 AST_STRING_FIELD(dproot);
00758 AST_STRING_FIELD(accountcode);
00759 AST_STRING_FIELD(mohinterpret);
00760 AST_STRING_FIELD(mohsuggest);
00761
00762 AST_STRING_FIELD(osptoken);
00763
00764 AST_STRING_FIELD(parkinglot);
00765 );
00766
00767 int authrej;
00768
00769 int authmethods;
00770
00771 int encmethods;
00772
00773 ast_aes_encrypt_key ecx;
00774
00775 ast_aes_decrypt_key mydcx;
00776
00777 ast_aes_decrypt_key dcx;
00778
00779
00780 int keyrotateid;
00781
00782 unsigned char semirand[32];
00783
00784 struct iax2_registry *reg;
00785
00786 struct iax2_peer *peerpoke;
00787
00788 uint64_t flags;
00789 int adsi;
00790
00791
00792 enum iax_transfer_state transferring;
00793
00794 int transferid;
00795
00796 struct sockaddr_in transfer;
00797
00798 unsigned short transfercallno;
00799
00800 ast_aes_encrypt_key tdcx;
00801
00802
00803 int peeradsicpe;
00804
00805
00806 unsigned short bridgecallno;
00807
00808 int pingid;
00809 int lagid;
00810 int autoid;
00811 int authid;
00812 int authfail;
00813 int initid;
00814 int calling_ton;
00815 int calling_tns;
00816 int calling_pres;
00817 int amaflags;
00818 AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
00819
00820 struct ast_variable *vars;
00821
00822 struct ast_variable *iaxvars;
00823
00824 struct iax_rr remote_rr;
00825
00826 int min;
00827
00828 int frames_dropped;
00829
00830 int frames_received;
00831
00832 unsigned char calltoken_ie_len;
00833
00834 char hold_signaling;
00835
00836 AST_LIST_HEAD_NOLOCK(signaling_queue, signaling_queue_entry) signaling_queue;
00837 };
00838
00839 struct signaling_queue_entry {
00840 struct ast_frame f;
00841 AST_LIST_ENTRY(signaling_queue_entry) next;
00842 };
00843
00844
00845 static struct ao2_container *callno_pool;
00846
00847
00848 static struct ao2_container *callno_pool_trunk;
00849
00850 static const unsigned int CALLNO_POOL_BUCKETS = 2699;
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861 static AST_LIST_HEAD_NOLOCK(, iax_frame) frame_queue[IAX_MAX_CALLS + 1];
00862
00863 static struct ast_taskprocessor *transmit_processor;
00864
00865 static int randomcalltokendata;
00866
00867 static const time_t MAX_CALLTOKEN_DELAY = 10;
00868
00869
00870
00871
00872
00873
00874
00875
00876 #ifdef LOW_MEMORY
00877 #define MAX_PEER_BUCKETS 17
00878 #else
00879 #define MAX_PEER_BUCKETS 563
00880 #endif
00881 static struct ao2_container *peers;
00882
00883 #define MAX_USER_BUCKETS MAX_PEER_BUCKETS
00884 static struct ao2_container *users;
00885
00886
00887 static struct ao2_container *peercnts;
00888
00889
00890 static struct ao2_container *callno_limits;
00891
00892
00893 static struct ao2_container *calltoken_ignores;
00894
00895 static uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048;
00896
00897 static uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192;
00898
00899 static uint16_t global_maxcallno;
00900
00901
00902 static uint16_t global_maxcallno_nonval;
00903
00904 static uint16_t total_nonval_callno_used = 0;
00905
00906
00907
00908 struct peercnt {
00909
00910 unsigned long addr;
00911
00912 uint16_t cur;
00913
00914 uint16_t limit;
00915
00916
00917 unsigned char reg;
00918 };
00919
00920
00921 struct addr_range {
00922
00923 struct ast_ha ha;
00924
00925 uint16_t limit;
00926
00927 unsigned char delme;
00928 };
00929
00930 struct callno_entry {
00931
00932 uint16_t callno;
00933
00934 unsigned char validated;
00935 };
00936
00937 static AST_LIST_HEAD_STATIC(firmwares, iax_firmware);
00938
00939 enum {
00940
00941 CACHE_FLAG_EXISTS = (1 << 0),
00942
00943 CACHE_FLAG_NONEXISTENT = (1 << 1),
00944
00945 CACHE_FLAG_CANEXIST = (1 << 2),
00946
00947 CACHE_FLAG_PENDING = (1 << 3),
00948
00949 CACHE_FLAG_TIMEOUT = (1 << 4),
00950
00951 CACHE_FLAG_TRANSMITTED = (1 << 5),
00952
00953 CACHE_FLAG_UNKNOWN = (1 << 6),
00954
00955 CACHE_FLAG_MATCHMORE = (1 << 7),
00956 };
00957
00958 struct iax2_dpcache {
00959 char peercontext[AST_MAX_CONTEXT];
00960 char exten[AST_MAX_EXTENSION];
00961 struct timeval orig;
00962 struct timeval expiry;
00963 int flags;
00964 unsigned short callno;
00965 int waiters[256];
00966 AST_LIST_ENTRY(iax2_dpcache) cache_list;
00967 AST_LIST_ENTRY(iax2_dpcache) peer_list;
00968 };
00969
00970 static AST_LIST_HEAD_STATIC(dpcache, iax2_dpcache);
00971
00972 static void reg_source_db(struct iax2_peer *p);
00973 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
00974 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin);
00975
00976 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt);
00977 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags);
00978 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state);
00979
00980 enum iax2_thread_iostate {
00981 IAX_IOSTATE_IDLE,
00982 IAX_IOSTATE_READY,
00983 IAX_IOSTATE_PROCESSING,
00984 IAX_IOSTATE_SCHEDREADY,
00985 };
00986
00987 enum iax2_thread_type {
00988 IAX_THREAD_TYPE_POOL,
00989 IAX_THREAD_TYPE_DYNAMIC,
00990 };
00991
00992 struct iax2_pkt_buf {
00993 AST_LIST_ENTRY(iax2_pkt_buf) entry;
00994 size_t len;
00995 unsigned char buf[1];
00996 };
00997
00998 struct iax2_thread {
00999 AST_LIST_ENTRY(iax2_thread) list;
01000 enum iax2_thread_type type;
01001 enum iax2_thread_iostate iostate;
01002 #ifdef SCHED_MULTITHREADED
01003 void (*schedfunc)(const void *);
01004 const void *scheddata;
01005 #endif
01006 #ifdef DEBUG_SCHED_MULTITHREAD
01007 char curfunc[80];
01008 #endif
01009 int actions;
01010 pthread_t threadid;
01011 int threadnum;
01012 struct sockaddr_in iosin;
01013 unsigned char readbuf[4096];
01014 unsigned char *buf;
01015 ssize_t buf_len;
01016 size_t buf_size;
01017 int iofd;
01018 time_t checktime;
01019 ast_mutex_t lock;
01020 ast_cond_t cond;
01021 ast_mutex_t init_lock;
01022 ast_cond_t init_cond;
01023
01024
01025
01026
01027 struct {
01028 unsigned short callno;
01029 struct sockaddr_in sin;
01030 unsigned char type;
01031 unsigned char csub;
01032 } ffinfo;
01033
01034
01035
01036 AST_LIST_HEAD_NOLOCK(, iax2_pkt_buf) full_frames;
01037 unsigned char stop;
01038 };
01039
01040
01041 static AST_LIST_HEAD_STATIC(idle_list, iax2_thread);
01042 static AST_LIST_HEAD_STATIC(active_list, iax2_thread);
01043 static AST_LIST_HEAD_STATIC(dynamic_list, iax2_thread);
01044
01045 static void *iax2_process_thread(void *data);
01046 static void iax2_destroy(int callno);
01047
01048 static void signal_condition(ast_mutex_t *lock, ast_cond_t *cond)
01049 {
01050 ast_mutex_lock(lock);
01051 ast_cond_signal(cond);
01052 ast_mutex_unlock(lock);
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063 static struct chan_iax2_pvt *iaxs[IAX_MAX_CALLS + 1];
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 static struct ao2_container *iax_peercallno_pvts;
01075
01076
01077
01078
01079
01080
01081
01082
01083 static ast_mutex_t iaxsl[ARRAY_LEN(iaxs)];
01084
01085
01086
01087
01088
01089
01090 static struct ao2_container *iax_transfercallno_pvts;
01091
01092
01093
01094 #define TRUNK_CALL_START IAX_MAX_CALLS / 2
01095
01096
01097 static struct sockaddr_in debugaddr;
01098
01099 static void iax_outputframe(struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen)
01100 {
01101 if (iaxdebug ||
01102 (sin && debugaddr.sin_addr.s_addr &&
01103 (!ntohs(debugaddr.sin_port) ||
01104 debugaddr.sin_port == sin->sin_port) &&
01105 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) {
01106 if (iaxdebug) {
01107 iax_showframe(f, fhi, rx, sin, datalen);
01108 } else {
01109 iaxdebug = 1;
01110 iax_showframe(f, fhi, rx, sin, datalen);
01111 iaxdebug = 0;
01112 }
01113 }
01114 }
01115
01116 static void iax_debug_output(const char *data)
01117 {
01118 if (iaxdebug)
01119 ast_verbose("%s", data);
01120 }
01121
01122 static void iax_error_output(const char *data)
01123 {
01124 ast_log(LOG_WARNING, "%s", data);
01125 }
01126
01127 static void __attribute__((format(printf, 1, 2))) jb_error_output(const char *fmt, ...)
01128 {
01129 va_list args;
01130 char buf[1024];
01131
01132 va_start(args, fmt);
01133 vsnprintf(buf, sizeof(buf), fmt, args);
01134 va_end(args);
01135
01136 ast_log(LOG_ERROR, "%s", buf);
01137 }
01138
01139 static void __attribute__((format(printf, 1, 2))) jb_warning_output(const char *fmt, ...)
01140 {
01141 va_list args;
01142 char buf[1024];
01143
01144 va_start(args, fmt);
01145 vsnprintf(buf, sizeof(buf), fmt, args);
01146 va_end(args);
01147
01148 ast_log(LOG_WARNING, "%s", buf);
01149 }
01150
01151 static void __attribute__((format(printf, 1, 2))) jb_debug_output(const char *fmt, ...)
01152 {
01153 va_list args;
01154 char buf[1024];
01155
01156 va_start(args, fmt);
01157 vsnprintf(buf, sizeof(buf), fmt, args);
01158 va_end(args);
01159
01160 ast_verbose("%s", buf);
01161 }
01162
01163 static int maxtrunkcall = TRUNK_CALL_START;
01164 static int maxnontrunkcall = 1;
01165
01166 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
01167 static int expire_registry(const void *data);
01168 static int iax2_answer(struct ast_channel *c);
01169 static int iax2_call(struct ast_channel *c, char *dest, int timeout);
01170 static int iax2_devicestate(void *data);
01171 static int iax2_digit_begin(struct ast_channel *c, char digit);
01172 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration);
01173 static int iax2_do_register(struct iax2_registry *reg);
01174 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan);
01175 static int iax2_hangup(struct ast_channel *c);
01176 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
01177 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
01178 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force);
01179 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final);
01180 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen);
01181 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img);
01182 static int iax2_sendtext(struct ast_channel *c, const char *text);
01183 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen);
01184 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen);
01185 static int iax2_transfer(struct ast_channel *c, const char *dest);
01186 static int iax2_write(struct ast_channel *c, struct ast_frame *f);
01187 static int iax2_sched_add(struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data);
01188
01189 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now);
01190 static int send_command(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01191 static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01192 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
01193 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
01194 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
01195 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
01196 static struct ast_frame *iax2_read(struct ast_channel *c);
01197 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01198 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
01199 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime);
01200 static void *iax2_dup_variable_datastore(void *);
01201 static void prune_peers(void);
01202 static void prune_users(void);
01203 static void iax2_free_variable_datastore(void *);
01204
01205 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen);
01206 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen);
01207 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen);
01208 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt);
01209 static void build_rand_pad(unsigned char *buf, ssize_t len);
01210 static struct callno_entry *get_unused_callno(int trunk, int validated);
01211 static int replace_callno(const void *obj);
01212 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
01213 static void network_change_event_cb(const struct ast_event *, void *);
01214
01215 static const struct ast_channel_tech iax2_tech = {
01216 .type = "IAX2",
01217 .description = tdesc,
01218 .capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
01219 .properties = AST_CHAN_TP_WANTSJITTER,
01220 .requester = iax2_request,
01221 .devicestate = iax2_devicestate,
01222 .send_digit_begin = iax2_digit_begin,
01223 .send_digit_end = iax2_digit_end,
01224 .send_text = iax2_sendtext,
01225 .send_image = iax2_sendimage,
01226 .send_html = iax2_sendhtml,
01227 .call = iax2_call,
01228 .hangup = iax2_hangup,
01229 .answer = iax2_answer,
01230 .read = iax2_read,
01231 .write = iax2_write,
01232 .write_video = iax2_write,
01233 .indicate = iax2_indicate,
01234 .setoption = iax2_setoption,
01235 .queryoption = iax2_queryoption,
01236 .bridge = iax2_bridge,
01237 .transfer = iax2_transfer,
01238 .fixup = iax2_fixup,
01239 .func_channel_read = acf_channel_read,
01240 };
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259 static void iax2_lock_owner(int callno)
01260 {
01261 for (;;) {
01262 if (!iaxs[callno] || !iaxs[callno]->owner) {
01263
01264 break;
01265 }
01266 if (!ast_channel_trylock(iaxs[callno]->owner)) {
01267
01268 break;
01269 }
01270
01271 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
01272 }
01273 }
01274
01275 static void mwi_event_cb(const struct ast_event *event, void *userdata)
01276 {
01277
01278
01279
01280 }
01281
01282 static void network_change_event_subscribe(void)
01283 {
01284 if (!network_change_event_subscription) {
01285 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE,
01286 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END);
01287 }
01288 }
01289
01290 static void network_change_event_unsubscribe(void)
01291 {
01292 if (network_change_event_subscription) {
01293 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription);
01294 }
01295 }
01296
01297 static int network_change_event_sched_cb(const void *data)
01298 {
01299 struct iax2_registry *reg;
01300 network_change_event_sched_id = -1;
01301 AST_LIST_LOCK(®istrations);
01302 AST_LIST_TRAVERSE(®istrations, reg, entry) {
01303 iax2_do_register(reg);
01304 }
01305 AST_LIST_UNLOCK(®istrations);
01306
01307 return 0;
01308 }
01309
01310 static void network_change_event_cb(const struct ast_event *event, void *userdata)
01311 {
01312 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n");
01313 if (network_change_event_sched_id == -1) {
01314 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL);
01315 }
01316
01317 }
01318
01319
01320
01321
01322 static void iax2_ami_channelupdate(struct chan_iax2_pvt *pvt)
01323 {
01324 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
01325 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n",
01326 pvt->owner ? pvt->owner->name : "",
01327 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : "");
01328 }
01329
01330 static struct ast_datastore_info iax2_variable_datastore_info = {
01331 .type = "IAX2_VARIABLE",
01332 .duplicate = iax2_dup_variable_datastore,
01333 .destroy = iax2_free_variable_datastore,
01334 };
01335
01336 static void *iax2_dup_variable_datastore(void *old)
01337 {
01338 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist;
01339 struct ast_var_t *oldvar, *newvar;
01340
01341 newlist = ast_calloc(sizeof(*newlist), 1);
01342 if (!newlist) {
01343 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n");
01344 return NULL;
01345 }
01346
01347 AST_LIST_HEAD_INIT(newlist);
01348 AST_LIST_LOCK(oldlist);
01349 AST_LIST_TRAVERSE(oldlist, oldvar, entries) {
01350 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar));
01351 if (newvar)
01352 AST_LIST_INSERT_TAIL(newlist, newvar, entries);
01353 else
01354 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar));
01355 }
01356 AST_LIST_UNLOCK(oldlist);
01357 return newlist;
01358 }
01359
01360 static void iax2_free_variable_datastore(void *old)
01361 {
01362 AST_LIST_HEAD(, ast_var_t) *oldlist = old;
01363 struct ast_var_t *oldvar;
01364
01365 AST_LIST_LOCK(oldlist);
01366 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) {
01367 ast_free(oldvar);
01368 }
01369 AST_LIST_UNLOCK(oldlist);
01370 AST_LIST_HEAD_DESTROY(oldlist);
01371 ast_free(oldlist);
01372 }
01373
01374
01375
01376
01377
01378 static void insert_idle_thread(struct iax2_thread *thread)
01379 {
01380 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
01381 AST_LIST_LOCK(&dynamic_list);
01382 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list);
01383 AST_LIST_UNLOCK(&dynamic_list);
01384 } else {
01385 AST_LIST_LOCK(&idle_list);
01386 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
01387 AST_LIST_UNLOCK(&idle_list);
01388 }
01389
01390 return;
01391 }
01392
01393 static struct iax2_thread *find_idle_thread(void)
01394 {
01395 struct iax2_thread *thread = NULL;
01396
01397
01398 AST_LIST_LOCK(&idle_list);
01399 thread = AST_LIST_REMOVE_HEAD(&idle_list, list);
01400 AST_LIST_UNLOCK(&idle_list);
01401
01402
01403 if (thread) {
01404 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01405 return thread;
01406 }
01407
01408
01409 AST_LIST_LOCK(&dynamic_list);
01410 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list);
01411 AST_LIST_UNLOCK(&dynamic_list);
01412
01413
01414 if (thread) {
01415 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01416 return thread;
01417 }
01418
01419
01420 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread))))
01421 return NULL;
01422
01423
01424 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1);
01425 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1);
01426 thread->type = IAX_THREAD_TYPE_DYNAMIC;
01427
01428
01429 ast_mutex_init(&thread->lock);
01430 ast_cond_init(&thread->cond, NULL);
01431 ast_mutex_init(&thread->init_lock);
01432 ast_cond_init(&thread->init_cond, NULL);
01433 ast_mutex_lock(&thread->init_lock);
01434
01435
01436 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
01437 ast_cond_destroy(&thread->cond);
01438 ast_mutex_destroy(&thread->lock);
01439 ast_mutex_unlock(&thread->init_lock);
01440 ast_cond_destroy(&thread->init_cond);
01441 ast_mutex_destroy(&thread->init_lock);
01442 ast_free(thread);
01443 return NULL;
01444 }
01445
01446
01447
01448 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo));
01449
01450
01451 ast_cond_wait(&thread->init_cond, &thread->init_lock);
01452
01453
01454 ast_mutex_unlock(&thread->init_lock);
01455
01456 return thread;
01457 }
01458
01459 #ifdef SCHED_MULTITHREADED
01460 static int __schedule_action(void (*func)(const void *data), const void *data, const char *funcname)
01461 {
01462 struct iax2_thread *thread = NULL;
01463 static time_t lasterror;
01464 static time_t t;
01465
01466 thread = find_idle_thread();
01467
01468 if (thread != NULL) {
01469 thread->schedfunc = func;
01470 thread->scheddata = data;
01471 thread->iostate = IAX_IOSTATE_SCHEDREADY;
01472 #ifdef DEBUG_SCHED_MULTITHREAD
01473 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc));
01474 #endif
01475 signal_condition(&thread->lock, &thread->cond);
01476 return 0;
01477 }
01478 time(&t);
01479 if (t != lasterror)
01480 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n");
01481 lasterror = t;
01482
01483 return -1;
01484 }
01485 #define schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__)
01486 #endif
01487
01488 static int iax2_sched_replace(int id, struct ast_sched_thread *st, int when,
01489 ast_sched_cb callback, const void *data)
01490 {
01491 ast_sched_thread_del(st, id);
01492
01493 return ast_sched_thread_add(st, when, callback, data);
01494 }
01495
01496 static int iax2_sched_add(struct ast_sched_thread *st, int when,
01497 ast_sched_cb callback, const void *data)
01498 {
01499 return ast_sched_thread_add(st, when, callback, data);
01500 }
01501
01502 static int send_ping(const void *data);
01503
01504 static void __send_ping(const void *data)
01505 {
01506 int callno = (long) data;
01507
01508 ast_mutex_lock(&iaxsl[callno]);
01509
01510 if (iaxs[callno]) {
01511 if (iaxs[callno]->peercallno) {
01512 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1);
01513 if (iaxs[callno]->pingid != DONT_RESCHEDULE) {
01514 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data);
01515 }
01516 }
01517 } else {
01518 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno);
01519 }
01520
01521 ast_mutex_unlock(&iaxsl[callno]);
01522 }
01523
01524 static int send_ping(const void *data)
01525 {
01526 int callno = (long) data;
01527 ast_mutex_lock(&iaxsl[callno]);
01528 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) {
01529 iaxs[callno]->pingid = -1;
01530 }
01531 ast_mutex_unlock(&iaxsl[callno]);
01532
01533 #ifdef SCHED_MULTITHREADED
01534 if (schedule_action(__send_ping, data))
01535 #endif
01536 __send_ping(data);
01537
01538 return 0;
01539 }
01540
01541 static void encmethods_to_str(int e, struct ast_str *buf)
01542 {
01543 ast_str_set(&buf, 0, "(");
01544 if (e & IAX_ENCRYPT_AES128) {
01545 ast_str_append(&buf, 0, "aes128");
01546 }
01547 if (e & IAX_ENCRYPT_KEYROTATE) {
01548 ast_str_append(&buf, 0, ",keyrotate");
01549 }
01550 if (ast_str_strlen(buf) > 1) {
01551 ast_str_append(&buf, 0, ")");
01552 } else {
01553 ast_str_set(&buf, 0, "No");
01554 }
01555 }
01556
01557 static int get_encrypt_methods(const char *s)
01558 {
01559 int e;
01560 if (!strcasecmp(s, "aes128"))
01561 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01562 else if (ast_true(s))
01563 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE;
01564 else
01565 e = 0;
01566 return e;
01567 }
01568
01569 static int send_lagrq(const void *data);
01570
01571 static void __send_lagrq(const void *data)
01572 {
01573 int callno = (long) data;
01574
01575 ast_mutex_lock(&iaxsl[callno]);
01576
01577 if (iaxs[callno]) {
01578 if (iaxs[callno]->peercallno) {
01579 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1);
01580 if (iaxs[callno]->lagid != DONT_RESCHEDULE) {
01581 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data);
01582 }
01583 }
01584 } else {
01585 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno);
01586 }
01587
01588 ast_mutex_unlock(&iaxsl[callno]);
01589 }
01590
01591 static int send_lagrq(const void *data)
01592 {
01593 int callno = (long) data;
01594 ast_mutex_lock(&iaxsl[callno]);
01595 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) {
01596 iaxs[callno]->lagid = -1;
01597 }
01598 ast_mutex_unlock(&iaxsl[callno]);
01599
01600 #ifdef SCHED_MULTITHREADED
01601 if (schedule_action(__send_lagrq, data))
01602 #endif
01603 __send_lagrq(data);
01604 return 0;
01605 }
01606
01607 static unsigned char compress_subclass(format_t subclass)
01608 {
01609 int x;
01610 int power=-1;
01611
01612 if (subclass < IAX_FLAG_SC_LOG)
01613 return subclass;
01614
01615 for (x = 0; x < IAX_MAX_SHIFT; x++) {
01616 if (subclass & (1LL << x)) {
01617 if (power > -1) {
01618 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass);
01619 return 0;
01620 } else
01621 power = x;
01622 }
01623 }
01624 return power | IAX_FLAG_SC_LOG;
01625 }
01626
01627 static format_t uncompress_subclass(unsigned char csub)
01628 {
01629
01630 if (csub & IAX_FLAG_SC_LOG) {
01631
01632 if (csub == 0xff)
01633 return -1;
01634 else
01635 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT);
01636 }
01637 else
01638 return csub;
01639 }
01640
01641
01642
01643
01644 static int peer_hash_cb(const void *obj, const int flags)
01645 {
01646 const struct iax2_peer *peer = obj;
01647
01648 return ast_str_hash(peer->name);
01649 }
01650
01651
01652
01653
01654 static int peer_cmp_cb(void *obj, void *arg, int flags)
01655 {
01656 struct iax2_peer *peer = obj, *peer2 = arg;
01657
01658 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01659 }
01660
01661
01662
01663
01664 static int user_hash_cb(const void *obj, const int flags)
01665 {
01666 const struct iax2_user *user = obj;
01667
01668 return ast_str_hash(user->name);
01669 }
01670
01671
01672
01673
01674 static int user_cmp_cb(void *obj, void *arg, int flags)
01675 {
01676 struct iax2_user *user = obj, *user2 = arg;
01677
01678 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0;
01679 }
01680
01681
01682
01683
01684
01685 static struct iax2_peer *find_peer(const char *name, int realtime)
01686 {
01687 struct iax2_peer *peer = NULL;
01688 struct iax2_peer tmp_peer = {
01689 .name = name,
01690 };
01691
01692 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
01693
01694
01695 if(!peer && realtime)
01696 peer = realtime_peer(name, NULL);
01697
01698 return peer;
01699 }
01700
01701 static struct iax2_peer *peer_ref(struct iax2_peer *peer)
01702 {
01703 ao2_ref(peer, +1);
01704 return peer;
01705 }
01706
01707 static inline struct iax2_peer *peer_unref(struct iax2_peer *peer)
01708 {
01709 ao2_ref(peer, -1);
01710 return NULL;
01711 }
01712
01713 static struct iax2_user *find_user(const char *name)
01714 {
01715 struct iax2_user tmp_user = {
01716 .name = name,
01717 };
01718
01719 return ao2_find(users, &tmp_user, OBJ_POINTER);
01720 }
01721 static inline struct iax2_user *user_ref(struct iax2_user *user)
01722 {
01723 ao2_ref(user, +1);
01724 return user;
01725 }
01726
01727 static inline struct iax2_user *user_unref(struct iax2_user *user)
01728 {
01729 ao2_ref(user, -1);
01730 return NULL;
01731 }
01732
01733 static int iax2_getpeername(struct sockaddr_in sin, char *host, int len)
01734 {
01735 struct iax2_peer *peer = NULL;
01736 int res = 0;
01737 struct ao2_iterator i;
01738
01739 i = ao2_iterator_init(peers, 0);
01740 while ((peer = ao2_iterator_next(&i))) {
01741 struct sockaddr_in peer_addr;
01742
01743 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
01744
01745 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
01746 (peer_addr.sin_port == sin.sin_port)) {
01747 ast_copy_string(host, peer->name, len);
01748 peer_unref(peer);
01749 res = 1;
01750 break;
01751 }
01752 peer_unref(peer);
01753 }
01754 ao2_iterator_destroy(&i);
01755
01756 if (!peer) {
01757 peer = realtime_peer(NULL, &sin);
01758 if (peer) {
01759 ast_copy_string(host, peer->name, len);
01760 peer_unref(peer);
01761 res = 1;
01762 }
01763 }
01764
01765 return res;
01766 }
01767
01768
01769
01770 static void iax2_destroy_helper(struct chan_iax2_pvt *pvt)
01771 {
01772
01773 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) {
01774 struct iax2_user *user;
01775 struct iax2_user tmp_user = {
01776 .name = pvt->username,
01777 };
01778
01779 user = ao2_find(users, &tmp_user, OBJ_POINTER);
01780 if (user) {
01781 ast_atomic_fetchadd_int(&user->curauthreq, -1);
01782 user_unref(user);
01783 }
01784
01785 ast_clear_flag64(pvt, IAX_MAXAUTHREQ);
01786 }
01787
01788 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]);
01789 pvt->pingid = DONT_RESCHEDULE;
01790 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]);
01791 pvt->lagid = DONT_RESCHEDULE;
01792 ast_sched_thread_del(sched, pvt->autoid);
01793 ast_sched_thread_del(sched, pvt->authid);
01794 ast_sched_thread_del(sched, pvt->initid);
01795 ast_sched_thread_del(sched, pvt->jbid);
01796 ast_sched_thread_del(sched, pvt->keyrotateid);
01797 }
01798
01799 static void iax2_frame_free(struct iax_frame *fr)
01800 {
01801 ast_sched_thread_del(sched, fr->retrans);
01802 iax_frame_free(fr);
01803 }
01804
01805 static int scheduled_destroy(const void *vid)
01806 {
01807 unsigned short callno = PTR_TO_CALLNO(vid);
01808 ast_mutex_lock(&iaxsl[callno]);
01809 if (iaxs[callno]) {
01810 if (option_debug) {
01811 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno);
01812 }
01813 iax2_destroy(callno);
01814 }
01815 ast_mutex_unlock(&iaxsl[callno]);
01816 return 0;
01817 }
01818
01819 static void free_signaling_queue_entry(struct signaling_queue_entry *s)
01820 {
01821 if (s->f.datalen) {
01822 ast_free(s->f.data.ptr);
01823 }
01824 ast_free(s);
01825 }
01826
01827
01828
01829 static void send_signaling(struct chan_iax2_pvt *pvt)
01830 {
01831 struct signaling_queue_entry *s = NULL;
01832
01833 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01834 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0);
01835 free_signaling_queue_entry(s);
01836 }
01837 pvt->hold_signaling = 0;
01838 }
01839
01840
01841
01842 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
01843 {
01844 struct signaling_queue_entry *new;
01845
01846 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
01847 return 1;
01848 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
01849 return -1;
01850 }
01851
01852 memcpy(&new->f, f, sizeof(new->f));
01853
01854 if (new->f.datalen) {
01855 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
01856 free_signaling_queue_entry(new);
01857 return -1;
01858 }
01859 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
01860 }
01861 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
01862
01863 return 0;
01864 }
01865
01866 static void pvt_destructor(void *obj)
01867 {
01868 struct chan_iax2_pvt *pvt = obj;
01869 struct iax_frame *cur = NULL;
01870 struct signaling_queue_entry *s = NULL;
01871
01872 ast_mutex_lock(&iaxsl[pvt->callno]);
01873
01874 iax2_destroy_helper(pvt);
01875
01876 sched_delay_remove(&pvt->addr, pvt->callno_entry);
01877 pvt->callno_entry = NULL;
01878
01879
01880 ast_set_flag64(pvt, IAX_ALREADYGONE);
01881
01882 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) {
01883
01884 cur->retries = -1;
01885 }
01886
01887 ast_mutex_unlock(&iaxsl[pvt->callno]);
01888
01889 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) {
01890 free_signaling_queue_entry(s);
01891 }
01892
01893 if (pvt->reg) {
01894 pvt->reg->callno = 0;
01895 }
01896
01897 if (!pvt->owner) {
01898 jb_frame frame;
01899 if (pvt->vars) {
01900 ast_variables_destroy(pvt->vars);
01901 pvt->vars = NULL;
01902 }
01903
01904 while (jb_getall(pvt->jb, &frame) == JB_OK) {
01905 iax2_frame_free(frame.data);
01906 }
01907
01908 jb_destroy(pvt->jb);
01909 ast_string_field_free_memory(pvt);
01910 }
01911 }
01912
01913 static struct chan_iax2_pvt *new_iax(struct sockaddr_in *sin, const char *host)
01914 {
01915 struct chan_iax2_pvt *tmp;
01916 jb_conf jbconf;
01917
01918 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) {
01919 return NULL;
01920 }
01921
01922 if (ast_string_field_init(tmp, 32)) {
01923 ao2_ref(tmp, -1);
01924 tmp = NULL;
01925 return NULL;
01926 }
01927
01928 tmp->prefs = prefs;
01929 tmp->pingid = -1;
01930 tmp->lagid = -1;
01931 tmp->autoid = -1;
01932 tmp->authid = -1;
01933 tmp->initid = -1;
01934 tmp->keyrotateid = -1;
01935
01936 ast_string_field_set(tmp,exten, "s");
01937 ast_string_field_set(tmp,host, host);
01938
01939 tmp->jb = jb_new();
01940 tmp->jbid = -1;
01941 jbconf.max_jitterbuf = maxjitterbuffer;
01942 jbconf.resync_threshold = resyncthreshold;
01943 jbconf.max_contig_interp = maxjitterinterps;
01944 jbconf.target_extra = jittertargetextra;
01945 jb_setconf(tmp->jb,&jbconf);
01946
01947 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries);
01948
01949 tmp->hold_signaling = 1;
01950 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue);
01951
01952 return tmp;
01953 }
01954
01955 static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
01956 {
01957 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
01958 if (new) {
01959 size_t afdatalen = new->afdatalen;
01960 memcpy(new, fr, sizeof(*new));
01961 iax_frame_wrap(new, &fr->af);
01962 new->afdatalen = afdatalen;
01963 new->data = NULL;
01964 new->datalen = 0;
01965 new->direction = DIRECTION_INGRESS;
01966 new->retrans = -1;
01967 }
01968 return new;
01969 }
01970
01971
01972 enum {
01973
01974 NEW_PREVENT = 0,
01975
01976 NEW_ALLOW = 1,
01977
01978 NEW_FORCE = 2,
01979
01980
01981 NEW_ALLOW_CALLTOKEN_VALIDATED = 3,
01982 };
01983
01984 static int match(struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno)
01985 {
01986 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01987 (cur->addr.sin_port == sin->sin_port)) {
01988
01989 if ( (cur->peercallno == 0 || cur->peercallno == callno) &&
01990 (check_dcallno ? dcallno == cur->callno : 1) ) {
01991
01992 return 1;
01993 }
01994 }
01995 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) &&
01996 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) {
01997
01998 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno))
01999 return 1;
02000 }
02001 return 0;
02002 }
02003
02004 static void update_max_trunk(void)
02005 {
02006 int max = TRUNK_CALL_START;
02007 int x;
02008
02009
02010 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) {
02011 if (iaxs[x]) {
02012 max = x + 1;
02013 }
02014 }
02015
02016 maxtrunkcall = max;
02017 if (iaxdebug)
02018 ast_debug(1, "New max trunk callno is %d\n", max);
02019 }
02020
02021 static void update_max_nontrunk(void)
02022 {
02023 int max = 1;
02024 int x;
02025
02026 for (x=1;x<TRUNK_CALL_START - 1; x++) {
02027 if (iaxs[x])
02028 max = x + 1;
02029 }
02030 maxnontrunkcall = max;
02031 if (iaxdebug)
02032 ast_debug(1, "New max nontrunk callno is %d\n", max);
02033 }
02034
02035 static int make_trunk(unsigned short callno, int locked)
02036 {
02037 int x;
02038 int res= 0;
02039 struct callno_entry *callno_entry;
02040 if (iaxs[callno]->oseqno) {
02041 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n");
02042 return -1;
02043 }
02044 if (callno & TRUNK_CALL_START) {
02045 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno);
02046 return -1;
02047 }
02048
02049 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) {
02050 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n");
02051 return -1;
02052 }
02053
02054 x = callno_entry->callno;
02055 ast_mutex_lock(&iaxsl[x]);
02056
02057
02058
02059
02060
02061 ast_sched_thread_del(sched, iaxs[callno]->pingid);
02062 ast_sched_thread_del(sched, iaxs[callno]->lagid);
02063 iaxs[callno]->lagid = iaxs[callno]->pingid = -1;
02064 iaxs[x] = iaxs[callno];
02065 iaxs[x]->callno = x;
02066
02067
02068
02069 if (iaxs[x]->callno_entry) {
02070 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry);
02071 }
02072 iaxs[x]->callno_entry = callno_entry;
02073
02074 iaxs[callno] = NULL;
02075
02076 iaxs[x]->pingid = iax2_sched_add(sched,
02077 ping_time * 1000, send_ping, (void *)(long)x);
02078 iaxs[x]->lagid = iax2_sched_add(sched,
02079 lagrq_time * 1000, send_lagrq, (void *)(long)x);
02080
02081 if (locked)
02082 ast_mutex_unlock(&iaxsl[callno]);
02083 res = x;
02084 if (!locked)
02085 ast_mutex_unlock(&iaxsl[x]);
02086
02087 ast_debug(1, "Made call %d into trunk call %d\n", callno, x);
02088
02089 update_max_trunk();
02090 update_max_nontrunk();
02091 return res;
02092 }
02093
02094 static void store_by_transfercallno(struct chan_iax2_pvt *pvt)
02095 {
02096 if (!pvt->transfercallno) {
02097 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02098 return;
02099 }
02100
02101 ao2_link(iax_transfercallno_pvts, pvt);
02102 }
02103
02104 static void remove_by_transfercallno(struct chan_iax2_pvt *pvt)
02105 {
02106 if (!pvt->transfercallno) {
02107 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n");
02108 return;
02109 }
02110
02111 ao2_unlink(iax_transfercallno_pvts, pvt);
02112 }
02113 static void store_by_peercallno(struct chan_iax2_pvt *pvt)
02114 {
02115 if (!pvt->peercallno) {
02116 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02117 return;
02118 }
02119
02120 ao2_link(iax_peercallno_pvts, pvt);
02121 }
02122
02123 static void remove_by_peercallno(struct chan_iax2_pvt *pvt)
02124 {
02125 if (!pvt->peercallno) {
02126 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n");
02127 return;
02128 }
02129
02130 ao2_unlink(iax_peercallno_pvts, pvt);
02131 }
02132
02133 static int addr_range_delme_cb(void *obj, void *arg, int flags)
02134 {
02135 struct addr_range *lim = obj;
02136 lim->delme = 1;
02137 return 0;
02138 }
02139
02140 static int addr_range_hash_cb(const void *obj, const int flags)
02141 {
02142 const struct addr_range *lim = obj;
02143 struct sockaddr_in sin;
02144 ast_sockaddr_to_sin(&lim->ha.addr, &sin);
02145 return abs((int) sin.sin_addr.s_addr);
02146 }
02147
02148 static int addr_range_cmp_cb(void *obj, void *arg, int flags)
02149 {
02150 struct addr_range *lim1 = obj, *lim2 = arg;
02151 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) &&
02152 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ?
02153 CMP_MATCH | CMP_STOP : 0;
02154 }
02155
02156 static int peercnt_hash_cb(const void *obj, const int flags)
02157 {
02158 const struct peercnt *peercnt = obj;
02159 return abs((int) peercnt->addr);
02160 }
02161
02162 static int peercnt_cmp_cb(void *obj, void *arg, int flags)
02163 {
02164 struct peercnt *peercnt1 = obj, *peercnt2 = arg;
02165 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0;
02166 }
02167
02168 static int addr_range_match_address_cb(void *obj, void *arg, int flags)
02169 {
02170 struct addr_range *addr_range = obj;
02171 struct sockaddr_in *sin = arg;
02172 struct sockaddr_in ha_netmask_sin;
02173 struct sockaddr_in ha_addr_sin;
02174
02175 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin);
02176 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin);
02177
02178 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) {
02179 return CMP_MATCH | CMP_STOP;
02180 }
02181 return 0;
02182 }
02183
02184
02185
02186
02187
02188
02189 static int calltoken_required(struct sockaddr_in *sin, const char *name, int subclass)
02190 {
02191 struct addr_range *addr_range;
02192 struct iax2_peer *peer = NULL;
02193 struct iax2_user *user = NULL;
02194
02195 const char *find = S_OR(name, "guest");
02196 int res = 1;
02197 int optional = 0;
02198 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT;
02199
02200
02201
02202
02203
02204
02205
02206 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) {
02207 ao2_ref(addr_range, -1);
02208 optional = 1;
02209 }
02210
02211
02212 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) {
02213 calltoken_required = user->calltoken_required;
02214 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) {
02215 calltoken_required = user->calltoken_required;
02216 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) {
02217 calltoken_required = peer->calltoken_required;
02218 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) {
02219 calltoken_required = peer->calltoken_required;
02220 }
02221
02222 if (peer) {
02223 peer_unref(peer);
02224 }
02225 if (user) {
02226 user_unref(user);
02227 }
02228
02229 ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required);
02230 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) ||
02231 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) {
02232 res = 0;
02233 }
02234
02235 return res;
02236 }
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 static void set_peercnt_limit(struct peercnt *peercnt)
02249 {
02250 uint16_t limit = global_maxcallno;
02251 struct addr_range *addr_range;
02252 struct sockaddr_in sin = {
02253 .sin_addr.s_addr = peercnt->addr,
02254 };
02255
02256
02257 if (peercnt->reg && peercnt->limit) {
02258 return;
02259 }
02260
02261 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) {
02262 limit = addr_range->limit;
02263 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr));
02264 ao2_ref(addr_range, -1);
02265 }
02266
02267 peercnt->limit = limit;
02268 }
02269
02270
02271
02272
02273
02274 static int set_peercnt_limit_all_cb(void *obj, void *arg, int flags)
02275 {
02276 struct peercnt *peercnt = obj;
02277
02278 set_peercnt_limit(peercnt);
02279 ast_debug(1, "Reset limits for peercnts table\n");
02280
02281 return 0;
02282 }
02283
02284
02285
02286
02287
02288 static int prune_addr_range_cb(void *obj, void *arg, int flags)
02289 {
02290 struct addr_range *addr_range = obj;
02291
02292 return addr_range->delme ? CMP_MATCH : 0;
02293 }
02294
02295
02296
02297
02298
02299 static void peercnt_modify(unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr)
02300 {
02301
02302 struct peercnt *peercnt;
02303 struct peercnt tmp = {
02304 .addr = 0,
02305 };
02306 struct sockaddr_in sin;
02307
02308 ast_sockaddr_to_sin(sockaddr, &sin);
02309
02310 tmp.addr = sin.sin_addr.s_addr;
02311
02312 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02313 peercnt->reg = reg;
02314 if (limit) {
02315 peercnt->limit = limit;
02316 } else {
02317 set_peercnt_limit(peercnt);
02318 }
02319 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg);
02320 ao2_ref(peercnt, -1);
02321 }
02322 }
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332 static int peercnt_add(struct sockaddr_in *sin)
02333 {
02334 struct peercnt *peercnt;
02335 unsigned long addr = sin->sin_addr.s_addr;
02336 int res = 0;
02337 struct peercnt tmp = {
02338 .addr = addr,
02339 };
02340
02341
02342
02343
02344
02345
02346
02347 ao2_lock(peercnts);
02348 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02349 ao2_lock(peercnt);
02350 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) {
02351 ao2_lock(peercnt);
02352
02353 peercnt->addr = addr;
02354 set_peercnt_limit(peercnt);
02355
02356
02357 ao2_link(peercnts, peercnt);
02358 } else {
02359 ao2_unlock(peercnts);
02360 return -1;
02361 }
02362
02363
02364 if (peercnt->limit > peercnt->cur) {
02365 peercnt->cur++;
02366 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr));
02367 } else {
02368 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr));
02369 res = -1;
02370 }
02371
02372
02373 ao2_unlock(peercnt);
02374 ao2_unlock(peercnts);
02375 ao2_ref(peercnt, -1);
02376
02377 return res;
02378 }
02379
02380
02381
02382
02383
02384 static void peercnt_remove(struct peercnt *peercnt)
02385 {
02386 struct sockaddr_in sin = {
02387 .sin_addr.s_addr = peercnt->addr,
02388 };
02389
02390 if (peercnt) {
02391
02392
02393
02394 ao2_lock(peercnts);
02395 peercnt->cur--;
02396 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr));
02397
02398 if (peercnt->cur == 0) {
02399 ao2_unlink(peercnts, peercnt);
02400 }
02401 ao2_unlock(peercnts);
02402 }
02403 }
02404
02405
02406
02407
02408
02409 static int peercnt_remove_cb(const void *obj)
02410 {
02411 struct peercnt *peercnt = (struct peercnt *) obj;
02412
02413 peercnt_remove(peercnt);
02414 ao2_ref(peercnt, -1);
02415
02416 return 0;
02417 }
02418
02419
02420
02421
02422
02423 static int peercnt_remove_by_addr(struct sockaddr_in *sin)
02424 {
02425 struct peercnt *peercnt;
02426 struct peercnt tmp = {
02427 .addr = sin->sin_addr.s_addr,
02428 };
02429
02430 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02431 peercnt_remove(peercnt);
02432 ao2_ref(peercnt, -1);
02433 }
02434 return 0;
02435 }
02436
02437
02438
02439
02440
02441 static void build_callno_limits(struct ast_variable *v)
02442 {
02443 struct addr_range *addr_range = NULL;
02444 struct addr_range tmp;
02445 struct ast_ha *ha;
02446 int limit;
02447 int error;
02448 int found;
02449
02450 for (; v; v = v->next) {
02451 limit = -1;
02452 error = 0;
02453 found = 0;
02454 ha = ast_append_ha("permit", v->name, NULL, &error);
02455
02456
02457 if (error) {
02458 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name);
02459 continue;
02460 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) {
02461 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value);
02462 ast_free_ha(ha);
02463 continue;
02464 }
02465
02466 ast_copy_ha(ha, &tmp.ha);
02467
02468 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) {
02469 ao2_lock(addr_range);
02470 found = 1;
02471 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02472 ast_free_ha(ha);
02473 return;
02474 }
02475
02476
02477 ast_copy_ha(ha, &addr_range->ha);
02478 ast_free_ha(ha);
02479 addr_range->limit = limit;
02480 addr_range->delme = 0;
02481
02482
02483 if (found) {
02484 ao2_unlock(addr_range);
02485 } else {
02486 ao2_link(callno_limits, addr_range);
02487 }
02488 ao2_ref(addr_range, -1);
02489 }
02490 }
02491
02492
02493
02494
02495
02496 static int add_calltoken_ignore(const char *addr)
02497 {
02498 struct addr_range tmp;
02499 struct addr_range *addr_range = NULL;
02500 struct ast_ha *ha = NULL;
02501 int error = 0;
02502
02503 if (ast_strlen_zero(addr)) {
02504 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr);
02505 return -1;
02506 }
02507
02508 ha = ast_append_ha("permit", addr, NULL, &error);
02509
02510
02511 if (error) {
02512 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr);
02513 return -1;
02514 }
02515
02516 ast_copy_ha(ha, &tmp.ha);
02517
02518 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) {
02519 ao2_lock(addr_range);
02520 addr_range->delme = 0;
02521 ao2_unlock(addr_range);
02522 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) {
02523
02524 ast_copy_ha(ha, &addr_range->ha);
02525 ao2_link(calltoken_ignores, addr_range);
02526 } else {
02527 ast_free_ha(ha);
02528 return -1;
02529 }
02530
02531 ast_free_ha(ha);
02532 ao2_ref(addr_range, -1);
02533
02534 return 0;
02535 }
02536
02537 static char *handle_cli_iax2_show_callno_limits(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
02538 {
02539 struct ao2_iterator i;
02540 struct peercnt *peercnt;
02541 struct sockaddr_in sin;
02542 int found = 0;
02543
02544 switch (cmd) {
02545 case CLI_INIT:
02546 e->command = "iax2 show callnumber usage";
02547 e->usage =
02548 "Usage: iax2 show callnumber usage [IP address]\n"
02549 " Shows current IP addresses which are consuming iax2 call numbers\n";
02550 return NULL;
02551 case CLI_GENERATE:
02552 return NULL;
02553 case CLI_HANDLER:
02554 if (a->argc < 4 || a->argc > 5)
02555 return CLI_SHOWUSAGE;
02556
02557 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit");
02558 i = ao2_iterator_init(peercnts, 0);
02559 while ((peercnt = ao2_iterator_next(&i))) {
02560 sin.sin_addr.s_addr = peercnt->addr;
02561 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) {
02562 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02563 found = 1;
02564 break;
02565 } else {
02566 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit);
02567 }
02568 ao2_ref(peercnt, -1);
02569 }
02570 ao2_iterator_destroy(&i);
02571
02572 if (a->argc == 4) {
02573 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n"
02574 "Non-CallToken Validated Callno Used: %d\n",
02575 global_maxcallno_nonval,
02576 total_nonval_callno_used);
02577
02578 ast_cli(a->fd, "Total Available Callno: %d\n"
02579 "Regular Callno Available: %d\n"
02580 "Trunk Callno Available: %d\n",
02581 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk),
02582 ao2_container_count(callno_pool),
02583 ao2_container_count(callno_pool_trunk));
02584 } else if (a->argc == 5 && !found) {
02585 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] );
02586 }
02587
02588
02589 return CLI_SUCCESS;
02590 default:
02591 return NULL;
02592 }
02593 }
02594
02595 static struct callno_entry *get_unused_callno(int trunk, int validated)
02596 {
02597 struct callno_entry *callno_entry = NULL;
02598 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) {
02599 ast_log(LOG_WARNING, "Out of CallNumbers\n");
02600
02601 return NULL;
02602 }
02603
02604
02605
02606 ao2_lock(callno_pool);
02607
02608
02609
02610
02611 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) {
02612 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval);
02613 ao2_unlock(callno_pool);
02614 return NULL;
02615 }
02616
02617
02618
02619 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE);
02620
02621 if (callno_entry) {
02622 callno_entry->validated = validated;
02623 if (!validated) {
02624 total_nonval_callno_used++;
02625 }
02626 }
02627
02628 ao2_unlock(callno_pool);
02629 return callno_entry;
02630 }
02631
02632 static int replace_callno(const void *obj)
02633 {
02634 struct callno_entry *callno_entry = (struct callno_entry *) obj;
02635
02636
02637
02638 ao2_lock(callno_pool);
02639
02640 if (!callno_entry->validated && (total_nonval_callno_used != 0)) {
02641 total_nonval_callno_used--;
02642 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) {
02643 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno);
02644 }
02645
02646 if (callno_entry->callno < TRUNK_CALL_START) {
02647 ao2_link(callno_pool, callno_entry);
02648 } else {
02649 ao2_link(callno_pool_trunk, callno_entry);
02650 }
02651 ao2_ref(callno_entry, -1);
02652
02653 ao2_unlock(callno_pool);
02654 return 0;
02655 }
02656
02657 static int callno_hash(const void *obj, const int flags)
02658 {
02659 return abs(ast_random());
02660 }
02661
02662 static int create_callno_pools(void)
02663 {
02664 uint16_t i;
02665
02666 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02667 return -1;
02668 }
02669
02670 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) {
02671 return -1;
02672 }
02673
02674
02675 for (i = 2; i <= IAX_MAX_CALLS; i++) {
02676 struct callno_entry *callno_entry;
02677
02678 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) {
02679 return -1;
02680 }
02681
02682 callno_entry->callno = i;
02683
02684 if (i < TRUNK_CALL_START) {
02685 ao2_link(callno_pool, callno_entry);
02686 } else {
02687 ao2_link(callno_pool_trunk, callno_entry);
02688 }
02689
02690 ao2_ref(callno_entry, -1);
02691 }
02692
02693 return 0;
02694 }
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry)
02705 {
02706 int i;
02707 struct peercnt *peercnt;
02708 struct peercnt tmp = {
02709 .addr = sin->sin_addr.s_addr,
02710 };
02711
02712 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) {
02713
02714 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME);
02715 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt);
02716 if (i == -1) {
02717 ao2_ref(peercnt, -1);
02718 }
02719 }
02720
02721 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry);
02722 }
02723
02724
02725
02726
02727
02728
02729
02730
02731 static inline int attribute_pure iax2_allow_new(int frametype, int subclass, int inbound)
02732 {
02733 if (frametype != AST_FRAME_IAX) {
02734 return 0;
02735 }
02736 switch (subclass) {
02737 case IAX_COMMAND_NEW:
02738 case IAX_COMMAND_REGREQ:
02739 case IAX_COMMAND_FWDOWNL:
02740 case IAX_COMMAND_REGREL:
02741 return 1;
02742 case IAX_COMMAND_POKE:
02743 if (!inbound) {
02744 return 1;
02745 }
02746 break;
02747 }
02748 return 0;
02749 }
02750
02751
02752
02753
02754 static int __find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno)
02755 {
02756 int res = 0;
02757 int x;
02758
02759
02760 int validated = (new > NEW_ALLOW) ? 1 : 0;
02761 char host[80];
02762
02763 if (new <= NEW_ALLOW) {
02764 if (callno) {
02765 struct chan_iax2_pvt *pvt;
02766 struct chan_iax2_pvt tmp_pvt = {
02767 .callno = dcallno,
02768 .peercallno = callno,
02769 .transfercallno = callno,
02770
02771 .frames_received = check_dcallno,
02772 };
02773
02774 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr));
02775
02776 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02777 if (return_locked) {
02778 ast_mutex_lock(&iaxsl[pvt->callno]);
02779 }
02780 res = pvt->callno;
02781 ao2_ref(pvt, -1);
02782 pvt = NULL;
02783 return res;
02784 }
02785
02786 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr));
02787 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer));
02788 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) {
02789 if (return_locked) {
02790 ast_mutex_lock(&iaxsl[pvt->callno]);
02791 }
02792 res = pvt->callno;
02793 ao2_ref(pvt, -1);
02794 pvt = NULL;
02795 return res;
02796 }
02797 }
02798
02799
02800 if (dcallno) {
02801 ast_mutex_lock(&iaxsl[dcallno]);
02802 }
02803 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) {
02804 iaxs[dcallno]->peercallno = callno;
02805 res = dcallno;
02806 store_by_peercallno(iaxs[dcallno]);
02807 if (!res || !return_locked) {
02808 ast_mutex_unlock(&iaxsl[dcallno]);
02809 }
02810 return res;
02811 }
02812 if (dcallno) {
02813 ast_mutex_unlock(&iaxsl[dcallno]);
02814 }
02815 #ifdef IAX_OLD_FIND
02816
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827 for (x = 1; !res && x < maxnontrunkcall; x++) {
02828 ast_mutex_lock(&iaxsl[x]);
02829 if (iaxs[x]) {
02830
02831 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02832 res = x;
02833 }
02834 }
02835 if (!res || !return_locked)
02836 ast_mutex_unlock(&iaxsl[x]);
02837 }
02838 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) {
02839 ast_mutex_lock(&iaxsl[x]);
02840 if (iaxs[x]) {
02841
02842 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) {
02843 res = x;
02844 }
02845 }
02846 if (!res || !return_locked)
02847 ast_mutex_unlock(&iaxsl[x]);
02848 }
02849 #endif
02850 }
02851 if (!res && (new >= NEW_ALLOW)) {
02852 struct callno_entry *callno_entry;
02853
02854
02855
02856
02857
02858
02859 if (!iax2_getpeername(*sin, host, sizeof(host)))
02860 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
02861
02862 if (peercnt_add(sin)) {
02863
02864
02865 return 0;
02866 }
02867
02868 if (!(callno_entry = get_unused_callno(0, validated))) {
02869
02870
02871 peercnt_remove_by_addr(sin);
02872 ast_log(LOG_WARNING, "No more space\n");
02873 return 0;
02874 }
02875 x = callno_entry->callno;
02876 ast_mutex_lock(&iaxsl[x]);
02877
02878 iaxs[x] = new_iax(sin, host);
02879 update_max_nontrunk();
02880 if (iaxs[x]) {
02881 if (iaxdebug)
02882 ast_debug(1, "Creating new call structure %d\n", x);
02883 iaxs[x]->callno_entry = callno_entry;
02884 iaxs[x]->sockfd = sockfd;
02885 iaxs[x]->addr.sin_port = sin->sin_port;
02886 iaxs[x]->addr.sin_family = sin->sin_family;
02887 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr;
02888 iaxs[x]->peercallno = callno;
02889 iaxs[x]->callno = x;
02890 iaxs[x]->pingtime = DEFAULT_RETRY_TIME;
02891 iaxs[x]->expiry = min_reg_expire;
02892 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x);
02893 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x);
02894 iaxs[x]->amaflags = amaflags;
02895 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
02896 ast_string_field_set(iaxs[x], accountcode, accountcode);
02897 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret);
02898 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest);
02899 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot);
02900
02901 if (iaxs[x]->peercallno) {
02902 store_by_peercallno(iaxs[x]);
02903 }
02904 } else {
02905 ast_log(LOG_WARNING, "Out of resources\n");
02906 ast_mutex_unlock(&iaxsl[x]);
02907 replace_callno(callno_entry);
02908 return 0;
02909 }
02910 if (!return_locked)
02911 ast_mutex_unlock(&iaxsl[x]);
02912 res = x;
02913 }
02914 return res;
02915 }
02916
02917 static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02918 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame);
02919 }
02920
02921 static int find_callno_locked(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) {
02922
02923 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame);
02924 }
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936 static int iax2_queue_frame(int callno, struct ast_frame *f)
02937 {
02938 iax2_lock_owner(callno);
02939 if (iaxs[callno] && iaxs[callno]->owner) {
02940 ast_queue_frame(iaxs[callno]->owner, f);
02941 ast_channel_unlock(iaxs[callno]->owner);
02942 }
02943 return 0;
02944 }
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959 static int iax2_queue_hangup(int callno)
02960 {
02961 iax2_lock_owner(callno);
02962 if (iaxs[callno] && iaxs[callno]->owner) {
02963 ast_queue_hangup(iaxs[callno]->owner);
02964 ast_channel_unlock(iaxs[callno]->owner);
02965 }
02966 return 0;
02967 }
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982 static int iax2_queue_control_data(int callno,
02983 enum ast_control_frame_type control, const void *data, size_t datalen)
02984 {
02985 iax2_lock_owner(callno);
02986 if (iaxs[callno] && iaxs[callno]->owner) {
02987 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen);
02988 ast_channel_unlock(iaxs[callno]->owner);
02989 }
02990 return 0;
02991 }
02992 static void destroy_firmware(struct iax_firmware *cur)
02993 {
02994
02995 if (cur->fwh) {
02996 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh)));
02997 }
02998 close(cur->fd);
02999 ast_free(cur);
03000 }
03001
03002 static int try_firmware(char *s)
03003 {
03004 struct stat stbuf;
03005 struct iax_firmware *cur = NULL;
03006 int ifd, fd, res, len, chunk;
03007 struct ast_iax2_firmware_header *fwh, fwh2;
03008 struct MD5Context md5;
03009 unsigned char sum[16], buf[1024];
03010 char *s2, *last;
03011
03012 if (!(s2 = alloca(strlen(s) + 100))) {
03013 ast_log(LOG_WARNING, "Alloca failed!\n");
03014 return -1;
03015 }
03016
03017 last = strrchr(s, '/');
03018 if (last)
03019 last++;
03020 else
03021 last = s;
03022
03023 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random());
03024
03025 if ((res = stat(s, &stbuf) < 0)) {
03026 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno));
03027 return -1;
03028 }
03029
03030
03031 if (S_ISDIR(stbuf.st_mode))
03032 return -1;
03033 ifd = open(s, O_RDONLY);
03034 if (ifd < 0) {
03035 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno));
03036 return -1;
03037 }
03038 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE);
03039 if (fd < 0) {
03040 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno));
03041 close(ifd);
03042 return -1;
03043 }
03044
03045 unlink(s2);
03046
03047
03048 len = stbuf.st_size;
03049 while(len) {
03050 chunk = len;
03051 if (chunk > sizeof(buf))
03052 chunk = sizeof(buf);
03053 res = read(ifd, buf, chunk);
03054 if (res != chunk) {
03055 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03056 close(ifd);
03057 close(fd);
03058 return -1;
03059 }
03060 res = write(fd, buf, chunk);
03061 if (res != chunk) {
03062 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno));
03063 close(ifd);
03064 close(fd);
03065 return -1;
03066 }
03067 len -= chunk;
03068 }
03069 close(ifd);
03070
03071 lseek(fd, 0, SEEK_SET);
03072 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) {
03073 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s);
03074 close(fd);
03075 return -1;
03076 }
03077 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) {
03078 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s);
03079 close(fd);
03080 return -1;
03081 }
03082 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) {
03083 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s);
03084 close(fd);
03085 return -1;
03086 }
03087 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) {
03088 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s);
03089 close(fd);
03090 return -1;
03091 }
03092 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
03093 if (fwh == MAP_FAILED) {
03094 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno));
03095 close(fd);
03096 return -1;
03097 }
03098 MD5Init(&md5);
03099 MD5Update(&md5, fwh->data, ntohl(fwh->datalen));
03100 MD5Final(sum, &md5);
03101 if (memcmp(sum, fwh->chksum, sizeof(sum))) {
03102 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s);
03103 munmap((void*)fwh, stbuf.st_size);
03104 close(fd);
03105 return -1;
03106 }
03107
03108 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03109 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) {
03110
03111 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version)))
03112
03113 break;
03114
03115
03116 munmap((void*)fwh, stbuf.st_size);
03117 close(fd);
03118 return 0;
03119 }
03120 }
03121
03122 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) {
03123 cur->fd = -1;
03124 AST_LIST_INSERT_TAIL(&firmwares, cur, list);
03125 }
03126
03127 if (cur) {
03128 if (cur->fwh)
03129 munmap((void*)cur->fwh, cur->mmaplen);
03130 if (cur->fd > -1)
03131 close(cur->fd);
03132 cur->fwh = fwh;
03133 cur->fd = fd;
03134 cur->mmaplen = stbuf.st_size;
03135 cur->dead = 0;
03136 }
03137
03138 return 0;
03139 }
03140
03141 static int iax_check_version(char *dev)
03142 {
03143 int res = 0;
03144 struct iax_firmware *cur = NULL;
03145
03146 if (ast_strlen_zero(dev))
03147 return 0;
03148
03149 AST_LIST_LOCK(&firmwares);
03150 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03151 if (!strcmp(dev, (char *)cur->fwh->devname)) {
03152 res = ntohs(cur->fwh->version);
03153 break;
03154 }
03155 }
03156 AST_LIST_UNLOCK(&firmwares);
03157
03158 return res;
03159 }
03160
03161 static int iax_firmware_append(struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc)
03162 {
03163 int res = -1;
03164 unsigned int bs = desc & 0xff;
03165 unsigned int start = (desc >> 8) & 0xffffff;
03166 unsigned int bytes;
03167 struct iax_firmware *cur;
03168
03169 if (ast_strlen_zero((char *)dev) || !bs)
03170 return -1;
03171
03172 start *= bs;
03173
03174 AST_LIST_LOCK(&firmwares);
03175 AST_LIST_TRAVERSE(&firmwares, cur, list) {
03176 if (strcmp((char *)dev, (char *)cur->fwh->devname))
03177 continue;
03178 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc);
03179 if (start < ntohl(cur->fwh->datalen)) {
03180 bytes = ntohl(cur->fwh->datalen) - start;
03181 if (bytes > bs)
03182 bytes = bs;
03183 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes);
03184 } else {
03185 bytes = 0;
03186 iax_ie_append(ied, IAX_IE_FWBLOCKDATA);
03187 }
03188 if (bytes == bs)
03189 res = 0;
03190 else
03191 res = 1;
03192 break;
03193 }
03194 AST_LIST_UNLOCK(&firmwares);
03195
03196 return res;
03197 }
03198
03199
03200 static void reload_firmware(int unload)
03201 {
03202 struct iax_firmware *cur = NULL;
03203 DIR *fwd;
03204 struct dirent *de;
03205 char dir[256], fn[256];
03206
03207 AST_LIST_LOCK(&firmwares);
03208
03209
03210 AST_LIST_TRAVERSE(&firmwares, cur, list)
03211 cur->dead = 1;
03212
03213
03214 if (!unload) {
03215 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR);
03216 fwd = opendir(dir);
03217 if (fwd) {
03218 while((de = readdir(fwd))) {
03219 if (de->d_name[0] != '.') {
03220 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name);
03221 if (!try_firmware(fn)) {
03222 ast_verb(2, "Loaded firmware '%s'\n", de->d_name);
03223 }
03224 }
03225 }
03226 closedir(fwd);
03227 } else
03228 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno));
03229 }
03230
03231
03232 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) {
03233 if (!cur->dead)
03234 continue;
03235 AST_LIST_REMOVE_CURRENT(list);
03236 destroy_firmware(cur);
03237 }
03238 AST_LIST_TRAVERSE_SAFE_END;
03239
03240 AST_LIST_UNLOCK(&firmwares);
03241 }
03242
03243
03244
03245
03246
03247
03248
03249
03250
03251 static int __do_deliver(void *data)
03252 {
03253
03254
03255 struct iax_frame *fr = data;
03256 fr->retrans = -1;
03257 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO);
03258 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE))
03259 iax2_queue_frame(fr->callno, &fr->af);
03260
03261 iax2_frame_free(fr);
03262
03263 return 0;
03264 }
03265
03266 static int handle_error(void)
03267 {
03268
03269
03270
03271 #if 0
03272 struct sockaddr_in *sin;
03273 int res;
03274 struct msghdr m;
03275 struct sock_extended_err e;
03276 m.msg_name = NULL;
03277 m.msg_namelen = 0;
03278 m.msg_iov = NULL;
03279 m.msg_control = &e;
03280 m.msg_controllen = sizeof(e);
03281 m.msg_flags = 0;
03282 res = recvmsg(netsocket, &m, MSG_ERRQUEUE);
03283 if (res < 0)
03284 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno));
03285 else {
03286 if (m.msg_controllen) {
03287 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e);
03288 if (sin)
03289 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr));
03290 else
03291 ast_log(LOG_WARNING, "No address detected??\n");
03292 } else {
03293 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno));
03294 }
03295 }
03296 #endif
03297 return 0;
03298 }
03299
03300 static int transmit_trunk(struct iax_frame *f, struct sockaddr_in *sin, int sockfd)
03301 {
03302 int res;
03303 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin,
03304 sizeof(*sin));
03305 if (res < 0) {
03306 ast_debug(1, "Received error: %s\n", strerror(errno));
03307 handle_error();
03308 } else
03309 res = 0;
03310 return res;
03311 }
03312
03313 static int send_packet(struct iax_frame *f)
03314 {
03315 int res;
03316 int callno = f->callno;
03317
03318
03319 if (!callno || !iaxs[callno] || iaxs[callno]->error)
03320 return -1;
03321
03322
03323 if (iaxdebug)
03324 ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port));
03325
03326 if (f->transfer) {
03327 if (iaxdebug)
03328 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr));
03329 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer));
03330 } else {
03331 if (iaxdebug)
03332 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr));
03333 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr));
03334 }
03335 if (res < 0) {
03336 if (iaxdebug)
03337 ast_debug(1, "Received error: %s\n", strerror(errno));
03338 handle_error();
03339 } else
03340 res = 0;
03341
03342 return res;
03343 }
03344
03345
03346
03347
03348
03349 static int iax2_predestroy(int callno)
03350 {
03351 struct ast_channel *c = NULL;
03352 struct chan_iax2_pvt *pvt = iaxs[callno];
03353
03354 if (!pvt)
03355 return -1;
03356
03357 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) {
03358 iax2_destroy_helper(pvt);
03359 ast_set_flag64(pvt, IAX_ALREADYGONE);
03360 }
03361
03362 if ((c = pvt->owner)) {
03363 c->tech_pvt = NULL;
03364 iax2_queue_hangup(callno);
03365 pvt->owner = NULL;
03366 ast_module_unref(ast_module_info->self);
03367 }
03368
03369 return 0;
03370 }
03371
03372 static void iax2_destroy(int callno)
03373 {
03374 struct chan_iax2_pvt *pvt = NULL;
03375 struct ast_channel *owner = NULL;
03376
03377 retry:
03378 if ((pvt = iaxs[callno])) {
03379 #if 0
03380
03381
03382
03383
03384
03385
03386
03387 iax2_destroy_helper(pvt);
03388 #endif
03389 }
03390
03391 owner = pvt ? pvt->owner : NULL;
03392
03393 if (owner) {
03394 if (ast_channel_trylock(owner)) {
03395 ast_debug(3, "Avoiding IAX destroy deadlock\n");
03396 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
03397 goto retry;
03398 }
03399 }
03400
03401 if (!owner) {
03402 iaxs[callno] = NULL;
03403 }
03404
03405 if (pvt) {
03406 if (!owner) {
03407 pvt->owner = NULL;
03408 } else {
03409
03410
03411
03412 ast_queue_hangup(owner);
03413 }
03414
03415 if (pvt->peercallno) {
03416 remove_by_peercallno(pvt);
03417 }
03418
03419 if (pvt->transfercallno) {
03420 remove_by_transfercallno(pvt);
03421 }
03422
03423 if (!owner) {
03424 ao2_ref(pvt, -1);
03425 pvt = NULL;
03426 }
03427 }
03428
03429 if (owner) {
03430 ast_channel_unlock(owner);
03431 }
03432
03433 if (callno & 0x4000) {
03434 update_max_trunk();
03435 }
03436 }
03437
03438 static int update_packet(struct iax_frame *f)
03439 {
03440
03441 struct ast_iax2_full_hdr *fh = f->data;
03442 struct ast_frame af;
03443
03444
03445 if (f->encmethods) {
03446 decode_frame(&f->mydcx, fh, &af, &f->datalen);
03447 }
03448
03449 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno);
03450
03451 f->iseqno = iaxs[f->callno]->iseqno;
03452 fh->iseqno = f->iseqno;
03453
03454
03455 if (f->encmethods) {
03456
03457
03458 build_rand_pad(f->semirand, sizeof(f->semirand));
03459 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen);
03460 }
03461 return 0;
03462 }
03463
03464 static int attempt_transmit(const void *data);
03465 static void __attempt_transmit(const void *data)
03466 {
03467
03468
03469 struct iax_frame *f = (struct iax_frame *)data;
03470 int freeme = 0;
03471 int callno = f->callno;
03472
03473 if (callno)
03474 ast_mutex_lock(&iaxsl[callno]);
03475 if (callno && iaxs[callno]) {
03476 if ((f->retries < 0) ||
03477 (f->retries >= max_retries) ) {
03478
03479 if (f->retries >= max_retries) {
03480 if (f->transfer) {
03481
03482 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
03483 } else if (f->final) {
03484 iax2_destroy(callno);
03485 } else {
03486 if (iaxs[callno]->owner)
03487 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass.integer, f->ts, f->oseqno);
03488 iaxs[callno]->error = ETIMEDOUT;
03489 if (iaxs[callno]->owner) {
03490 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER };
03491
03492 iax2_queue_frame(callno, &fr);
03493
03494 if (iaxs[callno] && iaxs[callno]->owner)
03495 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER;
03496 } else {
03497 if (iaxs[callno]->reg) {
03498 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us));
03499 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT;
03500 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE;
03501 }
03502 iax2_destroy(callno);
03503 }
03504 }
03505
03506 }
03507 freeme = 1;
03508 } else {
03509
03510 update_packet(f);
03511
03512 send_packet(f);
03513 f->retries++;
03514
03515 f->retrytime *= 10;
03516 if (f->retrytime > MAX_RETRY_TIME)
03517 f->retrytime = MAX_RETRY_TIME;
03518
03519 if (f->transfer && (f->retrytime > 1000))
03520 f->retrytime = 1000;
03521 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f);
03522 }
03523 } else {
03524
03525 f->retries = -1;
03526 freeme = 1;
03527 }
03528
03529 if (freeme) {
03530
03531 AST_LIST_REMOVE(&frame_queue[callno], f, list);
03532 ast_mutex_unlock(&iaxsl[callno]);
03533 f->retrans = -1;
03534
03535 iax2_frame_free(f);
03536 } else if (callno) {
03537 ast_mutex_unlock(&iaxsl[callno]);
03538 }
03539 }
03540
03541 static int attempt_transmit(const void *data)
03542 {
03543 #ifdef SCHED_MULTITHREADED
03544 if (schedule_action(__attempt_transmit, data))
03545 #endif
03546 __attempt_transmit(data);
03547 return 0;
03548 }
03549
03550 static char *handle_cli_iax2_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03551 {
03552 struct iax2_peer *peer = NULL;
03553 struct iax2_user *user = NULL;
03554 static const char * const choices[] = { "all", NULL };
03555 char *cmplt;
03556
03557 switch (cmd) {
03558 case CLI_INIT:
03559 e->command = "iax2 prune realtime";
03560 e->usage =
03561 "Usage: iax2 prune realtime [<peername>|all]\n"
03562 " Prunes object(s) from the cache\n";
03563 return NULL;
03564 case CLI_GENERATE:
03565 if (a->pos == 3) {
03566 cmplt = ast_cli_complete(a->word, choices, a->n);
03567 if (!cmplt)
03568 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS);
03569 return cmplt;
03570 }
03571 return NULL;
03572 }
03573 if (a->argc != 4)
03574 return CLI_SHOWUSAGE;
03575 if (!strcmp(a->argv[3], "all")) {
03576 prune_users();
03577 prune_peers();
03578 ast_cli(a->fd, "Cache flushed successfully.\n");
03579 return CLI_SUCCESS;
03580 }
03581 peer = find_peer(a->argv[3], 0);
03582 user = find_user(a->argv[3]);
03583 if (peer || user) {
03584 if (peer) {
03585 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
03586 ast_set_flag64(peer, IAX_RTAUTOCLEAR);
03587 expire_registry(peer_ref(peer));
03588 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]);
03589 } else {
03590 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]);
03591 }
03592 peer_unref(peer);
03593 }
03594 if (user) {
03595 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
03596 ast_set_flag64(user, IAX_RTAUTOCLEAR);
03597 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]);
03598 } else {
03599 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]);
03600 }
03601 ao2_unlink(users,user);
03602 user_unref(user);
03603 }
03604 } else {
03605 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]);
03606 }
03607
03608 return CLI_SUCCESS;
03609 }
03610
03611 static char *handle_cli_iax2_test_losspct(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03612 {
03613 switch (cmd) {
03614 case CLI_INIT:
03615 e->command = "iax2 test losspct";
03616 e->usage =
03617 "Usage: iax2 test losspct <percentage>\n"
03618 " For testing, throws away <percentage> percent of incoming packets\n";
03619 return NULL;
03620 case CLI_GENERATE:
03621 return NULL;
03622 }
03623 if (a->argc != 4)
03624 return CLI_SHOWUSAGE;
03625
03626 test_losspct = atoi(a->argv[3]);
03627
03628 return CLI_SUCCESS;
03629 }
03630
03631 #ifdef IAXTESTS
03632 static char *handle_cli_iax2_test_late(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03633 {
03634 switch (cmd) {
03635 case CLI_INIT:
03636 e->command = "iax2 test late";
03637 e->usage =
03638 "Usage: iax2 test late <ms>\n"
03639 " For testing, count the next frame as <ms> ms late\n";
03640 return NULL;
03641 case CLI_GENERATE:
03642 return NULL;
03643 }
03644
03645 if (a->argc != 4)
03646 return CLI_SHOWUSAGE;
03647
03648 test_late = atoi(a->argv[3]);
03649
03650 return CLI_SUCCESS;
03651 }
03652
03653 static char *handle_cli_iax2_test_resync(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03654 {
03655 switch (cmd) {
03656 case CLI_INIT:
03657 e->command = "iax2 test resync";
03658 e->usage =
03659 "Usage: iax2 test resync <ms>\n"
03660 " For testing, adjust all future frames by <ms> ms\n";
03661 return NULL;
03662 case CLI_GENERATE:
03663 return NULL;
03664 }
03665
03666 if (a->argc != 4)
03667 return CLI_SHOWUSAGE;
03668
03669 test_resync = atoi(a->argv[3]);
03670
03671 return CLI_SUCCESS;
03672 }
03673
03674 static char *handle_cli_iax2_test_jitter(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03675 {
03676 switch (cmd) {
03677 case CLI_INIT:
03678 e->command = "iax2 test jitter";
03679 e->usage =
03680 "Usage: iax2 test jitter <ms> <pct>\n"
03681 " For testing, simulate maximum jitter of +/- <ms> on <pct>\n"
03682 " percentage of packets. If <pct> is not specified, adds\n"
03683 " jitter to all packets.\n";
03684 return NULL;
03685 case CLI_GENERATE:
03686 return NULL;
03687 }
03688
03689 if (a->argc < 4 || a->argc > 5)
03690 return CLI_SHOWUSAGE;
03691
03692 test_jit = atoi(a->argv[3]);
03693 if (a->argc == 5)
03694 test_jitpct = atoi(a->argv[4]);
03695
03696 return CLI_SUCCESS;
03697 }
03698 #endif
03699
03700
03701
03702 static int peer_status(struct iax2_peer *peer, char *status, int statuslen)
03703 {
03704 int res = 0;
03705 if (peer->maxms) {
03706 if (peer->lastms < 0) {
03707 ast_copy_string(status, "UNREACHABLE", statuslen);
03708 } else if (peer->lastms > peer->maxms) {
03709 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
03710 res = 1;
03711 } else if (peer->lastms) {
03712 snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
03713 res = 1;
03714 } else {
03715 ast_copy_string(status, "UNKNOWN", statuslen);
03716 }
03717 } else {
03718 ast_copy_string(status, "Unmonitored", statuslen);
03719 res = -1;
03720 }
03721 return res;
03722 }
03723
03724
03725 static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03726 {
03727 char status[30];
03728 char cbuf[256];
03729 struct iax2_peer *peer;
03730 char codec_buf[512];
03731 struct ast_str *encmethods = ast_str_alloca(256);
03732 int x = 0, codec = 0, load_realtime = 0;
03733
03734 switch (cmd) {
03735 case CLI_INIT:
03736 e->command = "iax2 show peer";
03737 e->usage =
03738 "Usage: iax2 show peer <name>\n"
03739 " Display details on specific IAX peer\n";
03740 return NULL;
03741 case CLI_GENERATE:
03742 if (a->pos == 3)
03743 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
03744 return NULL;
03745 }
03746
03747 if (a->argc < 4)
03748 return CLI_SHOWUSAGE;
03749
03750 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0;
03751
03752 peer = find_peer(a->argv[3], load_realtime);
03753 if (peer) {
03754 struct sockaddr_in peer_addr;
03755
03756 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
03757
03758 encmethods_to_str(peer->encmethods, encmethods);
03759 ast_cli(a->fd, "\n\n");
03760 ast_cli(a->fd, " * Name : %s\n", peer->name);
03761 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>");
03762 ast_cli(a->fd, " Context : %s\n", peer->context);
03763 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot);
03764 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox);
03765 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
03766 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno);
03767 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No"));
03768 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
03769 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
03770 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
03771 ast_cli(a->fd, " Expire : %d\n", peer->expire);
03772 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No"));
03773 ast_cli(a->fd, " Addr->IP : %s Port %d\n", peer_addr.sin_addr.s_addr ? ast_inet_ntoa(peer_addr.sin_addr) : "(Unspecified)", ntohs(peer_addr.sin_port));
03774 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
03775 ast_cli(a->fd, " Username : %s\n", peer->username);
03776 ast_cli(a->fd, " Codecs : ");
03777 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
03778 ast_cli(a->fd, "%s\n", codec_buf);
03779
03780 ast_cli(a->fd, " Codec Order : (");
03781 for(x = 0; x < 32 ; x++) {
03782 codec = ast_codec_pref_index(&peer->prefs,x);
03783 if(!codec)
03784 break;
03785 ast_cli(a->fd, "%s", ast_getformatname(codec));
03786 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
03787 ast_cli(a->fd, "|");
03788 }
03789
03790 if (!x)
03791 ast_cli(a->fd, "none");
03792 ast_cli(a->fd, ")\n");
03793
03794 ast_cli(a->fd, " Status : ");
03795 peer_status(peer, status, sizeof(status));
03796 ast_cli(a->fd, "%s\n",status);
03797 ast_cli(a->fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off");
03798 ast_cli(a->fd, "\n");
03799 peer_unref(peer);
03800 } else {
03801 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]);
03802 ast_cli(a->fd, "\n");
03803 }
03804
03805 return CLI_SUCCESS;
03806 }
03807
03808 static char *complete_iax2_peers(const char *line, const char *word, int pos, int state, uint64_t flags)
03809 {
03810 int which = 0;
03811 struct iax2_peer *peer;
03812 char *res = NULL;
03813 int wordlen = strlen(word);
03814 struct ao2_iterator i;
03815
03816 i = ao2_iterator_init(peers, 0);
03817 while ((peer = ao2_iterator_next(&i))) {
03818 if (!strncasecmp(peer->name, word, wordlen) && ++which > state
03819 && (!flags || ast_test_flag64(peer, flags))) {
03820 res = ast_strdup(peer->name);
03821 peer_unref(peer);
03822 break;
03823 }
03824 peer_unref(peer);
03825 }
03826 ao2_iterator_destroy(&i);
03827
03828 return res;
03829 }
03830
03831 static char *handle_cli_iax2_show_stats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03832 {
03833 struct iax_frame *cur;
03834 int cnt = 0, dead = 0, final = 0, i = 0;
03835
03836 switch (cmd) {
03837 case CLI_INIT:
03838 e->command = "iax2 show stats";
03839 e->usage =
03840 "Usage: iax2 show stats\n"
03841 " Display statistics on IAX channel driver.\n";
03842 return NULL;
03843 case CLI_GENERATE:
03844 return NULL;
03845 }
03846
03847 if (a->argc != 3)
03848 return CLI_SHOWUSAGE;
03849
03850 for (i = 0; i < ARRAY_LEN(frame_queue); i++) {
03851 ast_mutex_lock(&iaxsl[i]);
03852 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) {
03853 if (cur->retries < 0)
03854 dead++;
03855 if (cur->final)
03856 final++;
03857 cnt++;
03858 }
03859 ast_mutex_unlock(&iaxsl[i]);
03860 }
03861
03862 ast_cli(a->fd, " IAX Statistics\n");
03863 ast_cli(a->fd, "---------------------\n");
03864 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes());
03865 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed,
03866 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu);
03867 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt);
03868
03869 trunk_timed = trunk_untimed = 0;
03870 if (trunk_maxmtu > trunk_nmaxmtu)
03871 trunk_nmaxmtu = trunk_maxmtu;
03872
03873 return CLI_SUCCESS;
03874 }
03875
03876
03877 static char *handle_cli_iax2_set_mtu(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03878 {
03879 int mtuv;
03880
03881 switch (cmd) {
03882 case CLI_INIT:
03883 e->command = "iax2 set mtu";
03884 e->usage =
03885 "Usage: iax2 set mtu <value>\n"
03886 " Set the system-wide IAX IP mtu to <value> bytes net or\n"
03887 " zero to disable. Disabling means that the operating system\n"
03888 " must handle fragmentation of UDP packets when the IAX2 trunk\n"
03889 " packet exceeds the UDP payload size. This is substantially\n"
03890 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n"
03891 " greater for G.711 samples.\n";
03892 return NULL;
03893 case CLI_GENERATE:
03894 return NULL;
03895 }
03896
03897 if (a->argc != 4)
03898 return CLI_SHOWUSAGE;
03899 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0)
03900 mtuv = MAX_TRUNK_MTU;
03901 else
03902 mtuv = atoi(a->argv[3]);
03903
03904 if (mtuv == 0) {
03905 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu);
03906 global_max_trunk_mtu = 0;
03907 return CLI_SUCCESS;
03908 }
03909 if (mtuv < 172 || mtuv > 4000) {
03910 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n");
03911 return CLI_SHOWUSAGE;
03912 }
03913 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv);
03914 global_max_trunk_mtu = mtuv;
03915 return CLI_SUCCESS;
03916 }
03917
03918 static char *handle_cli_iax2_show_cache(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03919 {
03920 struct iax2_dpcache *dp = NULL;
03921 char tmp[1024], *pc = NULL;
03922 int s, x, y;
03923 struct timeval now = ast_tvnow();
03924
03925 switch (cmd) {
03926 case CLI_INIT:
03927 e->command = "iax2 show cache";
03928 e->usage =
03929 "Usage: iax2 show cache\n"
03930 " Display currently cached IAX Dialplan results.\n";
03931 return NULL;
03932 case CLI_GENERATE:
03933 return NULL;
03934 }
03935
03936 AST_LIST_LOCK(&dpcache);
03937
03938 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags");
03939
03940 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) {
03941 s = dp->expiry.tv_sec - now.tv_sec;
03942 tmp[0] = '\0';
03943 if (dp->flags & CACHE_FLAG_EXISTS)
03944 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1);
03945 if (dp->flags & CACHE_FLAG_NONEXISTENT)
03946 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1);
03947 if (dp->flags & CACHE_FLAG_CANEXIST)
03948 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1);
03949 if (dp->flags & CACHE_FLAG_PENDING)
03950 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1);
03951 if (dp->flags & CACHE_FLAG_TIMEOUT)
03952 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1);
03953 if (dp->flags & CACHE_FLAG_TRANSMITTED)
03954 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1);
03955 if (dp->flags & CACHE_FLAG_MATCHMORE)
03956 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1);
03957 if (dp->flags & CACHE_FLAG_UNKNOWN)
03958 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1);
03959
03960 if (!ast_strlen_zero(tmp)) {
03961 tmp[strlen(tmp) - 1] = '\0';
03962 } else {
03963 ast_copy_string(tmp, "(none)", sizeof(tmp));
03964 }
03965 y = 0;
03966 pc = strchr(dp->peercontext, '@');
03967 if (!pc) {
03968 pc = dp->peercontext;
03969 } else {
03970 pc++;
03971 }
03972 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
03973 if (dp->waiters[x] > -1)
03974 y++;
03975 }
03976 if (s > 0) {
03977 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp);
03978 } else {
03979 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp);
03980 }
03981 }
03982
03983 AST_LIST_UNLOCK(&dpcache);
03984
03985 return CLI_SUCCESS;
03986 }
03987
03988 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset);
03989
03990 static void unwrap_timestamp(struct iax_frame *fr)
03991 {
03992
03993
03994 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16;
03995 const int lower_mask = (1 << ts_shift) - 1;
03996 const int upper_mask = ~lower_mask;
03997 const int last_upper = iaxs[fr->callno]->last & upper_mask;
03998
03999 if ( (fr->ts & upper_mask) == last_upper ) {
04000 const int x = fr->ts - iaxs[fr->callno]->last;
04001 const int threshold = (ts_shift == 15) ? 25000 : 50000;
04002
04003 if (x < -threshold) {
04004
04005
04006
04007
04008 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask);
04009 if (iaxdebug)
04010 ast_debug(1, "schedule_delivery: pushed forward timestamp\n");
04011 } else if (x > threshold) {
04012
04013
04014
04015
04016 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask);
04017 if (iaxdebug)
04018 ast_debug(1, "schedule_delivery: pushed back timestamp\n");
04019 }
04020 }
04021 }
04022
04023 static int get_from_jb(const void *p);
04024
04025 static void update_jbsched(struct chan_iax2_pvt *pvt)
04026 {
04027 int when;
04028
04029 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore);
04030
04031 when = jb_next(pvt->jb) - when;
04032
04033 if (when <= 0) {
04034
04035 when = 1;
04036 }
04037
04038 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb,
04039 CALLNO_TO_PTR(pvt->callno));
04040 }
04041
04042 static void __get_from_jb(const void *p)
04043 {
04044 int callno = PTR_TO_CALLNO(p);
04045 struct chan_iax2_pvt *pvt = NULL;
04046 struct iax_frame *fr;
04047 jb_frame frame;
04048 int ret;
04049 long ms;
04050 long next;
04051 struct timeval now = ast_tvnow();
04052
04053
04054 ast_mutex_lock(&iaxsl[callno]);
04055 pvt = iaxs[callno];
04056 if (!pvt) {
04057
04058 ast_mutex_unlock(&iaxsl[callno]);
04059 return;
04060 }
04061
04062 pvt->jbid = -1;
04063
04064
04065
04066
04067 now.tv_usec += 1000;
04068
04069 ms = ast_tvdiff_ms(now, pvt->rxcore);
04070
04071 if(ms >= (next = jb_next(pvt->jb))) {
04072 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
04073 switch(ret) {
04074 case JB_OK:
04075 fr = frame.data;
04076 __do_deliver(fr);
04077
04078 pvt = iaxs[callno];
04079 break;
04080 case JB_INTERP:
04081 {
04082 struct ast_frame af = { 0, };
04083
04084
04085 af.frametype = AST_FRAME_VOICE;
04086 af.subclass.codec = pvt->voiceformat;
04087 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
04088 af.src = "IAX2 JB interpolation";
04089 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
04090 af.offset = AST_FRIENDLY_OFFSET;
04091
04092
04093
04094 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) {
04095 iax2_queue_frame(callno, &af);
04096
04097 pvt = iaxs[callno];
04098 }
04099 }
04100 break;
04101 case JB_DROP:
04102 iax2_frame_free(frame.data);
04103 break;
04104 case JB_NOFRAME:
04105 case JB_EMPTY:
04106
04107 break;
04108 default:
04109
04110 break;
04111 }
04112 }
04113 if (pvt)
04114 update_jbsched(pvt);
04115 ast_mutex_unlock(&iaxsl[callno]);
04116 }
04117
04118 static int get_from_jb(const void *data)
04119 {
04120 #ifdef SCHED_MULTITHREADED
04121 if (schedule_action(__get_from_jb, data))
04122 #endif
04123 __get_from_jb(data);
04124 return 0;
04125 }
04126
04127
04128
04129
04130
04131
04132
04133 static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout)
04134 {
04135 int type, len;
04136 int ret;
04137 int needfree = 0;
04138 struct ast_channel *owner = NULL;
04139 struct ast_channel *bridge = NULL;
04140
04141
04142 unwrap_timestamp(fr);
04143
04144
04145 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore))
04146 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000));
04147 else {
04148 #if 0
04149 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n");
04150 #endif
04151 fr->af.delivery = ast_tv(0,0);
04152 }
04153
04154 type = JB_TYPE_CONTROL;
04155 len = 0;
04156
04157 if(fr->af.frametype == AST_FRAME_VOICE) {
04158 type = JB_TYPE_VOICE;
04159 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
04160 } else if(fr->af.frametype == AST_FRAME_CNG) {
04161 type = JB_TYPE_SILENCE;
04162 }
04163
04164 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) {
04165 if (tsout)
04166 *tsout = fr->ts;
04167 __do_deliver(fr);
04168 return -1;
04169 }
04170
04171 iax2_lock_owner(fr->callno);
04172 if (!iaxs[fr->callno]) {
04173
04174 iax2_frame_free(fr);
04175 return -1;
04176 }
04177 if ((owner = iaxs[fr->callno]->owner))
04178 bridge = ast_bridged_channel(owner);
04179
04180
04181
04182 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) {
04183 jb_frame frame;
04184
04185 ast_channel_unlock(owner);
04186
04187
04188 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) {
04189 __do_deliver(frame.data);
04190
04191 if (!iaxs[fr->callno])
04192 return -1;
04193 }
04194
04195 jb_reset(iaxs[fr->callno]->jb);
04196
04197 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid);
04198
04199
04200 if (tsout)
04201 *tsout = fr->ts;
04202 __do_deliver(fr);
04203 return -1;
04204 }
04205 if (owner) {
04206 ast_channel_unlock(owner);
04207 }
04208
04209
04210
04211 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts,
04212 calc_rxstamp(iaxs[fr->callno],fr->ts));
04213 if (ret == JB_DROP) {
04214 needfree++;
04215 } else if (ret == JB_SCHED) {
04216 update_jbsched(iaxs[fr->callno]);
04217 }
04218 if (tsout)
04219 *tsout = fr->ts;
04220 if (needfree) {
04221
04222 iax2_frame_free(fr);
04223 return -1;
04224 }
04225 return 0;
04226 }
04227
04228 static int transmit_frame(void *data)
04229 {
04230 struct iax_frame *fr = data;
04231
04232 ast_mutex_lock(&iaxsl[fr->callno]);
04233
04234 fr->sentyet = 1;
04235
04236 if (iaxs[fr->callno]) {
04237 send_packet(fr);
04238 }
04239
04240 if (fr->retries < 0) {
04241 ast_mutex_unlock(&iaxsl[fr->callno]);
04242
04243 iax_frame_free(fr);
04244 } else {
04245
04246 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list);
04247 fr->retries++;
04248 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr);
04249 ast_mutex_unlock(&iaxsl[fr->callno]);
04250 }
04251
04252 return 0;
04253 }
04254
04255 static int iax2_transmit(struct iax_frame *fr)
04256 {
04257 fr->sentyet = 0;
04258
04259 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr);
04260 }
04261
04262 static int iax2_digit_begin(struct ast_channel *c, char digit)
04263 {
04264 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1);
04265 }
04266
04267 static int iax2_digit_end(struct ast_channel *c, char digit, unsigned int duration)
04268 {
04269 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1);
04270 }
04271
04272 static int iax2_sendtext(struct ast_channel *c, const char *text)
04273 {
04274
04275 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT,
04276 0, 0, (unsigned char *)text, strlen(text) + 1, -1);
04277 }
04278
04279 static int iax2_sendimage(struct ast_channel *c, struct ast_frame *img)
04280 {
04281 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1);
04282 }
04283
04284 static int iax2_sendhtml(struct ast_channel *c, int subclass, const char *data, int datalen)
04285 {
04286 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1);
04287 }
04288
04289 static int iax2_fixup(struct ast_channel *oldchannel, struct ast_channel *newchan)
04290 {
04291 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt);
04292 ast_mutex_lock(&iaxsl[callno]);
04293 if (iaxs[callno])
04294 iaxs[callno]->owner = newchan;
04295 else
04296 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n");
04297 ast_mutex_unlock(&iaxsl[callno]);
04298 return 0;
04299 }
04300
04301
04302
04303
04304
04305 static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
04306 {
04307 struct ast_variable *var = NULL;
04308 struct ast_variable *tmp;
04309 struct iax2_peer *peer=NULL;
04310 time_t regseconds = 0, nowtime;
04311 int dynamic=0;
04312
04313 if (peername) {
04314 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL);
04315 if (!var && sin)
04316 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04317 } else if (sin) {
04318 char porta[25];
04319 sprintf(porta, "%d", ntohs(sin->sin_port));
04320 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04321 if (var) {
04322
04323 for (tmp = var; tmp; tmp = tmp->next) {
04324 if (!strcasecmp(tmp->name, "name"))
04325 peername = tmp->value;
04326 }
04327 }
04328 }
04329 if (!var && peername) {
04330 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL);
04331
04332
04333
04334
04335
04336
04337 if (var && sin) {
04338 for (tmp = var; tmp; tmp = tmp->next) {
04339 if (!strcasecmp(tmp->name, "host")) {
04340 struct ast_hostent ahp;
04341 struct hostent *hp;
04342 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04343
04344 ast_variables_destroy(var);
04345 var = NULL;
04346 }
04347 break;
04348 }
04349 }
04350 }
04351 }
04352 if (!var)
04353 return NULL;
04354
04355 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1);
04356
04357 if (!peer) {
04358 ast_variables_destroy(var);
04359 return NULL;
04360 }
04361
04362 for (tmp = var; tmp; tmp = tmp->next) {
04363
04364 if (!strcasecmp(tmp->name, "type")) {
04365 if (strcasecmp(tmp->value, "friend") &&
04366 strcasecmp(tmp->value, "peer")) {
04367
04368 peer = peer_unref(peer);
04369 break;
04370 }
04371 } else if (!strcasecmp(tmp->name, "regseconds")) {
04372 ast_get_time_t(tmp->value, ®seconds, 0, NULL);
04373 } else if (!strcasecmp(tmp->name, "ipaddr")) {
04374 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE);
04375 } else if (!strcasecmp(tmp->name, "port")) {
04376 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value));
04377 } else if (!strcasecmp(tmp->name, "host")) {
04378 if (!strcasecmp(tmp->value, "dynamic"))
04379 dynamic = 1;
04380 }
04381 }
04382
04383 ast_variables_destroy(var);
04384
04385 if (!peer)
04386 return NULL;
04387
04388 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04389 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS);
04390 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) {
04391 if (peer->expire > -1) {
04392 if (!ast_sched_thread_del(sched, peer->expire)) {
04393 peer->expire = -1;
04394 peer_unref(peer);
04395 }
04396 }
04397 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer));
04398 if (peer->expire == -1)
04399 peer_unref(peer);
04400 }
04401 ao2_link(peers, peer);
04402 if (ast_test_flag64(peer, IAX_DYNAMIC))
04403 reg_source_db(peer);
04404 } else {
04405 ast_set_flag64(peer, IAX_TEMPONLY);
04406 }
04407
04408 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) {
04409 time(&nowtime);
04410 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) {
04411 memset(&peer->addr, 0, sizeof(peer->addr));
04412 realtime_update_peer(peer->name, &peer->addr, 0);
04413 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n",
04414 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04415 }
04416 else {
04417 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n",
04418 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
04419 }
04420 }
04421
04422 return peer;
04423 }
04424
04425 static struct iax2_user *realtime_user(const char *username, struct sockaddr_in *sin)
04426 {
04427 struct ast_variable *var;
04428 struct ast_variable *tmp;
04429 struct iax2_user *user=NULL;
04430
04431 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL);
04432 if (!var)
04433 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04434 if (!var && sin) {
04435 char porta[6];
04436 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port));
04437 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04438 if (!var)
04439 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL);
04440 }
04441 if (!var) {
04442 var = ast_load_realtime("iaxusers", "name", username, SENTINEL);
04443
04444
04445
04446
04447
04448
04449 if (var) {
04450 for (tmp = var; tmp; tmp = tmp->next) {
04451 if (!strcasecmp(tmp->name, "host")) {
04452 struct ast_hostent ahp;
04453 struct hostent *hp;
04454 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04455
04456 ast_variables_destroy(var);
04457 var = NULL;
04458 }
04459 break;
04460 }
04461 }
04462 }
04463 }
04464 if (!var)
04465 return NULL;
04466
04467 tmp = var;
04468 while(tmp) {
04469
04470 if (!strcasecmp(tmp->name, "type")) {
04471 if (strcasecmp(tmp->value, "friend") &&
04472 strcasecmp(tmp->value, "user")) {
04473 return NULL;
04474 }
04475 }
04476 tmp = tmp->next;
04477 }
04478
04479 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS));
04480
04481 ast_variables_destroy(var);
04482
04483 if (!user)
04484 return NULL;
04485
04486 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) {
04487 ast_set_flag64(user, IAX_RTCACHEFRIENDS);
04488 ao2_link(users, user);
04489 } else {
04490 ast_set_flag64(user, IAX_TEMPONLY);
04491 }
04492
04493 return user;
04494 }
04495
04496 static void realtime_update_peer(const char *peername, struct ast_sockaddr *sockaddr, time_t regtime)
04497 {
04498 char port[10];
04499 char regseconds[20];
04500 const char *sysname = ast_config_AST_SYSTEM_NAME;
04501 char *syslabel = NULL;
04502
04503 if (ast_strlen_zero(sysname))
04504 sysname = NULL;
04505 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME))
04506 syslabel = "regserver";
04507
04508 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime);
04509 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr));
04510 ast_update_realtime("iaxpeers", "name", peername,
04511 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port,
04512 "regseconds", regseconds, syslabel, sysname, SENTINEL);
04513 }
04514
04515 struct create_addr_info {
04516 format_t capability;
04517 uint64_t flags;
04518 int maxtime;
04519 int encmethods;
04520 int found;
04521 int sockfd;
04522 int adsi;
04523 char username[80];
04524 char secret[80];
04525 char outkey[80];
04526 char timezone[80];
04527 char prefs[32];
04528 char cid_num[80];
04529 char cid_name[80];
04530 char context[AST_MAX_CONTEXT];
04531 char peercontext[AST_MAX_CONTEXT];
04532 char mohinterpret[MAX_MUSICCLASS];
04533 char mohsuggest[MAX_MUSICCLASS];
04534 };
04535
04536 static int create_addr(const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai)
04537 {
04538 struct iax2_peer *peer;
04539 int res = -1;
04540 struct ast_codec_pref ourprefs;
04541 struct sockaddr_in peer_addr;
04542
04543 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK);
04544 cai->sockfd = defaultsockfd;
04545 cai->maxtime = 0;
04546 sin->sin_family = AF_INET;
04547
04548 if (!(peer = find_peer(peername, 1))) {
04549 struct ast_sockaddr sin_tmp;
04550
04551 cai->found = 0;
04552 sin_tmp.ss.ss_family = AF_INET;
04553 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) {
04554 ast_log(LOG_WARNING, "No such host: %s\n", peername);
04555 return -1;
04556 }
04557 ast_sockaddr_to_sin(&sin_tmp, sin);
04558 if (sin->sin_port == 0) {
04559 sin->sin_port = htons(IAX_DEFAULT_PORTNO);
04560 }
04561
04562
04563 memcpy(&ourprefs, &prefs, sizeof(ourprefs));
04564 if (c)
04565 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04566 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04567 return 0;
04568 }
04569
04570 cai->found = 1;
04571
04572 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
04573
04574
04575 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) {
04576 goto return_unref;
04577 }
04578
04579
04580 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0)))
04581 goto return_unref;
04582
04583 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
04584 cai->maxtime = peer->maxms;
04585 cai->capability = peer->capability;
04586 cai->encmethods = peer->encmethods;
04587 cai->sockfd = peer->sockfd;
04588 cai->adsi = peer->adsi;
04589 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
04590
04591 if (c) {
04592 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
04593 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
04594 }
04595 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
04596 ast_copy_string(cai->context, peer->context, sizeof(cai->context));
04597 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext));
04598 ast_copy_string(cai->username, peer->username, sizeof(cai->username));
04599 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone));
04600 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey));
04601 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num));
04602 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name));
04603 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret));
04604 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest));
04605 if (ast_strlen_zero(peer->dbsecret)) {
04606 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret));
04607 } else {
04608 char *family;
04609 char *key = NULL;
04610
04611 family = ast_strdupa(peer->dbsecret);
04612 key = strchr(family, '/');
04613 if (key)
04614 *key++ = '\0';
04615 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) {
04616 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret);
04617 goto return_unref;
04618 }
04619 }
04620
04621 if (peer_addr.sin_addr.s_addr) {
04622 sin->sin_addr = peer_addr.sin_addr;
04623 sin->sin_port = peer_addr.sin_port;
04624 } else {
04625 sin->sin_addr = peer->defaddr.sin_addr;
04626 sin->sin_port = peer->defaddr.sin_port;
04627 }
04628
04629 res = 0;
04630
04631 return_unref:
04632 peer_unref(peer);
04633
04634 return res;
04635 }
04636
04637 static void __auto_congest(const void *nothing)
04638 {
04639 int callno = PTR_TO_CALLNO(nothing);
04640 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } };
04641 ast_mutex_lock(&iaxsl[callno]);
04642 if (iaxs[callno]) {
04643 iaxs[callno]->initid = -1;
04644 iax2_queue_frame(callno, &f);
04645 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n");
04646 }
04647 ast_mutex_unlock(&iaxsl[callno]);
04648 }
04649
04650 static int auto_congest(const void *data)
04651 {
04652 #ifdef SCHED_MULTITHREADED
04653 if (schedule_action(__auto_congest, data))
04654 #endif
04655 __auto_congest(data);
04656 return 0;
04657 }
04658
04659 static unsigned int iax2_datetime(const char *tz)
04660 {
04661 struct timeval t = ast_tvnow();
04662 struct ast_tm tm;
04663 unsigned int tmp;
04664 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz);
04665 tmp = (tm.tm_sec >> 1) & 0x1f;
04666 tmp |= (tm.tm_min & 0x3f) << 5;
04667 tmp |= (tm.tm_hour & 0x1f) << 11;
04668 tmp |= (tm.tm_mday & 0x1f) << 16;
04669 tmp |= ((tm.tm_mon + 1) & 0xf) << 21;
04670 tmp |= ((tm.tm_year - 100) & 0x7f) << 25;
04671 return tmp;
04672 }
04673
04674 struct parsed_dial_string {
04675 char *username;
04676 char *password;
04677 char *key;
04678 char *peer;
04679 char *port;
04680 char *exten;
04681 char *context;
04682 char *options;
04683 };
04684
04685 static int send_apathetic_reply(unsigned short callno, unsigned short dcallno,
04686 struct sockaddr_in *sin, int command, int ts, unsigned char seqno,
04687 int sockfd, struct iax_ie_data *ied)
04688 {
04689 struct {
04690 struct ast_iax2_full_hdr f;
04691 struct iax_ie_data ied;
04692 } data;
04693 size_t size = sizeof(struct ast_iax2_full_hdr);
04694
04695 if (ied) {
04696 size += ied->pos;
04697 memcpy(&data.ied, ied->buf, ied->pos);
04698 }
04699
04700 data.f.scallno = htons(0x8000 | callno);
04701 data.f.dcallno = htons(dcallno);
04702 data.f.ts = htonl(ts);
04703 data.f.iseqno = seqno;
04704 data.f.oseqno = 0;
04705 data.f.type = AST_FRAME_IAX;
04706 data.f.csub = compress_subclass(command);
04707
04708 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin));
04709 }
04710
04711 static void add_empty_calltoken_ie(struct chan_iax2_pvt *pvt, struct iax_ie_data *ied)
04712 {
04713
04714 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) {
04715 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN;
04716 ied->buf[ied->pos++] = 0;
04717 pvt->calltoken_ie_len = 2;
04718 }
04719 }
04720
04721 static void resend_with_token(int callno, struct iax_frame *f, const char *newtoken)
04722 {
04723 struct chan_iax2_pvt *pvt = iaxs[callno];
04724 int frametype = f->af.frametype;
04725 int subclass = f->af.subclass.integer;
04726 struct {
04727 struct ast_iax2_full_hdr fh;
04728 struct iax_ie_data ied;
04729 } data = {
04730 .ied.buf = { 0 },
04731 .ied.pos = 0,
04732 };
04733
04734 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr);
04735
04736 if (!pvt) {
04737 return;
04738 }
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0)
04752 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) ||
04753 (f->datalen > sizeof(data))) {
04754
04755 return;
04756 }
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772 memcpy(&data, f->data, f->datalen);
04773 data.ied.pos = ie_data_pos;
04774
04775
04776
04777 data.ied.pos -= pvt->calltoken_ie_len;
04778 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken);
04779
04780
04781 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos;
04782
04783
04784 AST_LIST_REMOVE(&frame_queue[callno], f, list);
04785
04786
04787 iax2_frame_free(f);
04788
04789
04790 pvt->oseqno = 0;
04791 pvt->rseqno = 0;
04792 pvt->iseqno = 0;
04793 pvt->aseqno = 0;
04794 if (pvt->peercallno) {
04795 remove_by_peercallno(pvt);
04796 pvt->peercallno = 0;
04797 }
04798
04799
04800 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1);
04801 }
04802
04803 static void requirecalltoken_mark_auto(const char *name, int subclass)
04804 {
04805 struct iax2_user *user = NULL;
04806 struct iax2_peer *peer = NULL;
04807
04808 if (ast_strlen_zero(name)) {
04809 return;
04810 }
04811
04812 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) {
04813 user->calltoken_required = CALLTOKEN_YES;
04814 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) {
04815 peer->calltoken_required = CALLTOKEN_YES;
04816 }
04817
04818 if (peer) {
04819 peer_unref(peer);
04820 }
04821 if (user) {
04822 user_unref(user);
04823 }
04824 }
04825
04826
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843 static int handle_call_token(struct ast_iax2_full_hdr *fh, struct iax_ies *ies,
04844 struct sockaddr_in *sin, int fd)
04845 {
04846 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d"
04847 #define CALLTOKEN_IE_FORMAT "%u?%s"
04848 struct ast_str *buf = ast_str_alloca(256);
04849 time_t t = time(NULL);
04850 char hash[41];
04851 int subclass = uncompress_subclass(fh->csub);
04852
04853
04854 if (ies->calltoken && !ies->calltokendata) {
04855 struct iax_ie_data ied = {
04856 .buf = { 0 },
04857 .pos = 0,
04858 };
04859
04860
04861 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata);
04862 ast_sha1_hash(hash, ast_str_buffer(buf));
04863
04864 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash);
04865 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf));
04866 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied);
04867
04868 return 1;
04869
04870
04871 } else if (ies->calltoken && ies->calltokendata) {
04872 char *rec_hash = NULL;
04873 char *rec_ts = NULL;
04874 unsigned int rec_time;
04875
04876
04877 rec_hash = strchr((char *) ies->calltokendata, '?');
04878 if (rec_hash) {
04879 *rec_hash++ = '\0';
04880 rec_ts = (char *) ies->calltokendata;
04881 }
04882
04883
04884 if (!rec_hash || !rec_ts) {
04885 goto reject;
04886 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) {
04887 goto reject;
04888 }
04889
04890
04891 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata);
04892 ast_sha1_hash(hash, ast_str_buffer(buf));
04893
04894
04895 if (strcmp(hash, rec_hash)) {
04896 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr));
04897 goto reject;
04898 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) {
04899 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr));
04900 goto reject;
04901 }
04902
04903
04904
04905 requirecalltoken_mark_auto(ies->username, subclass);
04906 return 0;
04907
04908
04909 } else {
04910 if (calltoken_required(sin, ies->username, subclass)) {
04911 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest"));
04912 goto reject;
04913 }
04914 return 0;
04915 }
04916
04917 reject:
04918
04919 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) {
04920 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04921 } else {
04922 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
04923 }
04924
04925 return 1;
04926 }
04927
04928
04929
04930
04931
04932
04933
04934
04935
04936
04937
04938
04939
04940
04941
04942
04943
04944
04945
04946 static void parse_dial_string(char *data, struct parsed_dial_string *pds)
04947 {
04948 if (ast_strlen_zero(data))
04949 return;
04950
04951 pds->peer = strsep(&data, "/");
04952 pds->exten = strsep(&data, "/");
04953 pds->options = data;
04954
04955 if (pds->exten) {
04956 data = pds->exten;
04957 pds->exten = strsep(&data, "@");
04958 pds->context = data;
04959 }
04960
04961 if (strchr(pds->peer, '@')) {
04962 data = pds->peer;
04963 pds->username = strsep(&data, "@");
04964 pds->peer = data;
04965 }
04966
04967 if (pds->username) {
04968 data = pds->username;
04969 pds->username = strsep(&data, ":");
04970 pds->password = data;
04971 }
04972
04973 data = pds->peer;
04974 pds->peer = strsep(&data, ":");
04975 pds->port = data;
04976
04977
04978
04979
04980 if (pds->password && (pds->password[0] == '[')) {
04981 pds->key = ast_strip_quoted(pds->password, "[", "]");
04982 pds->password = NULL;
04983 }
04984 }
04985
04986 static int iax2_call(struct ast_channel *c, char *dest, int timeout)
04987 {
04988 struct sockaddr_in sin;
04989 char *l=NULL, *n=NULL, *tmpstr;
04990 struct iax_ie_data ied;
04991 char *defaultrdest = "s";
04992 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
04993 struct parsed_dial_string pds;
04994 struct create_addr_info cai;
04995 struct ast_var_t *var;
04996 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL);
04997 const char* osp_token_ptr;
04998 unsigned int osp_token_length;
04999 unsigned char osp_block_index;
05000 unsigned int osp_block_length;
05001 unsigned char osp_buffer[256];
05002
05003 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
05004 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
05005 return -1;
05006 }
05007
05008 memset(&cai, 0, sizeof(cai));
05009 cai.encmethods = iax2_encryption;
05010
05011 memset(&pds, 0, sizeof(pds));
05012 tmpstr = ast_strdupa(dest);
05013 parse_dial_string(tmpstr, &pds);
05014
05015 if (ast_strlen_zero(pds.peer)) {
05016 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest);
05017 return -1;
05018 }
05019 if (!pds.exten) {
05020 pds.exten = defaultrdest;
05021 }
05022 if (create_addr(pds.peer, c, &sin, &cai)) {
05023 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer);
05024 return -1;
05025 }
05026 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) {
05027 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n");
05028 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05029 return -1;
05030 }
05031 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
05032 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n");
05033 return -1;
05034 }
05035 if (!pds.username && !ast_strlen_zero(cai.username))
05036 pds.username = cai.username;
05037 if (!pds.password && !ast_strlen_zero(cai.secret))
05038 pds.password = cai.secret;
05039 if (!pds.key && !ast_strlen_zero(cai.outkey))
05040 pds.key = cai.outkey;
05041 if (!pds.context && !ast_strlen_zero(cai.peercontext))
05042 pds.context = cai.peercontext;
05043
05044
05045 ast_copy_string(c->context, cai.context, sizeof(c->context));
05046
05047 if (pds.port)
05048 sin.sin_port = htons(atoi(pds.port));
05049
05050 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL;
05051 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL;
05052
05053
05054 memset(&ied, 0, sizeof(ied));
05055
05056
05057 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
05058 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten);
05059 if (pds.options && strchr(pds.options, 'a')) {
05060
05061 iax_ie_append(&ied, IAX_IE_AUTOANSWER);
05062 }
05063
05064
05065 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs);
05066
05067 if (l) {
05068 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l);
05069 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05070 ast_party_id_presentation(&c->connected.id));
05071 } else if (n) {
05072 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES,
05073 ast_party_id_presentation(&c->connected.id));
05074 } else {
05075 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE);
05076 }
05077
05078 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan);
05079 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select);
05080
05081 if (n)
05082 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n);
05083 if (ast_test_flag64(iaxs[callno], IAX_SENDANI)
05084 && c->connected.ani.number.valid
05085 && c->connected.ani.number.str) {
05086 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str);
05087 }
05088
05089 if (!ast_strlen_zero(c->language))
05090 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language);
05091 if (!ast_strlen_zero(c->dialed.number.str)) {
05092 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str);
05093 }
05094 if (c->redirecting.from.number.valid
05095 && !ast_strlen_zero(c->redirecting.from.number.str)) {
05096 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str);
05097 }
05098
05099 if (pds.context)
05100 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context);
05101
05102 if (pds.username)
05103 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
05104
05105 if (cai.encmethods)
05106 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods);
05107
05108 ast_mutex_lock(&iaxsl[callno]);
05109
05110 if (!ast_strlen_zero(c->context))
05111 ast_string_field_set(iaxs[callno], context, c->context);
05112
05113 if (pds.username)
05114 ast_string_field_set(iaxs[callno], username, pds.username);
05115
05116 iaxs[callno]->encmethods = cai.encmethods;
05117
05118 iaxs[callno]->adsi = cai.adsi;
05119
05120 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret);
05121 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest);
05122
05123 if (pds.key)
05124 ast_string_field_set(iaxs[callno], outkey, pds.key);
05125 if (pds.password)
05126 ast_string_field_set(iaxs[callno], secret, pds.password);
05127
05128 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
05129 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
05130 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
05131 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
05132 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
05133 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone));
05134
05135 if (iaxs[callno]->maxtime) {
05136
05137 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2;
05138 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno));
05139 } else if (autokill) {
05140 iaxs[callno]->pingtime = autokill / 2;
05141 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno));
05142 }
05143
05144
05145 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN");
05146 if (!ast_strlen_zero(osp_token_ptr)) {
05147 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) {
05148 osp_block_index = 0;
05149 while (osp_token_length > 0) {
05150 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length;
05151 osp_buffer[0] = osp_block_index;
05152 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length);
05153 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1);
05154 osp_block_index++;
05155 osp_token_ptr += osp_block_length;
05156 osp_token_length -= osp_block_length;
05157 }
05158 } else
05159 ast_log(LOG_WARNING, "OSP token is too long\n");
05160 } else if (iaxdebug)
05161 ast_debug(1, "OSP token is undefined\n");
05162
05163
05164 iaxs[callno]->sockfd = cai.sockfd;
05165
05166
05167 if (variablestore) {
05168 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
05169 ast_debug(1, "Found an IAX variable store on this channel\n");
05170 AST_LIST_LOCK(variablelist);
05171 AST_LIST_TRAVERSE(variablelist, var, entries) {
05172 char tmp[256];
05173 int i;
05174 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
05175
05176 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
05177 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
05178 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp);
05179 }
05180 }
05181 AST_LIST_UNLOCK(variablelist);
05182 }
05183
05184
05185 add_empty_calltoken_ie(iaxs[callno], &ied);
05186 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
05187
05188 ast_mutex_unlock(&iaxsl[callno]);
05189 ast_setstate(c, AST_STATE_RINGING);
05190
05191 return 0;
05192 }
05193
05194 static int iax2_hangup(struct ast_channel *c)
05195 {
05196 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05197 struct iax_ie_data ied;
05198 int alreadygone;
05199 memset(&ied, 0, sizeof(ied));
05200 ast_mutex_lock(&iaxsl[callno]);
05201 if (callno && iaxs[callno]) {
05202 ast_debug(1, "We're hanging up %s now...\n", c->name);
05203 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE);
05204
05205 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause);
05206 if (!iaxs[callno]->error && !alreadygone) {
05207 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) {
05208 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno);
05209 }
05210 if (!iaxs[callno]) {
05211 ast_mutex_unlock(&iaxsl[callno]);
05212 return 0;
05213 }
05214 }
05215
05216 iax2_predestroy(callno);
05217
05218 if (iaxs[callno] && alreadygone) {
05219 ast_debug(1, "Really destroying %s now...\n", c->name);
05220 iax2_destroy(callno);
05221 } else if (iaxs[callno]) {
05222 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) {
05223 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno);
05224 iax2_destroy(callno);
05225 }
05226 }
05227 } else if (c->tech_pvt) {
05228
05229
05230
05231
05232 c->tech_pvt = NULL;
05233 }
05234 ast_mutex_unlock(&iaxsl[callno]);
05235 ast_verb(3, "Hungup '%s'\n", c->name);
05236 return 0;
05237 }
05238
05239
05240
05241
05242 static int wait_for_peercallno(struct chan_iax2_pvt *pvt)
05243 {
05244 unsigned short callno = pvt->callno;
05245
05246 if (!pvt->peercallno) {
05247
05248 int count = 10;
05249 while (count-- && pvt && !pvt->peercallno) {
05250 DEADLOCK_AVOIDANCE(&iaxsl[callno]);
05251 pvt = iaxs[callno];
05252 }
05253 if (!pvt->peercallno) {
05254 return -1;
05255 }
05256 }
05257
05258 return 0;
05259 }
05260
05261 static int iax2_setoption(struct ast_channel *c, int option, void *data, int datalen)
05262 {
05263 struct ast_option_header *h;
05264 int res;
05265
05266 switch (option) {
05267 case AST_OPTION_TXGAIN:
05268 case AST_OPTION_RXGAIN:
05269
05270 errno = ENOSYS;
05271 return -1;
05272 case AST_OPTION_OPRMODE:
05273 errno = EINVAL;
05274 return -1;
05275 case AST_OPTION_SECURE_SIGNALING:
05276 case AST_OPTION_SECURE_MEDIA:
05277 {
05278 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05279 ast_mutex_lock(&iaxsl[callno]);
05280 if ((*(int *) data)) {
05281 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05282 } else {
05283 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT);
05284 }
05285 ast_mutex_unlock(&iaxsl[callno]);
05286 return 0;
05287 }
05288
05289
05290
05291
05292 case AST_OPTION_TONE_VERIFY:
05293 case AST_OPTION_TDD:
05294 case AST_OPTION_RELAXDTMF:
05295 case AST_OPTION_AUDIO_MODE:
05296 case AST_OPTION_DIGIT_DETECT:
05297 case AST_OPTION_FAX_DETECT:
05298 {
05299 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05300 struct chan_iax2_pvt *pvt;
05301
05302 ast_mutex_lock(&iaxsl[callno]);
05303 pvt = iaxs[callno];
05304
05305 if (wait_for_peercallno(pvt)) {
05306 ast_mutex_unlock(&iaxsl[callno]);
05307 return -1;
05308 }
05309
05310 ast_mutex_unlock(&iaxsl[callno]);
05311
05312 if (!(h = ast_malloc(datalen + sizeof(*h)))) {
05313 return -1;
05314 }
05315
05316 h->flag = AST_OPTION_FLAG_REQUEST;
05317 h->option = htons(option);
05318 memcpy(h->data, data, datalen);
05319 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL,
05320 AST_CONTROL_OPTION, 0, (unsigned char *) h,
05321 datalen + sizeof(*h), -1);
05322 ast_free(h);
05323 return res;
05324 }
05325 default:
05326 return -1;
05327 }
05328
05329
05330 return -1;
05331 }
05332
05333 static int iax2_queryoption(struct ast_channel *c, int option, void *data, int *datalen)
05334 {
05335 switch (option) {
05336 case AST_OPTION_SECURE_SIGNALING:
05337 case AST_OPTION_SECURE_MEDIA:
05338 {
05339 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05340 ast_mutex_lock(&iaxsl[callno]);
05341 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0;
05342 ast_mutex_unlock(&iaxsl[callno]);
05343 return 0;
05344 }
05345 default:
05346 return -1;
05347 }
05348 }
05349
05350 static struct ast_frame *iax2_read(struct ast_channel *c)
05351 {
05352 ast_debug(1, "I should never be called!\n");
05353 return &ast_null_frame;
05354 }
05355
05356 static int iax2_key_rotate(const void *vpvt)
05357 {
05358 int res = 0;
05359 struct chan_iax2_pvt *pvt = (void *) vpvt;
05360 struct MD5Context md5;
05361 char key[17] = "";
05362 struct iax_ie_data ied = {
05363 .pos = 0,
05364 };
05365
05366 ast_mutex_lock(&iaxsl[pvt->callno]);
05367 pvt->keyrotateid =
05368 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt);
05369
05370 snprintf(key, sizeof(key), "%lX", ast_random());
05371
05372 MD5Init(&md5);
05373 MD5Update(&md5, (unsigned char *) key, strlen(key));
05374 MD5Final((unsigned char *) key, &md5);
05375
05376 IAX_DEBUGDIGEST("Sending", key);
05377
05378 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16);
05379
05380 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1);
05381
05382 build_ecx_key((unsigned char *) key, pvt);
05383
05384 ast_mutex_unlock(&iaxsl[pvt->callno]);
05385
05386 return res;
05387 }
05388
05389 static int iax2_start_transfer(unsigned short callno0, unsigned short callno1, int mediaonly)
05390 {
05391 int res;
05392 struct iax_ie_data ied0;
05393 struct iax_ie_data ied1;
05394 unsigned int transferid = (unsigned int)ast_random();
05395
05396 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) {
05397 ast_debug(1, "transfers are not supported for encrypted calls at this time");
05398 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER);
05399 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER);
05400 return 0;
05401 }
05402
05403 memset(&ied0, 0, sizeof(ied0));
05404 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr);
05405 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno);
05406 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid);
05407
05408 memset(&ied1, 0, sizeof(ied1));
05409 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr);
05410 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno);
05411 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid);
05412
05413 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1);
05414 if (res)
05415 return -1;
05416 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1);
05417 if (res)
05418 return -1;
05419 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05420 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN;
05421 return 0;
05422 }
05423
05424 static void lock_both(unsigned short callno0, unsigned short callno1)
05425 {
05426 ast_mutex_lock(&iaxsl[callno0]);
05427 while (ast_mutex_trylock(&iaxsl[callno1])) {
05428 DEADLOCK_AVOIDANCE(&iaxsl[callno0]);
05429 }
05430 }
05431
05432 static void unlock_both(unsigned short callno0, unsigned short callno1)
05433 {
05434 ast_mutex_unlock(&iaxsl[callno1]);
05435 ast_mutex_unlock(&iaxsl[callno0]);
05436 }
05437
05438 static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms)
05439 {
05440 struct ast_channel *cs[3];
05441 struct ast_channel *who, *other;
05442 int to = -1;
05443 int res = -1;
05444 int transferstarted=0;
05445 struct ast_frame *f;
05446 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt);
05447 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt);
05448 struct timeval waittimer = {0, 0};
05449
05450
05451 if (timeoutms > 0) {
05452 return AST_BRIDGE_FAILED;
05453 }
05454
05455 timeoutms = -1;
05456
05457 lock_both(callno0, callno1);
05458 if (!iaxs[callno0] || !iaxs[callno1]) {
05459 unlock_both(callno0, callno1);
05460 return AST_BRIDGE_FAILED;
05461 }
05462
05463 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) {
05464 iaxs[callno0]->bridgecallno = callno1;
05465 iaxs[callno1]->bridgecallno = callno0;
05466 }
05467 unlock_both(callno0, callno1);
05468
05469
05470 cs[0] = c0;
05471 cs[1] = c1;
05472 for (;;) {
05473
05474 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) {
05475 ast_verb(3, "Can't masquerade, we're different...\n");
05476
05477 if (c0->tech == &iax2_tech) {
05478 ast_mutex_lock(&iaxsl[callno0]);
05479 iaxs[callno0]->bridgecallno = 0;
05480 ast_mutex_unlock(&iaxsl[callno0]);
05481 }
05482 if (c1->tech == &iax2_tech) {
05483 ast_mutex_lock(&iaxsl[callno1]);
05484 iaxs[callno1]->bridgecallno = 0;
05485 ast_mutex_unlock(&iaxsl[callno1]);
05486 }
05487 return AST_BRIDGE_FAILED_NOWARN;
05488 }
05489 if (c0->nativeformats != c1->nativeformats) {
05490 char buf0[256];
05491 char buf1[256];
05492 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
05493 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats);
05494 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1);
05495
05496 lock_both(callno0, callno1);
05497 if (iaxs[callno0])
05498 iaxs[callno0]->bridgecallno = 0;
05499 if (iaxs[callno1])
05500 iaxs[callno1]->bridgecallno = 0;
05501 unlock_both(callno0, callno1);
05502 return AST_BRIDGE_FAILED_NOWARN;
05503 }
05504
05505 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) {
05506
05507 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) ||
05508 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA)))
05509 ast_log(LOG_WARNING, "Unable to start the transfer\n");
05510 transferstarted = 1;
05511 }
05512 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) {
05513
05514 struct timeval now = ast_tvnow();
05515 if (ast_tvzero(waittimer)) {
05516 waittimer = now;
05517 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) {
05518 c0->_softhangup |= AST_SOFTHANGUP_DEV;
05519 c1->_softhangup |= AST_SOFTHANGUP_DEV;
05520 *fo = NULL;
05521 *rc = c0;
05522 res = AST_BRIDGE_COMPLETE;
05523 break;
05524 }
05525 }
05526 to = 1000;
05527 who = ast_waitfor_n(cs, 2, &to);
05528 if (timeoutms > -1) {
05529 timeoutms -= (1000 - to);
05530 if (timeoutms < 0)
05531 timeoutms = 0;
05532 }
05533 if (!who) {
05534 if (!timeoutms) {
05535 res = AST_BRIDGE_RETRY;
05536 break;
05537 }
05538 if (ast_check_hangup(c0) || ast_check_hangup(c1)) {
05539 res = AST_BRIDGE_FAILED;
05540 break;
05541 }
05542 continue;
05543 }
05544 f = ast_read(who);
05545 if (!f) {
05546 *fo = NULL;
05547 *rc = who;
05548 res = AST_BRIDGE_COMPLETE;
05549 break;
05550 }
05551 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) {
05552 *fo = f;
05553 *rc = who;
05554 res = AST_BRIDGE_COMPLETE;
05555 break;
05556 }
05557 other = (who == c0) ? c1 : c0;
05558 if ((f->frametype == AST_FRAME_VOICE) ||
05559 (f->frametype == AST_FRAME_TEXT) ||
05560 (f->frametype == AST_FRAME_VIDEO) ||
05561 (f->frametype == AST_FRAME_IMAGE) ||
05562 (f->frametype == AST_FRAME_DTMF) ||
05563 (f->frametype == AST_FRAME_CONTROL)) {
05564
05565
05566
05567 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1;
05568 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) {
05569 *rc = who;
05570 *fo = f;
05571 res = AST_BRIDGE_COMPLETE;
05572
05573 break;
05574 }
05575
05576 ast_write(other, f);
05577 }
05578 ast_frfree(f);
05579
05580 cs[2] = cs[0];
05581 cs[0] = cs[1];
05582 cs[1] = cs[2];
05583 }
05584 lock_both(callno0, callno1);
05585 if(iaxs[callno0])
05586 iaxs[callno0]->bridgecallno = 0;
05587 if(iaxs[callno1])
05588 iaxs[callno1]->bridgecallno = 0;
05589 unlock_both(callno0, callno1);
05590 return res;
05591 }
05592
05593 static int iax2_answer(struct ast_channel *c)
05594 {
05595 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05596 ast_debug(1, "Answering IAX2 call\n");
05597 ast_mutex_lock(&iaxsl[callno]);
05598 if (iaxs[callno])
05599 iax2_ami_channelupdate(iaxs[callno]);
05600 ast_mutex_unlock(&iaxsl[callno]);
05601 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1);
05602 }
05603
05604 static int iax2_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
05605 {
05606 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05607 struct chan_iax2_pvt *pvt;
05608 int res = 0;
05609
05610 if (iaxdebug)
05611 ast_debug(1, "Indicating condition %d\n", condition);
05612
05613 ast_mutex_lock(&iaxsl[callno]);
05614 pvt = iaxs[callno];
05615
05616 if (wait_for_peercallno(pvt)) {
05617 res = -1;
05618 goto done;
05619 }
05620
05621 switch (condition) {
05622 case AST_CONTROL_HOLD:
05623 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05624 ast_moh_start(c, data, pvt->mohinterpret);
05625 goto done;
05626 }
05627 break;
05628 case AST_CONTROL_UNHOLD:
05629 if (strcasecmp(pvt->mohinterpret, "passthrough")) {
05630 ast_moh_stop(c);
05631 goto done;
05632 }
05633 break;
05634 case AST_CONTROL_CONNECTED_LINE:
05635 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE))
05636 goto done;
05637 break;
05638 }
05639
05640 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1);
05641
05642 done:
05643 ast_mutex_unlock(&iaxsl[callno]);
05644
05645 return res;
05646 }
05647
05648 static int iax2_transfer(struct ast_channel *c, const char *dest)
05649 {
05650 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
05651 struct iax_ie_data ied = { "", };
05652 char tmp[256], *context;
05653 enum ast_control_transfer message = AST_TRANSFER_SUCCESS;
05654 ast_copy_string(tmp, dest, sizeof(tmp));
05655 context = strchr(tmp, '@');
05656 if (context) {
05657 *context = '\0';
05658 context++;
05659 }
05660 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp);
05661 if (context)
05662 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context);
05663 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest);
05664 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message));
05665 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1);
05666 }
05667
05668 static int iax2_getpeertrunk(struct sockaddr_in sin)
05669 {
05670 struct iax2_peer *peer;
05671 int res = 0;
05672 struct ao2_iterator i;
05673
05674 i = ao2_iterator_init(peers, 0);
05675 while ((peer = ao2_iterator_next(&i))) {
05676 struct sockaddr_in peer_addr;
05677
05678 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
05679
05680 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) &&
05681 (peer_addr.sin_port == sin.sin_port)) {
05682 res = ast_test_flag64(peer, IAX_TRUNK);
05683 peer_unref(peer);
05684 break;
05685 }
05686 peer_unref(peer);
05687 }
05688 ao2_iterator_destroy(&i);
05689
05690 return res;
05691 }
05692
05693
05694 static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
05695 {
05696 struct ast_channel *tmp;
05697 struct chan_iax2_pvt *i;
05698 struct ast_variable *v = NULL;
05699
05700 if (!(i = iaxs[callno])) {
05701 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
05702 return NULL;
05703 }
05704
05705
05706 ast_mutex_unlock(&iaxsl[callno]);
05707 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
05708 ast_mutex_lock(&iaxsl[callno]);
05709 if (i != iaxs[callno]) {
05710 if (tmp) {
05711
05712 ast_mutex_unlock(&iaxsl[callno]);
05713 tmp = ast_channel_release(tmp);
05714 ast_mutex_lock(&iaxsl[callno]);
05715 }
05716 return NULL;
05717 }
05718 iax2_ami_channelupdate(i);
05719 if (!tmp)
05720 return NULL;
05721 tmp->tech = &iax2_tech;
05722
05723 tmp->nativeformats = capability;
05724 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
05725 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
05726 tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
05727
05728 if (!ast_strlen_zero(i->parkinglot))
05729 ast_string_field_set(tmp, parkinglot, i->parkinglot);
05730
05731
05732 if (!ast_strlen_zero(i->ani)) {
05733 tmp->caller.ani.number.valid = 1;
05734 tmp->caller.ani.number.str = ast_strdup(i->ani);
05735 } else if (!ast_strlen_zero(i->cid_num)) {
05736 tmp->caller.ani.number.valid = 1;
05737 tmp->caller.ani.number.str = ast_strdup(i->cid_num);
05738 }
05739 tmp->dialed.number.str = ast_strdup(i->dnid);
05740 tmp->redirecting.from.number.valid = 1;
05741 tmp->redirecting.from.number.str = ast_strdup(i->rdnis);
05742 tmp->caller.id.name.presentation = i->calling_pres;
05743 tmp->caller.id.number.presentation = i->calling_pres;
05744 tmp->caller.id.number.plan = i->calling_ton;
05745 tmp->dialed.transit_network_select = i->calling_tns;
05746 if (!ast_strlen_zero(i->language))
05747 ast_string_field_set(tmp, language, i->language);
05748 if (!ast_strlen_zero(i->accountcode))
05749 ast_string_field_set(tmp, accountcode, i->accountcode);
05750 if (i->amaflags)
05751 tmp->amaflags = i->amaflags;
05752 ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
05753 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten));
05754 if (i->adsi)
05755 tmp->adsicpe = i->peeradsicpe;
05756 else
05757 tmp->adsicpe = AST_ADSI_UNAVAILABLE;
05758 i->owner = tmp;
05759 i->capability = capability;
05760
05761
05762 if (i->vars) {
05763 for (v = i->vars ; v ; v = v->next)
05764 pbx_builtin_setvar_helper(tmp, v->name, v->value);
05765 }
05766 if (i->iaxvars) {
05767 struct ast_datastore *variablestore;
05768 struct ast_variable *var, *prev = NULL;
05769 AST_LIST_HEAD(, ast_var_t) *varlist;
05770 ast_debug(1, "Loading up the channel with IAXVARs\n");
05771 varlist = ast_calloc(1, sizeof(*varlist));
05772 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
05773 if (variablestore && varlist) {
05774 variablestore->data = varlist;
05775 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
05776 AST_LIST_HEAD_INIT(varlist);
05777 for (var = i->iaxvars; var; var = var->next) {
05778 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
05779 if (prev)
05780 ast_free(prev);
05781 prev = var;
05782 if (!newvar) {
05783
05784 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
05785 } else {
05786 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
05787 }
05788 }
05789 if (prev)
05790 ast_free(prev);
05791 i->iaxvars = NULL;
05792 ast_channel_datastore_add(i->owner, variablestore);
05793 } else {
05794 if (variablestore) {
05795 ast_datastore_free(variablestore);
05796 }
05797 if (varlist) {
05798 ast_free(varlist);
05799 }
05800 }
05801 }
05802
05803 if (state != AST_STATE_DOWN) {
05804 if (ast_pbx_start(tmp)) {
05805 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
05806 ast_hangup(tmp);
05807 i->owner = NULL;
05808 return NULL;
05809 }
05810 }
05811
05812 ast_module_ref(ast_module_info->self);
05813 return tmp;
05814 }
05815
05816 static unsigned int calc_txpeerstamp(struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now)
05817 {
05818 unsigned long int mssincetx;
05819 long int ms, pred;
05820
05821 tpeer->trunkact = *now;
05822 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime);
05823 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) {
05824
05825 tpeer->txtrunktime = *now;
05826 tpeer->lastsent = 999999;
05827 }
05828
05829 tpeer->lasttxtime = *now;
05830
05831
05832 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime);
05833
05834 pred = tpeer->lastsent + sampms;
05835 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW)
05836 ms = pred;
05837
05838
05839 if (ms == tpeer->lastsent)
05840 ms = tpeer->lastsent + 1;
05841 tpeer->lastsent = ms;
05842 return ms;
05843 }
05844
05845 static unsigned int fix_peerts(struct timeval *rxtrunktime, int callno, unsigned int ts)
05846 {
05847 long ms;
05848 if (ast_tvzero(iaxs[callno]->rxcore)) {
05849
05850 iaxs[callno]->rxcore = ast_tvnow();
05851
05852 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000;
05853 }
05854
05855 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore);
05856
05857 return ms + ts;
05858 }
05859
05860 static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f)
05861 {
05862 int ms;
05863 int voice = 0;
05864 int genuine = 0;
05865 int adjust;
05866 int rate = ast_format_rate(f->subclass.codec) / 1000;
05867 struct timeval *delivery = NULL;
05868
05869
05870
05871
05872
05873
05874
05875
05876 if (f) {
05877 if (f->frametype == AST_FRAME_VOICE) {
05878 voice = 1;
05879 delivery = &f->delivery;
05880 } else if (f->frametype == AST_FRAME_IAX) {
05881 genuine = 1;
05882 } else if (f->frametype == AST_FRAME_CNG) {
05883 p->notsilenttx = 0;
05884 }
05885 }
05886 if (ast_tvzero(p->offset)) {
05887 p->offset = ast_tvnow();
05888
05889 p->offset.tv_usec -= p->offset.tv_usec % 20000;
05890 }
05891
05892 if (ts)
05893 return ts;
05894
05895 if (delivery && !ast_tvzero(*delivery)) {
05896 ms = ast_tvdiff_ms(*delivery, p->offset);
05897 if (ms < 0) {
05898 ms = 0;
05899 }
05900 if (iaxdebug)
05901 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno);
05902 } else {
05903 ms = ast_tvdiff_ms(ast_tvnow(), p->offset);
05904 if (ms < 0)
05905 ms = 0;
05906 if (voice) {
05907
05908 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) {
05909
05910
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921
05922
05923
05924
05925
05926
05927 adjust = (ms - p->nextpred);
05928 if (adjust < 0)
05929 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000));
05930 else if (adjust > 0)
05931 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000));
05932
05933 if (!p->nextpred) {
05934 p->nextpred = ms;
05935 if (p->nextpred <= p->lastsent)
05936 p->nextpred = p->lastsent + 3;
05937 }
05938 ms = p->nextpred;
05939 } else {
05940
05941
05942
05943
05944
05945
05946
05947
05948
05949 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW )
05950 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n",
05951 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW);
05952
05953 if (f->samples >= rate)
05954 {
05955 int diff = ms % (f->samples / rate);
05956 if (diff)
05957 ms += f->samples/rate - diff;
05958 }
05959
05960 p->nextpred = ms;
05961 p->notsilenttx = 1;
05962 }
05963 } else if ( f->frametype == AST_FRAME_VIDEO ) {
05964
05965
05966
05967
05968
05969
05970
05971
05972 if ( (unsigned int)ms < p->lastsent )
05973 ms = p->lastsent;
05974 } else {
05975
05976
05977 if (genuine) {
05978
05979 if (ms <= p->lastsent)
05980 ms = p->lastsent + 3;
05981 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) {
05982
05983 ms = p->lastsent + 3;
05984 }
05985 }
05986 }
05987 p->lastsent = ms;
05988 if (voice)
05989 p->nextpred = p->nextpred + f->samples / rate;
05990 return ms;
05991 }
05992
05993 static unsigned int calc_rxstamp(struct chan_iax2_pvt *p, unsigned int offset)
05994 {
05995
05996
05997 int ms;
05998 #ifdef IAXTESTS
05999 int jit;
06000 #endif
06001
06002 if (ast_tvzero(p->rxcore)) {
06003 p->rxcore = ast_tvnow();
06004 if (iaxdebug)
06005 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n",
06006 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset);
06007 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000));
06008 #if 1
06009 if (iaxdebug)
06010 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n",
06011 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec));
06012 #endif
06013 }
06014
06015 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore);
06016 #ifdef IAXTESTS
06017 if (test_jit) {
06018 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) {
06019 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0));
06020 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0)))
06021 jit = -jit;
06022 ms += jit;
06023 }
06024 }
06025 if (test_late) {
06026 ms += test_late;
06027 test_late = 0;
06028 }
06029 #endif
06030 return ms;
06031 }
06032
06033 static struct iax2_trunk_peer *find_tpeer(struct sockaddr_in *sin, int fd)
06034 {
06035 struct iax2_trunk_peer *tpeer = NULL;
06036
06037
06038 AST_LIST_LOCK(&tpeers);
06039
06040 AST_LIST_TRAVERSE(&tpeers, tpeer, list) {
06041 if (!inaddrcmp(&tpeer->addr, sin)) {
06042 ast_mutex_lock(&tpeer->lock);
06043 break;
06044 }
06045 }
06046
06047 if (!tpeer) {
06048 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) {
06049 ast_mutex_init(&tpeer->lock);
06050 tpeer->lastsent = 9999;
06051 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr));
06052 tpeer->trunkact = ast_tvnow();
06053 ast_mutex_lock(&tpeer->lock);
06054 tpeer->sockfd = fd;
06055 #ifdef SO_NO_CHECK
06056 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
06057 #endif
06058 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port));
06059 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list);
06060 }
06061 }
06062
06063 AST_LIST_UNLOCK(&tpeers);
06064
06065 return tpeer;
06066 }
06067
06068 static int iax2_trunk_queue(struct chan_iax2_pvt *pvt, struct iax_frame *fr)
06069 {
06070 struct ast_frame *f;
06071 struct iax2_trunk_peer *tpeer;
06072 void *tmp, *ptr;
06073 struct timeval now;
06074 struct ast_iax2_meta_trunk_entry *met;
06075 struct ast_iax2_meta_trunk_mini *mtm;
06076
06077 f = &fr->af;
06078 tpeer = find_tpeer(&pvt->addr, pvt->sockfd);
06079 if (tpeer) {
06080 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) {
06081
06082 if (tpeer->trunkdataalloc < trunkmaxsize) {
06083 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) {
06084 ast_mutex_unlock(&tpeer->lock);
06085 return -1;
06086 }
06087
06088 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA;
06089 tpeer->trunkdata = tmp;
06090 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);
06091 } else {
06092 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));
06093 ast_mutex_unlock(&tpeer->lock);
06094 return -1;
06095 }
06096 }
06097
06098
06099 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen;
06100 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) {
06101 mtm = (struct ast_iax2_meta_trunk_mini *)ptr;
06102 mtm->len = htons(f->datalen);
06103 mtm->mini.callno = htons(pvt->callno);
06104 mtm->mini.ts = htons(0xffff & fr->ts);
06105 ptr += sizeof(struct ast_iax2_meta_trunk_mini);
06106 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini);
06107 } else {
06108 met = (struct ast_iax2_meta_trunk_entry *)ptr;
06109
06110 met->callno = htons(pvt->callno);
06111 met->len = htons(f->datalen);
06112
06113 ptr += sizeof(struct ast_iax2_meta_trunk_entry);
06114 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry);
06115 }
06116
06117 memcpy(ptr, f->data.ptr, f->datalen);
06118 tpeer->trunkdatalen += f->datalen;
06119
06120 tpeer->calls++;
06121
06122
06123 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu)
06124 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ;
06125
06126
06127 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) {
06128 now = ast_tvnow();
06129 send_trunk(tpeer, &now);
06130 trunk_untimed ++;
06131 }
06132
06133 ast_mutex_unlock(&tpeer->lock);
06134 }
06135 return 0;
06136 }
06137
06138
06139
06140 static void build_rand_pad(unsigned char *buf, ssize_t len)
06141 {
06142 long tmp;
06143 for (tmp = ast_random(); len > 0; tmp = ast_random()) {
06144 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len);
06145 buf += sizeof(tmp);
06146 len -= sizeof(tmp);
06147 }
06148 }
06149
06150 static void build_encryption_keys(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06151 {
06152 build_ecx_key(digest, pvt);
06153 ast_aes_set_decrypt_key(digest, &pvt->dcx);
06154 }
06155
06156 static void build_ecx_key(const unsigned char *digest, struct chan_iax2_pvt *pvt)
06157 {
06158
06159
06160
06161 build_rand_pad(pvt->semirand, sizeof(pvt->semirand));
06162 ast_aes_set_encrypt_key(digest, &pvt->ecx);
06163 ast_aes_set_decrypt_key(digest, &pvt->mydcx);
06164 }
06165
06166 static void memcpy_decrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx)
06167 {
06168 #if 0
06169
06170 int x;
06171 if (len % 16)
06172 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06173 for (x=0;x<len;x++)
06174 dst[x] = src[x] ^ 0xff;
06175 #else
06176 unsigned char lastblock[16] = { 0 };
06177 int x;
06178 while(len > 0) {
06179 ast_aes_decrypt(src, dst, dcx);
06180 for (x=0;x<16;x++)
06181 dst[x] ^= lastblock[x];
06182 memcpy(lastblock, src, sizeof(lastblock));
06183 dst += 16;
06184 src += 16;
06185 len -= 16;
06186 }
06187 #endif
06188 }
06189
06190 static void memcpy_encrypt(unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx)
06191 {
06192 #if 0
06193
06194 int x;
06195 if (len % 16)
06196 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len);
06197 for (x=0;x<len;x++)
06198 dst[x] = src[x] ^ 0xff;
06199 #else
06200 unsigned char curblock[16] = { 0 };
06201 int x;
06202 while(len > 0) {
06203 for (x=0;x<16;x++)
06204 curblock[x] ^= src[x];
06205 ast_aes_encrypt(curblock, dst, ecx);
06206 memcpy(curblock, dst, sizeof(curblock));
06207 dst += 16;
06208 src += 16;
06209 len -= 16;
06210 }
06211 #endif
06212 }
06213
06214 static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06215 {
06216 int padding;
06217 unsigned char *workspace;
06218
06219 workspace = alloca(*datalen);
06220 memset(f, 0, sizeof(*f));
06221 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06222 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06223 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr))
06224 return -1;
06225
06226 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx);
06227
06228 padding = 16 + (workspace[15] & 0x0f);
06229 if (iaxdebug)
06230 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]);
06231 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr))
06232 return -1;
06233
06234 *datalen -= padding;
06235 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06236 f->frametype = fh->type;
06237 if (f->frametype == AST_FRAME_VIDEO) {
06238 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
06239 } else if (f->frametype == AST_FRAME_VOICE) {
06240 f->subclass.codec = uncompress_subclass(fh->csub);
06241 } else {
06242 f->subclass.integer = uncompress_subclass(fh->csub);
06243 }
06244 } else {
06245 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06246 if (iaxdebug)
06247 ast_debug(1, "Decoding mini with length %d\n", *datalen);
06248 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr))
06249 return -1;
06250
06251 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx);
06252 padding = 16 + (workspace[15] & 0x0f);
06253 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr))
06254 return -1;
06255 *datalen -= padding;
06256 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06257 }
06258 return 0;
06259 }
06260
06261 static int encrypt_frame(ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen)
06262 {
06263 int padding;
06264 unsigned char *workspace;
06265 workspace = alloca(*datalen + 32);
06266 if (!workspace)
06267 return -1;
06268 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
06269 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh;
06270 if (iaxdebug)
06271 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen);
06272 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16);
06273 padding = 16 + (padding & 0xf);
06274 memcpy(workspace, poo, padding);
06275 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
06276 workspace[15] &= 0xf0;
06277 workspace[15] |= (padding & 0xf);
06278 if (iaxdebug)
06279 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]);
06280 *datalen += padding;
06281 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx);
06282 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr))
06283 memcpy(poo, workspace + *datalen - 32, 32);
06284 } else {
06285 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh;
06286 if (iaxdebug)
06287 ast_debug(1, "Encoding mini frame with length %d\n", *datalen);
06288 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16);
06289 padding = 16 + (padding & 0xf);
06290 memcpy(workspace, poo, padding);
06291 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr));
06292 workspace[15] &= 0xf0;
06293 workspace[15] |= (padding & 0x0f);
06294 *datalen += padding;
06295 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx);
06296 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr))
06297 memcpy(poo, workspace + *datalen - 32, 32);
06298 }
06299 return 0;
06300 }
06301
06302 static int decrypt_frame(int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen)
06303 {
06304 int res=-1;
06305 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) {
06306
06307 struct MD5Context md5;
06308 unsigned char digest[16];
06309 char *tmppw, *stringp;
06310
06311 tmppw = ast_strdupa(iaxs[callno]->secret);
06312 stringp = tmppw;
06313 while ((tmppw = strsep(&stringp, ";"))) {
06314 MD5Init(&md5);
06315 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
06316 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
06317 MD5Final(digest, &md5);
06318 build_encryption_keys(digest, iaxs[callno]);
06319 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06320 if (!res) {
06321 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED);
06322 break;
06323 }
06324 }
06325 } else
06326 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen);
06327 return res;
06328 }
06329
06330 static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final)
06331 {
06332
06333
06334
06335 struct ast_iax2_full_hdr *fh;
06336 struct ast_iax2_mini_hdr *mh;
06337 struct ast_iax2_video_hdr *vh;
06338 struct {
06339 struct iax_frame fr2;
06340 unsigned char buffer[4096];
06341 } frb;
06342 struct iax_frame *fr;
06343 int res;
06344 int sendmini=0;
06345 unsigned int lastsent;
06346 unsigned int fts;
06347
06348 frb.fr2.afdatalen = sizeof(frb.buffer);
06349
06350 if (!pvt) {
06351 ast_log(LOG_WARNING, "No private structure for packet?\n");
06352 return -1;
06353 }
06354
06355 lastsent = pvt->lastsent;
06356
06357
06358 fts = calc_timestamp(pvt, ts, f);
06359
06360
06361
06362
06363 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0)
06364 return 0;
06365 #if 0
06366 ast_log(LOG_NOTICE,
06367 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n",
06368 *("=!" + (f->frametype == AST_FRAME_VOICE)),
06369 IAX_CALLENCRYPTED(pvt) ? "" : "not ",
06370 pvt->keyrotateid != -1 ? "" : "no "
06371 );
06372 #endif
06373 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) {
06374 iax2_key_rotate(pvt);
06375 }
06376
06377 if ((ast_test_flag64(pvt, IAX_TRUNK) ||
06378 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) ||
06379 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L))))
06380 &&
06381 (f->frametype == AST_FRAME_VOICE)
06382 &&
06383 (f->subclass.codec == pvt->svoiceformat)
06384 ) {
06385
06386 now = 1;
06387
06388 sendmini = 1;
06389 }
06390 if ( f->frametype == AST_FRAME_VIDEO ) {
06391
06392
06393
06394
06395
06396 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
06397 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
06398 ) {
06399 now = 1;
06400 sendmini = 1;
06401 } else {
06402 now = 0;
06403 sendmini = 0;
06404 }
06405 pvt->lastvsent = fts;
06406 }
06407 if (f->frametype == AST_FRAME_IAX) {
06408
06409 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX;
06410 if (!pvt->first_iax_message) {
06411 pvt->first_iax_message = pvt->last_iax_message;
06412 }
06413 }
06414
06415 if (now) {
06416 fr = &frb.fr2;
06417 } else
06418 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));
06419 if (!fr) {
06420 ast_log(LOG_WARNING, "Out of memory\n");
06421 return -1;
06422 }
06423
06424 iax_frame_wrap(fr, f);
06425
06426 fr->ts = fts;
06427 fr->callno = pvt->callno;
06428 fr->transfer = transfer;
06429 fr->final = final;
06430 fr->encmethods = 0;
06431 if (!sendmini) {
06432
06433 if (seqno > -1)
06434 fr->oseqno = seqno;
06435 else
06436 fr->oseqno = pvt->oseqno++;
06437 fr->iseqno = pvt->iseqno;
06438 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr));
06439 fh->scallno = htons(fr->callno | IAX_FLAG_FULL);
06440 fh->ts = htonl(fr->ts);
06441 fh->oseqno = fr->oseqno;
06442 if (transfer) {
06443 fh->iseqno = 0;
06444 } else
06445 fh->iseqno = fr->iseqno;
06446
06447 if (!transfer)
06448 pvt->aseqno = fr->iseqno;
06449 fh->type = fr->af.frametype & 0xFF;
06450
06451 if (fr->af.frametype == AST_FRAME_VIDEO) {
06452 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
06453 } else if (fr->af.frametype == AST_FRAME_VOICE) {
06454 fh->csub = compress_subclass(fr->af.subclass.codec);
06455 } else {
06456 fh->csub = compress_subclass(fr->af.subclass.integer);
06457 }
06458
06459 if (transfer) {
06460 fr->dcallno = pvt->transfercallno;
06461 } else
06462 fr->dcallno = pvt->peercallno;
06463 fh->dcallno = htons(fr->dcallno);
06464 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr);
06465 fr->data = fh;
06466 fr->retries = 0;
06467
06468 fr->retrytime = pvt->pingtime * 2;
06469 if (fr->retrytime < MIN_RETRY_TIME)
06470 fr->retrytime = MIN_RETRY_TIME;
06471 if (fr->retrytime > MAX_RETRY_TIME)
06472 fr->retrytime = MAX_RETRY_TIME;
06473
06474 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
06475 fr->retries = -1;
06476 else if (f->frametype == AST_FRAME_VOICE)
06477 pvt->svoiceformat = f->subclass.codec;
06478 else if (f->frametype == AST_FRAME_VIDEO)
06479 pvt->svideoformat = f->subclass.codec & ~0x1LL;
06480 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06481 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06482 if (fr->transfer)
06483 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06484 else
06485 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr));
06486 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen);
06487 fr->encmethods = pvt->encmethods;
06488 fr->ecx = pvt->ecx;
06489 fr->mydcx = pvt->mydcx;
06490 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand));
06491 } else
06492 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06493 }
06494
06495 if (now) {
06496 res = send_packet(fr);
06497 } else
06498 res = iax2_transmit(fr);
06499 } else {
06500 if (ast_test_flag64(pvt, IAX_TRUNK)) {
06501 iax2_trunk_queue(pvt, fr);
06502 res = 0;
06503 } else if (fr->af.frametype == AST_FRAME_VIDEO) {
06504
06505 fr->oseqno = -1;
06506 fr->iseqno = -1;
06507 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
06508 vh->zeros = 0;
06509 vh->callno = htons(0x8000 | fr->callno);
06510 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
06511 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
06512 fr->data = vh;
06513 fr->retries = -1;
06514 res = send_packet(fr);
06515 } else {
06516
06517 fr->oseqno = -1;
06518 fr->iseqno = -1;
06519
06520 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr));
06521 mh->callno = htons(fr->callno);
06522 mh->ts = htons(fr->ts & 0xFFFF);
06523 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr);
06524 fr->data = mh;
06525 fr->retries = -1;
06526 if (pvt->transferring == TRANSFER_MEDIAPASS)
06527 fr->transfer = 1;
06528 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
06529 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
06530 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen);
06531 } else
06532 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n");
06533 }
06534 res = send_packet(fr);
06535 }
06536 }
06537 return res;
06538 }
06539
06540 static char *handle_cli_iax2_show_users(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06541 {
06542 regex_t regexbuf;
06543 int havepattern = 0;
06544
06545 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n"
06546 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n"
06547
06548 struct iax2_user *user = NULL;
06549 char auth[90];
06550 char *pstr = "";
06551 struct ao2_iterator i;
06552
06553 switch (cmd) {
06554 case CLI_INIT:
06555 e->command = "iax2 show users [like]";
06556 e->usage =
06557 "Usage: iax2 show users [like <pattern>]\n"
06558 " Lists all known IAX2 users.\n"
06559 " Optional regular expression pattern is used to filter the user list.\n";
06560 return NULL;
06561 case CLI_GENERATE:
06562 return NULL;
06563 }
06564
06565 switch (a->argc) {
06566 case 5:
06567 if (!strcasecmp(a->argv[3], "like")) {
06568 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
06569 return CLI_SHOWUSAGE;
06570 havepattern = 1;
06571 } else
06572 return CLI_SHOWUSAGE;
06573 case 3:
06574 break;
06575 default:
06576 return CLI_SHOWUSAGE;
06577 }
06578
06579 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref");
06580 i = ao2_iterator_init(users, 0);
06581 for (user = ao2_iterator_next(&i); user;
06582 user_unref(user), user = ao2_iterator_next(&i)) {
06583 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0))
06584 continue;
06585
06586 if (!ast_strlen_zero(user->secret)) {
06587 ast_copy_string(auth,user->secret, sizeof(auth));
06588 } else if (!ast_strlen_zero(user->inkeys)) {
06589 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys);
06590 } else
06591 ast_copy_string(auth, "-no secret-", sizeof(auth));
06592
06593 if(ast_test_flag64(user, IAX_CODEC_NOCAP))
06594 pstr = "REQ Only";
06595 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS))
06596 pstr = "Disabled";
06597 else
06598 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host";
06599
06600 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods,
06601 user->contexts ? user->contexts->context : DEFAULT_CONTEXT,
06602 user->ha ? "Yes" : "No", pstr);
06603 }
06604 ao2_iterator_destroy(&i);
06605
06606 if (havepattern)
06607 regfree(®exbuf);
06608
06609 return CLI_SUCCESS;
06610 #undef FORMAT
06611 #undef FORMAT2
06612 }
06613
06614 static int __iax2_show_peers(int fd, int *total, struct mansession *s, const int argc, const char * const argv[])
06615 {
06616 regex_t regexbuf;
06617 int havepattern = 0;
06618 int total_peers = 0;
06619 int online_peers = 0;
06620 int offline_peers = 0;
06621 int unmonitored_peers = 0;
06622 struct ao2_iterator i;
06623
06624 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n"
06625 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n"
06626
06627 struct iax2_peer *peer = NULL;
06628 char name[256];
06629 struct ast_str *encmethods = ast_str_alloca(256);
06630 int registeredonly=0;
06631 char idtext[256] = "";
06632 switch (argc) {
06633 case 6:
06634 if (!strcasecmp(argv[3], "registered"))
06635 registeredonly = 1;
06636 else
06637 return RESULT_SHOWUSAGE;
06638 if (!strcasecmp(argv[4], "like")) {
06639 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB))
06640 return RESULT_SHOWUSAGE;
06641 havepattern = 1;
06642 } else
06643 return RESULT_SHOWUSAGE;
06644 break;
06645 case 5:
06646 if (!strcasecmp(argv[3], "like")) {
06647 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB))
06648 return RESULT_SHOWUSAGE;
06649 havepattern = 1;
06650 } else
06651 return RESULT_SHOWUSAGE;
06652 break;
06653 case 4:
06654 if (!strcasecmp(argv[3], "registered"))
06655 registeredonly = 1;
06656 else
06657 return RESULT_SHOWUSAGE;
06658 break;
06659 case 3:
06660 break;
06661 default:
06662 return RESULT_SHOWUSAGE;
06663 }
06664
06665
06666 if (!s)
06667 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status");
06668
06669 i = ao2_iterator_init(peers, 0);
06670 for (peer = ao2_iterator_next(&i); peer;
06671 peer_unref(peer), peer = ao2_iterator_next(&i)) {
06672 char nm[20];
06673 char status[20];
06674 int retstatus;
06675 struct sockaddr_in peer_addr;
06676
06677 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
06678
06679 if (registeredonly && !peer_addr.sin_addr.s_addr) {
06680 continue;
06681 }
06682 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) {
06683 continue;
06684 }
06685
06686 if (!ast_strlen_zero(peer->username))
06687 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
06688 else
06689 ast_copy_string(name, peer->name, sizeof(name));
06690
06691 encmethods_to_str(peer->encmethods, encmethods);
06692 retstatus = peer_status(peer, status, sizeof(status));
06693 if (retstatus > 0)
06694 online_peers++;
06695 else if (!retstatus)
06696 offline_peers++;
06697 else
06698 unmonitored_peers++;
06699
06700 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
06701
06702 if (s) {
06703 astman_append(s,
06704 "Event: PeerEntry\r\n%s"
06705 "Channeltype: IAX2\r\n"
06706 "ObjectName: %s\r\n"
06707 "ChanObjectType: peer\r\n"
06708 "IPaddress: %s\r\n"
06709 "IPport: %d\r\n"
06710 "Dynamic: %s\r\n"
06711 "Trunk: %s\r\n"
06712 "Encryption: %s\r\n"
06713 "Status: %s\r\n\r\n",
06714 idtext,
06715 name,
06716 ast_sockaddr_stringify_addr(&peer->addr),
06717 ast_sockaddr_port(&peer->addr),
06718 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no",
06719 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no",
06720 peer->encmethods ? ast_str_buffer(encmethods) : "no",
06721 status);
06722 } else {
06723 ast_cli(fd, FORMAT, name,
06724 ast_sockaddr_stringify_addr(&peer->addr),
06725 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)",
06726 nm,
06727 ast_sockaddr_port(&peer->addr),
06728 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ",
06729 peer->encmethods ? "(E)" : " ",
06730 status);
06731 }
06732 total_peers++;
06733 }
06734 ao2_iterator_destroy(&i);
06735
06736 if (!s)
06737 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n",
06738 total_peers, online_peers, offline_peers, unmonitored_peers);
06739
06740 if (havepattern)
06741 regfree(®exbuf);
06742
06743 if (total)
06744 *total = total_peers;
06745
06746 return RESULT_SUCCESS;
06747 #undef FORMAT
06748 #undef FORMAT2
06749 }
06750
06751 static char *handle_cli_iax2_show_threads(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06752 {
06753 struct iax2_thread *thread = NULL;
06754 time_t t;
06755 int threadcount = 0, dynamiccount = 0;
06756 char type;
06757
06758 switch (cmd) {
06759 case CLI_INIT:
06760 e->command = "iax2 show threads";
06761 e->usage =
06762 "Usage: iax2 show threads\n"
06763 " Lists status of IAX helper threads\n";
06764 return NULL;
06765 case CLI_GENERATE:
06766 return NULL;
06767 }
06768 if (a->argc != 3)
06769 return CLI_SHOWUSAGE;
06770
06771 ast_cli(a->fd, "IAX2 Thread Information\n");
06772 time(&t);
06773 ast_cli(a->fd, "Idle Threads:\n");
06774 AST_LIST_LOCK(&idle_list);
06775 AST_LIST_TRAVERSE(&idle_list, thread, list) {
06776 #ifdef DEBUG_SCHED_MULTITHREAD
06777 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06778 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06779 #else
06780 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06781 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06782 #endif
06783 threadcount++;
06784 }
06785 AST_LIST_UNLOCK(&idle_list);
06786 ast_cli(a->fd, "Active Threads:\n");
06787 AST_LIST_LOCK(&active_list);
06788 AST_LIST_TRAVERSE(&active_list, thread, list) {
06789 if (thread->type == IAX_THREAD_TYPE_DYNAMIC)
06790 type = 'D';
06791 else
06792 type = 'P';
06793 #ifdef DEBUG_SCHED_MULTITHREAD
06794 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n",
06795 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06796 #else
06797 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n",
06798 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06799 #endif
06800 threadcount++;
06801 }
06802 AST_LIST_UNLOCK(&active_list);
06803 ast_cli(a->fd, "Dynamic Threads:\n");
06804 AST_LIST_LOCK(&dynamic_list);
06805 AST_LIST_TRAVERSE(&dynamic_list, thread, list) {
06806 #ifdef DEBUG_SCHED_MULTITHREAD
06807 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n",
06808 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc);
06809 #else
06810 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n",
06811 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions);
06812 #endif
06813 dynamiccount++;
06814 }
06815 AST_LIST_UNLOCK(&dynamic_list);
06816 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount);
06817 return CLI_SUCCESS;
06818 }
06819
06820 static char *handle_cli_iax2_unregister(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06821 {
06822 struct iax2_peer *p;
06823
06824 switch (cmd) {
06825 case CLI_INIT:
06826 e->command = "iax2 unregister";
06827 e->usage =
06828 "Usage: iax2 unregister <peername>\n"
06829 " Unregister (force expiration) an IAX2 peer from the registry.\n";
06830 return NULL;
06831 case CLI_GENERATE:
06832 return complete_iax2_unregister(a->line, a->word, a->pos, a->n);
06833 }
06834
06835 if (a->argc != 3)
06836 return CLI_SHOWUSAGE;
06837
06838 p = find_peer(a->argv[2], 1);
06839 if (p) {
06840 if (p->expire > 0) {
06841 struct iax2_peer tmp_peer = {
06842 .name = a->argv[2],
06843 };
06844 struct iax2_peer *peer;
06845
06846 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
06847 if (peer) {
06848 expire_registry(peer_ref(peer));
06849 peer_unref(peer);
06850 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]);
06851 } else {
06852 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]);
06853 }
06854 } else {
06855 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
06856 }
06857 } else {
06858 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]);
06859 }
06860 return CLI_SUCCESS;
06861 }
06862
06863 static char *complete_iax2_unregister(const char *line, const char *word, int pos, int state)
06864 {
06865 int which = 0;
06866 struct iax2_peer *p = NULL;
06867 char *res = NULL;
06868 int wordlen = strlen(word);
06869
06870
06871 if (pos == 2) {
06872 struct ao2_iterator i = ao2_iterator_init(peers, 0);
06873 while ((p = ao2_iterator_next(&i))) {
06874 if (!strncasecmp(p->name, word, wordlen) &&
06875 ++which > state && p->expire > 0) {
06876 res = ast_strdup(p->name);
06877 peer_unref(p);
06878 break;
06879 }
06880 peer_unref(p);
06881 }
06882 ao2_iterator_destroy(&i);
06883 }
06884
06885 return res;
06886 }
06887
06888 static char *handle_cli_iax2_show_peers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06889 {
06890 switch (cmd) {
06891 case CLI_INIT:
06892 e->command = "iax2 show peers";
06893 e->usage =
06894 "Usage: iax2 show peers [registered] [like <pattern>]\n"
06895 " Lists all known IAX2 peers.\n"
06896 " Optional 'registered' argument lists only peers with known addresses.\n"
06897 " Optional regular expression pattern is used to filter the peer list.\n";
06898 return NULL;
06899 case CLI_GENERATE:
06900 return NULL;
06901 }
06902
06903 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) {
06904 case RESULT_SHOWUSAGE:
06905 return CLI_SHOWUSAGE;
06906 case RESULT_FAILURE:
06907 return CLI_FAILURE;
06908 default:
06909 return CLI_SUCCESS;
06910 }
06911 }
06912
06913 static int manager_iax2_show_netstats(struct mansession *s, const struct message *m)
06914 {
06915 ast_cli_netstats(s, -1, 0);
06916 astman_append(s, "\r\n");
06917 return RESULT_SUCCESS;
06918 }
06919
06920 static char *handle_cli_iax2_show_firmware(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
06921 {
06922 struct iax_firmware *cur = NULL;
06923
06924 switch (cmd) {
06925 case CLI_INIT:
06926 e->command = "iax2 show firmware";
06927 e->usage =
06928 "Usage: iax2 show firmware\n"
06929 " Lists all known IAX firmware images.\n";
06930 return NULL;
06931 case CLI_GENERATE:
06932 return NULL;
06933 }
06934
06935 if (a->argc != 3 && a->argc != 4)
06936 return CLI_SHOWUSAGE;
06937
06938 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size");
06939 AST_LIST_LOCK(&firmwares);
06940 AST_LIST_TRAVERSE(&firmwares, cur, list) {
06941 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) {
06942 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname,
06943 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen));
06944 }
06945 }
06946 AST_LIST_UNLOCK(&firmwares);
06947
06948 return CLI_SUCCESS;
06949 }
06950
06951
06952 static int manager_iax2_show_peers(struct mansession *s, const struct message *m)
06953 {
06954 static const char * const a[] = { "iax2", "show", "peers" };
06955 const char *id = astman_get_header(m,"ActionID");
06956 char idtext[256] = "";
06957 int total = 0;
06958
06959 if (!ast_strlen_zero(id))
06960 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06961
06962 astman_send_listack(s, m, "Peer status list will follow", "start");
06963
06964 __iax2_show_peers(-1, &total, s, 3, a);
06965
06966 astman_append(s,
06967 "Event: PeerlistComplete\r\n"
06968 "EventList: Complete\r\n"
06969 "ListItems: %d\r\n"
06970 "%s"
06971 "\r\n", total, idtext);
06972 return 0;
06973 }
06974
06975
06976 static int manager_iax2_show_peer_list(struct mansession *s, const struct message *m)
06977 {
06978 struct iax2_peer *peer = NULL;
06979 int peer_count = 0;
06980 char nm[20];
06981 char status[20];
06982 const char *id = astman_get_header(m,"ActionID");
06983 char idtext[256] = "";
06984 struct ast_str *encmethods = ast_str_alloca(256);
06985 struct ao2_iterator i;
06986
06987 if (!ast_strlen_zero(id))
06988 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
06989
06990 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext);
06991
06992
06993 i = ao2_iterator_init(peers, 0);
06994 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) {
06995 encmethods_to_str(peer->encmethods, encmethods);
06996 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext);
06997 if (!ast_strlen_zero(peer->username)) {
06998 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username);
06999 } else {
07000 astman_append(s, "ObjectName: %s\r\n", peer->name);
07001 }
07002 astman_append(s, "ChanObjectType: peer\r\n");
07003 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr));
07004 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm));
07005 astman_append(s, "Mask: %s\r\n", nm);
07006 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr));
07007 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No");
07008 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No");
07009 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No");
07010 peer_status(peer, status, sizeof(status));
07011 astman_append(s, "Status: %s\r\n\r\n", status);
07012 peer_count++;
07013 }
07014 ao2_iterator_destroy(&i);
07015
07016 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count);
07017 return RESULT_SUCCESS;
07018 }
07019
07020
07021 static char *regstate2str(int regstate)
07022 {
07023 switch(regstate) {
07024 case REG_STATE_UNREGISTERED:
07025 return "Unregistered";
07026 case REG_STATE_REGSENT:
07027 return "Request Sent";
07028 case REG_STATE_AUTHSENT:
07029 return "Auth. Sent";
07030 case REG_STATE_REGISTERED:
07031 return "Registered";
07032 case REG_STATE_REJECTED:
07033 return "Rejected";
07034 case REG_STATE_TIMEOUT:
07035 return "Timeout";
07036 case REG_STATE_NOAUTH:
07037 return "No Authentication";
07038 default:
07039 return "Unknown";
07040 }
07041 }
07042
07043 static char *handle_cli_iax2_show_registry(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07044 {
07045 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n"
07046 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n"
07047 struct iax2_registry *reg = NULL;
07048 char host[80];
07049 char perceived[80];
07050 int counter = 0;
07051
07052 switch (cmd) {
07053 case CLI_INIT:
07054 e->command = "iax2 show registry";
07055 e->usage =
07056 "Usage: iax2 show registry\n"
07057 " Lists all registration requests and status.\n";
07058 return NULL;
07059 case CLI_GENERATE:
07060 return NULL;
07061 }
07062 if (a->argc != 3)
07063 return CLI_SHOWUSAGE;
07064 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State");
07065 AST_LIST_LOCK(®istrations);
07066 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07067 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07068 if (reg->us.sin_addr.s_addr)
07069 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07070 else
07071 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07072 ast_cli(a->fd, FORMAT, host,
07073 (reg->dnsmgr) ? "Y" : "N",
07074 reg->username, perceived, reg->refresh, regstate2str(reg->regstate));
07075 counter++;
07076 }
07077 AST_LIST_UNLOCK(®istrations);
07078 ast_cli(a->fd, "%d IAX2 registrations.\n", counter);
07079 return CLI_SUCCESS;
07080 #undef FORMAT
07081 #undef FORMAT2
07082 }
07083
07084 static int manager_iax2_show_registry(struct mansession *s, const struct message *m)
07085 {
07086 const char *id = astman_get_header(m, "ActionID");
07087 struct iax2_registry *reg = NULL;
07088 char idtext[256] = "";
07089 char host[80] = "";
07090 char perceived[80] = "";
07091 int total = 0;
07092
07093 if (!ast_strlen_zero(id))
07094 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
07095
07096 astman_send_listack(s, m, "Registrations will follow", "start");
07097
07098 AST_LIST_LOCK(®istrations);
07099 AST_LIST_TRAVERSE(®istrations, reg, entry) {
07100 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr));
07101
07102 if (reg->us.sin_addr.s_addr) {
07103 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
07104 } else {
07105 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived));
07106 }
07107
07108 astman_append(s,
07109 "Event: RegistryEntry\r\n"
07110 "%s"
07111 "Host: %s\r\n"
07112 "DNSmanager: %s\r\n"
07113 "Username: %s\r\n"
07114 "Perceived: %s\r\n"
07115 "Refresh: %d\r\n"
07116 "State: %s\r\n"
07117 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived,
07118 reg->refresh, regstate2str(reg->regstate));
07119
07120 total++;
07121 }
07122 AST_LIST_UNLOCK(®istrations);
07123
07124 astman_append(s,
07125 "Event: RegistrationsComplete\r\n"
07126 "EventList: Complete\r\n"
07127 "ListItems: %d\r\n"
07128 "%s"
07129 "\r\n", total, idtext);
07130
07131 return 0;
07132 }
07133
07134 static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07135 {
07136 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n"
07137 #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"
07138 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n"
07139 int x;
07140 int numchans = 0;
07141 char first_message[10] = { 0, };
07142 char last_message[10] = { 0, };
07143
07144 switch (cmd) {
07145 case CLI_INIT:
07146 e->command = "iax2 show channels";
07147 e->usage =
07148 "Usage: iax2 show channels\n"
07149 " Lists all currently active IAX channels.\n";
07150 return NULL;
07151 case CLI_GENERATE:
07152 return NULL;
07153 }
07154
07155 if (a->argc != 3)
07156 return CLI_SHOWUSAGE;
07157 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg");
07158 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07159 ast_mutex_lock(&iaxsl[x]);
07160 if (iaxs[x]) {
07161 int lag, jitter, localdelay;
07162 jb_info jbinfo;
07163 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07164 jb_getinfo(iaxs[x]->jb, &jbinfo);
07165 jitter = jbinfo.jitter;
07166 localdelay = jbinfo.current - jbinfo.min;
07167 } else {
07168 jitter = -1;
07169 localdelay = 0;
07170 }
07171
07172 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07173 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07174 lag = iaxs[x]->remote_rr.delay;
07175 ast_cli(a->fd, FORMAT,
07176 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07177 ast_inet_ntoa(iaxs[x]->addr.sin_addr),
07178 S_OR(iaxs[x]->username, "(None)"),
07179 iaxs[x]->callno, iaxs[x]->peercallno,
07180 iaxs[x]->oseqno, iaxs[x]->iseqno,
07181 lag,
07182 jitter,
07183 localdelay,
07184 ast_getformatname(iaxs[x]->voiceformat),
07185 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07186 first_message,
07187 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07188 last_message);
07189 numchans++;
07190 }
07191 ast_mutex_unlock(&iaxsl[x]);
07192 }
07193 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07194 return CLI_SUCCESS;
07195 #undef FORMAT
07196 #undef FORMAT2
07197 #undef FORMATB
07198 }
07199
07200 static int ast_cli_netstats(struct mansession *s, int fd, int limit_fmt)
07201 {
07202 int x;
07203 int numchans = 0;
07204 char first_message[10] = { 0, };
07205 char last_message[10] = { 0, };
07206 #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"
07207 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n"
07208 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
07209 ast_mutex_lock(&iaxsl[x]);
07210 if (iaxs[x]) {
07211 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo;
07212 jb_info jbinfo;
07213 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message));
07214 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message));
07215
07216 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) {
07217 jb_getinfo(iaxs[x]->jb, &jbinfo);
07218 localjitter = jbinfo.jitter;
07219 localdelay = jbinfo.current - jbinfo.min;
07220 locallost = jbinfo.frames_lost;
07221 locallosspct = jbinfo.losspct/1000;
07222 localdropped = jbinfo.frames_dropped;
07223 localooo = jbinfo.frames_ooo;
07224 } else {
07225 localjitter = -1;
07226 localdelay = 0;
07227 locallost = -1;
07228 locallosspct = -1;
07229 localdropped = 0;
07230 localooo = -1;
07231 }
07232 if (s)
07233 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07234 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07235 iaxs[x]->pingtime,
07236 localjitter,
07237 localdelay,
07238 locallost,
07239 locallosspct,
07240 localdropped,
07241 localooo,
07242 iaxs[x]->frames_received/1000,
07243 iaxs[x]->remote_rr.jitter,
07244 iaxs[x]->remote_rr.delay,
07245 iaxs[x]->remote_rr.losscnt,
07246 iaxs[x]->remote_rr.losspct,
07247 iaxs[x]->remote_rr.dropped,
07248 iaxs[x]->remote_rr.ooo,
07249 iaxs[x]->remote_rr.packets/1000,
07250 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07251 first_message,
07252 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07253 last_message);
07254 else
07255 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2,
07256 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)",
07257 iaxs[x]->pingtime,
07258 localjitter,
07259 localdelay,
07260 locallost,
07261 locallosspct,
07262 localdropped,
07263 localooo,
07264 iaxs[x]->frames_received/1000,
07265 iaxs[x]->remote_rr.jitter,
07266 iaxs[x]->remote_rr.delay,
07267 iaxs[x]->remote_rr.losscnt,
07268 iaxs[x]->remote_rr.losspct,
07269 iaxs[x]->remote_rr.dropped,
07270 iaxs[x]->remote_rr.ooo,
07271 iaxs[x]->remote_rr.packets/1000,
07272 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07273 first_message,
07274 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
07275 last_message);
07276 numchans++;
07277 }
07278 ast_mutex_unlock(&iaxsl[x]);
07279 }
07280
07281 return numchans;
07282 }
07283
07284 static char *handle_cli_iax2_show_netstats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07285 {
07286 int numchans = 0;
07287
07288 switch (cmd) {
07289 case CLI_INIT:
07290 e->command = "iax2 show netstats";
07291 e->usage =
07292 "Usage: iax2 show netstats\n"
07293 " Lists network status for all currently active IAX channels.\n";
07294 return NULL;
07295 case CLI_GENERATE:
07296 return NULL;
07297 }
07298 if (a->argc != 3)
07299 return CLI_SHOWUSAGE;
07300 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n");
07301 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n");
07302 numchans = ast_cli_netstats(NULL, a->fd, 1);
07303 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : "");
07304 return CLI_SUCCESS;
07305 }
07306
07307 static char *handle_cli_iax2_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07308 {
07309 switch (cmd) {
07310 case CLI_INIT:
07311 e->command = "iax2 set debug {on|off|peer}";
07312 e->usage =
07313 "Usage: iax2 set debug {on|off|peer peername}\n"
07314 " Enables/Disables dumping of IAX packets for debugging purposes.\n";
07315 return NULL;
07316 case CLI_GENERATE:
07317 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer"))
07318 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0);
07319 return NULL;
07320 }
07321
07322 if (a->argc < e->args || a->argc > e->args + 1)
07323 return CLI_SHOWUSAGE;
07324
07325 if (!strcasecmp(a->argv[3], "peer")) {
07326 struct iax2_peer *peer;
07327 struct sockaddr_in peer_addr;
07328
07329
07330 if (a->argc != e->args + 1)
07331 return CLI_SHOWUSAGE;
07332
07333 peer = find_peer(a->argv[4], 1);
07334
07335 if (!peer) {
07336 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]);
07337 return CLI_FAILURE;
07338 }
07339
07340 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
07341
07342 debugaddr.sin_addr = peer_addr.sin_addr;
07343 debugaddr.sin_port = peer_addr.sin_port;
07344
07345 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n",
07346 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
07347
07348 ao2_ref(peer, -1);
07349 } else if (!strncasecmp(a->argv[3], "on", 2)) {
07350 iaxdebug = 1;
07351 ast_cli(a->fd, "IAX2 Debugging Enabled\n");
07352 } else {
07353 iaxdebug = 0;
07354 memset(&debugaddr, 0, sizeof(debugaddr));
07355 ast_cli(a->fd, "IAX2 Debugging Disabled\n");
07356 }
07357 return CLI_SUCCESS;
07358 }
07359
07360 static char *handle_cli_iax2_set_debug_trunk(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07361 {
07362 switch (cmd) {
07363 case CLI_INIT:
07364 e->command = "iax2 set debug trunk {on|off}";
07365 e->usage =
07366 "Usage: iax2 set debug trunk {on|off}\n"
07367 " Enables/Disables debugging of IAX trunking\n";
07368 return NULL;
07369 case CLI_GENERATE:
07370 return NULL;
07371 }
07372
07373 if (a->argc != e->args)
07374 return CLI_SHOWUSAGE;
07375
07376 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
07377 iaxtrunkdebug = 1;
07378 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n");
07379 } else {
07380 iaxtrunkdebug = 0;
07381 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n");
07382 }
07383 return CLI_SUCCESS;
07384 }
07385
07386 static char *handle_cli_iax2_set_debug_jb(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
07387 {
07388 switch (cmd) {
07389 case CLI_INIT:
07390 e->command = "iax2 set debug jb {on|off}";
07391 e->usage =
07392 "Usage: iax2 set debug jb {on|off}\n"
07393 " Enables/Disables jitterbuffer debugging information\n";
07394 return NULL;
07395 case CLI_GENERATE:
07396 return NULL;
07397 }
07398
07399 if (a->argc != e->args)
07400 return CLI_SHOWUSAGE;
07401
07402 if (!strncasecmp(a->argv[e->args -1], "on", 2)) {
07403 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output);
07404 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n");
07405 } else {
07406 jb_setoutput(jb_error_output, jb_warning_output, NULL);
07407 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n");
07408 }
07409 return CLI_SUCCESS;
07410 }
07411
07412 static int iax2_write(struct ast_channel *c, struct ast_frame *f)
07413 {
07414 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt);
07415 int res = -1;
07416 ast_mutex_lock(&iaxsl[callno]);
07417 if (iaxs[callno]) {
07418
07419 if (!iaxs[callno]->error) {
07420 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE))
07421 res = 0;
07422
07423 else if (f->frametype == AST_FRAME_NULL)
07424 res = 0;
07425 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH))
07426 res = 0;
07427 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
07428 res = 0;
07429 else
07430
07431 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0);
07432 } else {
07433 ast_debug(1, "Write error: %s\n", strerror(errno));
07434 }
07435 }
07436
07437 ast_mutex_unlock(&iaxsl[callno]);
07438 return res;
07439 }
07440
07441 static int __send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno,
07442 int now, int transfer, int final)
07443 {
07444 struct ast_frame f = { 0, };
07445 int res = 0;
07446
07447 f.frametype = type;
07448 f.subclass.integer = command;
07449 f.datalen = datalen;
07450 f.src = __FUNCTION__;
07451 f.data.ptr = (void *) data;
07452
07453 if ((res = queue_signalling(i, &f)) <= 0) {
07454 return res;
07455 }
07456
07457 return iax2_send(i, &f, ts, seqno, now, transfer, final);
07458 }
07459
07460 static int send_command(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07461 {
07462 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0);
07463 }
07464
07465 static int send_command_locked(unsigned short callno, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno)
07466 {
07467 int res;
07468 ast_mutex_lock(&iaxsl[callno]);
07469 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno);
07470 ast_mutex_unlock(&iaxsl[callno]);
07471 return res;
07472 }
07473
07474
07475
07476
07477
07478
07479 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)
07480 {
07481 int call_num = i->callno;
07482
07483 iax2_predestroy(i->callno);
07484 if (!iaxs[call_num])
07485 return -1;
07486 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1);
07487 }
07488
07489 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)
07490 {
07491 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0);
07492 }
07493
07494 static int send_command_transfer(struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen)
07495 {
07496 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0);
07497 }
07498
07499 static int apply_context(struct iax2_context *con, const char *context)
07500 {
07501 while(con) {
07502 if (!strcmp(con->context, context) || !strcmp(con->context, "*"))
07503 return -1;
07504 con = con->next;
07505 }
07506 return 0;
07507 }
07508
07509
07510 static int check_access(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07511 {
07512
07513 int res = -1;
07514 int version = 2;
07515 struct iax2_user *user = NULL, *best = NULL;
07516 int bestscore = 0;
07517 int gotcapability = 0;
07518 struct ast_variable *v = NULL, *tmpvar = NULL;
07519 struct ao2_iterator i;
07520 struct ast_sockaddr addr;
07521
07522 if (!iaxs[callno])
07523 return res;
07524 if (ies->called_number)
07525 ast_string_field_set(iaxs[callno], exten, ies->called_number);
07526 if (ies->calling_number) {
07527 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) {
07528 ast_shrink_phone_number(ies->calling_number);
07529 }
07530 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number);
07531 }
07532 if (ies->calling_name)
07533 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name);
07534 if (ies->calling_ani)
07535 ast_string_field_set(iaxs[callno], ani, ies->calling_ani);
07536 if (ies->dnid)
07537 ast_string_field_set(iaxs[callno], dnid, ies->dnid);
07538 if (ies->rdnis)
07539 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis);
07540 if (ies->called_context)
07541 ast_string_field_set(iaxs[callno], context, ies->called_context);
07542 if (ies->language)
07543 ast_string_field_set(iaxs[callno], language, ies->language);
07544 if (ies->username)
07545 ast_string_field_set(iaxs[callno], username, ies->username);
07546 if (ies->calling_ton > -1)
07547 iaxs[callno]->calling_ton = ies->calling_ton;
07548 if (ies->calling_tns > -1)
07549 iaxs[callno]->calling_tns = ies->calling_tns;
07550 if (ies->calling_pres > -1)
07551 iaxs[callno]->calling_pres = ies->calling_pres;
07552 if (ies->format)
07553 iaxs[callno]->peerformat = ies->format;
07554 if (ies->adsicpe)
07555 iaxs[callno]->peeradsicpe = ies->adsicpe;
07556 if (ies->capability) {
07557 gotcapability = 1;
07558 iaxs[callno]->peercapability = ies->capability;
07559 }
07560 if (ies->version)
07561 version = ies->version;
07562
07563
07564 if (ies->codec_prefs) {
07565 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0);
07566 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0);
07567 }
07568
07569 if (!gotcapability)
07570 iaxs[callno]->peercapability = iaxs[callno]->peerformat;
07571 if (version > IAX_PROTO_VERSION) {
07572 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n",
07573 ast_inet_ntoa(sin->sin_addr), version);
07574 return res;
07575 }
07576
07577 i = ao2_iterator_init(users, 0);
07578 ast_sockaddr_from_sin(&addr, sin);
07579 while ((user = ao2_iterator_next(&i))) {
07580 if ((ast_strlen_zero(iaxs[callno]->username) ||
07581 !strcmp(iaxs[callno]->username, user->name))
07582 && ast_apply_ha(user->ha, &addr)
07583 && (ast_strlen_zero(iaxs[callno]->context) ||
07584 apply_context(user->contexts, iaxs[callno]->context))) {
07585 if (!ast_strlen_zero(iaxs[callno]->username)) {
07586
07587 if (best)
07588 user_unref(best);
07589 best = user;
07590 break;
07591 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) {
07592
07593 if (user->ha) {
07594
07595 if (bestscore < 4) {
07596 bestscore = 4;
07597 if (best)
07598 user_unref(best);
07599 best = user;
07600 continue;
07601 }
07602 } else {
07603
07604 if (bestscore < 3) {
07605 bestscore = 3;
07606 if (best)
07607 user_unref(best);
07608 best = user;
07609 continue;
07610 }
07611 }
07612 } else {
07613 if (user->ha) {
07614
07615 if (bestscore < 2) {
07616 bestscore = 2;
07617 if (best)
07618 user_unref(best);
07619 best = user;
07620 continue;
07621 }
07622 } else {
07623
07624 if (bestscore < 1) {
07625 bestscore = 1;
07626 if (best)
07627 user_unref(best);
07628 best = user;
07629 continue;
07630 }
07631 }
07632 }
07633 }
07634 user_unref(user);
07635 }
07636 ao2_iterator_destroy(&i);
07637 user = best;
07638 if (!user && !ast_strlen_zero(iaxs[callno]->username)) {
07639 user = realtime_user(iaxs[callno]->username, sin);
07640 if (user && !ast_strlen_zero(iaxs[callno]->context) &&
07641 !apply_context(user->contexts, iaxs[callno]->context)) {
07642 user = user_unref(user);
07643 }
07644 }
07645 if (user) {
07646
07647
07648 for (v = user->vars ; v ; v = v->next) {
07649 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) {
07650 tmpvar->next = iaxs[callno]->vars;
07651 iaxs[callno]->vars = tmpvar;
07652 }
07653 }
07654
07655 if (user->maxauthreq > 0)
07656 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ);
07657 iaxs[callno]->prefs = user->prefs;
07658 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT);
07659 iaxs[callno]->encmethods = user->encmethods;
07660
07661 if (ast_strlen_zero(iaxs[callno]->username))
07662 ast_string_field_set(iaxs[callno], username, user->name);
07663
07664 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK);
07665 iaxs[callno]->capability = user->capability;
07666
07667 if (ast_strlen_zero(iaxs[callno]->context)) {
07668 if (user->contexts)
07669 ast_string_field_set(iaxs[callno], context, user->contexts->context);
07670 else
07671 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT);
07672 }
07673
07674 ast_string_field_set(iaxs[callno], inkeys, user->inkeys);
07675
07676 iaxs[callno]->authmethods = user->authmethods;
07677 iaxs[callno]->adsi = user->adsi;
07678
07679 if (ast_test_flag64(user, IAX_HASCALLERID)) {
07680 iaxs[callno]->calling_tns = 0;
07681 iaxs[callno]->calling_ton = 0;
07682 ast_string_field_set(iaxs[callno], cid_num, user->cid_num);
07683 ast_string_field_set(iaxs[callno], cid_name, user->cid_name);
07684 ast_string_field_set(iaxs[callno], ani, user->cid_num);
07685 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN;
07686 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) {
07687 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
07688 }
07689 if (!ast_strlen_zero(user->accountcode))
07690 ast_string_field_set(iaxs[callno], accountcode, user->accountcode);
07691 if (!ast_strlen_zero(user->mohinterpret))
07692 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret);
07693 if (!ast_strlen_zero(user->mohsuggest))
07694 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest);
07695 if (!ast_strlen_zero(user->parkinglot))
07696 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot);
07697 if (user->amaflags)
07698 iaxs[callno]->amaflags = user->amaflags;
07699 if (!ast_strlen_zero(user->language))
07700 ast_string_field_set(iaxs[callno], language, user->language);
07701 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
07702
07703 if (!ast_strlen_zero(user->dbsecret)) {
07704 char *family, *key=NULL;
07705 char buf[80];
07706 family = ast_strdupa(user->dbsecret);
07707 key = strchr(family, '/');
07708 if (key) {
07709 *key = '\0';
07710 key++;
07711 }
07712 if (!key || ast_db_get(family, key, buf, sizeof(buf)))
07713 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret);
07714 else
07715 ast_string_field_set(iaxs[callno], secret, buf);
07716 } else
07717 ast_string_field_set(iaxs[callno], secret, user->secret);
07718 res = 0;
07719 user = user_unref(user);
07720 } else {
07721
07722
07723
07724
07725 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
07726 ast_string_field_set(iaxs[callno], secret, "badsecret");
07727 iaxs[callno]->authrej = 1;
07728 if (!ast_strlen_zero(iaxs[callno]->username)) {
07729
07730 res = 0;
07731 }
07732 }
07733 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK);
07734 return res;
07735 }
07736
07737 static int raw_hangup(struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd)
07738 {
07739 struct ast_iax2_full_hdr fh;
07740 fh.scallno = htons(src | IAX_FLAG_FULL);
07741 fh.dcallno = htons(dst);
07742 fh.ts = 0;
07743 fh.oseqno = 0;
07744 fh.iseqno = 0;
07745 fh.type = AST_FRAME_IAX;
07746 fh.csub = compress_subclass(IAX_COMMAND_INVAL);
07747 iax_outputframe(NULL, &fh, 0, sin, 0);
07748 #if 0
07749 if (option_debug)
07750 #endif
07751 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n",
07752 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst);
07753 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin));
07754 }
07755
07756 static void merge_encryption(struct chan_iax2_pvt *p, unsigned int enc)
07757 {
07758
07759 p->encmethods &= enc;
07760 if (p->encmethods) {
07761 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){
07762 p->keyrotateid = -2;
07763 }
07764 if (p->encmethods & IAX_ENCRYPT_AES128)
07765 p->encmethods = IAX_ENCRYPT_AES128;
07766 else
07767 p->encmethods = 0;
07768 }
07769 }
07770
07771
07772
07773
07774
07775
07776
07777 static int authenticate_request(int call_num)
07778 {
07779 struct iax_ie_data ied;
07780 int res = -1, authreq_restrict = 0;
07781 char challenge[10];
07782 struct chan_iax2_pvt *p = iaxs[call_num];
07783
07784 memset(&ied, 0, sizeof(ied));
07785
07786
07787 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07788 struct iax2_user *user, tmp_user = {
07789 .name = p->username,
07790 };
07791
07792 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07793 if (user) {
07794 if (user->curauthreq == user->maxauthreq)
07795 authreq_restrict = 1;
07796 else
07797 user->curauthreq++;
07798 user = user_unref(user);
07799 }
07800 }
07801
07802
07803 if (authreq_restrict) {
07804 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached");
07805 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED);
07806 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1);
07807 return 0;
07808 }
07809
07810 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods);
07811 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) {
07812 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
07813 ast_string_field_set(p, challenge, challenge);
07814
07815 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge);
07816 }
07817 if (p->encmethods)
07818 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods);
07819
07820 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username);
07821
07822 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1);
07823
07824 if (p->encmethods)
07825 ast_set_flag64(p, IAX_ENCRYPTED);
07826
07827 return res;
07828 }
07829
07830 static int authenticate_verify(struct chan_iax2_pvt *p, struct iax_ies *ies)
07831 {
07832 char requeststr[256];
07833 char md5secret[256] = "";
07834 char secret[256] = "";
07835 char rsasecret[256] = "";
07836 int res = -1;
07837 int x;
07838 struct iax2_user *user, tmp_user = {
07839 .name = p->username,
07840 };
07841
07842 if (p->authrej) {
07843 return res;
07844 }
07845 user = ao2_find(users, &tmp_user, OBJ_POINTER);
07846 if (user) {
07847 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) {
07848 ast_atomic_fetchadd_int(&user->curauthreq, -1);
07849 ast_clear_flag64(p, IAX_MAXAUTHREQ);
07850 }
07851 ast_string_field_set(p, host, user->name);
07852 user = user_unref(user);
07853 }
07854 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) {
07855 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.");
07856 return res;
07857 }
07858 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED))
07859 return res;
07860 if (ies->password)
07861 ast_copy_string(secret, ies->password, sizeof(secret));
07862 if (ies->md5_result)
07863 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07864 if (ies->rsa_result)
07865 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07866 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) {
07867 struct ast_key *key;
07868 char *keyn;
07869 char tmpkey[256];
07870 char *stringp=NULL;
07871 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey));
07872 stringp=tmpkey;
07873 keyn = strsep(&stringp, ":");
07874 while(keyn) {
07875 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07876 if (key && !ast_check_signature(key, p->challenge, rsasecret)) {
07877 res = 0;
07878 break;
07879 } else if (!key)
07880 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn);
07881 keyn = strsep(&stringp, ":");
07882 }
07883 } else if (p->authmethods & IAX_AUTH_MD5) {
07884 struct MD5Context md5;
07885 unsigned char digest[16];
07886 char *tmppw, *stringp;
07887
07888 tmppw = ast_strdupa(p->secret);
07889 stringp = tmppw;
07890 while((tmppw = strsep(&stringp, ";"))) {
07891 MD5Init(&md5);
07892 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge));
07893 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
07894 MD5Final(digest, &md5);
07895
07896 for (x=0;x<16;x++)
07897 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
07898 if (!strcasecmp(requeststr, md5secret)) {
07899 res = 0;
07900 break;
07901 }
07902 }
07903 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) {
07904 if (!strcmp(secret, p->secret))
07905 res = 0;
07906 }
07907 return res;
07908 }
07909
07910
07911 static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies *ies)
07912 {
07913 char requeststr[256] = "";
07914 char peer[256] = "";
07915 char md5secret[256] = "";
07916 char rsasecret[256] = "";
07917 char secret[256] = "";
07918 struct iax2_peer *p = NULL;
07919 struct ast_key *key;
07920 char *keyn;
07921 int x;
07922 int expire = 0;
07923 int res = -1;
07924 struct ast_sockaddr addr;
07925
07926 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07927
07928 if (ies->username)
07929 ast_copy_string(peer, ies->username, sizeof(peer));
07930 if (ies->password)
07931 ast_copy_string(secret, ies->password, sizeof(secret));
07932 if (ies->md5_result)
07933 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret));
07934 if (ies->rsa_result)
07935 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret));
07936 if (ies->refresh)
07937 expire = ies->refresh;
07938
07939 if (ast_strlen_zero(peer)) {
07940 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr));
07941 return -1;
07942 }
07943
07944
07945 ast_mutex_unlock(&iaxsl[callno]);
07946 p = find_peer(peer, 1);
07947 ast_mutex_lock(&iaxsl[callno]);
07948 if (!p || !iaxs[callno]) {
07949 if (iaxs[callno]) {
07950 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT));
07951
07952 ast_string_field_set(iaxs[callno], secret, "badsecret");
07953
07954
07955
07956
07957
07958
07959
07960
07961
07962 if (ast_strlen_zero(iaxs[callno]->challenge) &&
07963 !(!ast_strlen_zero(secret) && plaintext)) {
07964
07965 res = 0;
07966 }
07967 }
07968 if (authdebug && !p)
07969 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07970 goto return_unref;
07971 }
07972
07973 if (!ast_test_flag64(p, IAX_DYNAMIC)) {
07974 if (authdebug)
07975 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr));
07976 goto return_unref;
07977 }
07978
07979 ast_sockaddr_from_sin(&addr, sin);
07980 if (!ast_apply_ha(p->ha, &addr)) {
07981 if (authdebug)
07982 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
07983 goto return_unref;
07984 }
07985 ast_string_field_set(iaxs[callno], secret, p->secret);
07986 ast_string_field_set(iaxs[callno], inkeys, p->inkeys);
07987
07988 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) {
07989 if (!ast_strlen_zero(p->inkeys)) {
07990 char tmpkeys[256];
07991 char *stringp=NULL;
07992 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys));
07993 stringp=tmpkeys;
07994 keyn = strsep(&stringp, ":");
07995 while(keyn) {
07996 key = ast_key_get(keyn, AST_KEY_PUBLIC);
07997 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) {
07998 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
07999 break;
08000 } else if (!key)
08001 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn);
08002 keyn = strsep(&stringp, ":");
08003 }
08004 if (!keyn) {
08005 if (authdebug)
08006 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys);
08007 goto return_unref;
08008 }
08009 } else {
08010 if (authdebug)
08011 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer);
08012 goto return_unref;
08013 }
08014 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) {
08015 struct MD5Context md5;
08016 unsigned char digest[16];
08017 char *tmppw, *stringp;
08018
08019 tmppw = ast_strdupa(p->secret);
08020 stringp = tmppw;
08021 while((tmppw = strsep(&stringp, ";"))) {
08022 MD5Init(&md5);
08023 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge));
08024 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw));
08025 MD5Final(digest, &md5);
08026 for (x=0;x<16;x++)
08027 sprintf(requeststr + (x << 1), "%2.2x", digest[x]);
08028 if (!strcasecmp(requeststr, md5secret))
08029 break;
08030 }
08031 if (tmppw) {
08032 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08033 } else {
08034 if (authdebug)
08035 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret);
08036 goto return_unref;
08037 }
08038 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) {
08039
08040 if (strcmp(secret, p->secret)) {
08041 if (authdebug)
08042 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name);
08043 goto return_unref;
08044 } else
08045 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED);
08046 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) {
08047
08048 goto return_unref;
08049 }
08050 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08051
08052
08053 res = 0;
08054
08055 return_unref:
08056 if (iaxs[callno]) {
08057 ast_string_field_set(iaxs[callno], peer, peer);
08058
08059
08060 if (expire && (expire < iaxs[callno]->expiry)) {
08061 iaxs[callno]->expiry = expire;
08062 }
08063 }
08064
08065 if (p) {
08066 peer_unref(p);
08067 }
08068 return res;
08069 }
08070
08071 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)
08072 {
08073 int res = -1;
08074 int x;
08075 if (!ast_strlen_zero(keyn)) {
08076 if (!(authmethods & IAX_AUTH_RSA)) {
08077 if (ast_strlen_zero(secret))
08078 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));
08079 } else if (ast_strlen_zero(challenge)) {
08080 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr));
08081 } else {
08082 char sig[256];
08083 struct ast_key *key;
08084 key = ast_key_get(keyn, AST_KEY_PRIVATE);
08085 if (!key) {
08086 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn);
08087 } else {
08088 if (ast_sign(key, (char*)challenge, sig)) {
08089 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n");
08090 res = -1;
08091 } else {
08092 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig);
08093 res = 0;
08094 }
08095 }
08096 }
08097 }
08098
08099 if (res && !ast_strlen_zero(secret)) {
08100 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) {
08101 struct MD5Context md5;
08102 unsigned char digest[16];
08103 char digres[128];
08104 MD5Init(&md5);
08105 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge));
08106 MD5Update(&md5, (unsigned char *)secret, strlen(secret));
08107 MD5Final(digest, &md5);
08108
08109 for (x=0;x<16;x++)
08110 sprintf(digres + (x << 1), "%2.2x", digest[x]);
08111 if (pvt) {
08112 build_encryption_keys(digest, pvt);
08113 }
08114 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres);
08115 res = 0;
08116 } else if (authmethods & IAX_AUTH_PLAINTEXT) {
08117 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret);
08118 res = 0;
08119 } else
08120 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods);
08121 }
08122 return res;
08123 }
08124
08125
08126
08127
08128
08129 static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
08130 {
08131 struct iax2_peer *peer = NULL;
08132
08133 int res = -1;
08134 int authmethods = 0;
08135 struct iax_ie_data ied;
08136 uint16_t callno = p->callno;
08137
08138 memset(&ied, 0, sizeof(ied));
08139
08140 if (ies->username)
08141 ast_string_field_set(p, username, ies->username);
08142 if (ies->challenge)
08143 ast_string_field_set(p, challenge, ies->challenge);
08144 if (ies->authmethods)
08145 authmethods = ies->authmethods;
08146 if (authmethods & IAX_AUTH_MD5)
08147 merge_encryption(p, ies->encmethods);
08148 else
08149 p->encmethods = 0;
08150
08151
08152 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) {
08153
08154 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p);
08155 } else {
08156 struct ao2_iterator i = ao2_iterator_init(peers, 0);
08157 while ((peer = ao2_iterator_next(&i))) {
08158 struct sockaddr_in peer_addr;
08159
08160 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
08161
08162 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name))
08163
08164 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username)))
08165
08166 && (!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)))
08167
08168 ) {
08169 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p);
08170 if (!res) {
08171 peer_unref(peer);
08172 break;
08173 }
08174 }
08175 peer_unref(peer);
08176 }
08177 ao2_iterator_destroy(&i);
08178 if (!peer) {
08179
08180
08181 const char *peer_name = ast_strdupa(p->peer);
08182 ast_mutex_unlock(&iaxsl[callno]);
08183 if ((peer = realtime_peer(peer_name, NULL))) {
08184 ast_mutex_lock(&iaxsl[callno]);
08185 if (!(p = iaxs[callno])) {
08186 peer_unref(peer);
08187 return -1;
08188 }
08189 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p);
08190 peer_unref(peer);
08191 }
08192 if (!peer) {
08193 ast_mutex_lock(&iaxsl[callno]);
08194 if (!(p = iaxs[callno]))
08195 return -1;
08196 }
08197 }
08198 }
08199
08200 if (ies->encmethods) {
08201 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED);
08202 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) {
08203 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set");
08204 return -1;
08205 }
08206 if (!res) {
08207 struct ast_datastore *variablestore;
08208 struct ast_variable *var, *prev = NULL;
08209 AST_LIST_HEAD(, ast_var_t) *varlist;
08210 varlist = ast_calloc(1, sizeof(*varlist));
08211 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
08212 if (variablestore && varlist && p->owner) {
08213 variablestore->data = varlist;
08214 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
08215 AST_LIST_HEAD_INIT(varlist);
08216 for (var = ies->vars; var; var = var->next) {
08217 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
08218 if (prev)
08219 ast_free(prev);
08220 prev = var;
08221 if (!newvar) {
08222
08223 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08224 } else {
08225 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
08226 }
08227 }
08228 if (prev)
08229 ast_free(prev);
08230 ies->vars = NULL;
08231 ast_channel_datastore_add(p->owner, variablestore);
08232 } else {
08233 if (p->owner)
08234 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
08235 if (variablestore)
08236 ast_datastore_free(variablestore);
08237 if (varlist)
08238 ast_free(varlist);
08239 }
08240 }
08241
08242 if (!res)
08243 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1);
08244 return res;
08245 }
08246
08247 static int iax2_do_register(struct iax2_registry *reg);
08248
08249 static void __iax2_do_register_s(const void *data)
08250 {
08251 struct iax2_registry *reg = (struct iax2_registry *)data;
08252 reg->expire = -1;
08253 iax2_do_register(reg);
08254 }
08255
08256 static int iax2_do_register_s(const void *data)
08257 {
08258 #ifdef SCHED_MULTITHREADED
08259 if (schedule_action(__iax2_do_register_s, data))
08260 #endif
08261 __iax2_do_register_s(data);
08262 return 0;
08263 }
08264
08265 static int try_transfer(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08266 {
08267 int newcall = 0;
08268 char newip[256];
08269 struct iax_ie_data ied;
08270 struct sockaddr_in new;
08271
08272
08273 memset(&ied, 0, sizeof(ied));
08274 if (ies->apparent_addr)
08275 memmove(&new, ies->apparent_addr, sizeof(new));
08276 if (ies->callno)
08277 newcall = ies->callno;
08278 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) {
08279 ast_log(LOG_WARNING, "Invalid transfer request\n");
08280 return -1;
08281 }
08282 pvt->transfercallno = newcall;
08283 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer));
08284 inet_aton(newip, &pvt->transfer.sin_addr);
08285 pvt->transfer.sin_family = AF_INET;
08286 pvt->transferid = ies->transferid;
08287
08288
08289 if (pvt->transferring == TRANSFER_NONE) {
08290 store_by_transfercallno(pvt);
08291 }
08292 pvt->transferring = TRANSFER_BEGIN;
08293
08294 if (ies->transferid)
08295 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid);
08296 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos);
08297 return 0;
08298 }
08299
08300 static int complete_dpreply(struct chan_iax2_pvt *pvt, struct iax_ies *ies)
08301 {
08302 char exten[256] = "";
08303 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0;
08304 struct iax2_dpcache *dp = NULL;
08305
08306 if (ies->called_number)
08307 ast_copy_string(exten, ies->called_number, sizeof(exten));
08308
08309 if (ies->dpstatus & IAX_DPSTATUS_EXISTS)
08310 status = CACHE_FLAG_EXISTS;
08311 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST)
08312 status = CACHE_FLAG_CANEXIST;
08313 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT)
08314 status = CACHE_FLAG_NONEXISTENT;
08315
08316 if (ies->refresh)
08317 expiry = ies->refresh;
08318 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE)
08319 matchmore = CACHE_FLAG_MATCHMORE;
08320
08321 AST_LIST_LOCK(&dpcache);
08322 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) {
08323 if (strcmp(dp->exten, exten))
08324 continue;
08325 AST_LIST_REMOVE_CURRENT(peer_list);
08326 dp->callno = 0;
08327 dp->expiry.tv_sec = dp->orig.tv_sec + expiry;
08328 if (dp->flags & CACHE_FLAG_PENDING) {
08329 dp->flags &= ~CACHE_FLAG_PENDING;
08330 dp->flags |= status;
08331 dp->flags |= matchmore;
08332 }
08333
08334 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
08335 if (dp->waiters[x] > -1) {
08336 if (write(dp->waiters[x], "asdf", 4) < 0) {
08337 }
08338 }
08339 }
08340 }
08341 AST_LIST_TRAVERSE_SAFE_END;
08342 AST_LIST_UNLOCK(&dpcache);
08343
08344 return 0;
08345 }
08346
08347 static int complete_transfer(int callno, struct iax_ies *ies)
08348 {
08349 int peercallno = 0;
08350 struct chan_iax2_pvt *pvt = iaxs[callno];
08351 struct iax_frame *cur;
08352 jb_frame frame;
08353
08354 if (ies->callno)
08355 peercallno = ies->callno;
08356
08357 if (peercallno < 1) {
08358 ast_log(LOG_WARNING, "Invalid transfer request\n");
08359 return -1;
08360 }
08361 remove_by_transfercallno(pvt);
08362
08363
08364
08365 peercnt_remove_by_addr(&pvt->addr);
08366 peercnt_add(&pvt->transfer);
08367
08368 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr));
08369 memset(&pvt->transfer, 0, sizeof(pvt->transfer));
08370
08371 pvt->oseqno = 0;
08372 pvt->rseqno = 0;
08373 pvt->iseqno = 0;
08374 pvt->aseqno = 0;
08375
08376 if (pvt->peercallno) {
08377 remove_by_peercallno(pvt);
08378 }
08379 pvt->peercallno = peercallno;
08380
08381 store_by_peercallno(pvt);
08382 pvt->transferring = TRANSFER_NONE;
08383 pvt->svoiceformat = -1;
08384 pvt->voiceformat = 0;
08385 pvt->svideoformat = -1;
08386 pvt->videoformat = 0;
08387 pvt->transfercallno = 0;
08388 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore));
08389 memset(&pvt->offset, 0, sizeof(pvt->offset));
08390
08391 while(jb_getall(pvt->jb,&frame) == JB_OK)
08392 iax2_frame_free(frame.data);
08393 jb_reset(pvt->jb);
08394 pvt->lag = 0;
08395 pvt->last = 0;
08396 pvt->lastsent = 0;
08397 pvt->nextpred = 0;
08398 pvt->pingtime = DEFAULT_RETRY_TIME;
08399 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) {
08400
08401
08402
08403 cur->retries = -1;
08404 }
08405 return 0;
08406 }
08407
08408
08409 static int iax2_ack_registry(struct iax_ies *ies, struct sockaddr_in *sin, int callno)
08410 {
08411 struct iax2_registry *reg;
08412
08413 char peer[256] = "";
08414 char msgstatus[60];
08415 int refresh = 60;
08416 char ourip[256] = "<Unspecified>";
08417 struct sockaddr_in oldus;
08418 struct sockaddr_in us;
08419 int oldmsgs;
08420 struct sockaddr_in reg_addr;
08421
08422 memset(&us, 0, sizeof(us));
08423 if (ies->apparent_addr)
08424 memmove(&us, ies->apparent_addr, sizeof(us));
08425 if (ies->username)
08426 ast_copy_string(peer, ies->username, sizeof(peer));
08427 if (ies->refresh)
08428 refresh = ies->refresh;
08429 if (ies->calling_number) {
08430
08431 }
08432 reg = iaxs[callno]->reg;
08433 if (!reg) {
08434 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer);
08435 return -1;
08436 }
08437 memcpy(&oldus, ®->us, sizeof(oldus));
08438 oldmsgs = reg->messages;
08439 ast_sockaddr_to_sin(®->addr, ®_addr);
08440 if (inaddrcmp(®_addr, sin)) {
08441 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08442 return -1;
08443 }
08444 memcpy(®->us, &us, sizeof(reg->us));
08445 if (ies->msgcount >= 0)
08446 reg->messages = ies->msgcount & 0xffff;
08447
08448
08449
08450 reg->refresh = refresh;
08451 reg->expire = iax2_sched_replace(reg->expire, sched,
08452 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
08453 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) {
08454 if (reg->messages > 255)
08455 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8);
08456 else if (reg->messages > 1)
08457 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages);
08458 else if (reg->messages > 0)
08459 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus));
08460 else
08461 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus));
08462 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port));
08463 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus);
08464 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr));
08465 }
08466 reg->regstate = REG_STATE_REGISTERED;
08467 return 0;
08468 }
08469
08470 static int iax2_append_register(const char *hostname, const char *username,
08471 const char *secret, const char *porta)
08472 {
08473 struct iax2_registry *reg;
08474
08475 if (!(reg = ast_calloc(1, sizeof(*reg))))
08476 return -1;
08477
08478 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) {
08479 ast_free(reg);
08480 return -1;
08481 }
08482
08483 ast_copy_string(reg->username, username, sizeof(reg->username));
08484
08485 if (secret)
08486 ast_copy_string(reg->secret, secret, sizeof(reg->secret));
08487
08488 reg->expire = -1;
08489 reg->refresh = IAX_DEFAULT_REG_EXPIRE;
08490 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO);
08491
08492 AST_LIST_LOCK(®istrations);
08493 AST_LIST_INSERT_HEAD(®istrations, reg, entry);
08494 AST_LIST_UNLOCK(®istrations);
08495
08496 return 0;
08497 }
08498
08499 static int iax2_register(const char *value, int lineno)
08500 {
08501 char copy[256];
08502 char *username, *hostname, *secret;
08503 char *porta;
08504 char *stringp=NULL;
08505
08506 if (!value)
08507 return -1;
08508
08509 ast_copy_string(copy, value, sizeof(copy));
08510 stringp = copy;
08511 username = strsep(&stringp, "@");
08512 hostname = strsep(&stringp, "@");
08513
08514 if (!hostname) {
08515 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno);
08516 return -1;
08517 }
08518
08519 stringp = username;
08520 username = strsep(&stringp, ":");
08521 secret = strsep(&stringp, ":");
08522 stringp = hostname;
08523 hostname = strsep(&stringp, ":");
08524 porta = strsep(&stringp, ":");
08525
08526 if (porta && !atoi(porta)) {
08527 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno);
08528 return -1;
08529 }
08530
08531 return iax2_append_register(hostname, username, secret, porta);
08532 }
08533
08534
08535 static void register_peer_exten(struct iax2_peer *peer, int onoff)
08536 {
08537 char multi[256];
08538 char *stringp, *ext;
08539 if (!ast_strlen_zero(regcontext)) {
08540 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
08541 stringp = multi;
08542 while((ext = strsep(&stringp, "&"))) {
08543 if (onoff) {
08544 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL))
08545 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL,
08546 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2");
08547 } else
08548 ast_context_remove_extension(regcontext, ext, 1, NULL);
08549 }
08550 }
08551 }
08552 static void prune_peers(void);
08553
08554 static void unlink_peer(struct iax2_peer *peer)
08555 {
08556 if (peer->expire > -1) {
08557 if (!ast_sched_thread_del(sched, peer->expire)) {
08558 peer->expire = -1;
08559 peer_unref(peer);
08560 }
08561 }
08562
08563 if (peer->pokeexpire > -1) {
08564 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
08565 peer->pokeexpire = -1;
08566 peer_unref(peer);
08567 }
08568 }
08569
08570 ao2_unlink(peers, peer);
08571 }
08572
08573 static void __expire_registry(const void *data)
08574 {
08575 struct iax2_peer *peer = (struct iax2_peer *) data;
08576
08577 if (!peer)
08578 return;
08579
08580 peer->expire = -1;
08581
08582 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name);
08583 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS)))
08584 realtime_update_peer(peer->name, &peer->addr, 0);
08585 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
08586
08587 peercnt_modify(0, 0, &peer->addr);
08588
08589 memset(&peer->addr, 0, sizeof(peer->addr));
08590
08591 peer->expiry = min_reg_expire;
08592 if (!ast_test_flag64(peer, IAX_TEMPONLY))
08593 ast_db_del("IAX/Registry", peer->name);
08594 register_peer_exten(peer, 0);
08595 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
08596 if (iax2_regfunk)
08597 iax2_regfunk(peer->name, 0);
08598
08599 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR))
08600 unlink_peer(peer);
08601
08602 peer_unref(peer);
08603 }
08604
08605 static int expire_registry(const void *data)
08606 {
08607 #ifdef SCHED_MULTITHREADED
08608 if (schedule_action(__expire_registry, data))
08609 #endif
08610 __expire_registry(data);
08611 return 0;
08612 }
08613
08614 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall);
08615
08616 static void reg_source_db(struct iax2_peer *p)
08617 {
08618 char data[80];
08619 char *expiry;
08620
08621 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) {
08622 return;
08623 }
08624
08625 expiry = strrchr(data, ':');
08626 if (!expiry) {
08627 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data);
08628 }
08629 *expiry++ = '\0';
08630
08631 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) {
08632 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data);
08633 return;
08634 }
08635
08636 p->expiry = atoi(expiry);
08637
08638 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name,
08639 ast_sockaddr_stringify(&p->addr), p->expiry);
08640
08641 iax2_poke_peer(p, 0);
08642 if (p->expire > -1) {
08643 if (!ast_sched_thread_del(sched, p->expire)) {
08644 p->expire = -1;
08645 peer_unref(p);
08646 }
08647 }
08648
08649 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08650
08651 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08652 if (p->expire == -1) {
08653 peer_unref(p);
08654 }
08655
08656 if (iax2_regfunk) {
08657 iax2_regfunk(p->name, 1);
08658 }
08659
08660 register_peer_exten(p, 1);
08661 }
08662
08663
08664
08665
08666
08667
08668
08669 static int update_registry(struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh)
08670 {
08671
08672 struct iax_ie_data ied = {
08673 .pos = 0,
08674 };
08675 struct iax2_peer *p;
08676 int msgcount;
08677 char data[80];
08678 int version;
08679 const char *peer_name;
08680 int res = -1;
08681 struct ast_sockaddr sockaddr;
08682
08683 ast_sockaddr_from_sin(&sockaddr, sin);
08684
08685 peer_name = ast_strdupa(iaxs[callno]->peer);
08686
08687
08688 ast_mutex_unlock(&iaxsl[callno]);
08689 if (!(p = find_peer(peer_name, 1))) {
08690 ast_mutex_lock(&iaxsl[callno]);
08691 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name);
08692 return -1;
08693 }
08694 ast_mutex_lock(&iaxsl[callno]);
08695 if (!iaxs[callno])
08696 goto return_unref;
08697
08698 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) {
08699 if (sin->sin_addr.s_addr) {
08700 time_t nowtime;
08701 time(&nowtime);
08702 realtime_update_peer(peer_name, &sockaddr, nowtime);
08703 } else {
08704 realtime_update_peer(peer_name, &sockaddr, 0);
08705 }
08706 }
08707
08708 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) {
08709 if (iax2_regfunk) {
08710 iax2_regfunk(p->name, 1);
08711 }
08712
08713
08714 peercnt_modify(0, 0, &p->addr);
08715
08716
08717 ast_sockaddr_from_sin(&p->addr, sin);
08718
08719 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry);
08720 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) {
08721 ast_db_put("IAX/Registry", p->name, data);
08722 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name,
08723 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
08724 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name);
08725 register_peer_exten(p, 1);
08726 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name);
08727 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) {
08728 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name,
08729 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED");
08730 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name);
08731 register_peer_exten(p, 0);
08732 ast_db_del("IAX/Registry", p->name);
08733 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name);
08734 }
08735
08736
08737 iax2_poke_peer(p, callno);
08738 }
08739
08740
08741 if (p->maxcallno) {
08742 peercnt_modify(1, p->maxcallno, &p->addr);
08743 }
08744
08745
08746 if (!iaxs[callno]) {
08747 res = -1;
08748 goto return_unref;
08749 }
08750
08751
08752 p->sockfd = fd;
08753
08754 if (p->expire > -1) {
08755 if (!ast_sched_thread_del(sched, p->expire)) {
08756 p->expire = -1;
08757 peer_unref(p);
08758 }
08759 }
08760
08761 if (!refresh)
08762 refresh = min_reg_expire;
08763 if (refresh > max_reg_expire) {
08764 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08765 p->name, max_reg_expire, refresh);
08766 p->expiry = max_reg_expire;
08767 } else if (refresh < min_reg_expire) {
08768 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n",
08769 p->name, min_reg_expire, refresh);
08770 p->expiry = min_reg_expire;
08771 } else {
08772 p->expiry = refresh;
08773 }
08774 if (p->expiry && sin->sin_addr.s_addr) {
08775 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p));
08776 if (p->expire == -1)
08777 peer_unref(p);
08778 }
08779 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name);
08780 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag));
08781 if (sin->sin_addr.s_addr) {
08782 struct sockaddr_in peer_addr;
08783
08784 ast_sockaddr_to_sin(&p->addr, &peer_addr);
08785
08786 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry);
08787 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr);
08788 if (!ast_strlen_zero(p->mailbox)) {
08789 struct ast_event *event;
08790 int new, old;
08791 char *mailbox, *context;
08792
08793 context = mailbox = ast_strdupa(p->mailbox);
08794 strsep(&context, "@");
08795 if (ast_strlen_zero(context))
08796 context = "default";
08797
08798 event = ast_event_get_cached(AST_EVENT_MWI,
08799 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
08800 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
08801 AST_EVENT_IE_END);
08802 if (event) {
08803 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08804 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
08805 ast_event_destroy(event);
08806 } else {
08807 ast_app_inboxcount(p->mailbox, &new, &old);
08808 }
08809
08810 if (new > 255) {
08811 new = 255;
08812 }
08813 if (old > 255) {
08814 old = 255;
08815 }
08816 msgcount = (old << 8) | new;
08817
08818 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount);
08819 }
08820 if (ast_test_flag64(p, IAX_HASCALLERID)) {
08821 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num);
08822 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name);
08823 }
08824 }
08825 version = iax_check_version(devtype);
08826 if (version)
08827 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version);
08828
08829 res = 0;
08830
08831 return_unref:
08832 peer_unref(p);
08833
08834 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);
08835 }
08836
08837 static int registry_authrequest(int callno)
08838 {
08839 struct iax_ie_data ied;
08840 struct iax2_peer *p;
08841 char challenge[10];
08842 const char *peer_name;
08843 int sentauthmethod;
08844
08845 peer_name = ast_strdupa(iaxs[callno]->peer);
08846
08847
08848 ast_mutex_unlock(&iaxsl[callno]);
08849 if ((p = find_peer(peer_name, 1))) {
08850 last_authmethod = p->authmethods;
08851 }
08852
08853 ast_mutex_lock(&iaxsl[callno]);
08854 if (!iaxs[callno])
08855 goto return_unref;
08856
08857 memset(&ied, 0, sizeof(ied));
08858
08859
08860
08861
08862
08863
08864 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT);
08865 if (!p) {
08866 iaxs[callno]->authmethods = sentauthmethod;
08867 }
08868 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod);
08869 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) {
08870
08871 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random());
08872 ast_string_field_set(iaxs[callno], challenge, challenge);
08873 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge);
08874 }
08875 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name);
08876
08877 return_unref:
08878 if (p) {
08879 peer_unref(p);
08880 }
08881
08882 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1;
08883 }
08884
08885 static int registry_rerequest(struct iax_ies *ies, int callno, struct sockaddr_in *sin)
08886 {
08887 struct iax2_registry *reg;
08888
08889 struct iax_ie_data ied;
08890 char peer[256] = "";
08891 char challenge[256] = "";
08892 int res;
08893 int authmethods = 0;
08894 if (ies->authmethods)
08895 authmethods = ies->authmethods;
08896 if (ies->username)
08897 ast_copy_string(peer, ies->username, sizeof(peer));
08898 if (ies->challenge)
08899 ast_copy_string(challenge, ies->challenge, sizeof(challenge));
08900 memset(&ied, 0, sizeof(ied));
08901 reg = iaxs[callno]->reg;
08902 if (reg) {
08903 struct sockaddr_in reg_addr;
08904
08905 ast_sockaddr_to_sin(®->addr, ®_addr);
08906
08907 if (inaddrcmp(®_addr, sin)) {
08908 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr));
08909 return -1;
08910 }
08911 if (ast_strlen_zero(reg->secret)) {
08912 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username);
08913 reg->regstate = REG_STATE_NOAUTH;
08914 return -1;
08915 }
08916 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
08917 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
08918 if (reg->secret[0] == '[') {
08919 char tmpkey[256];
08920 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey));
08921 tmpkey[strlen(tmpkey) - 1] = '\0';
08922 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL);
08923 } else
08924 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL);
08925 if (!res) {
08926 reg->regstate = REG_STATE_AUTHSENT;
08927 add_empty_calltoken_ie(iaxs[callno], &ied);
08928 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
08929 } else
08930 return -1;
08931 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer);
08932 } else
08933 ast_log(LOG_NOTICE, "Can't reregister without a reg\n");
08934 return -1;
08935 }
08936
08937 static void stop_stuff(int callno)
08938 {
08939 iax2_destroy_helper(iaxs[callno]);
08940 }
08941
08942 static void __auth_reject(const void *nothing)
08943 {
08944
08945 int callno = (int)(long)(nothing);
08946 struct iax_ie_data ied;
08947 ast_mutex_lock(&iaxsl[callno]);
08948 if (iaxs[callno]) {
08949 memset(&ied, 0, sizeof(ied));
08950 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) {
08951 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused");
08952 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED);
08953 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) {
08954 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found");
08955 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
08956 }
08957 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1);
08958 }
08959 ast_mutex_unlock(&iaxsl[callno]);
08960 }
08961
08962 static int auth_reject(const void *data)
08963 {
08964 int callno = (int)(long)(data);
08965 ast_mutex_lock(&iaxsl[callno]);
08966 if (iaxs[callno])
08967 iaxs[callno]->authid = -1;
08968 ast_mutex_unlock(&iaxsl[callno]);
08969 #ifdef SCHED_MULTITHREADED
08970 if (schedule_action(__auth_reject, data))
08971 #endif
08972 __auth_reject(data);
08973 return 0;
08974 }
08975
08976 static int auth_fail(int callno, int failcode)
08977 {
08978
08979
08980 if (iaxs[callno]) {
08981 iaxs[callno]->authfail = failcode;
08982 if (delayreject) {
08983 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid,
08984 sched, 1000, auth_reject, (void *)(long)callno);
08985 } else
08986 auth_reject((void *)(long)callno);
08987 }
08988 return 0;
08989 }
08990
08991 static void __auto_hangup(const void *nothing)
08992 {
08993
08994 int callno = (int)(long)(nothing);
08995 struct iax_ie_data ied;
08996 ast_mutex_lock(&iaxsl[callno]);
08997 if (iaxs[callno]) {
08998 memset(&ied, 0, sizeof(ied));
08999 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout");
09000 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE);
09001 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1);
09002 }
09003 ast_mutex_unlock(&iaxsl[callno]);
09004 }
09005
09006 static int auto_hangup(const void *data)
09007 {
09008 int callno = (int)(long)(data);
09009 ast_mutex_lock(&iaxsl[callno]);
09010 if (iaxs[callno]) {
09011 iaxs[callno]->autoid = -1;
09012 }
09013 ast_mutex_unlock(&iaxsl[callno]);
09014 #ifdef SCHED_MULTITHREADED
09015 if (schedule_action(__auto_hangup, data))
09016 #endif
09017 __auto_hangup(data);
09018 return 0;
09019 }
09020
09021 static void iax2_dprequest(struct iax2_dpcache *dp, int callno)
09022 {
09023 struct iax_ie_data ied;
09024
09025 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
09026 sched, 30000, auto_hangup, (void *)(long)callno);
09027 memset(&ied, 0, sizeof(ied));
09028 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten);
09029 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1);
09030 dp->flags |= CACHE_FLAG_TRANSMITTED;
09031 }
09032
09033 static int iax2_vnak(int callno)
09034 {
09035 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno);
09036 }
09037
09038 static void vnak_retransmit(int callno, int last)
09039 {
09040 struct iax_frame *f;
09041
09042 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) {
09043
09044 if (((unsigned char) (f->oseqno - last) < 128) &&
09045 (f->retries >= 0)) {
09046 send_packet(f);
09047 }
09048 }
09049 }
09050
09051 static void __iax2_poke_peer_s(const void *data)
09052 {
09053 struct iax2_peer *peer = (struct iax2_peer *)data;
09054 iax2_poke_peer(peer, 0);
09055 peer_unref(peer);
09056 }
09057
09058 static int iax2_poke_peer_s(const void *data)
09059 {
09060 struct iax2_peer *peer = (struct iax2_peer *)data;
09061 peer->pokeexpire = -1;
09062 #ifdef SCHED_MULTITHREADED
09063 if (schedule_action(__iax2_poke_peer_s, data))
09064 #endif
09065 __iax2_poke_peer_s(data);
09066 return 0;
09067 }
09068
09069 static int send_trunk(struct iax2_trunk_peer *tpeer, struct timeval *now)
09070 {
09071 int res = 0;
09072 struct iax_frame *fr;
09073 struct ast_iax2_meta_hdr *meta;
09074 struct ast_iax2_meta_trunk_hdr *mth;
09075 int calls = 0;
09076
09077
09078 fr = (struct iax_frame *)tpeer->trunkdata;
09079
09080 meta = (struct ast_iax2_meta_hdr *)fr->afdata;
09081 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data;
09082 if (tpeer->trunkdatalen) {
09083
09084 meta->zeros = 0;
09085 meta->metacmd = IAX_META_TRUNK;
09086 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS))
09087 meta->cmddata = IAX_META_TRUNK_MINI;
09088 else
09089 meta->cmddata = IAX_META_TRUNK_SUPERMINI;
09090 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now));
09091
09092 fr->direction = DIRECTION_OUTGRESS;
09093 fr->retrans = -1;
09094 fr->transfer = 0;
09095
09096 fr->data = fr->afdata;
09097 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr);
09098 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd);
09099 calls = tpeer->calls;
09100 #if 0
09101 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));
09102 #endif
09103
09104 tpeer->trunkdatalen = 0;
09105 tpeer->calls = 0;
09106 }
09107 if (res < 0)
09108 return res;
09109 return calls;
09110 }
09111
09112 static inline int iax2_trunk_expired(struct iax2_trunk_peer *tpeer, struct timeval *now)
09113 {
09114
09115 if (now->tv_sec > tpeer->trunkact.tv_sec + 5)
09116 return 1;
09117 return 0;
09118 }
09119
09120 static int timing_read(int *id, int fd, short events, void *cbdata)
09121 {
09122 int res, processed = 0, totalcalls = 0;
09123 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL;
09124 struct timeval now = ast_tvnow();
09125
09126 if (iaxtrunkdebug)
09127 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize);
09128
09129 if (timer) {
09130 ast_timer_ack(timer, 1);
09131 }
09132
09133
09134 AST_LIST_LOCK(&tpeers);
09135 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) {
09136 processed++;
09137 res = 0;
09138 ast_mutex_lock(&tpeer->lock);
09139
09140
09141 if (!drop && iax2_trunk_expired(tpeer, &now)) {
09142
09143
09144 AST_LIST_REMOVE_CURRENT(list);
09145 drop = tpeer;
09146 } else {
09147 res = send_trunk(tpeer, &now);
09148 trunk_timed++;
09149 if (iaxtrunkdebug)
09150 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);
09151 }
09152 totalcalls += res;
09153 res = 0;
09154 ast_mutex_unlock(&tpeer->lock);
09155 }
09156 AST_LIST_TRAVERSE_SAFE_END;
09157 AST_LIST_UNLOCK(&tpeers);
09158
09159 if (drop) {
09160 ast_mutex_lock(&drop->lock);
09161
09162
09163 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port));
09164 if (drop->trunkdata) {
09165 ast_free(drop->trunkdata);
09166 drop->trunkdata = NULL;
09167 }
09168 ast_mutex_unlock(&drop->lock);
09169 ast_mutex_destroy(&drop->lock);
09170 ast_free(drop);
09171
09172 }
09173
09174 if (iaxtrunkdebug)
09175 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls);
09176 iaxtrunkdebug = 0;
09177
09178 return 1;
09179 }
09180
09181 struct dpreq_data {
09182 int callno;
09183 char context[AST_MAX_EXTENSION];
09184 char callednum[AST_MAX_EXTENSION];
09185 char *callerid;
09186 };
09187
09188 static void dp_lookup(int callno, const char *context, const char *callednum, const char *callerid, int skiplock)
09189 {
09190 unsigned short dpstatus = 0;
09191 struct iax_ie_data ied1;
09192 int mm;
09193
09194 memset(&ied1, 0, sizeof(ied1));
09195 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid);
09196
09197 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) {
09198 dpstatus = IAX_DPSTATUS_EXISTS;
09199 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) {
09200 dpstatus = IAX_DPSTATUS_CANEXIST;
09201 } else {
09202 dpstatus = IAX_DPSTATUS_NONEXISTENT;
09203 }
09204 if (ast_ignore_pattern(context, callednum))
09205 dpstatus |= IAX_DPSTATUS_IGNOREPAT;
09206 if (mm)
09207 dpstatus |= IAX_DPSTATUS_MATCHMORE;
09208 if (!skiplock)
09209 ast_mutex_lock(&iaxsl[callno]);
09210 if (iaxs[callno]) {
09211 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum);
09212 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus);
09213 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache);
09214 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1);
09215 }
09216 if (!skiplock)
09217 ast_mutex_unlock(&iaxsl[callno]);
09218 }
09219
09220 static void *dp_lookup_thread(void *data)
09221 {
09222
09223 struct dpreq_data *dpr = data;
09224 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0);
09225 if (dpr->callerid)
09226 ast_free(dpr->callerid);
09227 ast_free(dpr);
09228 return NULL;
09229 }
09230
09231 static void spawn_dp_lookup(int callno, const char *context, const char *callednum, const char *callerid)
09232 {
09233 pthread_t newthread;
09234 struct dpreq_data *dpr;
09235
09236 if (!(dpr = ast_calloc(1, sizeof(*dpr))))
09237 return;
09238
09239 dpr->callno = callno;
09240 ast_copy_string(dpr->context, context, sizeof(dpr->context));
09241 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum));
09242 if (callerid)
09243 dpr->callerid = ast_strdup(callerid);
09244 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) {
09245 ast_log(LOG_WARNING, "Unable to start lookup thread!\n");
09246 }
09247 }
09248
09249 struct iax_dual {
09250 struct ast_channel *chan1;
09251 struct ast_channel *chan2;
09252 const char *parkexten;
09253 };
09254
09255 static void *iax_park_thread(void *stuff)
09256 {
09257 struct ast_channel *chan1, *chan2;
09258 struct iax_dual *d;
09259 struct ast_frame *f;
09260 int ext = 0;
09261
09262 d = stuff;
09263 chan1 = d->chan1;
09264 chan2 = d->chan2;
09265 ast_free(d);
09266 f = ast_read(chan1);
09267 if (f)
09268 ast_frfree(f);
09269 ast_park_call(chan1, chan2, 0, d->parkexten, &ext);
09270 ast_hangup(chan2);
09271 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext);
09272 return NULL;
09273 }
09274
09275 static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2, const char *parkexten)
09276 {
09277 struct iax_dual *d;
09278 struct ast_channel *chan1m, *chan2m;
09279 pthread_t th;
09280 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name);
09281 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name);
09282 if (chan2m && chan1m) {
09283
09284 chan1m->readformat = chan1->readformat;
09285 chan1m->writeformat = chan1->writeformat;
09286 ast_channel_masquerade(chan1m, chan1);
09287
09288 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context));
09289 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten));
09290 chan1m->priority = chan1->priority;
09291
09292
09293
09294
09295 chan2m->readformat = chan2->readformat;
09296 chan2m->writeformat = chan2->writeformat;
09297 ast_channel_masquerade(chan2m, chan2);
09298
09299 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context));
09300 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten));
09301 chan2m->priority = chan2->priority;
09302 if (ast_do_masquerade(chan2m)) {
09303 ast_log(LOG_WARNING, "Masquerade failed :(\n");
09304 ast_hangup(chan2m);
09305 return -1;
09306 }
09307 } else {
09308 if (chan1m)
09309 ast_hangup(chan1m);
09310 if (chan2m)
09311 ast_hangup(chan2m);
09312 return -1;
09313 }
09314 if ((d = ast_calloc(1, sizeof(*d)))) {
09315 d->chan1 = chan1m;
09316 d->chan2 = chan2m;
09317 d->parkexten = parkexten;
09318 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) {
09319 return 0;
09320 }
09321 ast_free(d);
09322 }
09323 return -1;
09324 }
09325
09326 static int check_provisioning(struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver)
09327 {
09328 unsigned int ourver;
09329 char rsi[80];
09330 snprintf(rsi, sizeof(rsi), "si-%s", si);
09331 if (iax_provision_version(&ourver, rsi, 1))
09332 return 0;
09333 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver);
09334 if (ourver != ver)
09335 iax2_provision(sin, sockfd, NULL, rsi, 1);
09336 return 0;
09337 }
09338
09339 static void construct_rr(struct chan_iax2_pvt *pvt, struct iax_ie_data *iep)
09340 {
09341 jb_info stats;
09342 jb_getinfo(pvt->jb, &stats);
09343
09344 memset(iep, 0, sizeof(*iep));
09345
09346 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter);
09347 if(stats.frames_in == 0) stats.frames_in = 1;
09348 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff)));
09349 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in);
09350 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min);
09351 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped);
09352 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo);
09353 }
09354
09355 static void save_rr(struct iax_frame *fr, struct iax_ies *ies)
09356 {
09357 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter;
09358 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24;
09359 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff;
09360 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts;
09361 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay;
09362 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped;
09363 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo;
09364 }
09365
09366 static void save_osptoken(struct iax_frame *fr, struct iax_ies *ies)
09367 {
09368 int i;
09369 unsigned int length, offset = 0;
09370 char full_osptoken[IAX_MAX_OSPBUFF_SIZE];
09371
09372 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) {
09373 length = ies->ospblocklength[i];
09374 if (length != 0) {
09375 if (length > IAX_MAX_OSPBLOCK_SIZE) {
09376
09377 offset = 0;
09378 break;
09379 } else {
09380 memcpy(full_osptoken + offset, ies->osptokenblock[i], length);
09381 offset += length;
09382 }
09383 } else {
09384 break;
09385 }
09386 }
09387 *(full_osptoken + offset) = '\0';
09388 if (strlen(full_osptoken) != offset) {
09389
09390 *full_osptoken = '\0';
09391 }
09392
09393 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken);
09394 }
09395
09396 static void log_jitterstats(unsigned short callno)
09397 {
09398 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1;
09399 jb_info jbinfo;
09400
09401 ast_mutex_lock(&iaxsl[callno]);
09402 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) {
09403 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) {
09404 jb_getinfo(iaxs[callno]->jb, &jbinfo);
09405 localjitter = jbinfo.jitter;
09406 localdelay = jbinfo.current - jbinfo.min;
09407 locallost = jbinfo.frames_lost;
09408 locallosspct = jbinfo.losspct/1000;
09409 localdropped = jbinfo.frames_dropped;
09410 localooo = jbinfo.frames_ooo;
09411 localpackets = jbinfo.frames_in;
09412 }
09413 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",
09414 iaxs[callno]->owner->name,
09415 iaxs[callno]->pingtime,
09416 localjitter,
09417 localdelay,
09418 locallost,
09419 locallosspct,
09420 localdropped,
09421 localooo,
09422 localpackets,
09423 iaxs[callno]->remote_rr.jitter,
09424 iaxs[callno]->remote_rr.delay,
09425 iaxs[callno]->remote_rr.losscnt,
09426 iaxs[callno]->remote_rr.losspct/1000,
09427 iaxs[callno]->remote_rr.dropped,
09428 iaxs[callno]->remote_rr.ooo,
09429 iaxs[callno]->remote_rr.packets);
09430 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",
09431 iaxs[callno]->owner->name,
09432 iaxs[callno]->pingtime,
09433 localjitter,
09434 localdelay,
09435 locallost,
09436 locallosspct,
09437 localdropped,
09438 localooo,
09439 localpackets,
09440 iaxs[callno]->remote_rr.jitter,
09441 iaxs[callno]->remote_rr.delay,
09442 iaxs[callno]->remote_rr.losscnt,
09443 iaxs[callno]->remote_rr.losspct/1000,
09444 iaxs[callno]->remote_rr.dropped,
09445 iaxs[callno]->remote_rr.ooo,
09446 iaxs[callno]->remote_rr.packets);
09447 }
09448 ast_mutex_unlock(&iaxsl[callno]);
09449 }
09450
09451 static int socket_process(struct iax2_thread *thread);
09452
09453
09454
09455
09456 static void handle_deferred_full_frames(struct iax2_thread *thread)
09457 {
09458 struct iax2_pkt_buf *pkt_buf;
09459
09460 ast_mutex_lock(&thread->lock);
09461
09462 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) {
09463 ast_mutex_unlock(&thread->lock);
09464
09465 thread->buf = pkt_buf->buf;
09466 thread->buf_len = pkt_buf->len;
09467 thread->buf_size = pkt_buf->len + 1;
09468
09469 socket_process(thread);
09470
09471 thread->buf = NULL;
09472 ast_free(pkt_buf);
09473
09474 ast_mutex_lock(&thread->lock);
09475 }
09476
09477 ast_mutex_unlock(&thread->lock);
09478 }
09479
09480
09481
09482
09483
09484
09485
09486 static void defer_full_frame(struct iax2_thread *from_here, struct iax2_thread *to_here)
09487 {
09488 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf;
09489 struct ast_iax2_full_hdr *fh, *cur_fh;
09490
09491 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len)))
09492 return;
09493
09494 pkt_buf->len = from_here->buf_len;
09495 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len);
09496
09497 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf;
09498 ast_mutex_lock(&to_here->lock);
09499 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) {
09500 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf;
09501 if (fh->oseqno < cur_fh->oseqno) {
09502 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry);
09503 break;
09504 }
09505 }
09506 AST_LIST_TRAVERSE_SAFE_END
09507
09508 if (!cur_pkt_buf)
09509 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry);
09510
09511 ast_mutex_unlock(&to_here->lock);
09512 }
09513
09514 static int socket_read(int *id, int fd, short events, void *cbdata)
09515 {
09516 struct iax2_thread *thread;
09517 socklen_t len;
09518 time_t t;
09519 static time_t last_errtime = 0;
09520 struct ast_iax2_full_hdr *fh;
09521
09522 if (!(thread = find_idle_thread())) {
09523 time(&t);
09524 if (t != last_errtime)
09525 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n");
09526 last_errtime = t;
09527 usleep(1);
09528 return 1;
09529 }
09530
09531 len = sizeof(thread->iosin);
09532 thread->iofd = fd;
09533 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len);
09534 thread->buf_size = sizeof(thread->readbuf);
09535 thread->buf = thread->readbuf;
09536 if (thread->buf_len < 0) {
09537 if (errno != ECONNREFUSED && errno != EAGAIN)
09538 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
09539 handle_error();
09540 thread->iostate = IAX_IOSTATE_IDLE;
09541 signal_condition(&thread->lock, &thread->cond);
09542 return 1;
09543 }
09544 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) {
09545 thread->iostate = IAX_IOSTATE_IDLE;
09546 signal_condition(&thread->lock, &thread->cond);
09547 return 1;
09548 }
09549
09550
09551
09552
09553 fh = (struct ast_iax2_full_hdr *) thread->buf;
09554 if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
09555 struct iax2_thread *cur = NULL;
09556 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL;
09557
09558 AST_LIST_LOCK(&active_list);
09559 AST_LIST_TRAVERSE(&active_list, cur, list) {
09560 if ((cur->ffinfo.callno == callno) &&
09561 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin))
09562 break;
09563 }
09564 if (cur) {
09565
09566
09567 defer_full_frame(thread, cur);
09568 AST_LIST_UNLOCK(&active_list);
09569 thread->iostate = IAX_IOSTATE_IDLE;
09570 signal_condition(&thread->lock, &thread->cond);
09571 return 1;
09572 } else {
09573
09574 thread->ffinfo.callno = callno;
09575 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin));
09576 thread->ffinfo.type = fh->type;
09577 thread->ffinfo.csub = fh->csub;
09578 AST_LIST_INSERT_HEAD(&active_list, thread, list);
09579 }
09580 AST_LIST_UNLOCK(&active_list);
09581 }
09582
09583
09584 thread->iostate = IAX_IOSTATE_READY;
09585 #ifdef DEBUG_SCHED_MULTITHREAD
09586 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
09587 #endif
09588 signal_condition(&thread->lock, &thread->cond);
09589
09590 return 1;
09591 }
09592
09593 static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd,
09594 struct iax_frame *fr)
09595 {
09596 unsigned char metatype;
09597 struct ast_iax2_meta_trunk_mini *mtm;
09598 struct ast_iax2_meta_trunk_hdr *mth;
09599 struct ast_iax2_meta_trunk_entry *mte;
09600 struct iax2_trunk_peer *tpeer;
09601 unsigned int ts;
09602 void *ptr;
09603 struct timeval rxtrunktime;
09604 struct ast_frame f = { 0, };
09605
09606 if (packet_len < sizeof(*meta)) {
09607 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n",
09608 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09609 return 1;
09610 }
09611
09612 if (meta->metacmd != IAX_META_TRUNK)
09613 return 1;
09614
09615 if (packet_len < (sizeof(*meta) + sizeof(*mth))) {
09616 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len,
09617 (int) (sizeof(*meta) + sizeof(*mth)));
09618 return 1;
09619 }
09620 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data);
09621 ts = ntohl(mth->ts);
09622 metatype = meta->cmddata;
09623 packet_len -= (sizeof(*meta) + sizeof(*mth));
09624 ptr = mth->data;
09625 tpeer = find_tpeer(sin, sockfd);
09626 if (!tpeer) {
09627 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n",
09628 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09629 return 1;
09630 }
09631 tpeer->trunkact = ast_tvnow();
09632 if (!ts || ast_tvzero(tpeer->rxtrunktime))
09633 tpeer->rxtrunktime = tpeer->trunkact;
09634 rxtrunktime = tpeer->rxtrunktime;
09635 ast_mutex_unlock(&tpeer->lock);
09636 while (packet_len >= sizeof(*mte)) {
09637
09638 unsigned short callno, trunked_ts, len;
09639
09640 if (metatype == IAX_META_TRUNK_MINI) {
09641 mtm = (struct ast_iax2_meta_trunk_mini *) ptr;
09642 ptr += sizeof(*mtm);
09643 packet_len -= sizeof(*mtm);
09644 len = ntohs(mtm->len);
09645 callno = ntohs(mtm->mini.callno);
09646 trunked_ts = ntohs(mtm->mini.ts);
09647 } else if (metatype == IAX_META_TRUNK_SUPERMINI) {
09648 mte = (struct ast_iax2_meta_trunk_entry *)ptr;
09649 ptr += sizeof(*mte);
09650 packet_len -= sizeof(*mte);
09651 len = ntohs(mte->len);
09652 callno = ntohs(mte->callno);
09653 trunked_ts = 0;
09654 } else {
09655 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
09656 break;
09657 }
09658
09659 if (len > packet_len)
09660 break;
09661 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0);
09662 if (!fr->callno)
09663 continue;
09664
09665
09666
09667
09668 memset(&f, 0, sizeof(f));
09669 f.frametype = AST_FRAME_VOICE;
09670 if (!iaxs[fr->callno]) {
09671
09672 } else if (iaxs[fr->callno]->voiceformat == 0) {
09673 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
09674 iax2_vnak(fr->callno);
09675 } else {
09676 f.subclass.codec = iaxs[fr->callno]->voiceformat;
09677 f.datalen = len;
09678 if (f.datalen >= 0) {
09679 if (f.datalen)
09680 f.data.ptr = ptr;
09681 else
09682 f.data.ptr = NULL;
09683 if (trunked_ts)
09684 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff);
09685 else
09686 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts);
09687
09688 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
09689 struct iax_frame *duped_fr;
09690
09691
09692 f.src = "IAX2";
09693 f.mallocd = 0;
09694 f.offset = 0;
09695 if (f.datalen && (f.frametype == AST_FRAME_VOICE))
09696 f.samples = ast_codec_get_samples(&f);
09697 else
09698 f.samples = 0;
09699 fr->outoforder = 0;
09700 iax_frame_wrap(fr, &f);
09701 duped_fr = iaxfrdup2(fr);
09702 if (duped_fr)
09703 schedule_delivery(duped_fr, 1, 1, &fr->ts);
09704 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts)
09705 iaxs[fr->callno]->last = fr->ts;
09706 }
09707 } else {
09708 ast_log(LOG_WARNING, "Datalen < 0?\n");
09709 }
09710 }
09711 ast_mutex_unlock(&iaxsl[fr->callno]);
09712 ptr += len;
09713 packet_len -= len;
09714 }
09715
09716 return 1;
09717 }
09718
09719 static int acf_iaxvar_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
09720 {
09721 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09722 AST_LIST_HEAD(, ast_var_t) *varlist;
09723 struct ast_var_t *var;
09724
09725 if (!variablestore) {
09726 *buf = '\0';
09727 return 0;
09728 }
09729 varlist = variablestore->data;
09730
09731 AST_LIST_LOCK(varlist);
09732 AST_LIST_TRAVERSE(varlist, var, entries) {
09733 if (strcmp(var->name, data) == 0) {
09734 ast_copy_string(buf, var->value, len);
09735 break;
09736 }
09737 }
09738 AST_LIST_UNLOCK(varlist);
09739 return 0;
09740 }
09741
09742 static int acf_iaxvar_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
09743 {
09744 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL);
09745 AST_LIST_HEAD(, ast_var_t) *varlist;
09746 struct ast_var_t *var;
09747
09748 if (!variablestore) {
09749 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
09750 if (!variablestore) {
09751 ast_log(LOG_ERROR, "Memory allocation error\n");
09752 return -1;
09753 }
09754 varlist = ast_calloc(1, sizeof(*varlist));
09755 if (!varlist) {
09756 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09757 return -1;
09758 }
09759
09760 AST_LIST_HEAD_INIT(varlist);
09761 variablestore->data = varlist;
09762 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
09763 ast_channel_datastore_add(chan, variablestore);
09764 } else
09765 varlist = variablestore->data;
09766
09767 AST_LIST_LOCK(varlist);
09768 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) {
09769 if (strcmp(var->name, data) == 0) {
09770 AST_LIST_REMOVE_CURRENT(entries);
09771 ast_var_delete(var);
09772 break;
09773 }
09774 }
09775 AST_LIST_TRAVERSE_SAFE_END;
09776 var = ast_var_assign(data, value);
09777 if (var)
09778 AST_LIST_INSERT_TAIL(varlist, var, entries);
09779 else
09780 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data);
09781 AST_LIST_UNLOCK(varlist);
09782 return 0;
09783 }
09784
09785 static struct ast_custom_function iaxvar_function = {
09786 .name = "IAXVAR",
09787 .read = acf_iaxvar_read,
09788 .write = acf_iaxvar_write,
09789 };
09790
09791 static void set_hangup_source_and_cause(int callno, unsigned char causecode)
09792 {
09793 iax2_lock_owner(callno);
09794 if (iaxs[callno] && iaxs[callno]->owner) {
09795 if (causecode) {
09796 iaxs[callno]->owner->hangupcause = causecode;
09797 }
09798 ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0);
09799 ast_channel_unlock(iaxs[callno]->owner);
09800 }
09801 }
09802
09803 static int socket_process(struct iax2_thread *thread)
09804 {
09805 struct sockaddr_in sin;
09806 int res;
09807 int updatehistory=1;
09808 int new = NEW_PREVENT;
09809 int dcallno = 0;
09810 char decrypted = 0;
09811 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf;
09812 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf;
09813 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf;
09814 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf;
09815 struct iax_frame *fr;
09816 struct iax_frame *cur;
09817 struct ast_frame f = { 0, };
09818 struct ast_channel *c = NULL;
09819 struct iax2_dpcache *dp;
09820 struct iax2_peer *peer;
09821 struct iax_ies ies;
09822 struct iax_ie_data ied0, ied1;
09823 format_t format;
09824 int fd;
09825 int exists;
09826 int minivid = 0;
09827 char empty[32]="";
09828 struct iax_frame *duped_fr;
09829 char host_pref_buf[128];
09830 char caller_pref_buf[128];
09831 struct ast_codec_pref pref;
09832 char *using_prefs = "mine";
09833
09834
09835 fr = alloca(sizeof(*fr) + 4096);
09836 memset(fr, 0, sizeof(*fr));
09837 fr->afdatalen = 4096;
09838
09839
09840 res = thread->buf_len;
09841 fd = thread->iofd;
09842 memcpy(&sin, &thread->iosin, sizeof(sin));
09843
09844 if (res < sizeof(*mh)) {
09845 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh));
09846 return 1;
09847 }
09848 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) {
09849 if (res < sizeof(*vh)) {
09850 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));
09851 return 1;
09852 }
09853
09854
09855 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0);
09856 minivid = 1;
09857 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000))
09858 return socket_process_meta(res, meta, &sin, fd, fr);
09859
09860 #ifdef DEBUG_SUPPORT
09861 if (res >= sizeof(*fh))
09862 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh));
09863 #endif
09864 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09865 if (res < sizeof(*fh)) {
09866 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));
09867 return 1;
09868 }
09869
09870
09871 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS;
09872
09873
09874
09875
09876
09877
09878 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) {
09879 ast_mutex_lock(&iaxsl[fr->callno]);
09880 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) {
09881 if (decrypt_frame(fr->callno, fh, &f, &res)) {
09882 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
09883 ast_mutex_unlock(&iaxsl[fr->callno]);
09884 return 1;
09885 }
09886 decrypted = 1;
09887 }
09888 ast_mutex_unlock(&iaxsl[fr->callno]);
09889 }
09890
09891
09892 f.frametype = fh->type;
09893 if (f.frametype == AST_FRAME_VIDEO) {
09894 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
09895 } else if (f.frametype == AST_FRAME_VOICE) {
09896 f.subclass.codec = uncompress_subclass(fh->csub);
09897 } else {
09898 f.subclass.integer = uncompress_subclass(fh->csub);
09899 }
09900
09901
09902 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) {
09903
09904 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09905 return 1;
09906 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) {
09907
09908 return 1;
09909 }
09910
09911 f.datalen = res - sizeof(*fh);
09912 if (f.datalen) {
09913 if (f.frametype == AST_FRAME_IAX) {
09914 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) {
09915 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr));
09916 ast_variables_destroy(ies.vars);
09917 return 1;
09918 }
09919 f.data.ptr = NULL;
09920 f.datalen = 0;
09921 } else {
09922 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr);
09923 memset(&ies, 0, sizeof(ies));
09924 }
09925 } else {
09926 if (f.frametype == AST_FRAME_IAX)
09927 f.data.ptr = NULL;
09928 else
09929 f.data.ptr = empty;
09930 memset(&ies, 0, sizeof(ies));
09931 }
09932
09933 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) {
09934
09935 if (handle_call_token(fh, &ies, &sin, fd)) {
09936 ast_variables_destroy(ies.vars);
09937 return 1;
09938 }
09939
09940 if (ies.calltoken && ies.calltokendata) {
09941
09942
09943
09944
09945 new = NEW_ALLOW_CALLTOKEN_VALIDATED;
09946 } else {
09947 new = NEW_ALLOW;
09948 }
09949 }
09950 } else {
09951
09952 f.frametype = AST_FRAME_NULL;
09953 f.subclass.integer = 0;
09954 memset(&ies, 0, sizeof(ies));
09955 }
09956
09957 if (!fr->callno) {
09958 int check_dcallno = 0;
09959
09960
09961
09962
09963
09964
09965
09966
09967
09968 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) {
09969 check_dcallno = 1;
09970 }
09971
09972 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) {
09973 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) {
09974 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09975 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) {
09976 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL);
09977 }
09978 ast_variables_destroy(ies.vars);
09979 return 1;
09980 }
09981 }
09982
09983 if (fr->callno > 0)
09984 ast_mutex_lock(&iaxsl[fr->callno]);
09985
09986 if (!fr->callno || !iaxs[fr->callno]) {
09987
09988
09989 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
09990
09991 if (((f.subclass.integer != IAX_COMMAND_INVAL) &&
09992 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
09993 (f.subclass.integer != IAX_COMMAND_TXACC) &&
09994 (f.subclass.integer != IAX_COMMAND_FWDOWNL))||
09995 (f.frametype != AST_FRAME_IAX))
09996 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL,
09997 fd);
09998 }
09999 if (fr->callno > 0)
10000 ast_mutex_unlock(&iaxsl[fr->callno]);
10001 ast_variables_destroy(ies.vars);
10002 return 1;
10003 }
10004 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) {
10005 if (decrypt_frame(fr->callno, fh, &f, &res)) {
10006 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n");
10007 ast_variables_destroy(ies.vars);
10008 ast_mutex_unlock(&iaxsl[fr->callno]);
10009 return 1;
10010 }
10011 decrypted = 1;
10012 }
10013
10014 #ifdef DEBUG_SUPPORT
10015 if (decrypted) {
10016 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh));
10017 }
10018 #endif
10019
10020
10021
10022 iaxs[fr->callno]->frames_received++;
10023
10024 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid &&
10025 f.subclass.integer != IAX_COMMAND_TXCNT &&
10026 f.subclass.integer != IAX_COMMAND_TXACC) {
10027 unsigned short new_peercallno;
10028
10029 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL);
10030 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) {
10031 if (iaxs[fr->callno]->peercallno) {
10032 remove_by_peercallno(iaxs[fr->callno]);
10033 }
10034 iaxs[fr->callno]->peercallno = new_peercallno;
10035 store_by_peercallno(iaxs[fr->callno]);
10036 }
10037 }
10038 if (ntohs(mh->callno) & IAX_FLAG_FULL) {
10039 if (iaxdebug)
10040 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer);
10041
10042 fr->oseqno = fh->oseqno;
10043 fr->iseqno = fh->iseqno;
10044 fr->ts = ntohl(fh->ts);
10045 #ifdef IAXTESTS
10046 if (test_resync) {
10047 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync);
10048 fr->ts += test_resync;
10049 }
10050 #endif
10051 #if 0
10052 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) ||
10053 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX &&
10054 (f.subclass == IAX_COMMAND_NEW ||
10055 f.subclass == IAX_COMMAND_AUTHREQ ||
10056 f.subclass == IAX_COMMAND_ACCEPT ||
10057 f.subclass == IAX_COMMAND_REJECT)) ) )
10058 #endif
10059 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE))
10060 updatehistory = 0;
10061 if ((iaxs[fr->callno]->iseqno != fr->oseqno) &&
10062 (iaxs[fr->callno]->iseqno ||
10063 ((f.subclass.integer != IAX_COMMAND_TXCNT) &&
10064 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10065 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10066 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10067 (f.subclass.integer != IAX_COMMAND_TXACC)) ||
10068 (f.frametype != AST_FRAME_IAX))) {
10069 if (
10070 ((f.subclass.integer != IAX_COMMAND_ACK) &&
10071 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10072 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10073 (f.subclass.integer != IAX_COMMAND_TXREADY) &&
10074 (f.subclass.integer != IAX_COMMAND_TXREL) &&
10075 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) &&
10076 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10077 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10078 (f.frametype != AST_FRAME_IAX)) {
10079
10080 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n",
10081 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer);
10082
10083
10084 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) {
10085
10086 if ((f.frametype != AST_FRAME_IAX) ||
10087 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) {
10088 ast_debug(1, "Acking anyway\n");
10089
10090
10091 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10092 }
10093 } else {
10094
10095 iax2_vnak(fr->callno);
10096 }
10097 ast_variables_destroy(ies.vars);
10098 ast_mutex_unlock(&iaxsl[fr->callno]);
10099 return 1;
10100 }
10101 } else {
10102
10103 if (((f.subclass.integer != IAX_COMMAND_ACK) &&
10104 (f.subclass.integer != IAX_COMMAND_INVAL) &&
10105 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
10106 (f.subclass.integer != IAX_COMMAND_TXACC) &&
10107 (f.subclass.integer != IAX_COMMAND_VNAK)) ||
10108 (f.frametype != AST_FRAME_IAX))
10109 iaxs[fr->callno]->iseqno++;
10110 }
10111
10112 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') {
10113 if (res < thread->buf_size)
10114 thread->buf[res++] = '\0';
10115 else
10116 thread->buf[res - 1] = '\0';
10117 }
10118
10119
10120
10121 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10122 ((f.subclass.integer != IAX_COMMAND_INVAL) ||
10123 (f.frametype != AST_FRAME_IAX))) {
10124 unsigned char x;
10125 int call_to_destroy;
10126
10127 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno))
10128 x = fr->iseqno;
10129 else
10130 x = iaxs[fr->callno]->oseqno;
10131 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) {
10132
10133
10134 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) {
10135
10136 if (iaxdebug)
10137 ast_debug(1, "Cancelling transmission of packet %d\n", x);
10138 call_to_destroy = 0;
10139 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10140
10141 if (x == cur->oseqno) {
10142 cur->retries = -1;
10143
10144 if (cur->final)
10145 call_to_destroy = fr->callno;
10146 }
10147 }
10148 if (call_to_destroy) {
10149 if (iaxdebug)
10150 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy);
10151 ast_mutex_lock(&iaxsl[call_to_destroy]);
10152 iax2_destroy(call_to_destroy);
10153 ast_mutex_unlock(&iaxsl[call_to_destroy]);
10154 }
10155 }
10156
10157 if (iaxs[fr->callno])
10158 iaxs[fr->callno]->rseqno = fr->iseqno;
10159 else {
10160
10161 ast_variables_destroy(ies.vars);
10162 ast_mutex_unlock(&iaxsl[fr->callno]);
10163 return 1;
10164 }
10165 } else {
10166 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno);
10167 }
10168 }
10169 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) &&
10170 ((f.frametype != AST_FRAME_IAX) ||
10171 ((f.subclass.integer != IAX_COMMAND_TXACC) &&
10172 (f.subclass.integer != IAX_COMMAND_TXCNT)))) {
10173
10174 ast_variables_destroy(ies.vars);
10175 ast_mutex_unlock(&iaxsl[fr->callno]);
10176 return 1;
10177 }
10178
10179
10180
10181
10182 if ((f.frametype == AST_FRAME_VOICE) ||
10183 (f.frametype == AST_FRAME_VIDEO) ||
10184 (f.frametype == AST_FRAME_IAX)) {
10185 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
10186 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10187 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) {
10188 ast_variables_destroy(ies.vars);
10189 ast_mutex_unlock(&iaxsl[fr->callno]);
10190 return 1;
10191 }
10192 }
10193
10194 if (ies.vars) {
10195 struct ast_datastore *variablestore = NULL;
10196 struct ast_variable *var, *prev = NULL;
10197 AST_LIST_HEAD(, ast_var_t) *varlist;
10198
10199 iax2_lock_owner(fr->callno);
10200 if (!iaxs[fr->callno]) {
10201 ast_variables_destroy(ies.vars);
10202 ast_mutex_unlock(&iaxsl[fr->callno]);
10203 return 1;
10204 }
10205 if ((c = iaxs[fr->callno]->owner)) {
10206 varlist = ast_calloc(1, sizeof(*varlist));
10207 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
10208
10209 if (variablestore && varlist) {
10210 variablestore->data = varlist;
10211 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
10212 AST_LIST_HEAD_INIT(varlist);
10213 ast_debug(1, "I can haz IAX vars?\n");
10214 for (var = ies.vars; var; var = var->next) {
10215 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
10216 if (prev) {
10217 ast_free(prev);
10218 }
10219 prev = var;
10220 if (!newvar) {
10221
10222 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10223 } else {
10224 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
10225 }
10226 }
10227 if (prev) {
10228 ast_free(prev);
10229 }
10230 ies.vars = NULL;
10231 ast_channel_datastore_add(c, variablestore);
10232 } else {
10233 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
10234 if (variablestore) {
10235 ast_datastore_free(variablestore);
10236 }
10237 if (varlist) {
10238 ast_free(varlist);
10239 }
10240 }
10241 ast_channel_unlock(c);
10242 } else {
10243
10244
10245 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
10246 for (var = ies.vars; var && var->next; var = var->next);
10247 if (var) {
10248 var->next = iaxs[fr->callno]->iaxvars;
10249 iaxs[fr->callno]->iaxvars = ies.vars;
10250 ies.vars = NULL;
10251 }
10252 }
10253 }
10254
10255 if (ies.vars) {
10256 ast_debug(1, "I have IAX variables, but they were not processed\n");
10257 }
10258 }
10259
10260
10261
10262 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) {
10263 send_signaling(iaxs[fr->callno]);
10264 }
10265
10266 if (f.frametype == AST_FRAME_VOICE) {
10267 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
10268 iaxs[fr->callno]->voiceformat = f.subclass.codec;
10269 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
10270 if (iaxs[fr->callno]->owner) {
10271 iax2_lock_owner(fr->callno);
10272 if (iaxs[fr->callno]) {
10273 if (iaxs[fr->callno]->owner) {
10274 format_t orignative;
10275
10276 orignative = iaxs[fr->callno]->owner->nativeformats;
10277 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
10278 if (iaxs[fr->callno]->owner->readformat)
10279 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10280 iaxs[fr->callno]->owner->nativeformats = orignative;
10281 ast_channel_unlock(iaxs[fr->callno]->owner);
10282 }
10283 } else {
10284 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
10285
10286 if (ies.vars) {
10287 ast_variables_destroy(ies.vars);
10288 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n");
10289 ies.vars = NULL;
10290 }
10291 ast_mutex_unlock(&iaxsl[fr->callno]);
10292 return 1;
10293 }
10294 }
10295 }
10296 }
10297 if (f.frametype == AST_FRAME_VIDEO) {
10298 if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
10299 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
10300 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
10301 }
10302 }
10303 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
10304 if (f.subclass.integer == AST_CONTROL_BUSY) {
10305 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY;
10306 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) {
10307 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION;
10308 }
10309 }
10310 if (f.frametype == AST_FRAME_IAX) {
10311 ast_sched_thread_del(sched, iaxs[fr->callno]->initid);
10312
10313 if (iaxdebug)
10314 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer);
10315
10316
10317 if (iaxs[fr->callno]->last < fr->ts &&
10318 f.subclass.integer != IAX_COMMAND_ACK &&
10319 f.subclass.integer != IAX_COMMAND_PONG &&
10320 f.subclass.integer != IAX_COMMAND_LAGRP) {
10321 iaxs[fr->callno]->last = fr->ts;
10322 if (iaxdebug)
10323 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
10324 }
10325 iaxs[fr->callno]->last_iax_message = f.subclass.integer;
10326 if (!iaxs[fr->callno]->first_iax_message) {
10327 iaxs[fr->callno]->first_iax_message = f.subclass.integer;
10328 }
10329 switch(f.subclass.integer) {
10330 case IAX_COMMAND_ACK:
10331
10332 break;
10333 case IAX_COMMAND_QUELCH:
10334 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10335
10336 if (iaxs[fr->callno]->owner) {
10337 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10338 "Status: On\r\n"
10339 "Channel: %s\r\n"
10340 "Uniqueid: %s\r\n",
10341 iaxs[fr->callno]->owner->name,
10342 iaxs[fr->callno]->owner->uniqueid);
10343 }
10344
10345 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH);
10346 if (ies.musiconhold) {
10347 iax2_lock_owner(fr->callno);
10348 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) {
10349 break;
10350 }
10351 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10352 const char *moh_suggest = iaxs[fr->callno]->mohsuggest;
10353
10354
10355
10356
10357
10358 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD,
10359 S_OR(moh_suggest, NULL),
10360 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0);
10361 }
10362 ast_channel_unlock(iaxs[fr->callno]->owner);
10363 }
10364 }
10365 break;
10366 case IAX_COMMAND_UNQUELCH:
10367 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
10368 iax2_lock_owner(fr->callno);
10369 if (!iaxs[fr->callno]) {
10370 break;
10371 }
10372
10373 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) {
10374 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold",
10375 "Status: Off\r\n"
10376 "Channel: %s\r\n"
10377 "Uniqueid: %s\r\n",
10378 iaxs[fr->callno]->owner->name,
10379 iaxs[fr->callno]->owner->uniqueid);
10380 }
10381
10382 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH);
10383 if (!iaxs[fr->callno]->owner) {
10384 break;
10385 }
10386 if (ast_bridged_channel(iaxs[fr->callno]->owner)) {
10387
10388
10389
10390
10391 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0);
10392 }
10393 ast_channel_unlock(iaxs[fr->callno]->owner);
10394 }
10395 break;
10396 case IAX_COMMAND_TXACC:
10397 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
10398
10399 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
10400
10401 if (cur->transfer) {
10402 cur->retries = -1;
10403 }
10404 }
10405 memset(&ied1, 0, sizeof(ied1));
10406 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno);
10407 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1);
10408 iaxs[fr->callno]->transferring = TRANSFER_READY;
10409 }
10410 break;
10411 case IAX_COMMAND_NEW:
10412
10413 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
10414 break;
10415 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
10416 ast_mutex_unlock(&iaxsl[fr->callno]);
10417 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
10418 ast_mutex_lock(&iaxsl[fr->callno]);
10419 if (!iaxs[fr->callno]) {
10420 break;
10421 }
10422 }
10423
10424 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) {
10425 int new_callno;
10426 if ((new_callno = make_trunk(fr->callno, 1)) != -1)
10427 fr->callno = new_callno;
10428 }
10429
10430 if (delayreject)
10431 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10432 if (check_access(fr->callno, &sin, &ies)) {
10433
10434 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10435 if (authdebug)
10436 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);
10437 break;
10438 }
10439 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) {
10440 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10441 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n");
10442 break;
10443 }
10444 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10445 const char *context, *exten, *cid_num;
10446
10447 context = ast_strdupa(iaxs[fr->callno]->context);
10448 exten = ast_strdupa(iaxs[fr->callno]->exten);
10449 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num);
10450
10451
10452 ast_mutex_unlock(&iaxsl[fr->callno]);
10453 exists = ast_exists_extension(NULL, context, exten, 1, cid_num);
10454 ast_mutex_lock(&iaxsl[fr->callno]);
10455
10456 if (!iaxs[fr->callno]) {
10457 break;
10458 }
10459 } else
10460 exists = 0;
10461
10462 save_osptoken(fr, &ies);
10463 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) {
10464 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10465 memset(&ied0, 0, sizeof(ied0));
10466 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10467 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10468 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10469 if (!iaxs[fr->callno]) {
10470 break;
10471 }
10472 if (authdebug)
10473 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);
10474 } else {
10475
10476
10477 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10478 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10479 using_prefs = "reqonly";
10480 } else {
10481 using_prefs = "disabled";
10482 }
10483 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10484 memset(&pref, 0, sizeof(pref));
10485 strcpy(caller_pref_buf, "disabled");
10486 strcpy(host_pref_buf, "disabled");
10487 } else {
10488 using_prefs = "mine";
10489
10490 if (ies.codec_prefs)
10491 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10492 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10493
10494 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10495 pref = iaxs[fr->callno]->rprefs;
10496 using_prefs = "caller";
10497 } else {
10498 pref = iaxs[fr->callno]->prefs;
10499 }
10500 } else
10501 pref = iaxs[fr->callno]->prefs;
10502
10503 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10504 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10505 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10506 }
10507 if (!format) {
10508 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP))
10509 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10510 if (!format) {
10511 memset(&ied0, 0, sizeof(ied0));
10512 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10513 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10514 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10515 if (!iaxs[fr->callno]) {
10516 break;
10517 }
10518 if (authdebug) {
10519 char tmp[256], tmp2[256], tmp3[256];
10520 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10521 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
10522 ast_inet_ntoa(sin.sin_addr),
10523 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10524 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10525 } else {
10526 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10527 ast_inet_ntoa(sin.sin_addr),
10528 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10529 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10530 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10531 }
10532 }
10533 } else {
10534
10535 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10536 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10537 format = 0;
10538 } else {
10539 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10540 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10541 memset(&pref, 0, sizeof(pref));
10542 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10543 strcpy(caller_pref_buf,"disabled");
10544 strcpy(host_pref_buf,"disabled");
10545 } else {
10546 using_prefs = "mine";
10547 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10548
10549 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10550 pref = iaxs[fr->callno]->prefs;
10551 } else {
10552 pref = iaxs[fr->callno]->rprefs;
10553 using_prefs = "caller";
10554 }
10555 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
10556 } else
10557 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10558 }
10559 }
10560
10561 if (!format) {
10562 char tmp[256], tmp2[256], tmp3[256];
10563 memset(&ied0, 0, sizeof(ied0));
10564 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10565 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10566 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
10567 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10568 if (!iaxs[fr->callno]) {
10569 break;
10570 }
10571 if (authdebug) {
10572 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10573 ast_inet_ntoa(sin.sin_addr),
10574 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
10575 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10576 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10577 }
10578 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10579 break;
10580 }
10581 }
10582 }
10583 if (format) {
10584
10585 memset(&ied1, 0, sizeof(ied1));
10586 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
10587 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
10588 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
10589 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
10590 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10591 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n"
10592 "%srequested format = %s,\n"
10593 "%srequested prefs = %s,\n"
10594 "%sactual format = %s,\n"
10595 "%shost prefs = %s,\n"
10596 "%spriority = %s\n",
10597 ast_inet_ntoa(sin.sin_addr),
10598 VERBOSE_PREFIX_4,
10599 ast_getformatname(iaxs[fr->callno]->peerformat),
10600 VERBOSE_PREFIX_4,
10601 caller_pref_buf,
10602 VERBOSE_PREFIX_4,
10603 ast_getformatname(format),
10604 VERBOSE_PREFIX_4,
10605 host_pref_buf,
10606 VERBOSE_PREFIX_4,
10607 using_prefs);
10608
10609 iaxs[fr->callno]->chosenformat = format;
10610 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
10611 } else {
10612 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
10613
10614 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
10615 }
10616 }
10617 }
10618 break;
10619 }
10620 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5)
10621 merge_encryption(iaxs[fr->callno],ies.encmethods);
10622 else
10623 iaxs[fr->callno]->encmethods = 0;
10624 if (!authenticate_request(fr->callno) && iaxs[fr->callno])
10625 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED);
10626 break;
10627 case IAX_COMMAND_DPREQ:
10628
10629 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) &&
10630 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) {
10631 if (iaxcompat) {
10632
10633 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num);
10634 } else {
10635
10636 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1);
10637 }
10638 }
10639 break;
10640 case IAX_COMMAND_HANGUP:
10641 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
10642 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno);
10643
10644 if (iaxs[fr->callno]->owner) {
10645 set_hangup_source_and_cause(fr->callno, ies.causecode);
10646 if (!iaxs[fr->callno]) {
10647 break;
10648 }
10649 }
10650
10651
10652 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10653 iax2_destroy(fr->callno);
10654 break;
10655 case IAX_COMMAND_REJECT:
10656
10657 if (iaxs[fr->callno]->owner) {
10658 set_hangup_source_and_cause(fr->callno, ies.causecode);
10659 if (!iaxs[fr->callno]) {
10660 break;
10661 }
10662 }
10663
10664 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10665 if (iaxs[fr->callno]->owner && authdebug)
10666 ast_log(LOG_WARNING, "Call rejected by %s: %s\n",
10667 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr),
10668 ies.cause ? ies.cause : "<Unknown>");
10669 ast_debug(1, "Immediately destroying %d, having received reject\n",
10670 fr->callno);
10671 }
10672
10673 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK,
10674 fr->ts, NULL, 0, fr->iseqno);
10675 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION))
10676 iaxs[fr->callno]->error = EPERM;
10677 iax2_destroy(fr->callno);
10678 break;
10679 case IAX_COMMAND_TRANSFER:
10680 {
10681 struct ast_channel *bridged_chan;
10682 struct ast_channel *owner;
10683
10684 iax2_lock_owner(fr->callno);
10685 if (!iaxs[fr->callno]) {
10686
10687 break;
10688 }
10689 owner = iaxs[fr->callno]->owner;
10690 bridged_chan = owner ? ast_bridged_channel(owner) : NULL;
10691 if (bridged_chan && ies.called_number) {
10692 ast_mutex_unlock(&iaxsl[fr->callno]);
10693
10694
10695 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name);
10696 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name);
10697
10698 if (ast_parking_ext_valid(ies.called_number, owner, iaxs[fr->callno]->context)) {
10699 ast_debug(1, "Parking call '%s'\n", bridged_chan->name);
10700 if (iax_park(bridged_chan, owner, ies.called_number)) {
10701 ast_log(LOG_WARNING, "Failed to park call '%s'\n",
10702 bridged_chan->name);
10703 }
10704 ast_mutex_lock(&iaxsl[fr->callno]);
10705 } else {
10706 ast_mutex_lock(&iaxsl[fr->callno]);
10707
10708 if (iaxs[fr->callno]) {
10709 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context,
10710 ies.called_number, 1)) {
10711 ast_log(LOG_WARNING,
10712 "Async goto of '%s' to '%s@%s' failed\n",
10713 bridged_chan->name, ies.called_number,
10714 iaxs[fr->callno]->context);
10715 } else {
10716 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n",
10717 bridged_chan->name, ies.called_number,
10718 iaxs[fr->callno]->context);
10719 }
10720 } else {
10721
10722 }
10723 }
10724 } else {
10725 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno);
10726 }
10727 if (owner) {
10728 ast_channel_unlock(owner);
10729 }
10730
10731 break;
10732 }
10733 case IAX_COMMAND_ACCEPT:
10734
10735 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED))
10736 break;
10737 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) {
10738
10739 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10740 iax2_destroy(fr->callno);
10741 break;
10742 }
10743 if (ies.format) {
10744 iaxs[fr->callno]->peerformat = ies.format;
10745 } else {
10746 if (iaxs[fr->callno]->owner)
10747 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
10748 else
10749 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
10750 }
10751 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));
10752 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
10753 memset(&ied0, 0, sizeof(ied0));
10754 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10755 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10756 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10757 if (!iaxs[fr->callno]) {
10758 break;
10759 }
10760 if (authdebug) {
10761 char tmp1[256], tmp2[256];
10762 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
10763 ast_inet_ntoa(sin.sin_addr),
10764 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10765 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10766 }
10767 } else {
10768 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
10769 iax2_lock_owner(fr->callno);
10770 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
10771
10772 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
10773 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
10774
10775
10776 if (iaxs[fr->callno]->owner->writeformat)
10777 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);
10778 if (iaxs[fr->callno]->owner->readformat)
10779 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
10780 ast_channel_unlock(iaxs[fr->callno]->owner);
10781 }
10782 }
10783 if (iaxs[fr->callno]) {
10784 AST_LIST_LOCK(&dpcache);
10785 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list)
10786 if (!(dp->flags & CACHE_FLAG_TRANSMITTED))
10787 iax2_dprequest(dp, fr->callno);
10788 AST_LIST_UNLOCK(&dpcache);
10789 }
10790 break;
10791 case IAX_COMMAND_POKE:
10792
10793 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1);
10794 break;
10795 case IAX_COMMAND_PING:
10796 {
10797 struct iax_ie_data pingied;
10798 construct_rr(iaxs[fr->callno], &pingied);
10799
10800 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1);
10801 }
10802 break;
10803 case IAX_COMMAND_PONG:
10804
10805 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts;
10806
10807 save_rr(fr, &ies);
10808
10809
10810 log_jitterstats(fr->callno);
10811
10812 if (iaxs[fr->callno]->peerpoke) {
10813 peer = iaxs[fr->callno]->peerpoke;
10814 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) {
10815 if (iaxs[fr->callno]->pingtime <= peer->maxms) {
10816 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime);
10817 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);
10818 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name);
10819 }
10820 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) {
10821 if (iaxs[fr->callno]->pingtime > peer->maxms) {
10822 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime);
10823 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);
10824 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
10825 }
10826 }
10827 peer->lastms = iaxs[fr->callno]->pingtime;
10828 if (peer->smoothing && (peer->lastms > -1))
10829 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2;
10830 else if (peer->smoothing && peer->lastms < 0)
10831 peer->historicms = (0 + peer->historicms) / 2;
10832 else
10833 peer->historicms = iaxs[fr->callno]->pingtime;
10834
10835
10836 if (peer->pokeexpire > -1) {
10837 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
10838 peer_unref(peer);
10839 peer->pokeexpire = -1;
10840 }
10841 }
10842
10843 if ((peer->lastms < 0) || (peer->historicms > peer->maxms))
10844 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
10845 else
10846 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer));
10847 if (peer->pokeexpire == -1)
10848 peer_unref(peer);
10849
10850 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10851
10852 iax2_destroy(fr->callno);
10853 peer->callno = 0;
10854 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms);
10855 }
10856 break;
10857 case IAX_COMMAND_LAGRQ:
10858 case IAX_COMMAND_LAGRP:
10859 f.src = "LAGRQ";
10860 f.mallocd = 0;
10861 f.offset = 0;
10862 f.samples = 0;
10863 iax_frame_wrap(fr, &f);
10864 if (f.subclass.integer == IAX_COMMAND_LAGRQ) {
10865
10866 fr->af.subclass.integer = IAX_COMMAND_LAGRP;
10867 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0);
10868 } else {
10869
10870 unsigned int ts;
10871
10872 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af);
10873 iaxs[fr->callno]->lag = ts - fr->ts;
10874 if (iaxdebug)
10875 ast_debug(1, "Peer %s lag measured as %dms\n",
10876 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag);
10877 }
10878 break;
10879 case IAX_COMMAND_AUTHREQ:
10880 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10881 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>");
10882 break;
10883 }
10884 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) {
10885 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL,
10886 .subclass.integer = AST_CONTROL_HANGUP,
10887 };
10888 ast_log(LOG_WARNING,
10889 "I don't know how to authenticate %s to %s\n",
10890 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
10891 iax2_queue_frame(fr->callno, &hangup_fr);
10892 }
10893 break;
10894 case IAX_COMMAND_AUTHREP:
10895
10896 if (delayreject)
10897 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
10898
10899 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) {
10900 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>");
10901 break;
10902 }
10903 if (authenticate_verify(iaxs[fr->callno], &ies)) {
10904 if (authdebug)
10905 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);
10906 memset(&ied0, 0, sizeof(ied0));
10907 auth_fail(fr->callno, IAX_COMMAND_REJECT);
10908 break;
10909 }
10910 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) {
10911
10912 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num);
10913 } else
10914 exists = 0;
10915 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) {
10916 if (authdebug)
10917 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);
10918 memset(&ied0, 0, sizeof(ied0));
10919 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
10920 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
10921 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10922 if (!iaxs[fr->callno]) {
10923 break;
10924 }
10925 } else {
10926
10927 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10928 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10929 using_prefs = "reqonly";
10930 } else {
10931 using_prefs = "disabled";
10932 }
10933 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability;
10934 memset(&pref, 0, sizeof(pref));
10935 strcpy(caller_pref_buf, "disabled");
10936 strcpy(host_pref_buf, "disabled");
10937 } else {
10938 using_prefs = "mine";
10939 if (ies.codec_prefs)
10940 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
10941 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10942 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
10943 pref = iaxs[fr->callno]->rprefs;
10944 using_prefs = "caller";
10945 } else {
10946 pref = iaxs[fr->callno]->prefs;
10947 }
10948 } else
10949 pref = iaxs[fr->callno]->prefs;
10950 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
10951 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
10952 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
10953 }
10954 if (!format) {
10955 char tmp1[256], tmp2[256], tmp3[256];
10956 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10957 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
10958 ast_getformatname(iaxs[fr->callno]->peerformat),
10959 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
10960 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
10961 }
10962 if (!format) {
10963 if (authdebug) {
10964 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10965 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
10966 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10967 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
10968 } else {
10969 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
10970 ast_inet_ntoa(sin.sin_addr),
10971 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
10972 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
10973 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
10974 }
10975 }
10976 memset(&ied0, 0, sizeof(ied0));
10977 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
10978 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
10979 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
10980 if (!iaxs[fr->callno]) {
10981 break;
10982 }
10983 } else {
10984
10985 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
10986 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability))
10987 format = 0;
10988 } else {
10989 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
10990 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
10991 memset(&pref, 0, sizeof(pref));
10992 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
10993 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
10994 strcpy(caller_pref_buf,"disabled");
10995 strcpy(host_pref_buf,"disabled");
10996 } else {
10997 using_prefs = "mine";
10998 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
10999
11000 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
11001 pref = iaxs[fr->callno]->prefs;
11002 } else {
11003 pref = iaxs[fr->callno]->rprefs;
11004 using_prefs = "caller";
11005 }
11006 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
11007 } else
11008 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
11009 }
11010 }
11011 if (!format) {
11012 char tmp1[256], tmp2[256], tmp3[256];
11013 ast_log(LOG_ERROR, "No best format in %s???\n",
11014 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
11015 if (authdebug) {
11016 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
11017 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
11018 ast_inet_ntoa(sin.sin_addr),
11019 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11020 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
11021 } else {
11022 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
11023 ast_inet_ntoa(sin.sin_addr),
11024 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
11025 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
11026 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
11027 }
11028 }
11029 memset(&ied0, 0, sizeof(ied0));
11030 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
11031 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
11032 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11033 if (!iaxs[fr->callno]) {
11034 break;
11035 }
11036 }
11037 }
11038 }
11039 if (format) {
11040
11041 memset(&ied1, 0, sizeof(ied1));
11042 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format);
11043 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format);
11044 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1);
11045 if (strcmp(iaxs[fr->callno]->exten, "TBD")) {
11046 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11047 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n"
11048 "%srequested format = %s,\n"
11049 "%srequested prefs = %s,\n"
11050 "%sactual format = %s,\n"
11051 "%shost prefs = %s,\n"
11052 "%spriority = %s\n",
11053 ast_inet_ntoa(sin.sin_addr),
11054 VERBOSE_PREFIX_4,
11055 ast_getformatname(iaxs[fr->callno]->peerformat),
11056 VERBOSE_PREFIX_4,
11057 caller_pref_buf,
11058 VERBOSE_PREFIX_4,
11059 ast_getformatname(format),
11060 VERBOSE_PREFIX_4,
11061 host_pref_buf,
11062 VERBOSE_PREFIX_4,
11063 using_prefs);
11064
11065 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11066 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL)))
11067 iax2_destroy(fr->callno);
11068 else if (ies.vars) {
11069 struct ast_datastore *variablestore;
11070 struct ast_variable *var, *prev = NULL;
11071 AST_LIST_HEAD(, ast_var_t) *varlist;
11072 varlist = ast_calloc(1, sizeof(*varlist));
11073 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11074 if (variablestore && varlist) {
11075 variablestore->data = varlist;
11076 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11077 AST_LIST_HEAD_INIT(varlist);
11078 ast_debug(1, "I can haz IAX vars? w00t\n");
11079 for (var = ies.vars; var; var = var->next) {
11080 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11081 if (prev)
11082 ast_free(prev);
11083 prev = var;
11084 if (!newvar) {
11085
11086 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11087 } else {
11088 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11089 }
11090 }
11091 if (prev)
11092 ast_free(prev);
11093 ies.vars = NULL;
11094 ast_channel_datastore_add(c, variablestore);
11095 } else {
11096 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11097 if (variablestore)
11098 ast_datastore_free(variablestore);
11099 if (varlist)
11100 ast_free(varlist);
11101 }
11102 }
11103 } else {
11104 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11105
11106 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr));
11107 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) {
11108 goto immediatedial;
11109 }
11110 }
11111 }
11112 }
11113 break;
11114 case IAX_COMMAND_DIAL:
11115 immediatedial:
11116 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) {
11117 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD);
11118 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s");
11119 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) {
11120 if (authdebug)
11121 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);
11122 memset(&ied0, 0, sizeof(ied0));
11123 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension");
11124 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION);
11125 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11126 if (!iaxs[fr->callno]) {
11127 break;
11128 }
11129 } else {
11130 char tmp[256];
11131 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11132 ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
11133 ast_inet_ntoa(sin.sin_addr),
11134 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
11135 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
11136 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
11137 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
11138 iax2_destroy(fr->callno);
11139 else if (ies.vars) {
11140 struct ast_datastore *variablestore;
11141 struct ast_variable *var, *prev = NULL;
11142 AST_LIST_HEAD(, ast_var_t) *varlist;
11143 varlist = ast_calloc(1, sizeof(*varlist));
11144 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
11145 ast_debug(1, "I can haz IAX vars? w00t\n");
11146 if (variablestore && varlist) {
11147 variablestore->data = varlist;
11148 variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
11149 AST_LIST_HEAD_INIT(varlist);
11150 for (var = ies.vars; var; var = var->next) {
11151 struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
11152 if (prev)
11153 ast_free(prev);
11154 prev = var;
11155 if (!newvar) {
11156
11157 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11158 } else {
11159 AST_LIST_INSERT_TAIL(varlist, newvar, entries);
11160 }
11161 }
11162 if (prev)
11163 ast_free(prev);
11164 ies.vars = NULL;
11165 ast_channel_datastore_add(c, variablestore);
11166 } else {
11167 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
11168 if (variablestore)
11169 ast_datastore_free(variablestore);
11170 if (varlist)
11171 ast_free(varlist);
11172 }
11173 }
11174 }
11175 }
11176 break;
11177 case IAX_COMMAND_INVAL:
11178 iaxs[fr->callno]->error = ENOTCONN;
11179 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno);
11180 iax2_destroy(fr->callno);
11181 ast_debug(1, "Destroying call %d\n", fr->callno);
11182 break;
11183 case IAX_COMMAND_VNAK:
11184 ast_debug(1, "Received VNAK: resending outstanding frames\n");
11185
11186 vnak_retransmit(fr->callno, fr->iseqno);
11187 break;
11188 case IAX_COMMAND_REGREQ:
11189 case IAX_COMMAND_REGREL:
11190
11191 if (delayreject)
11192 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11193 if (register_verify(fr->callno, &sin, &ies)) {
11194 if (!iaxs[fr->callno]) {
11195 break;
11196 }
11197
11198 auth_fail(fr->callno, IAX_COMMAND_REGREJ);
11199 break;
11200 }
11201 if (!iaxs[fr->callno]) {
11202 break;
11203 }
11204 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) ||
11205 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) {
11206
11207 if (f.subclass.integer == IAX_COMMAND_REGREL) {
11208 memset(&sin, 0, sizeof(sin));
11209 sin.sin_family = AF_INET;
11210 }
11211 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) {
11212 ast_log(LOG_WARNING, "Registry error\n");
11213 }
11214 if (!iaxs[fr->callno]) {
11215 break;
11216 }
11217 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
11218 ast_mutex_unlock(&iaxsl[fr->callno]);
11219 check_provisioning(&sin, fd, ies.serviceident, ies.provver);
11220 ast_mutex_lock(&iaxsl[fr->callno]);
11221 }
11222 break;
11223 }
11224 registry_authrequest(fr->callno);
11225 break;
11226 case IAX_COMMAND_REGACK:
11227 if (iax2_ack_registry(&ies, &sin, fr->callno))
11228 ast_log(LOG_WARNING, "Registration failure\n");
11229
11230 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11231 iax2_destroy(fr->callno);
11232 break;
11233 case IAX_COMMAND_REGREJ:
11234 if (iaxs[fr->callno]->reg) {
11235 if (authdebug) {
11236 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));
11237 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>");
11238 }
11239 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED;
11240 }
11241
11242 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11243 iax2_destroy(fr->callno);
11244 break;
11245 case IAX_COMMAND_REGAUTH:
11246
11247 if (registry_rerequest(&ies, fr->callno, &sin)) {
11248 memset(&ied0, 0, sizeof(ied0));
11249 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found");
11250 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED);
11251 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11252 }
11253 break;
11254 case IAX_COMMAND_TXREJ:
11255 iaxs[fr->callno]->transferring = 0;
11256 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11257 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
11258 if (iaxs[fr->callno]->bridgecallno) {
11259 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
11260 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
11261 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
11262 }
11263 }
11264 break;
11265 case IAX_COMMAND_TXREADY:
11266 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
11267 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
11268 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
11269 iaxs[fr->callno]->transferring = TRANSFER_MREADY;
11270 else
11271 iaxs[fr->callno]->transferring = TRANSFER_READY;
11272 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>");
11273 if (iaxs[fr->callno]->bridgecallno) {
11274 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
11275 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
11276
11277 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
11278 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11279 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11280
11281 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
11282 iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
11283
11284 memset(&ied0, 0, sizeof(ied0));
11285 memset(&ied1, 0, sizeof(ied1));
11286 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11287 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11288 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
11289 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
11290 } else {
11291 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>",
11292 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>");
11293
11294 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
11295 iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
11296 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
11297 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
11298
11299
11300 stop_stuff(fr->callno);
11301 stop_stuff(iaxs[fr->callno]->bridgecallno);
11302
11303 memset(&ied0, 0, sizeof(ied0));
11304 memset(&ied1, 0, sizeof(ied1));
11305 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
11306 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
11307 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
11308 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
11309 }
11310
11311 }
11312 }
11313 }
11314 break;
11315 case IAX_COMMAND_TXREQ:
11316 try_transfer(iaxs[fr->callno], &ies);
11317 break;
11318 case IAX_COMMAND_TXCNT:
11319 if (iaxs[fr->callno]->transferring)
11320 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0);
11321 break;
11322 case IAX_COMMAND_TXREL:
11323
11324 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11325 complete_transfer(fr->callno, &ies);
11326 stop_stuff(fr->callno);
11327 break;
11328 case IAX_COMMAND_TXMEDIA:
11329 if (iaxs[fr->callno]->transferring == TRANSFER_READY) {
11330 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) {
11331
11332 if (cur->transfer) {
11333 cur->retries = -1;
11334 }
11335 }
11336
11337 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS;
11338 }
11339 break;
11340 case IAX_COMMAND_RTKEY:
11341 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) {
11342 ast_log(LOG_WARNING,
11343 "we've been told to rotate our encryption key, "
11344 "but this isn't an encrypted call. bad things will happen.\n"
11345 );
11346 break;
11347 }
11348
11349 IAX_DEBUGDIGEST("Receiving", ies.challenge);
11350
11351 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx);
11352 break;
11353 case IAX_COMMAND_DPREP:
11354 complete_dpreply(iaxs[fr->callno], &ies);
11355 break;
11356 case IAX_COMMAND_UNSUPPORT:
11357 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown);
11358 break;
11359 case IAX_COMMAND_FWDOWNL:
11360
11361 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) {
11362 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1);
11363 break;
11364 }
11365 memset(&ied0, 0, sizeof(ied0));
11366 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc);
11367 if (res < 0)
11368 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
11369 else if (res > 0)
11370 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11371 else
11372 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1);
11373 break;
11374 case IAX_COMMAND_CALLTOKEN:
11375 {
11376 struct iax_frame *cur;
11377
11378 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) {
11379 resend_with_token(fr->callno, cur, (char *) ies.calltokendata);
11380 }
11381 break;
11382 }
11383 default:
11384 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno);
11385 memset(&ied0, 0, sizeof(ied0));
11386 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer);
11387 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
11388 }
11389
11390 if (ies.vars) {
11391 ast_variables_destroy(ies.vars);
11392 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
11393 ies.vars = NULL;
11394 }
11395
11396
11397 if ((f.subclass.integer != IAX_COMMAND_ACK) &&
11398 (f.subclass.integer != IAX_COMMAND_TXCNT) &&
11399 (f.subclass.integer != IAX_COMMAND_TXACC) &&
11400 (f.subclass.integer != IAX_COMMAND_INVAL) &&
11401 (f.subclass.integer != IAX_COMMAND_VNAK)) {
11402 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11403 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11404 }
11405 ast_mutex_unlock(&iaxsl[fr->callno]);
11406 return 1;
11407 }
11408
11409 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno)
11410 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
11411 } else if (minivid) {
11412 f.frametype = AST_FRAME_VIDEO;
11413 if (iaxs[fr->callno]->videoformat > 0)
11414 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
11415 else {
11416 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
11417 iax2_vnak(fr->callno);
11418 ast_variables_destroy(ies.vars);
11419 ast_mutex_unlock(&iaxsl[fr->callno]);
11420 return 1;
11421 }
11422 f.datalen = res - sizeof(*vh);
11423 if (f.datalen)
11424 f.data.ptr = thread->buf + sizeof(*vh);
11425 else
11426 f.data.ptr = NULL;
11427 #ifdef IAXTESTS
11428 if (test_resync) {
11429 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff);
11430 } else
11431 #endif
11432 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff);
11433 } else {
11434
11435 f.frametype = AST_FRAME_VOICE;
11436 if (iaxs[fr->callno]->voiceformat > 0)
11437 f.subclass.codec = iaxs[fr->callno]->voiceformat;
11438 else {
11439 ast_debug(1, "Received mini frame before first full voice frame\n");
11440 iax2_vnak(fr->callno);
11441 ast_variables_destroy(ies.vars);
11442 ast_mutex_unlock(&iaxsl[fr->callno]);
11443 return 1;
11444 }
11445 f.datalen = res - sizeof(struct ast_iax2_mini_hdr);
11446 if (f.datalen < 0) {
11447 ast_log(LOG_WARNING, "Datalen < 0?\n");
11448 ast_variables_destroy(ies.vars);
11449 ast_mutex_unlock(&iaxsl[fr->callno]);
11450 return 1;
11451 }
11452 if (f.datalen)
11453 f.data.ptr = thread->buf + sizeof(*mh);
11454 else
11455 f.data.ptr = NULL;
11456 #ifdef IAXTESTS
11457 if (test_resync) {
11458 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff);
11459 } else
11460 #endif
11461 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts);
11462
11463 }
11464
11465 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) {
11466 ast_variables_destroy(ies.vars);
11467 ast_mutex_unlock(&iaxsl[fr->callno]);
11468 return 1;
11469 }
11470
11471 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) {
11472 struct ast_party_connected_line connected;
11473
11474 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) {
11475 ast_variables_destroy(ies.vars);
11476 ast_mutex_unlock(&iaxsl[fr->callno]);
11477 return 1;
11478 }
11479
11480
11481 ast_party_connected_line_init(&connected);
11482 connected.id.number.presentation = iaxs[fr->callno]->calling_pres;
11483 connected.id.name.presentation = iaxs[fr->callno]->calling_pres;
11484
11485 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) {
11486 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str);
11487 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str);
11488 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id);
11489
11490 if (iaxs[fr->callno]->owner) {
11491 ast_set_callerid(iaxs[fr->callno]->owner,
11492 S_COR(connected.id.number.valid, connected.id.number.str, ""),
11493 S_COR(connected.id.name.valid, connected.id.name.str, ""),
11494 NULL);
11495 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation;
11496 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation;
11497 }
11498 }
11499 ast_party_connected_line_free(&connected);
11500 }
11501
11502 f.src = "IAX2";
11503 f.mallocd = 0;
11504 f.offset = 0;
11505 f.len = 0;
11506 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
11507 f.samples = ast_codec_get_samples(&f);
11508
11509 if (f.subclass.codec == AST_FORMAT_SLINEAR)
11510 ast_frame_byteswap_be(&f);
11511 } else
11512 f.samples = 0;
11513 iax_frame_wrap(fr, &f);
11514
11515
11516 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11517
11518 fr->outoforder = 0;
11519 } else {
11520 if (iaxdebug && iaxs[fr->callno])
11521 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);
11522 fr->outoforder = -1;
11523 }
11524 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO));
11525 duped_fr = iaxfrdup2(fr);
11526 if (duped_fr) {
11527 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts);
11528 }
11529 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) {
11530 iaxs[fr->callno]->last = fr->ts;
11531 #if 1
11532 if (iaxdebug)
11533 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts);
11534 #endif
11535 }
11536
11537
11538 ast_variables_destroy(ies.vars);
11539 ast_mutex_unlock(&iaxsl[fr->callno]);
11540 return 1;
11541 }
11542
11543
11544 static void iax2_process_thread_cleanup(void *data)
11545 {
11546 struct iax2_thread *thread = data;
11547 ast_mutex_destroy(&thread->lock);
11548 ast_cond_destroy(&thread->cond);
11549 ast_mutex_destroy(&thread->init_lock);
11550 ast_cond_destroy(&thread->init_cond);
11551 ast_free(thread);
11552 ast_atomic_dec_and_test(&iaxactivethreadcount);
11553 }
11554
11555 static void *iax2_process_thread(void *data)
11556 {
11557 struct iax2_thread *thread = data;
11558 struct timeval wait;
11559 struct timespec ts;
11560 int put_into_idle = 0;
11561 int first_time = 1;
11562 int old_state;
11563
11564 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1);
11565
11566 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);
11567 pthread_cleanup_push(iax2_process_thread_cleanup, data);
11568
11569 for (;;) {
11570
11571 ast_mutex_lock(&thread->lock);
11572
11573 if (thread->stop) {
11574 ast_mutex_unlock(&thread->lock);
11575 break;
11576 }
11577
11578
11579 if (first_time) {
11580 signal_condition(&thread->init_lock, &thread->init_cond);
11581 first_time = 0;
11582 }
11583
11584
11585 if (put_into_idle) {
11586 insert_idle_thread(thread);
11587 }
11588
11589 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) {
11590 struct iax2_thread *t = NULL;
11591
11592 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11593 ts.tv_sec = wait.tv_sec;
11594 ts.tv_nsec = wait.tv_usec * 1000;
11595 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11596
11597
11598 if (!put_into_idle || thread->stop) {
11599 ast_mutex_unlock(&thread->lock);
11600 break;
11601 }
11602 AST_LIST_LOCK(&dynamic_list);
11603
11604 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list)))
11605 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1);
11606 AST_LIST_UNLOCK(&dynamic_list);
11607 if (t) {
11608
11609
11610
11611 ast_mutex_unlock(&thread->lock);
11612 break;
11613 }
11614
11615
11616
11617 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000));
11618 ts.tv_sec = wait.tv_sec;
11619 ts.tv_nsec = wait.tv_usec * 1000;
11620 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) {
11621 ast_mutex_unlock(&thread->lock);
11622 break;
11623 }
11624 }
11625 } else {
11626 ast_cond_wait(&thread->cond, &thread->lock);
11627 }
11628
11629
11630 put_into_idle = 1;
11631
11632 ast_mutex_unlock(&thread->lock);
11633
11634 if (thread->stop) {
11635 break;
11636 }
11637
11638 if (thread->iostate == IAX_IOSTATE_IDLE)
11639 continue;
11640
11641
11642 switch (thread->iostate) {
11643 case IAX_IOSTATE_READY:
11644 thread->actions++;
11645 thread->iostate = IAX_IOSTATE_PROCESSING;
11646 socket_process(thread);
11647 handle_deferred_full_frames(thread);
11648 break;
11649 case IAX_IOSTATE_SCHEDREADY:
11650 thread->actions++;
11651 thread->iostate = IAX_IOSTATE_PROCESSING;
11652 #ifdef SCHED_MULTITHREADED
11653 thread->schedfunc(thread->scheddata);
11654 #endif
11655 default:
11656 break;
11657 }
11658 time(&thread->checktime);
11659 thread->iostate = IAX_IOSTATE_IDLE;
11660 #ifdef DEBUG_SCHED_MULTITHREAD
11661 thread->curfunc[0]='\0';
11662 #endif
11663
11664
11665
11666
11667 AST_LIST_LOCK(&active_list);
11668 AST_LIST_REMOVE(&active_list, thread, list);
11669 AST_LIST_UNLOCK(&active_list);
11670
11671
11672 handle_deferred_full_frames(thread);
11673 }
11674
11675
11676
11677
11678
11679 AST_LIST_LOCK(&idle_list);
11680 AST_LIST_REMOVE(&idle_list, thread, list);
11681 AST_LIST_UNLOCK(&idle_list);
11682
11683 AST_LIST_LOCK(&dynamic_list);
11684 AST_LIST_REMOVE(&dynamic_list, thread, list);
11685 AST_LIST_UNLOCK(&dynamic_list);
11686
11687
11688
11689
11690 pthread_cleanup_pop(1);
11691 return NULL;
11692 }
11693
11694 static int iax2_do_register(struct iax2_registry *reg)
11695 {
11696 struct iax_ie_data ied;
11697 if (iaxdebug)
11698 ast_debug(1, "Sending registration request for '%s'\n", reg->username);
11699
11700 if (reg->dnsmgr &&
11701 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) {
11702
11703 ast_dnsmgr_refresh(reg->dnsmgr);
11704 }
11705
11706
11707
11708
11709
11710 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) {
11711 int callno = reg->callno;
11712 ast_mutex_lock(&iaxsl[callno]);
11713 iax2_destroy(callno);
11714 ast_mutex_unlock(&iaxsl[callno]);
11715 reg->callno = 0;
11716 }
11717 if (!ast_sockaddr_ipv4(®->addr)) {
11718 if (iaxdebug)
11719 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username);
11720
11721 reg->expire = iax2_sched_replace(reg->expire, sched,
11722 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11723 return -1;
11724 }
11725
11726 if (!reg->callno) {
11727 struct sockaddr_in reg_addr;
11728
11729 ast_debug(3, "Allocate call number\n");
11730
11731 ast_sockaddr_to_sin(®->addr, ®_addr);
11732
11733 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0);
11734 if (reg->callno < 1) {
11735 ast_log(LOG_WARNING, "Unable to create call for registration\n");
11736 return -1;
11737 } else
11738 ast_debug(3, "Registration created on call %d\n", reg->callno);
11739 iaxs[reg->callno]->reg = reg;
11740 ast_mutex_unlock(&iaxsl[reg->callno]);
11741 }
11742
11743 reg->expire = iax2_sched_replace(reg->expire, sched,
11744 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg);
11745
11746 memset(&ied, 0, sizeof(ied));
11747 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username);
11748 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh);
11749 add_empty_calltoken_ie(iaxs[reg->callno], &ied);
11750 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1);
11751 reg->regstate = REG_STATE_REGSENT;
11752 return 0;
11753 }
11754
11755 static int iax2_provision(struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force)
11756 {
11757
11758
11759 struct iax_ie_data provdata;
11760 struct iax_ie_data ied;
11761 unsigned int sig;
11762 struct sockaddr_in sin;
11763 int callno;
11764 struct create_addr_info cai;
11765
11766 memset(&cai, 0, sizeof(cai));
11767
11768 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template);
11769
11770 if (iax_provision_build(&provdata, &sig, template, force)) {
11771 ast_debug(1, "No provisioning found for template '%s'\n", template);
11772 return 0;
11773 }
11774
11775 if (end) {
11776 memcpy(&sin, end, sizeof(sin));
11777 cai.sockfd = sockfd;
11778 } else if (create_addr(dest, NULL, &sin, &cai))
11779 return -1;
11780
11781
11782 memset(&ied, 0, sizeof(ied));
11783 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos);
11784
11785 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
11786 if (!callno)
11787 return -1;
11788
11789 if (iaxs[callno]) {
11790
11791 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid,
11792 sched, 15000, auto_hangup, (void *)(long)callno);
11793 ast_set_flag64(iaxs[callno], IAX_PROVISION);
11794
11795 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1);
11796 }
11797 ast_mutex_unlock(&iaxsl[callno]);
11798
11799 return 1;
11800 }
11801
11802 static char *papp = "IAX2Provision";
11803
11804
11805
11806
11807 static int iax2_prov_app(struct ast_channel *chan, const char *data)
11808 {
11809 int res;
11810 char *sdata;
11811 char *opts;
11812 int force =0;
11813 unsigned short callno = PTR_TO_CALLNO(chan->tech_pvt);
11814 if (ast_strlen_zero(data))
11815 data = "default";
11816 sdata = ast_strdupa(data);
11817 opts = strchr(sdata, '|');
11818 if (opts)
11819 *opts='\0';
11820
11821 if (chan->tech != &iax2_tech) {
11822 ast_log(LOG_NOTICE, "Can't provision a non-IAX device!\n");
11823 return -1;
11824 }
11825 if (!callno || !iaxs[callno] || !iaxs[callno]->addr.sin_addr.s_addr) {
11826 ast_log(LOG_NOTICE, "Can't provision something with no IP?\n");
11827 return -1;
11828 }
11829 res = iax2_provision(&iaxs[callno]->addr, iaxs[callno]->sockfd, NULL, sdata, force);
11830 ast_verb(3, "Provisioned IAXY at '%s' with '%s'= %d\n",
11831 ast_inet_ntoa(iaxs[callno]->addr.sin_addr),
11832 sdata, res);
11833 return res;
11834 }
11835
11836 static char *handle_cli_iax2_provision(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
11837 {
11838 int force = 0;
11839 int res;
11840
11841 switch (cmd) {
11842 case CLI_INIT:
11843 e->command = "iax2 provision";
11844 e->usage =
11845 "Usage: iax2 provision <host> <template> [forced]\n"
11846 " Provisions the given peer or IP address using a template\n"
11847 " matching either 'template' or '*' if the template is not\n"
11848 " found. If 'forced' is specified, even empty provisioning\n"
11849 " fields will be provisioned as empty fields.\n";
11850 return NULL;
11851 case CLI_GENERATE:
11852 if (a->pos == 3)
11853 return iax_prov_complete_template(a->line, a->word, a->pos, a->n);
11854 return NULL;
11855 }
11856
11857 if (a->argc < 4)
11858 return CLI_SHOWUSAGE;
11859 if (a->argc > 4) {
11860 if (!strcasecmp(a->argv[4], "forced"))
11861 force = 1;
11862 else
11863 return CLI_SHOWUSAGE;
11864 }
11865 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force);
11866 if (res < 0)
11867 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]);
11868 else if (res < 1)
11869 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]);
11870 else
11871 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : "");
11872 return CLI_SUCCESS;
11873 }
11874
11875 static void __iax2_poke_noanswer(const void *data)
11876 {
11877 struct iax2_peer *peer = (struct iax2_peer *)data;
11878 int callno;
11879
11880 if (peer->lastms > -1) {
11881 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms);
11882 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms);
11883 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name);
11884 }
11885 if ((callno = peer->callno) > 0) {
11886 ast_mutex_lock(&iaxsl[callno]);
11887 iax2_destroy(callno);
11888 ast_mutex_unlock(&iaxsl[callno]);
11889 }
11890 peer->callno = 0;
11891 peer->lastms = -1;
11892
11893 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer));
11894 if (peer->pokeexpire == -1)
11895 peer_unref(peer);
11896 }
11897
11898 static int iax2_poke_noanswer(const void *data)
11899 {
11900 struct iax2_peer *peer = (struct iax2_peer *)data;
11901 peer->pokeexpire = -1;
11902 #ifdef SCHED_MULTITHREADED
11903 if (schedule_action(__iax2_poke_noanswer, data))
11904 #endif
11905 __iax2_poke_noanswer(data);
11906 peer_unref(peer);
11907 return 0;
11908 }
11909
11910 static int iax2_poke_peer_cb(void *obj, void *arg, int flags)
11911 {
11912 struct iax2_peer *peer = obj;
11913
11914 iax2_poke_peer(peer, 0);
11915
11916 return 0;
11917 }
11918
11919 static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
11920 {
11921 int callno;
11922 struct sockaddr_in peer_addr;
11923
11924 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) {
11925
11926
11927 peer->lastms = 0;
11928 peer->historicms = 0;
11929 peer->pokeexpire = -1;
11930 peer->callno = 0;
11931 return 0;
11932 }
11933
11934 ast_sockaddr_to_sin(&peer->addr, &peer_addr);
11935
11936
11937 if ((callno = peer->callno) > 0) {
11938 ast_log(LOG_NOTICE, "Still have a callno...\n");
11939 ast_mutex_lock(&iaxsl[callno]);
11940 iax2_destroy(callno);
11941 ast_mutex_unlock(&iaxsl[callno]);
11942 }
11943 if (heldcall)
11944 ast_mutex_unlock(&iaxsl[heldcall]);
11945 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0);
11946 if (heldcall)
11947 ast_mutex_lock(&iaxsl[heldcall]);
11948 if (peer->callno < 1) {
11949 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name);
11950 return -1;
11951 }
11952
11953
11954 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1;
11955 iaxs[peer->callno]->peerpoke = peer;
11956
11957 if (peer->pokeexpire > -1) {
11958 if (!ast_sched_thread_del(sched, peer->pokeexpire)) {
11959 peer->pokeexpire = -1;
11960 peer_unref(peer);
11961 }
11962 }
11963
11964
11965
11966 if (peer->lastms < 0)
11967 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer));
11968 else
11969 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer));
11970
11971 if (peer->pokeexpire == -1)
11972 peer_unref(peer);
11973
11974
11975 ast_mutex_lock(&iaxsl[callno]);
11976 if (iaxs[callno]) {
11977 struct iax_ie_data ied = {
11978 .buf = { 0 },
11979 .pos = 0,
11980 };
11981 add_empty_calltoken_ie(iaxs[callno], &ied);
11982 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1);
11983 }
11984 ast_mutex_unlock(&iaxsl[callno]);
11985
11986 return 0;
11987 }
11988
11989 static void free_context(struct iax2_context *con)
11990 {
11991 struct iax2_context *conl;
11992 while(con) {
11993 conl = con;
11994 con = con->next;
11995 ast_free(conl);
11996 }
11997 }
11998
11999 static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
12000 {
12001 int callno;
12002 int res;
12003 format_t fmt, native;
12004 struct sockaddr_in sin;
12005 struct ast_channel *c;
12006 struct parsed_dial_string pds;
12007 struct create_addr_info cai;
12008 char *tmpstr;
12009
12010 memset(&pds, 0, sizeof(pds));
12011 tmpstr = ast_strdupa(data);
12012 parse_dial_string(tmpstr, &pds);
12013
12014 if (ast_strlen_zero(pds.peer)) {
12015 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
12016 return NULL;
12017 }
12018
12019 memset(&cai, 0, sizeof(cai));
12020 cai.capability = iax2_capability;
12021
12022 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12023
12024
12025 if (create_addr(pds.peer, NULL, &sin, &cai)) {
12026 *cause = AST_CAUSE_UNREGISTERED;
12027 return NULL;
12028 }
12029
12030 if (pds.port)
12031 sin.sin_port = htons(atoi(pds.port));
12032
12033 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
12034 if (callno < 1) {
12035 ast_log(LOG_WARNING, "Unable to create call\n");
12036 *cause = AST_CAUSE_CONGESTION;
12037 return NULL;
12038 }
12039
12040
12041 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12042 if (ast_test_flag64(&cai, IAX_TRUNK)) {
12043 int new_callno;
12044 if ((new_callno = make_trunk(callno, 1)) != -1)
12045 callno = new_callno;
12046 }
12047 iaxs[callno]->maxtime = cai.maxtime;
12048 if (cai.found)
12049 ast_string_field_set(iaxs[callno], host, pds.peer);
12050
12051 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL);
12052
12053 ast_mutex_unlock(&iaxsl[callno]);
12054
12055 if (c) {
12056
12057 if (c->nativeformats & format)
12058 c->nativeformats &= format;
12059 else {
12060 native = c->nativeformats;
12061 fmt = format;
12062 res = ast_translator_best_choice(&fmt, &native);
12063 if (res < 0) {
12064 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
12065 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
12066 ast_hangup(c);
12067 return NULL;
12068 }
12069 c->nativeformats = native;
12070 }
12071 c->readformat = ast_best_codec(c->nativeformats);
12072 c->writeformat = c->readformat;
12073 }
12074
12075 return c;
12076 }
12077
12078 static void *network_thread(void *ignore)
12079 {
12080 if (timer) {
12081 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL);
12082 }
12083
12084 for (;;) {
12085 pthread_testcancel();
12086
12087
12088
12089 ast_io_wait(io, 1000);
12090 }
12091
12092 return NULL;
12093 }
12094
12095 static int start_network_thread(void)
12096 {
12097 struct iax2_thread *thread;
12098 int threadcount = 0;
12099 int x;
12100 for (x = 0; x < iaxthreadcount; x++) {
12101 thread = ast_calloc(1, sizeof(*thread));
12102 if (thread) {
12103 thread->type = IAX_THREAD_TYPE_POOL;
12104 thread->threadnum = ++threadcount;
12105 ast_mutex_init(&thread->lock);
12106 ast_cond_init(&thread->cond, NULL);
12107 ast_mutex_init(&thread->init_lock);
12108 ast_cond_init(&thread->init_cond, NULL);
12109 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) {
12110 ast_log(LOG_WARNING, "Failed to create new thread!\n");
12111 ast_mutex_destroy(&thread->lock);
12112 ast_cond_destroy(&thread->cond);
12113 ast_mutex_destroy(&thread->init_lock);
12114 ast_cond_destroy(&thread->init_cond);
12115 ast_free(thread);
12116 thread = NULL;
12117 continue;
12118 }
12119 AST_LIST_LOCK(&idle_list);
12120 AST_LIST_INSERT_TAIL(&idle_list, thread, list);
12121 AST_LIST_UNLOCK(&idle_list);
12122 }
12123 }
12124 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL);
12125 ast_verb(2, "%d helper threads started\n", threadcount);
12126 return 0;
12127 }
12128
12129 static struct iax2_context *build_context(const char *context)
12130 {
12131 struct iax2_context *con;
12132
12133 if ((con = ast_calloc(1, sizeof(*con))))
12134 ast_copy_string(con->context, context, sizeof(con->context));
12135
12136 return con;
12137 }
12138
12139 static int get_auth_methods(const char *value)
12140 {
12141 int methods = 0;
12142 if (strstr(value, "rsa"))
12143 methods |= IAX_AUTH_RSA;
12144 if (strstr(value, "md5"))
12145 methods |= IAX_AUTH_MD5;
12146 if (strstr(value, "plaintext"))
12147 methods |= IAX_AUTH_PLAINTEXT;
12148 return methods;
12149 }
12150
12151
12152
12153
12154
12155 static int check_srcaddr(struct sockaddr *sa, socklen_t salen)
12156 {
12157 int sd;
12158 int res;
12159
12160 sd = socket(AF_INET, SOCK_DGRAM, 0);
12161 if (sd < 0) {
12162 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno));
12163 return -1;
12164 }
12165
12166 res = bind(sd, sa, salen);
12167 if (res < 0) {
12168 ast_debug(1, "Can't bind: %s\n", strerror(errno));
12169 close(sd);
12170 return 1;
12171 }
12172
12173 close(sd);
12174 return 0;
12175 }
12176
12177
12178
12179
12180 static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr)
12181 {
12182 struct sockaddr_in sin;
12183 struct ast_sockaddr sin_tmp;
12184 int nonlocal = 1;
12185 int port = IAX_DEFAULT_PORTNO;
12186 int sockfd = defaultsockfd;
12187 char *tmp;
12188 char *addr;
12189 char *portstr;
12190
12191 if (!(tmp = ast_strdupa(srcaddr)))
12192 return -1;
12193
12194 addr = strsep(&tmp, ":");
12195 portstr = tmp;
12196
12197 if (portstr) {
12198 port = atoi(portstr);
12199 if (port < 1)
12200 port = IAX_DEFAULT_PORTNO;
12201 }
12202
12203 if (!ast_get_ip(&sin_tmp, addr)) {
12204 struct ast_netsock *sock;
12205 int res;
12206
12207 ast_sockaddr_to_sin(&sin_tmp, &sin);
12208 sin.sin_port = 0;
12209 sin.sin_family = AF_INET;
12210 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin));
12211 if (res == 0) {
12212
12213 sin.sin_port = htons(port);
12214 if (!(sock = ast_netsock_find(netsock, &sin)))
12215 sock = ast_netsock_find(outsock, &sin);
12216 if (sock) {
12217 sockfd = ast_netsock_sockfd(sock);
12218 nonlocal = 0;
12219 } else {
12220 unsigned int orig_saddr = sin.sin_addr.s_addr;
12221
12222 sin.sin_addr.s_addr = INADDR_ANY;
12223 if (ast_netsock_find(netsock, &sin)) {
12224 sin.sin_addr.s_addr = orig_saddr;
12225 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL);
12226 if (sock) {
12227 sockfd = ast_netsock_sockfd(sock);
12228 ast_netsock_unref(sock);
12229 nonlocal = 0;
12230 } else {
12231 nonlocal = 2;
12232 }
12233 }
12234 }
12235 }
12236 }
12237
12238 peer->sockfd = sockfd;
12239
12240 if (nonlocal == 1) {
12241 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
12242 srcaddr, peer->name);
12243 return -1;
12244 } else if (nonlocal == 2) {
12245 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
12246 srcaddr, peer->name);
12247 return -1;
12248 } else {
12249 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
12250 return 0;
12251 }
12252 }
12253
12254 static void peer_destructor(void *obj)
12255 {
12256 struct iax2_peer *peer = obj;
12257 int callno = peer->callno;
12258
12259 ast_free_ha(peer->ha);
12260
12261 if (callno > 0) {
12262 ast_mutex_lock(&iaxsl[callno]);
12263 iax2_destroy(callno);
12264 ast_mutex_unlock(&iaxsl[callno]);
12265 }
12266
12267 register_peer_exten(peer, 0);
12268
12269 if (peer->dnsmgr)
12270 ast_dnsmgr_release(peer->dnsmgr);
12271
12272 if (peer->mwi_event_sub)
12273 ast_event_unsubscribe(peer->mwi_event_sub);
12274
12275 ast_string_field_free_memory(peer);
12276 }
12277
12278
12279 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12280 {
12281 struct iax2_peer *peer = NULL;
12282 struct ast_ha *oldha = NULL;
12283 int maskfound = 0;
12284 int found = 0;
12285 int firstpass = 1;
12286 struct iax2_peer tmp_peer = {
12287 .name = name,
12288 };
12289
12290 if (!temponly) {
12291 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER);
12292 if (peer && !ast_test_flag64(peer, IAX_DELME))
12293 firstpass = 0;
12294 }
12295
12296 if (peer) {
12297 found++;
12298 if (firstpass) {
12299 oldha = peer->ha;
12300 peer->ha = NULL;
12301 }
12302 unlink_peer(peer);
12303 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) {
12304 peer->expire = -1;
12305 peer->pokeexpire = -1;
12306 peer->sockfd = defaultsockfd;
12307 if (ast_string_field_init(peer, 32))
12308 peer = peer_unref(peer);
12309 }
12310
12311 if (peer) {
12312 if (firstpass) {
12313 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT);
12314 peer->encmethods = iax2_encryption;
12315 peer->adsi = adsi;
12316 ast_string_field_set(peer,secret,"");
12317 if (!found) {
12318 ast_string_field_set(peer, name, name);
12319 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12320 peer->expiry = min_reg_expire;
12321 }
12322 peer->prefs = prefs;
12323 peer->capability = iax2_capability;
12324 peer->smoothing = 0;
12325 peer->pokefreqok = DEFAULT_FREQ_OK;
12326 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK;
12327 peer->maxcallno = 0;
12328 peercnt_modify(0, 0, &peer->addr);
12329 peer->calltoken_required = CALLTOKEN_DEFAULT;
12330 ast_string_field_set(peer,context,"");
12331 ast_string_field_set(peer,peercontext,"");
12332 ast_clear_flag64(peer, IAX_HASCALLERID);
12333 ast_string_field_set(peer, cid_name, "");
12334 ast_string_field_set(peer, cid_num, "");
12335 ast_string_field_set(peer, mohinterpret, mohinterpret);
12336 ast_string_field_set(peer, mohsuggest, mohsuggest);
12337 }
12338
12339 if (!v) {
12340 v = alt;
12341 alt = NULL;
12342 }
12343 while(v) {
12344 if (!strcasecmp(v->name, "secret")) {
12345 ast_string_field_set(peer, secret, v->value);
12346 } else if (!strcasecmp(v->name, "mailbox")) {
12347 ast_string_field_set(peer, mailbox, v->value);
12348 } else if (!strcasecmp(v->name, "hasvoicemail")) {
12349 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) {
12350 ast_string_field_set(peer, mailbox, name);
12351 }
12352 } else if (!strcasecmp(v->name, "mohinterpret")) {
12353 ast_string_field_set(peer, mohinterpret, v->value);
12354 } else if (!strcasecmp(v->name, "mohsuggest")) {
12355 ast_string_field_set(peer, mohsuggest, v->value);
12356 } else if (!strcasecmp(v->name, "dbsecret")) {
12357 ast_string_field_set(peer, dbsecret, v->value);
12358 } else if (!strcasecmp(v->name, "trunk")) {
12359 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK);
12360 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) {
12361 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name);
12362 ast_clear_flag64(peer, IAX_TRUNK);
12363 }
12364 } else if (!strcasecmp(v->name, "auth")) {
12365 peer->authmethods = get_auth_methods(v->value);
12366 } else if (!strcasecmp(v->name, "encryption")) {
12367 peer->encmethods |= get_encrypt_methods(v->value);
12368 if (!peer->encmethods) {
12369 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12370 }
12371 } else if (!strcasecmp(v->name, "forceencryption")) {
12372 if (ast_false(v->value)) {
12373 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT);
12374 } else {
12375 peer->encmethods |= get_encrypt_methods(v->value);
12376 if (peer->encmethods) {
12377 ast_set_flag64(peer, IAX_FORCE_ENCRYPT);
12378 }
12379 }
12380 } else if (!strcasecmp(v->name, "transfer")) {
12381 if (!strcasecmp(v->value, "mediaonly")) {
12382 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12383 } else if (ast_true(v->value)) {
12384 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12385 } else
12386 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12387 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12388 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF);
12389 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12390 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF);
12391 } else if (!strcasecmp(v->name, "host")) {
12392 if (!strcasecmp(v->value, "dynamic")) {
12393
12394 ast_set_flag64(peer, IAX_DYNAMIC);
12395 if (!found) {
12396
12397
12398 if (ast_sockaddr_port(&peer->addr)) {
12399 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr));
12400 }
12401 ast_sockaddr_setnull(&peer->addr);
12402 }
12403 } else {
12404
12405 ast_sched_thread_del(sched, peer->expire);
12406 ast_clear_flag64(peer, IAX_DYNAMIC);
12407 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL))
12408 return peer_unref(peer);
12409 if (!ast_sockaddr_port(&peer->addr)) {
12410 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO);
12411 }
12412 }
12413 if (!maskfound)
12414 inet_aton("255.255.255.255", &peer->mask);
12415 } else if (!strcasecmp(v->name, "defaultip")) {
12416 struct ast_sockaddr peer_defaddr_tmp;
12417
12418 if (ast_get_ip(&peer_defaddr_tmp, v->value)) {
12419 return peer_unref(peer);
12420 }
12421 ast_sockaddr_to_sin(&peer_defaddr_tmp,
12422 &peer->defaddr);
12423 } else if (!strcasecmp(v->name, "sourceaddress")) {
12424 peer_set_srcaddr(peer, v->value);
12425 } else if (!strcasecmp(v->name, "permit") ||
12426 !strcasecmp(v->name, "deny")) {
12427 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL);
12428 } else if (!strcasecmp(v->name, "mask")) {
12429 maskfound++;
12430 inet_aton(v->value, &peer->mask);
12431 } else if (!strcasecmp(v->name, "context")) {
12432 ast_string_field_set(peer, context, v->value);
12433 } else if (!strcasecmp(v->name, "regexten")) {
12434 ast_string_field_set(peer, regexten, v->value);
12435 } else if (!strcasecmp(v->name, "peercontext")) {
12436 ast_string_field_set(peer, peercontext, v->value);
12437 } else if (!strcasecmp(v->name, "port")) {
12438 if (ast_test_flag64(peer, IAX_DYNAMIC)) {
12439 peer->defaddr.sin_port = htons(atoi(v->value));
12440 } else {
12441 ast_sockaddr_set_port(&peer->addr, atoi(v->value));
12442 }
12443 } else if (!strcasecmp(v->name, "username")) {
12444 ast_string_field_set(peer, username, v->value);
12445 } else if (!strcasecmp(v->name, "allow")) {
12446 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
12447 } else if (!strcasecmp(v->name, "disallow")) {
12448 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
12449 } else if (!strcasecmp(v->name, "callerid")) {
12450 if (!ast_strlen_zero(v->value)) {
12451 char name2[80];
12452 char num2[80];
12453 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12454 ast_string_field_set(peer, cid_name, name2);
12455 ast_string_field_set(peer, cid_num, num2);
12456 } else {
12457 ast_string_field_set(peer, cid_name, "");
12458 ast_string_field_set(peer, cid_num, "");
12459 }
12460 ast_set_flag64(peer, IAX_HASCALLERID);
12461 } else if (!strcasecmp(v->name, "fullname")) {
12462 ast_string_field_set(peer, cid_name, S_OR(v->value, ""));
12463 ast_set_flag64(peer, IAX_HASCALLERID);
12464 } else if (!strcasecmp(v->name, "cid_number")) {
12465 ast_string_field_set(peer, cid_num, S_OR(v->value, ""));
12466 ast_set_flag64(peer, IAX_HASCALLERID);
12467 } else if (!strcasecmp(v->name, "sendani")) {
12468 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI);
12469 } else if (!strcasecmp(v->name, "inkeys")) {
12470 ast_string_field_set(peer, inkeys, v->value);
12471 } else if (!strcasecmp(v->name, "outkey")) {
12472 ast_string_field_set(peer, outkey, v->value);
12473 } else if (!strcasecmp(v->name, "qualify")) {
12474 if (!strcasecmp(v->value, "no")) {
12475 peer->maxms = 0;
12476 } else if (!strcasecmp(v->value, "yes")) {
12477 peer->maxms = DEFAULT_MAXMS;
12478 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
12479 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);
12480 peer->maxms = 0;
12481 }
12482 } else if (!strcasecmp(v->name, "qualifysmoothing")) {
12483 peer->smoothing = ast_true(v->value);
12484 } else if (!strcasecmp(v->name, "qualifyfreqok")) {
12485 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) {
12486 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);
12487 }
12488 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) {
12489 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) {
12490 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);
12491 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok);
12492 } else if (!strcasecmp(v->name, "timezone")) {
12493 ast_string_field_set(peer, zonetag, v->value);
12494 } else if (!strcasecmp(v->name, "adsi")) {
12495 peer->adsi = ast_true(v->value);
12496 } else if (!strcasecmp(v->name, "connectedline")) {
12497 if (ast_true(v->value)) {
12498 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12499 } else if (!strcasecmp(v->value, "send")) {
12500 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE);
12501 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE);
12502 } else if (!strcasecmp(v->value, "receive")) {
12503 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE);
12504 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE);
12505 } else {
12506 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12507 }
12508 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
12509 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) {
12510 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno);
12511 } else {
12512 peercnt_modify(1, peer->maxcallno, &peer->addr);
12513 }
12514 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12515
12516 if (ast_false(v->value)) {
12517 peer->calltoken_required = CALLTOKEN_NO;
12518 } else if (!strcasecmp(v->value, "auto")) {
12519 peer->calltoken_required = CALLTOKEN_AUTO;
12520 } else if (ast_true(v->value)) {
12521 peer->calltoken_required = CALLTOKEN_YES;
12522 } else {
12523 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12524 }
12525 }
12526
12527 v = v->next;
12528 if (!v) {
12529 v = alt;
12530 alt = NULL;
12531 }
12532 }
12533 if (!peer->authmethods)
12534 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12535 ast_clear_flag64(peer, IAX_DELME);
12536 }
12537
12538 if (oldha)
12539 ast_free_ha(oldha);
12540
12541 if (!ast_strlen_zero(peer->mailbox)) {
12542 char *mailbox, *context;
12543 context = mailbox = ast_strdupa(peer->mailbox);
12544 strsep(&context, "@");
12545 if (ast_strlen_zero(context))
12546 context = "default";
12547 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL,
12548 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
12549 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
12550 AST_EVENT_IE_END);
12551 }
12552
12553 return peer;
12554 }
12555
12556 static void user_destructor(void *obj)
12557 {
12558 struct iax2_user *user = obj;
12559
12560 ast_free_ha(user->ha);
12561 free_context(user->contexts);
12562 if(user->vars) {
12563 ast_variables_destroy(user->vars);
12564 user->vars = NULL;
12565 }
12566 ast_string_field_free_memory(user);
12567 }
12568
12569
12570 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly)
12571 {
12572 struct iax2_user *user = NULL;
12573 struct iax2_context *con, *conl = NULL;
12574 struct ast_ha *oldha = NULL;
12575 struct iax2_context *oldcon = NULL;
12576 int format;
12577 int firstpass=1;
12578 int oldcurauthreq = 0;
12579 char *varname = NULL, *varval = NULL;
12580 struct ast_variable *tmpvar = NULL;
12581 struct iax2_user tmp_user = {
12582 .name = name,
12583 };
12584
12585 if (!temponly) {
12586 user = ao2_find(users, &tmp_user, OBJ_POINTER);
12587 if (user && !ast_test_flag64(user, IAX_DELME))
12588 firstpass = 0;
12589 }
12590
12591 if (user) {
12592 if (firstpass) {
12593 oldcurauthreq = user->curauthreq;
12594 oldha = user->ha;
12595 oldcon = user->contexts;
12596 user->ha = NULL;
12597 user->contexts = NULL;
12598 }
12599
12600 ao2_unlink(users, user);
12601 } else {
12602 user = ao2_alloc(sizeof(*user), user_destructor);
12603 }
12604
12605 if (user) {
12606 if (firstpass) {
12607 ast_string_field_free_memory(user);
12608 memset(user, 0, sizeof(struct iax2_user));
12609 if (ast_string_field_init(user, 32)) {
12610 user = user_unref(user);
12611 goto cleanup;
12612 }
12613 user->maxauthreq = maxauthreq;
12614 user->curauthreq = oldcurauthreq;
12615 user->prefs = prefs;
12616 user->capability = iax2_capability;
12617 user->encmethods = iax2_encryption;
12618 user->adsi = adsi;
12619 user->calltoken_required = CALLTOKEN_DEFAULT;
12620 ast_string_field_set(user, name, name);
12621 ast_string_field_set(user, language, language);
12622 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);
12623 ast_clear_flag64(user, IAX_HASCALLERID);
12624 ast_string_field_set(user, cid_name, "");
12625 ast_string_field_set(user, cid_num, "");
12626 ast_string_field_set(user, accountcode, accountcode);
12627 ast_string_field_set(user, mohinterpret, mohinterpret);
12628 ast_string_field_set(user, mohsuggest, mohsuggest);
12629 }
12630 if (!v) {
12631 v = alt;
12632 alt = NULL;
12633 }
12634 while(v) {
12635 if (!strcasecmp(v->name, "context")) {
12636 con = build_context(v->value);
12637 if (con) {
12638 if (conl)
12639 conl->next = con;
12640 else
12641 user->contexts = con;
12642 conl = con;
12643 }
12644 } else if (!strcasecmp(v->name, "permit") ||
12645 !strcasecmp(v->name, "deny")) {
12646 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL);
12647 } else if (!strcasecmp(v->name, "setvar")) {
12648 varname = ast_strdupa(v->value);
12649 if (varname && (varval = strchr(varname,'='))) {
12650 *varval = '\0';
12651 varval++;
12652 if((tmpvar = ast_variable_new(varname, varval, ""))) {
12653 tmpvar->next = user->vars;
12654 user->vars = tmpvar;
12655 }
12656 }
12657 } else if (!strcasecmp(v->name, "allow")) {
12658 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
12659 } else if (!strcasecmp(v->name, "disallow")) {
12660 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
12661 } else if (!strcasecmp(v->name, "trunk")) {
12662 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);
12663 if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
12664 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name);
12665 ast_clear_flag64(user, IAX_TRUNK);
12666 }
12667 } else if (!strcasecmp(v->name, "auth")) {
12668 user->authmethods = get_auth_methods(v->value);
12669 } else if (!strcasecmp(v->name, "encryption")) {
12670 user->encmethods |= get_encrypt_methods(v->value);
12671 if (!user->encmethods) {
12672 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12673 }
12674 } else if (!strcasecmp(v->name, "forceencryption")) {
12675 if (ast_false(v->value)) {
12676 ast_clear_flag64(user, IAX_FORCE_ENCRYPT);
12677 } else {
12678 user->encmethods |= get_encrypt_methods(v->value);
12679 if (user->encmethods) {
12680 ast_set_flag64(user, IAX_FORCE_ENCRYPT);
12681 }
12682 }
12683 } else if (!strcasecmp(v->name, "transfer")) {
12684 if (!strcasecmp(v->value, "mediaonly")) {
12685 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
12686 } else if (ast_true(v->value)) {
12687 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
12688 } else
12689 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
12690 } else if (!strcasecmp(v->name, "codecpriority")) {
12691 if(!strcasecmp(v->value, "caller"))
12692 ast_set_flag64(user, IAX_CODEC_USER_FIRST);
12693 else if(!strcasecmp(v->value, "disabled"))
12694 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12695 else if(!strcasecmp(v->value, "reqonly")) {
12696 ast_set_flag64(user, IAX_CODEC_NOCAP);
12697 ast_set_flag64(user, IAX_CODEC_NOPREFS);
12698 }
12699 } else if (!strcasecmp(v->name, "immediate")) {
12700 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE);
12701 } else if (!strcasecmp(v->name, "jitterbuffer")) {
12702 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF);
12703 } else if (!strcasecmp(v->name, "forcejitterbuffer")) {
12704 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF);
12705 } else if (!strcasecmp(v->name, "dbsecret")) {
12706 ast_string_field_set(user, dbsecret, v->value);
12707 } else if (!strcasecmp(v->name, "secret")) {
12708 if (!ast_strlen_zero(user->secret)) {
12709 char *old = ast_strdupa(user->secret);
12710
12711 ast_string_field_build(user, secret, "%s;%s", old, v->value);
12712 } else
12713 ast_string_field_set(user, secret, v->value);
12714 } else if (!strcasecmp(v->name, "callerid")) {
12715 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) {
12716 char name2[80];
12717 char num2[80];
12718 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2));
12719 ast_string_field_set(user, cid_name, name2);
12720 ast_string_field_set(user, cid_num, num2);
12721 ast_set_flag64(user, IAX_HASCALLERID);
12722 } else {
12723 ast_clear_flag64(user, IAX_HASCALLERID);
12724 ast_string_field_set(user, cid_name, "");
12725 ast_string_field_set(user, cid_num, "");
12726 }
12727 } else if (!strcasecmp(v->name, "fullname")) {
12728 if (!ast_strlen_zero(v->value)) {
12729 ast_string_field_set(user, cid_name, v->value);
12730 ast_set_flag64(user, IAX_HASCALLERID);
12731 } else {
12732 ast_string_field_set(user, cid_name, "");
12733 if (ast_strlen_zero(user->cid_num))
12734 ast_clear_flag64(user, IAX_HASCALLERID);
12735 }
12736 } else if (!strcasecmp(v->name, "cid_number")) {
12737 if (!ast_strlen_zero(v->value)) {
12738 ast_string_field_set(user, cid_num, v->value);
12739 ast_set_flag64(user, IAX_HASCALLERID);
12740 } else {
12741 ast_string_field_set(user, cid_num, "");
12742 if (ast_strlen_zero(user->cid_name))
12743 ast_clear_flag64(user, IAX_HASCALLERID);
12744 }
12745 } else if (!strcasecmp(v->name, "accountcode")) {
12746 ast_string_field_set(user, accountcode, v->value);
12747 } else if (!strcasecmp(v->name, "mohinterpret")) {
12748 ast_string_field_set(user, mohinterpret, v->value);
12749 } else if (!strcasecmp(v->name, "mohsuggest")) {
12750 ast_string_field_set(user, mohsuggest, v->value);
12751 } else if (!strcasecmp(v->name, "parkinglot")) {
12752 ast_string_field_set(user, parkinglot, v->value);
12753 } else if (!strcasecmp(v->name, "language")) {
12754 ast_string_field_set(user, language, v->value);
12755 } else if (!strcasecmp(v->name, "amaflags")) {
12756 format = ast_cdr_amaflags2int(v->value);
12757 if (format < 0) {
12758 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
12759 } else {
12760 user->amaflags = format;
12761 }
12762 } else if (!strcasecmp(v->name, "inkeys")) {
12763 ast_string_field_set(user, inkeys, v->value);
12764 } else if (!strcasecmp(v->name, "maxauthreq")) {
12765 user->maxauthreq = atoi(v->value);
12766 if (user->maxauthreq < 0)
12767 user->maxauthreq = 0;
12768 } else if (!strcasecmp(v->name, "adsi")) {
12769 user->adsi = ast_true(v->value);
12770 } else if (!strcasecmp(v->name, "connectedline")) {
12771 if (ast_true(v->value)) {
12772 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12773 } else if (!strcasecmp(v->value, "send")) {
12774 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE);
12775 ast_set_flag64(user, IAX_SENDCONNECTEDLINE);
12776 } else if (!strcasecmp(v->value, "receive")) {
12777 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE);
12778 ast_set_flag64(user, IAX_RECVCONNECTEDLINE);
12779 } else {
12780 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12781 }
12782 } else if (!strcasecmp(v->name, "requirecalltoken")) {
12783
12784 if (ast_false(v->value)) {
12785 user->calltoken_required = CALLTOKEN_NO;
12786 } else if (!strcasecmp(v->value, "auto")) {
12787 user->calltoken_required = CALLTOKEN_AUTO;
12788 } else if (ast_true(v->value)) {
12789 user->calltoken_required = CALLTOKEN_YES;
12790 } else {
12791 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno);
12792 }
12793 }
12794
12795 v = v->next;
12796 if (!v) {
12797 v = alt;
12798 alt = NULL;
12799 }
12800 }
12801 if (!user->authmethods) {
12802 if (!ast_strlen_zero(user->secret)) {
12803 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12804 if (!ast_strlen_zero(user->inkeys))
12805 user->authmethods |= IAX_AUTH_RSA;
12806 } else if (!ast_strlen_zero(user->inkeys)) {
12807 user->authmethods = IAX_AUTH_RSA;
12808 } else {
12809 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT;
12810 }
12811 }
12812 ast_clear_flag64(user, IAX_DELME);
12813 }
12814 cleanup:
12815 if (oldha)
12816 ast_free_ha(oldha);
12817 if (oldcon)
12818 free_context(oldcon);
12819 return user;
12820 }
12821
12822 static int peer_delme_cb(void *obj, void *arg, int flags)
12823 {
12824 struct iax2_peer *peer = obj;
12825
12826 ast_set_flag64(peer, IAX_DELME);
12827
12828 return 0;
12829 }
12830
12831 static int user_delme_cb(void *obj, void *arg, int flags)
12832 {
12833 struct iax2_user *user = obj;
12834
12835 ast_set_flag64(user, IAX_DELME);
12836
12837 return 0;
12838 }
12839
12840 static void delete_users(void)
12841 {
12842 struct iax2_registry *reg;
12843
12844 ao2_callback(users, 0, user_delme_cb, NULL);
12845
12846 AST_LIST_LOCK(®istrations);
12847 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) {
12848 if (sched) {
12849 ast_sched_thread_del(sched, reg->expire);
12850 }
12851 if (reg->callno) {
12852 int callno = reg->callno;
12853 ast_mutex_lock(&iaxsl[callno]);
12854 if (iaxs[callno]) {
12855 iaxs[callno]->reg = NULL;
12856 iax2_destroy(callno);
12857 }
12858 ast_mutex_unlock(&iaxsl[callno]);
12859 }
12860 if (reg->dnsmgr)
12861 ast_dnsmgr_release(reg->dnsmgr);
12862 ast_free(reg);
12863 }
12864 AST_LIST_UNLOCK(®istrations);
12865
12866 ao2_callback(peers, 0, peer_delme_cb, NULL);
12867 }
12868
12869 static void prune_users(void)
12870 {
12871 struct iax2_user *user;
12872 struct ao2_iterator i;
12873
12874 i = ao2_iterator_init(users, 0);
12875 while ((user = ao2_iterator_next(&i))) {
12876 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) {
12877 ao2_unlink(users, user);
12878 }
12879 user_unref(user);
12880 }
12881 ao2_iterator_destroy(&i);
12882 }
12883
12884
12885 static void prune_peers(void)
12886 {
12887 struct iax2_peer *peer;
12888 struct ao2_iterator i;
12889
12890 i = ao2_iterator_init(peers, 0);
12891 while ((peer = ao2_iterator_next(&i))) {
12892 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) {
12893 unlink_peer(peer);
12894 }
12895 peer_unref(peer);
12896 }
12897 ao2_iterator_destroy(&i);
12898 }
12899
12900 static void set_config_destroy(void)
12901 {
12902 strcpy(accountcode, "");
12903 strcpy(language, "");
12904 strcpy(mohinterpret, "default");
12905 strcpy(mohsuggest, "");
12906 trunkmaxsize = MAX_TRUNKDATA;
12907 amaflags = 0;
12908 delayreject = 0;
12909 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF |
12910 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
12911 delete_users();
12912 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL);
12913 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL);
12914 }
12915
12916
12917 static int set_config(const char *config_file, int reload)
12918 {
12919 struct ast_config *cfg, *ucfg;
12920 format_t capability = iax2_capability;
12921 struct ast_variable *v;
12922 char *cat;
12923 const char *utype;
12924 const char *tosval;
12925 int format;
12926 int portno = IAX_DEFAULT_PORTNO;
12927 int x;
12928 int mtuv;
12929 int subscribe_network_change = 1;
12930 struct iax2_user *user;
12931 struct iax2_peer *peer;
12932 struct ast_netsock *ns;
12933 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
12934 #if 0
12935 static unsigned short int last_port=0;
12936 #endif
12937
12938 cfg = ast_config_load(config_file, config_flags);
12939
12940 if (!cfg) {
12941 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file);
12942 return -1;
12943 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
12944 ucfg = ast_config_load("users.conf", config_flags);
12945 if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
12946 return 0;
12947
12948 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12949 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) {
12950 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12951 ast_config_destroy(ucfg);
12952 return 0;
12953 }
12954 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
12955 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file);
12956 return 0;
12957 } else {
12958 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
12959 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) {
12960 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n");
12961 ast_config_destroy(cfg);
12962 return 0;
12963 }
12964 }
12965
12966 if (reload) {
12967 set_config_destroy();
12968 }
12969
12970
12971 memset(&prefs, 0 , sizeof(struct ast_codec_pref));
12972
12973
12974 memset(&globalflags, 0, sizeof(globalflags));
12975 ast_set_flag64(&globalflags, IAX_RTUPDATE);
12976 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
12977
12978 #ifdef SO_NO_CHECK
12979 nochecksums = 0;
12980 #endif
12981
12982 default_parkinglot[0] = '\0';
12983
12984 min_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12985 max_reg_expire = IAX_DEFAULT_REG_EXPIRE;
12986 global_max_trunk_mtu = MAX_TRUNK_MTU;
12987 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT;
12988 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL;
12989
12990 maxauthreq = 3;
12991
12992 srvlookup = 0;
12993
12994 v = ast_variable_browse(cfg, "general");
12995
12996
12997 tosval = ast_variable_retrieve(cfg, "general", "tos");
12998 if (tosval) {
12999 if (ast_str2tos(tosval, &qos.tos))
13000 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n");
13001 }
13002
13003 tosval = ast_variable_retrieve(cfg, "general", "cos");
13004 if (tosval) {
13005 if (ast_str2cos(tosval, &qos.cos))
13006 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n");
13007 }
13008 while(v) {
13009 if (!strcasecmp(v->name, "bindport")){
13010 if (reload)
13011 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n");
13012 else
13013 portno = atoi(v->value);
13014 } else if (!strcasecmp(v->name, "pingtime"))
13015 ping_time = atoi(v->value);
13016 else if (!strcasecmp(v->name, "iaxthreadcount")) {
13017 if (reload) {
13018 if (atoi(v->value) != iaxthreadcount)
13019 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n");
13020 } else {
13021 iaxthreadcount = atoi(v->value);
13022 if (iaxthreadcount < 1) {
13023 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n");
13024 iaxthreadcount = 1;
13025 } else if (iaxthreadcount > 256) {
13026 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n");
13027 iaxthreadcount = 256;
13028 }
13029 }
13030 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) {
13031 if (reload) {
13032 AST_LIST_LOCK(&dynamic_list);
13033 iaxmaxthreadcount = atoi(v->value);
13034 AST_LIST_UNLOCK(&dynamic_list);
13035 } else {
13036 iaxmaxthreadcount = atoi(v->value);
13037 if (iaxmaxthreadcount < 0) {
13038 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n");
13039 iaxmaxthreadcount = 0;
13040 } else if (iaxmaxthreadcount > 256) {
13041 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n");
13042 iaxmaxthreadcount = 256;
13043 }
13044 }
13045 } else if (!strcasecmp(v->name, "nochecksums")) {
13046 #ifdef SO_NO_CHECK
13047 if (ast_true(v->value))
13048 nochecksums = 1;
13049 else
13050 nochecksums = 0;
13051 #else
13052 if (ast_true(v->value))
13053 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
13054 #endif
13055 }
13056 else if (!strcasecmp(v->name, "maxjitterbuffer"))
13057 maxjitterbuffer = atoi(v->value);
13058 else if (!strcasecmp(v->name, "resyncthreshold"))
13059 resyncthreshold = atoi(v->value);
13060 else if (!strcasecmp(v->name, "maxjitterinterps"))
13061 maxjitterinterps = atoi(v->value);
13062 else if (!strcasecmp(v->name, "jittertargetextra"))
13063 jittertargetextra = atoi(v->value);
13064 else if (!strcasecmp(v->name, "lagrqtime"))
13065 lagrq_time = atoi(v->value);
13066 else if (!strcasecmp(v->name, "maxregexpire"))
13067 max_reg_expire = atoi(v->value);
13068 else if (!strcasecmp(v->name, "minregexpire"))
13069 min_reg_expire = atoi(v->value);
13070 else if (!strcasecmp(v->name, "bindaddr")) {
13071 if (reload) {
13072 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n");
13073 } else {
13074 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) {
13075 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno);
13076 } else {
13077 if (strchr(v->value, ':'))
13078 ast_verb(2, "Binding IAX2 to '%s'\n", v->value);
13079 else
13080 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno);
13081 if (defaultsockfd < 0)
13082 defaultsockfd = ast_netsock_sockfd(ns);
13083 ast_netsock_unref(ns);
13084 }
13085 }
13086 } else if (!strcasecmp(v->name, "authdebug")) {
13087 authdebug = ast_true(v->value);
13088 } else if (!strcasecmp(v->name, "encryption")) {
13089 iax2_encryption |= get_encrypt_methods(v->value);
13090 if (!iax2_encryption) {
13091 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13092 }
13093 } else if (!strcasecmp(v->name, "forceencryption")) {
13094 if (ast_false(v->value)) {
13095 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13096 } else {
13097 iax2_encryption |= get_encrypt_methods(v->value);
13098 if (iax2_encryption) {
13099 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT);
13100 }
13101 }
13102 } else if (!strcasecmp(v->name, "transfer")) {
13103 if (!strcasecmp(v->value, "mediaonly")) {
13104 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA);
13105 } else if (ast_true(v->value)) {
13106 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0);
13107 } else
13108 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER);
13109 } else if (!strcasecmp(v->name, "codecpriority")) {
13110 if(!strcasecmp(v->value, "caller"))
13111 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST);
13112 else if(!strcasecmp(v->value, "disabled"))
13113 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13114 else if(!strcasecmp(v->value, "reqonly")) {
13115 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP);
13116 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS);
13117 }
13118 } else if (!strcasecmp(v->name, "jitterbuffer"))
13119 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF);
13120 else if (!strcasecmp(v->name, "forcejitterbuffer"))
13121 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF);
13122 else if (!strcasecmp(v->name, "delayreject"))
13123 delayreject = ast_true(v->value);
13124 else if (!strcasecmp(v->name, "allowfwdownload"))
13125 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD);
13126 else if (!strcasecmp(v->name, "rtcachefriends"))
13127 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS);
13128 else if (!strcasecmp(v->name, "rtignoreregexpire"))
13129 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE);
13130 else if (!strcasecmp(v->name, "rtupdate"))
13131 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE);
13132 else if (!strcasecmp(v->name, "rtsavesysname"))
13133 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME);
13134 else if (!strcasecmp(v->name, "trunktimestamps"))
13135 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS);
13136 else if (!strcasecmp(v->name, "rtautoclear")) {
13137 int i = atoi(v->value);
13138 if(i > 0)
13139 global_rtautoclear = i;
13140 else
13141 i = 0;
13142 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR);
13143 } else if (!strcasecmp(v->name, "trunkfreq")) {
13144 trunkfreq = atoi(v->value);
13145 if (trunkfreq < 10)
13146 trunkfreq = 10;
13147 } else if (!strcasecmp(v->name, "trunkmtu")) {
13148 mtuv = atoi(v->value);
13149 if (mtuv == 0 )
13150 global_max_trunk_mtu = 0;
13151 else if (mtuv >= 172 && mtuv < 4000)
13152 global_max_trunk_mtu = mtuv;
13153 else
13154 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n",
13155 mtuv, v->lineno);
13156 } else if (!strcasecmp(v->name, "trunkmaxsize")) {
13157 trunkmaxsize = atoi(v->value);
13158 if (trunkmaxsize == 0)
13159 trunkmaxsize = MAX_TRUNKDATA;
13160 } else if (!strcasecmp(v->name, "autokill")) {
13161 if (sscanf(v->value, "%30d", &x) == 1) {
13162 if (x >= 0)
13163 autokill = x;
13164 else
13165 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno);
13166 } else if (ast_true(v->value)) {
13167 autokill = DEFAULT_MAXMS;
13168 } else {
13169 autokill = 0;
13170 }
13171 } else if (!strcasecmp(v->name, "bandwidth")) {
13172 if (!strcasecmp(v->value, "low")) {
13173 capability = IAX_CAPABILITY_LOWBANDWIDTH;
13174 } else if (!strcasecmp(v->value, "medium")) {
13175 capability = IAX_CAPABILITY_MEDBANDWIDTH;
13176 } else if (!strcasecmp(v->value, "high")) {
13177 capability = IAX_CAPABILITY_FULLBANDWIDTH;
13178 } else
13179 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
13180 } else if (!strcasecmp(v->name, "allow")) {
13181 ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
13182 } else if (!strcasecmp(v->name, "disallow")) {
13183 ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
13184 } else if (!strcasecmp(v->name, "register")) {
13185 iax2_register(v->value, v->lineno);
13186 } else if (!strcasecmp(v->name, "iaxcompat")) {
13187 iaxcompat = ast_true(v->value);
13188 } else if (!strcasecmp(v->name, "regcontext")) {
13189 ast_copy_string(regcontext, v->value, sizeof(regcontext));
13190
13191 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2");
13192 } else if (!strcasecmp(v->name, "tos")) {
13193 if (ast_str2tos(v->value, &qos.tos))
13194 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno);
13195 } else if (!strcasecmp(v->name, "cos")) {
13196 if (ast_str2cos(v->value, &qos.cos))
13197 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno);
13198 } else if (!strcasecmp(v->name, "parkinglot")) {
13199 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot));
13200 } else if (!strcasecmp(v->name, "accountcode")) {
13201 ast_copy_string(accountcode, v->value, sizeof(accountcode));
13202 } else if (!strcasecmp(v->name, "mohinterpret")) {
13203 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret));
13204 } else if (!strcasecmp(v->name, "mohsuggest")) {
13205 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest));
13206 } else if (!strcasecmp(v->name, "amaflags")) {
13207 format = ast_cdr_amaflags2int(v->value);
13208 if (format < 0) {
13209 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno);
13210 } else {
13211 amaflags = format;
13212 }
13213 } else if (!strcasecmp(v->name, "language")) {
13214 ast_copy_string(language, v->value, sizeof(language));
13215 } else if (!strcasecmp(v->name, "maxauthreq")) {
13216 maxauthreq = atoi(v->value);
13217 if (maxauthreq < 0)
13218 maxauthreq = 0;
13219 } else if (!strcasecmp(v->name, "adsi")) {
13220 adsi = ast_true(v->value);
13221 } else if (!strcasecmp(v->name, "srvlookup")) {
13222 srvlookup = ast_true(v->value);
13223 } else if (!strcasecmp(v->name, "connectedline")) {
13224 if (ast_true(v->value)) {
13225 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13226 } else if (!strcasecmp(v->value, "send")) {
13227 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13228 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13229 } else if (!strcasecmp(v->value, "receive")) {
13230 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE);
13231 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE);
13232 } else {
13233 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
13234 }
13235 } else if (!strcasecmp(v->name, "maxcallnumbers")) {
13236 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) {
13237 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno);
13238 }
13239 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) {
13240 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) {
13241 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);
13242 }
13243 } else if (!strcasecmp(v->name, "calltokenoptional")) {
13244 if (add_calltoken_ignore(v->value)) {
13245 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno);
13246 }
13247 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) {
13248 if (ast_true(v->value)) {
13249 subscribe_network_change = 1;
13250 } else if (ast_false(v->value)) {
13251 subscribe_network_change = 0;
13252 } else {
13253 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno);
13254 }
13255 } else if (!strcasecmp(v->name, "shrinkcallerid")) {
13256 if (ast_true(v->value)) {
13257 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID);
13258 } else if (ast_false(v->value)) {
13259 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID);
13260 } else {
13261 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
13262 }
13263 }
13264
13265 v = v->next;
13266 }
13267
13268 if (subscribe_network_change) {
13269 network_change_event_subscribe();
13270 } else {
13271 network_change_event_unsubscribe();
13272 }
13273
13274 if (defaultsockfd < 0) {
13275 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) {
13276 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
13277 } else {
13278 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno);
13279 defaultsockfd = ast_netsock_sockfd(ns);
13280 ast_netsock_unref(ns);
13281 }
13282 }
13283 if (reload) {
13284 ast_netsock_release(outsock);
13285 outsock = ast_netsock_list_alloc();
13286 if (!outsock) {
13287 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
13288 return -1;
13289 }
13290 ast_netsock_init(outsock);
13291 }
13292
13293 if (min_reg_expire > max_reg_expire) {
13294 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
13295 min_reg_expire, max_reg_expire, max_reg_expire);
13296 min_reg_expire = max_reg_expire;
13297 }
13298 iax2_capability = capability;
13299
13300 if (ucfg) {
13301 struct ast_variable *gen;
13302 int genhasiax;
13303 int genregisteriax;
13304 const char *hasiax, *registeriax;
13305
13306 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax"));
13307 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax"));
13308 gen = ast_variable_browse(ucfg, "general");
13309 cat = ast_category_browse(ucfg, NULL);
13310 while (cat) {
13311 if (strcasecmp(cat, "general")) {
13312 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax");
13313 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax");
13314 if (ast_true(hasiax) || (!hasiax && genhasiax)) {
13315
13316 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0);
13317 if (user) {
13318 ao2_link(users, user);
13319 user = user_unref(user);
13320 }
13321 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0);
13322 if (peer) {
13323 if (ast_test_flag64(peer, IAX_DYNAMIC))
13324 reg_source_db(peer);
13325 ao2_link(peers, peer);
13326 peer = peer_unref(peer);
13327 }
13328 }
13329 if (ast_true(registeriax) || (!registeriax && genregisteriax)) {
13330 char tmp[256];
13331 const char *host = ast_variable_retrieve(ucfg, cat, "host");
13332 const char *username = ast_variable_retrieve(ucfg, cat, "username");
13333 const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
13334 if (!host)
13335 host = ast_variable_retrieve(ucfg, "general", "host");
13336 if (!username)
13337 username = ast_variable_retrieve(ucfg, "general", "username");
13338 if (!secret)
13339 secret = ast_variable_retrieve(ucfg, "general", "secret");
13340 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
13341 if (!ast_strlen_zero(secret))
13342 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host);
13343 else
13344 snprintf(tmp, sizeof(tmp), "%s@%s", username, host);
13345 iax2_register(tmp, 0);
13346 }
13347 }
13348 }
13349 cat = ast_category_browse(ucfg, cat);
13350 }
13351 ast_config_destroy(ucfg);
13352 }
13353
13354 cat = ast_category_browse(cfg, NULL);
13355 while(cat) {
13356 if (strcasecmp(cat, "general")) {
13357 utype = ast_variable_retrieve(cfg, cat, "type");
13358 if (!strcasecmp(cat, "callnumberlimits")) {
13359 build_callno_limits(ast_variable_browse(cfg, cat));
13360 } else if (utype) {
13361 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) {
13362 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0);
13363 if (user) {
13364 ao2_link(users, user);
13365 user = user_unref(user);
13366 }
13367 }
13368 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) {
13369 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0);
13370 if (peer) {
13371 if (ast_test_flag64(peer, IAX_DYNAMIC))
13372 reg_source_db(peer);
13373 ao2_link(peers, peer);
13374 peer = peer_unref(peer);
13375 }
13376 } else if (strcasecmp(utype, "user")) {
13377 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file);
13378 }
13379 } else
13380 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
13381 }
13382 cat = ast_category_browse(cfg, cat);
13383 }
13384 ast_config_destroy(cfg);
13385 return 1;
13386 }
13387
13388 static void poke_all_peers(void)
13389 {
13390 struct ao2_iterator i;
13391 struct iax2_peer *peer;
13392
13393 i = ao2_iterator_init(peers, 0);
13394 while ((peer = ao2_iterator_next(&i))) {
13395 iax2_poke_peer(peer, 0);
13396 peer_unref(peer);
13397 }
13398 ao2_iterator_destroy(&i);
13399 }
13400 static int reload_config(void)
13401 {
13402 static const char config[] = "iax.conf";
13403 struct iax2_registry *reg;
13404
13405 if (set_config(config, 1) > 0) {
13406 prune_peers();
13407 prune_users();
13408 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13409 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL);
13410 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL);
13411 trunk_timed = trunk_untimed = 0;
13412 trunk_nmaxmtu = trunk_maxmtu = 0;
13413 memset(&debugaddr, '\0', sizeof(debugaddr));
13414
13415 AST_LIST_LOCK(®istrations);
13416 AST_LIST_TRAVERSE(®istrations, reg, entry)
13417 iax2_do_register(reg);
13418 AST_LIST_UNLOCK(®istrations);
13419
13420
13421 poke_all_peers();
13422 }
13423
13424 reload_firmware(0);
13425 iax_provision_reload(1);
13426 ast_unload_realtime("iaxpeers");
13427
13428 return 0;
13429 }
13430
13431 static char *handle_cli_iax2_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
13432 {
13433 switch (cmd) {
13434 case CLI_INIT:
13435 e->command = "iax2 reload";
13436 e->usage =
13437 "Usage: iax2 reload\n"
13438 " Reloads IAX configuration from iax.conf\n";
13439 return NULL;
13440 case CLI_GENERATE:
13441 return NULL;
13442 }
13443
13444 reload_config();
13445
13446 return CLI_SUCCESS;
13447 }
13448
13449 static int reload(void)
13450 {
13451 return reload_config();
13452 }
13453
13454 static int cache_get_callno_locked(const char *data)
13455 {
13456 struct sockaddr_in sin;
13457 int x;
13458 int callno;
13459 struct iax_ie_data ied;
13460 struct create_addr_info cai;
13461 struct parsed_dial_string pds;
13462 char *tmpstr;
13463
13464 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
13465
13466
13467 if (!ast_mutex_trylock(&iaxsl[x])) {
13468 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot))
13469 return x;
13470 ast_mutex_unlock(&iaxsl[x]);
13471 }
13472 }
13473
13474
13475
13476 memset(&cai, 0, sizeof(cai));
13477 memset(&ied, 0, sizeof(ied));
13478 memset(&pds, 0, sizeof(pds));
13479
13480 tmpstr = ast_strdupa(data);
13481 parse_dial_string(tmpstr, &pds);
13482
13483 if (ast_strlen_zero(pds.peer)) {
13484 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data);
13485 return -1;
13486 }
13487
13488
13489 if (create_addr(pds.peer, NULL, &sin, &cai))
13490 return -1;
13491
13492 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n",
13493 pds.peer, pds.username, pds.password, pds.context);
13494
13495 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0);
13496 if (callno < 1) {
13497 ast_log(LOG_WARNING, "Unable to create call\n");
13498 return -1;
13499 }
13500
13501 ast_string_field_set(iaxs[callno], dproot, data);
13502 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH;
13503
13504 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION);
13505 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD");
13506
13507
13508
13509 if (pds.exten)
13510 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten);
13511 if (pds.username)
13512 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username);
13513 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH);
13514 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH);
13515
13516 if (pds.password)
13517 ast_string_field_set(iaxs[callno], secret, pds.password);
13518 if (pds.key)
13519 ast_string_field_set(iaxs[callno], outkey, pds.key);
13520
13521 add_empty_calltoken_ie(iaxs[callno], &ied);
13522 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1);
13523
13524 return callno;
13525 }
13526
13527 static struct iax2_dpcache *find_cache(struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority)
13528 {
13529 struct iax2_dpcache *dp = NULL;
13530 struct timeval now = ast_tvnow();
13531 int x, com[2], timeout, old = 0, outfd, doabort, callno;
13532 struct ast_channel *c = NULL;
13533 struct ast_frame *f = NULL;
13534
13535 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) {
13536 if (ast_tvcmp(now, dp->expiry) > 0) {
13537 AST_LIST_REMOVE_CURRENT(cache_list);
13538 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno)
13539 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno);
13540 else
13541 ast_free(dp);
13542 continue;
13543 }
13544 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten))
13545 break;
13546 }
13547 AST_LIST_TRAVERSE_SAFE_END;
13548
13549 if (!dp) {
13550
13551
13552 if ((callno = cache_get_callno_locked(data)) < 0) {
13553 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data);
13554 return NULL;
13555 }
13556 if (!(dp = ast_calloc(1, sizeof(*dp)))) {
13557 ast_mutex_unlock(&iaxsl[callno]);
13558 return NULL;
13559 }
13560 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext));
13561 ast_copy_string(dp->exten, exten, sizeof(dp->exten));
13562 dp->expiry = ast_tvnow();
13563 dp->orig = dp->expiry;
13564
13565 dp->expiry.tv_sec += iaxdefaultdpcache;
13566 dp->flags = CACHE_FLAG_PENDING;
13567 for (x = 0; x < ARRAY_LEN(dp->waiters); x++)
13568 dp->waiters[x] = -1;
13569
13570 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list);
13571 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list);
13572
13573 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED))
13574 iax2_dprequest(dp, callno);
13575 ast_mutex_unlock(&iaxsl[callno]);
13576 }
13577
13578
13579 if (dp->flags & CACHE_FLAG_PENDING) {
13580
13581
13582 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13583
13584 if (dp->waiters[x] < 0)
13585 break;
13586 }
13587 if (x >= ARRAY_LEN(dp->waiters)) {
13588 ast_log(LOG_WARNING, "No more waiter positions available\n");
13589 return NULL;
13590 }
13591 if (pipe(com)) {
13592 ast_log(LOG_WARNING, "Unable to create pipe for comm\n");
13593 return NULL;
13594 }
13595 dp->waiters[x] = com[1];
13596
13597 timeout = iaxdefaulttimeout * 1000;
13598
13599 AST_LIST_UNLOCK(&dpcache);
13600
13601 if (chan)
13602 old = ast_channel_defer_dtmf(chan);
13603 doabort = 0;
13604 while(timeout) {
13605 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout);
13606 if (outfd > -1)
13607 break;
13608 if (!c)
13609 continue;
13610 if (!(f = ast_read(c))) {
13611 doabort = 1;
13612 break;
13613 }
13614 ast_frfree(f);
13615 }
13616 if (!timeout) {
13617 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten);
13618 }
13619 AST_LIST_LOCK(&dpcache);
13620 dp->waiters[x] = -1;
13621 close(com[1]);
13622 close(com[0]);
13623 if (doabort) {
13624
13625
13626 if (!old && chan)
13627 ast_channel_undefer_dtmf(chan);
13628 return NULL;
13629 }
13630 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) {
13631
13632 if (dp->flags & CACHE_FLAG_PENDING) {
13633
13634
13635 dp->flags &= ~CACHE_FLAG_PENDING;
13636 dp->flags |= CACHE_FLAG_TIMEOUT;
13637
13638
13639 dp->expiry.tv_sec = dp->orig.tv_sec + 60;
13640 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) {
13641 if (dp->waiters[x] > -1) {
13642 if (write(dp->waiters[x], "asdf", 4) < 0) {
13643 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
13644 }
13645 }
13646 }
13647 }
13648 }
13649
13650 if (!old && chan)
13651 ast_channel_undefer_dtmf(chan);
13652 }
13653 return dp;
13654 }
13655
13656
13657 static int iax2_exists(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13658 {
13659 int res = 0;
13660 struct iax2_dpcache *dp = NULL;
13661 #if 0
13662 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13663 #endif
13664 if ((priority != 1) && (priority != 2))
13665 return 0;
13666
13667 AST_LIST_LOCK(&dpcache);
13668 if ((dp = find_cache(chan, data, context, exten, priority))) {
13669 if (dp->flags & CACHE_FLAG_EXISTS)
13670 res = 1;
13671 } else {
13672 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13673 }
13674 AST_LIST_UNLOCK(&dpcache);
13675
13676 return res;
13677 }
13678
13679
13680 static int iax2_canmatch(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13681 {
13682 int res = 0;
13683 struct iax2_dpcache *dp = NULL;
13684 #if 0
13685 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13686 #endif
13687 if ((priority != 1) && (priority != 2))
13688 return 0;
13689
13690 AST_LIST_LOCK(&dpcache);
13691 if ((dp = find_cache(chan, data, context, exten, priority))) {
13692 if (dp->flags & CACHE_FLAG_CANEXIST)
13693 res = 1;
13694 } else {
13695 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13696 }
13697 AST_LIST_UNLOCK(&dpcache);
13698
13699 return res;
13700 }
13701
13702
13703 static int iax2_matchmore(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13704 {
13705 int res = 0;
13706 struct iax2_dpcache *dp = NULL;
13707 #if 0
13708 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data);
13709 #endif
13710 if ((priority != 1) && (priority != 2))
13711 return 0;
13712
13713 AST_LIST_LOCK(&dpcache);
13714 if ((dp = find_cache(chan, data, context, exten, priority))) {
13715 if (dp->flags & CACHE_FLAG_MATCHMORE)
13716 res = 1;
13717 } else {
13718 ast_log(LOG_WARNING, "Unable to make DP cache\n");
13719 }
13720 AST_LIST_UNLOCK(&dpcache);
13721
13722 return res;
13723 }
13724
13725
13726 static int iax2_exec(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data)
13727 {
13728 char odata[256];
13729 char req[256];
13730 char *ncontext;
13731 struct iax2_dpcache *dp = NULL;
13732 struct ast_app *dial = NULL;
13733 #if 0
13734 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);
13735 #endif
13736 if (priority == 2) {
13737
13738 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS");
13739 if (dialstatus) {
13740 dial = pbx_findapp(dialstatus);
13741 if (dial)
13742 pbx_exec(chan, dial, "");
13743 }
13744 return -1;
13745 } else if (priority != 1)
13746 return -1;
13747
13748 AST_LIST_LOCK(&dpcache);
13749 if ((dp = find_cache(chan, data, context, exten, priority))) {
13750 if (dp->flags & CACHE_FLAG_EXISTS) {
13751 ast_copy_string(odata, data, sizeof(odata));
13752 ncontext = strchr(odata, '/');
13753 if (ncontext) {
13754 *ncontext = '\0';
13755 ncontext++;
13756 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext);
13757 } else {
13758 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten);
13759 }
13760 ast_verb(3, "Executing Dial('%s')\n", req);
13761 } else {
13762 AST_LIST_UNLOCK(&dpcache);
13763 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data);
13764 return -1;
13765 }
13766 }
13767 AST_LIST_UNLOCK(&dpcache);
13768
13769 if ((dial = pbx_findapp("Dial")))
13770 return pbx_exec(chan, dial, req);
13771 else
13772 ast_log(LOG_WARNING, "No dial application registered\n");
13773
13774 return -1;
13775 }
13776
13777 static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
13778 {
13779 struct iax2_peer *peer;
13780 char *peername, *colname;
13781
13782 peername = ast_strdupa(data);
13783
13784
13785 if (!strcmp(peername,"CURRENTCHANNEL")) {
13786 unsigned short callno;
13787 if (chan->tech != &iax2_tech)
13788 return -1;
13789 callno = PTR_TO_CALLNO(chan->tech_pvt);
13790 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len);
13791 return 0;
13792 }
13793
13794 if ((colname = strchr(peername, ',')))
13795 *colname++ = '\0';
13796 else
13797 colname = "ip";
13798
13799 if (!(peer = find_peer(peername, 1)))
13800 return -1;
13801
13802 if (!strcasecmp(colname, "ip")) {
13803 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len);
13804 } else if (!strcasecmp(colname, "status")) {
13805 peer_status(peer, buf, len);
13806 } else if (!strcasecmp(colname, "mailbox")) {
13807 ast_copy_string(buf, peer->mailbox, len);
13808 } else if (!strcasecmp(colname, "context")) {
13809 ast_copy_string(buf, peer->context, len);
13810 } else if (!strcasecmp(colname, "expire")) {
13811 snprintf(buf, len, "%d", peer->expire);
13812 } else if (!strcasecmp(colname, "dynamic")) {
13813 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len);
13814 } else if (!strcasecmp(colname, "callerid_name")) {
13815 ast_copy_string(buf, peer->cid_name, len);
13816 } else if (!strcasecmp(colname, "callerid_num")) {
13817 ast_copy_string(buf, peer->cid_num, len);
13818 } else if (!strcasecmp(colname, "codecs")) {
13819 ast_getformatname_multiple(buf, len -1, peer->capability);
13820 } else if (!strncasecmp(colname, "codec[", 6)) {
13821 char *codecnum, *ptr;
13822 int codec = 0;
13823
13824 codecnum = strchr(colname, '[');
13825 *codecnum = '\0';
13826 codecnum++;
13827 if ((ptr = strchr(codecnum, ']'))) {
13828 *ptr = '\0';
13829 }
13830 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
13831 ast_copy_string(buf, ast_getformatname(codec), len);
13832 } else {
13833 buf[0] = '\0';
13834 }
13835 } else {
13836 buf[0] = '\0';
13837 }
13838
13839 peer_unref(peer);
13840
13841 return 0;
13842 }
13843
13844 static struct ast_custom_function iaxpeer_function = {
13845 .name = "IAXPEER",
13846 .read = function_iaxpeer,
13847 };
13848
13849 static int acf_channel_read(struct ast_channel *chan, const char *funcname, char *args, char *buf, size_t buflen)
13850 {
13851 struct chan_iax2_pvt *pvt;
13852 unsigned int callno;
13853 int res = 0;
13854
13855 if (!chan || chan->tech != &iax2_tech) {
13856 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n");
13857 return -1;
13858 }
13859
13860 callno = PTR_TO_CALLNO(chan->tech_pvt);
13861 ast_mutex_lock(&iaxsl[callno]);
13862 if (!(pvt = iaxs[callno])) {
13863 ast_mutex_unlock(&iaxsl[callno]);
13864 return -1;
13865 }
13866
13867 if (!strcasecmp(args, "osptoken")) {
13868 ast_copy_string(buf, pvt->osptoken, buflen);
13869 } else if (!strcasecmp(args, "peerip")) {
13870 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen);
13871 } else if (!strcasecmp(args, "peername")) {
13872 ast_copy_string(buf, pvt->username, buflen);
13873 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) {
13874 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : "");
13875 } else {
13876 res = -1;
13877 }
13878
13879 ast_mutex_unlock(&iaxsl[callno]);
13880
13881 return res;
13882 }
13883
13884
13885 static int iax2_devicestate(void *data)
13886 {
13887 struct parsed_dial_string pds;
13888 char *tmp = ast_strdupa(data);
13889 struct iax2_peer *p;
13890 int res = AST_DEVICE_INVALID;
13891
13892 memset(&pds, 0, sizeof(pds));
13893 parse_dial_string(tmp, &pds);
13894
13895 if (ast_strlen_zero(pds.peer)) {
13896 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
13897 return res;
13898 }
13899
13900 ast_debug(3, "Checking device state for device %s\n", pds.peer);
13901
13902
13903 if (!(p = find_peer(pds.peer, 1)))
13904 return res;
13905
13906 res = AST_DEVICE_UNAVAILABLE;
13907 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n",
13908 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms);
13909
13910 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) &&
13911 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) {
13912
13913
13914 if (p->historicms == 0 || p->historicms <= p->maxms)
13915
13916 res = AST_DEVICE_UNKNOWN;
13917 }
13918
13919 peer_unref(p);
13920
13921 return res;
13922 }
13923
13924 static struct ast_switch iax2_switch =
13925 {
13926 name: "IAX2",
13927 description: "IAX Remote Dialplan Switch",
13928 exists: iax2_exists,
13929 canmatch: iax2_canmatch,
13930 exec: iax2_exec,
13931 matchmore: iax2_matchmore,
13932 };
13933
13934
13935
13936
13937
13938
13939
13940
13941
13942
13943
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962
13963
13964
13965
13966
13967
13968
13969
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979
13980
13981
13982
13983
13984
13985
13986
13987
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
14000
14001
14002
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037
14038 static struct ast_cli_entry cli_iax2[] = {
14039 AST_CLI_DEFINE(handle_cli_iax2_provision, "Provision an IAX device"),
14040 AST_CLI_DEFINE(handle_cli_iax2_prune_realtime, "Prune a cached realtime lookup"),
14041 AST_CLI_DEFINE(handle_cli_iax2_reload, "Reload IAX configuration"),
14042 AST_CLI_DEFINE(handle_cli_iax2_set_mtu, "Set the IAX systemwide trunking MTU"),
14043 AST_CLI_DEFINE(handle_cli_iax2_set_debug, "Enable/Disable IAX debugging"),
14044 AST_CLI_DEFINE(handle_cli_iax2_set_debug_trunk, "Enable/Disable IAX trunk debugging"),
14045 AST_CLI_DEFINE(handle_cli_iax2_set_debug_jb, "Enable/Disable IAX jitterbuffer debugging"),
14046 AST_CLI_DEFINE(handle_cli_iax2_show_cache, "Display IAX cached dialplan"),
14047 AST_CLI_DEFINE(handle_cli_iax2_show_channels, "List active IAX channels"),
14048 AST_CLI_DEFINE(handle_cli_iax2_show_firmware, "List available IAX firmware"),
14049 AST_CLI_DEFINE(handle_cli_iax2_show_netstats, "List active IAX channel netstats"),
14050 AST_CLI_DEFINE(handle_cli_iax2_show_peer, "Show details on specific IAX peer"),
14051 AST_CLI_DEFINE(handle_cli_iax2_show_peers, "List defined IAX peers"),
14052 AST_CLI_DEFINE(handle_cli_iax2_show_registry, "Display IAX registration status"),
14053 AST_CLI_DEFINE(handle_cli_iax2_show_stats, "Display IAX statistics"),
14054 AST_CLI_DEFINE(handle_cli_iax2_show_threads, "Display IAX helper thread info"),
14055 AST_CLI_DEFINE(handle_cli_iax2_show_users, "List defined IAX users"),
14056 AST_CLI_DEFINE(handle_cli_iax2_test_losspct, "Set IAX2 incoming frame loss percentage"),
14057 AST_CLI_DEFINE(handle_cli_iax2_unregister, "Unregister (force expiration) an IAX2 peer from the registry"),
14058 AST_CLI_DEFINE(handle_cli_iax2_show_callno_limits, "Show current entries in IP call number limit table"),
14059 #ifdef IAXTESTS
14060 AST_CLI_DEFINE(handle_cli_iax2_test_jitter, "Simulates jitter for testing"),
14061 AST_CLI_DEFINE(handle_cli_iax2_test_late, "Test the receipt of a late frame"),
14062 AST_CLI_DEFINE(handle_cli_iax2_test_resync, "Test a resync in received timestamps"),
14063 #endif
14064 };
14065
14066 #ifdef TEST_FRAMEWORK
14067 AST_TEST_DEFINE(test_iax2_peers_get)
14068 {
14069 struct ast_data_query query = {
14070 .path = "/asterisk/channel/iax2/peers",
14071 .search = "peers/peer/name=test_peer_data_provider"
14072 };
14073 struct ast_data *node;
14074 struct iax2_peer *peer;
14075
14076 switch (cmd) {
14077 case TEST_INIT:
14078 info->name = "iax2_peers_get_data_test";
14079 info->category = "/main/data/iax2/peers/";
14080 info->summary = "IAX2 peers data providers unit test";
14081 info->description =
14082 "Tests whether the IAX2 peers data provider implementation works as expected.";
14083 return AST_TEST_NOT_RUN;
14084 case TEST_EXECUTE:
14085 break;
14086 }
14087
14088
14089 peer = build_peer("test_peer_data_provider", NULL, NULL, 0);
14090 if (!peer) {
14091 return AST_TEST_FAIL;
14092 }
14093 peer->expiry= 1010;
14094 ao2_link(peers, peer);
14095
14096 node = ast_data_get(&query);
14097 if (!node) {
14098 ao2_unlink(peers, peer);
14099 peer_unref(peer);
14100 return AST_TEST_FAIL;
14101 }
14102
14103
14104 if (strcmp(ast_data_retrieve_string(node, "peer/name"), "test_peer_data_provider")) {
14105 ao2_unlink(peers, peer);
14106 peer_unref(peer);
14107 ast_data_free(node);
14108 return AST_TEST_FAIL;
14109 }
14110
14111 if (ast_data_retrieve_int(node, "peer/expiry") != 1010) {
14112 ao2_unlink(peers, peer);
14113 peer_unref(peer);
14114 ast_data_free(node);
14115 return AST_TEST_FAIL;
14116 }
14117
14118
14119 ast_data_free(node);
14120
14121 ao2_unlink(peers, peer);
14122 peer_unref(peer);
14123
14124 return AST_TEST_PASS;
14125 }
14126
14127 AST_TEST_DEFINE(test_iax2_users_get)
14128 {
14129 struct ast_data_query query = {
14130 .path = "/asterisk/channel/iax2/users",
14131 .search = "users/user/name=test_user_data_provider"
14132 };
14133 struct ast_data *node;
14134 struct iax2_user *user;
14135
14136 switch (cmd) {
14137 case TEST_INIT:
14138 info->name = "iax2_users_get_data_test";
14139 info->category = "/main/data/iax2/users/";
14140 info->summary = "IAX2 users data providers unit test";
14141 info->description =
14142 "Tests whether the IAX2 users data provider implementation works as expected.";
14143 return AST_TEST_NOT_RUN;
14144 case TEST_EXECUTE:
14145 break;
14146 }
14147
14148 user = build_user("test_user_data_provider", NULL, NULL, 0);
14149 if (!user) {
14150 ast_test_status_update(test, "Failed to build a test user\n");
14151 return AST_TEST_FAIL;
14152 }
14153 user->amaflags = 1010;
14154 ao2_link(users, user);
14155
14156 node = ast_data_get(&query);
14157 if (!node) {
14158 ast_test_status_update(test, "The data query to find our test user failed\n");
14159 ao2_unlink(users, user);
14160 user_unref(user);
14161 return AST_TEST_FAIL;
14162 }
14163
14164 if (strcmp(ast_data_retrieve_string(node, "user/name"), "test_user_data_provider")) {
14165 ast_test_status_update(test, "Our data results did not return the test user created in the previous step.\n");
14166 ao2_unlink(users, user);
14167 user_unref(user);
14168 ast_data_free(node);
14169 return AST_TEST_FAIL;
14170 }
14171
14172 if (ast_data_retrieve_int(node, "user/amaflags/value") != 1010) {
14173 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"));
14174 ao2_unlink(users, user);
14175 user_unref(user);
14176 ast_data_free(node);
14177 return AST_TEST_FAIL;
14178 }
14179
14180 ast_data_free(node);
14181
14182 ao2_unlink(users, user);
14183 user_unref(user);
14184
14185 return AST_TEST_PASS;
14186 }
14187 #endif
14188
14189 static void cleanup_thread_list(void *head)
14190 {
14191 AST_LIST_HEAD(iax2_thread_list, iax2_thread);
14192 struct iax2_thread_list *list_head = head;
14193 struct iax2_thread *thread;
14194
14195 AST_LIST_LOCK(list_head);
14196 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) {
14197 pthread_t thread_id = thread->threadid;
14198
14199 thread->stop = 1;
14200 signal_condition(&thread->lock, &thread->cond);
14201
14202 AST_LIST_UNLOCK(list_head);
14203 pthread_join(thread_id, NULL);
14204 AST_LIST_LOCK(list_head);
14205 }
14206 AST_LIST_UNLOCK(list_head);
14207 }
14208
14209 static int __unload_module(void)
14210 {
14211 struct ast_context *con;
14212 int x;
14213
14214 network_change_event_unsubscribe();
14215
14216 ast_manager_unregister("IAXpeers");
14217 ast_manager_unregister("IAXpeerlist");
14218 ast_manager_unregister("IAXnetstats");
14219 ast_manager_unregister("IAXregistry");
14220 ast_unregister_application(papp);
14221 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14222 ast_unregister_switch(&iax2_switch);
14223 ast_channel_unregister(&iax2_tech);
14224
14225 if (netthreadid != AST_PTHREADT_NULL) {
14226 pthread_cancel(netthreadid);
14227 pthread_kill(netthreadid, SIGURG);
14228 pthread_join(netthreadid, NULL);
14229 }
14230
14231 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14232 if (iaxs[x]) {
14233 iax2_destroy(x);
14234 }
14235 }
14236
14237
14238 cleanup_thread_list(&idle_list);
14239 cleanup_thread_list(&active_list);
14240 cleanup_thread_list(&dynamic_list);
14241
14242 ast_netsock_release(netsock);
14243 ast_netsock_release(outsock);
14244 for (x = 0; x < ARRAY_LEN(iaxs); x++) {
14245 if (iaxs[x]) {
14246 iax2_destroy(x);
14247 }
14248 }
14249 ast_manager_unregister( "IAXpeers" );
14250 ast_manager_unregister( "IAXpeerlist" );
14251 ast_manager_unregister( "IAXnetstats" );
14252 ast_manager_unregister( "IAXregistry" );
14253 ast_unregister_application(papp);
14254 #ifdef TEST_FRAMEWORK
14255 AST_TEST_UNREGISTER(test_iax2_peers_get);
14256 AST_TEST_UNREGISTER(test_iax2_users_get);
14257 #endif
14258 ast_data_unregister(NULL);
14259 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14260 ast_unregister_switch(&iax2_switch);
14261 ast_channel_unregister(&iax2_tech);
14262 delete_users();
14263 iax_provision_unload();
14264 reload_firmware(1);
14265
14266 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14267 ast_mutex_destroy(&iaxsl[x]);
14268 }
14269
14270 ao2_ref(peers, -1);
14271 ao2_ref(users, -1);
14272 ao2_ref(iax_peercallno_pvts, -1);
14273 ao2_ref(iax_transfercallno_pvts, -1);
14274 ao2_ref(peercnts, -1);
14275 ao2_ref(callno_limits, -1);
14276 ao2_ref(calltoken_ignores, -1);
14277 ao2_ref(callno_pool, -1);
14278 ao2_ref(callno_pool_trunk, -1);
14279 if (timer) {
14280 ast_timer_close(timer);
14281 }
14282 transmit_processor = ast_taskprocessor_unreference(transmit_processor);
14283 sched = ast_sched_thread_destroy(sched);
14284
14285 con = ast_context_find(regcontext);
14286 if (con)
14287 ast_context_destroy(con, "IAX2");
14288 ast_unload_realtime("iaxpeers");
14289 return 0;
14290 }
14291
14292 static int unload_module(void)
14293 {
14294 ast_custom_function_unregister(&iaxpeer_function);
14295 ast_custom_function_unregister(&iaxvar_function);
14296 return __unload_module();
14297 }
14298
14299 static int peer_set_sock_cb(void *obj, void *arg, int flags)
14300 {
14301 struct iax2_peer *peer = obj;
14302
14303 if (peer->sockfd < 0)
14304 peer->sockfd = defaultsockfd;
14305
14306 return 0;
14307 }
14308
14309 static int pvt_hash_cb(const void *obj, const int flags)
14310 {
14311 const struct chan_iax2_pvt *pvt = obj;
14312
14313 return pvt->peercallno;
14314 }
14315
14316 static int pvt_cmp_cb(void *obj, void *arg, int flags)
14317 {
14318 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14319
14320
14321
14322
14323 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt,
14324 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14325 }
14326
14327 static int transfercallno_pvt_hash_cb(const void *obj, const int flags)
14328 {
14329 const struct chan_iax2_pvt *pvt = obj;
14330
14331 return pvt->transfercallno;
14332 }
14333
14334 static int transfercallno_pvt_cmp_cb(void *obj, void *arg, int flags)
14335 {
14336 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg;
14337
14338
14339
14340
14341 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt,
14342 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0;
14343 }
14344
14345 static int load_objects(void)
14346 {
14347 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL;
14348 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL;
14349
14350 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) {
14351 goto container_fail;
14352 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) {
14353 goto container_fail;
14354 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) {
14355 goto container_fail;
14356 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) {
14357 goto container_fail;
14358 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) {
14359 goto container_fail;
14360 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14361 goto container_fail;
14362 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) {
14363 goto container_fail;
14364 } else if (create_callno_pools()) {
14365 goto container_fail;
14366 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) {
14367 goto container_fail;
14368 }
14369
14370 return 0;
14371
14372 container_fail:
14373 if (peers) {
14374 ao2_ref(peers, -1);
14375 }
14376 if (users) {
14377 ao2_ref(users, -1);
14378 }
14379 if (iax_peercallno_pvts) {
14380 ao2_ref(iax_peercallno_pvts, -1);
14381 }
14382 if (iax_transfercallno_pvts) {
14383 ao2_ref(iax_transfercallno_pvts, -1);
14384 }
14385 if (peercnts) {
14386 ao2_ref(peercnts, -1);
14387 }
14388 if (callno_limits) {
14389 ao2_ref(callno_limits, -1);
14390 }
14391 if (calltoken_ignores) {
14392 ao2_ref(calltoken_ignores, -1);
14393 }
14394 if (callno_pool) {
14395 ao2_ref(callno_pool, -1);
14396 }
14397 if (callno_pool_trunk) {
14398 ao2_ref(callno_pool_trunk, -1);
14399 }
14400 return AST_MODULE_LOAD_FAILURE;
14401 }
14402
14403
14404 #define DATA_EXPORT_IAX2_PEER(MEMBER) \
14405 MEMBER(iax2_peer, name, AST_DATA_STRING) \
14406 MEMBER(iax2_peer, username, AST_DATA_STRING) \
14407 MEMBER(iax2_peer, secret, AST_DATA_PASSWORD) \
14408 MEMBER(iax2_peer, dbsecret, AST_DATA_PASSWORD) \
14409 MEMBER(iax2_peer, outkey, AST_DATA_STRING) \
14410 MEMBER(iax2_peer, regexten, AST_DATA_STRING) \
14411 MEMBER(iax2_peer, context, AST_DATA_STRING) \
14412 MEMBER(iax2_peer, peercontext, AST_DATA_STRING) \
14413 MEMBER(iax2_peer, mailbox, AST_DATA_STRING) \
14414 MEMBER(iax2_peer, mohinterpret, AST_DATA_STRING) \
14415 MEMBER(iax2_peer, mohsuggest, AST_DATA_STRING) \
14416 MEMBER(iax2_peer, inkeys, AST_DATA_STRING) \
14417 MEMBER(iax2_peer, cid_num, AST_DATA_STRING) \
14418 MEMBER(iax2_peer, cid_name, AST_DATA_STRING) \
14419 MEMBER(iax2_peer, zonetag, AST_DATA_STRING) \
14420 MEMBER(iax2_peer, parkinglot, AST_DATA_STRING) \
14421 MEMBER(iax2_peer, expiry, AST_DATA_SECONDS) \
14422 MEMBER(iax2_peer, callno, AST_DATA_INTEGER) \
14423 MEMBER(iax2_peer, lastms, AST_DATA_MILLISECONDS) \
14424 MEMBER(iax2_peer, maxms, AST_DATA_MILLISECONDS) \
14425 MEMBER(iax2_peer, pokefreqok, AST_DATA_MILLISECONDS) \
14426 MEMBER(iax2_peer, pokefreqnotok, AST_DATA_MILLISECONDS) \
14427 MEMBER(iax2_peer, historicms, AST_DATA_INTEGER) \
14428 MEMBER(iax2_peer, smoothing, AST_DATA_BOOLEAN) \
14429 MEMBER(iax2_peer, maxcallno, AST_DATA_INTEGER)
14430
14431 AST_DATA_STRUCTURE(iax2_peer, DATA_EXPORT_IAX2_PEER);
14432
14433 static int peers_data_provider_get(const struct ast_data_search *search,
14434 struct ast_data *data_root)
14435 {
14436 struct ast_data *data_peer;
14437 struct iax2_peer *peer;
14438 struct ao2_iterator i;
14439 char status[20];
14440 struct ast_str *encmethods = ast_str_alloca(256);
14441
14442 i = ao2_iterator_init(peers, 0);
14443 while ((peer = ao2_iterator_next(&i))) {
14444 data_peer = ast_data_add_node(data_root, "peer");
14445 if (!data_peer) {
14446 peer_unref(peer);
14447 continue;
14448 }
14449
14450 ast_data_add_structure(iax2_peer, data_peer, peer);
14451
14452 ast_data_add_codecs(data_peer, "codecs", peer->capability);
14453
14454 peer_status(peer, status, sizeof(status));
14455 ast_data_add_str(data_peer, "status", status);
14456
14457 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr));
14458
14459 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask));
14460
14461 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr));
14462
14463 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK));
14464
14465 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC));
14466
14467 encmethods_to_str(peer->encmethods, encmethods);
14468 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no");
14469
14470 peer_unref(peer);
14471
14472 if (!ast_data_search_match(search, data_peer)) {
14473 ast_data_remove_node(data_root, data_peer);
14474 }
14475 }
14476 ao2_iterator_destroy(&i);
14477
14478 return 0;
14479 }
14480
14481 #define DATA_EXPORT_IAX2_USER(MEMBER) \
14482 MEMBER(iax2_user, name, AST_DATA_STRING) \
14483 MEMBER(iax2_user, dbsecret, AST_DATA_PASSWORD) \
14484 MEMBER(iax2_user, accountcode, AST_DATA_STRING) \
14485 MEMBER(iax2_user, mohinterpret, AST_DATA_STRING) \
14486 MEMBER(iax2_user, mohsuggest, AST_DATA_STRING) \
14487 MEMBER(iax2_user, inkeys, AST_DATA_STRING) \
14488 MEMBER(iax2_user, language, AST_DATA_STRING) \
14489 MEMBER(iax2_user, cid_num, AST_DATA_STRING) \
14490 MEMBER(iax2_user, cid_name, AST_DATA_STRING) \
14491 MEMBER(iax2_user, parkinglot, AST_DATA_STRING) \
14492 MEMBER(iax2_user, maxauthreq, AST_DATA_INTEGER) \
14493 MEMBER(iax2_user, curauthreq, AST_DATA_INTEGER)
14494
14495 AST_DATA_STRUCTURE(iax2_user, DATA_EXPORT_IAX2_USER);
14496
14497 static int users_data_provider_get(const struct ast_data_search *search,
14498 struct ast_data *data_root)
14499 {
14500 struct ast_data *data_user, *data_authmethods, *data_enum_node;
14501 struct iax2_user *user;
14502 struct ao2_iterator i;
14503 char auth[90];
14504 char *pstr = "";
14505
14506 i = ao2_iterator_init(users, 0);
14507 while ((user = ao2_iterator_next(&i))) {
14508 data_user = ast_data_add_node(data_root, "user");
14509 if (!data_user) {
14510 user_unref(user);
14511 continue;
14512 }
14513
14514 ast_data_add_structure(iax2_user, data_user, user);
14515
14516 ast_data_add_codecs(data_user, "codecs", user->capability);
14517
14518 if (!ast_strlen_zero(user->secret)) {
14519 ast_copy_string(auth, user->secret, sizeof(auth));
14520 } else if (!ast_strlen_zero(user->inkeys)) {
14521 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys);
14522 } else {
14523 ast_copy_string(auth, "no secret", sizeof(auth));
14524 }
14525 ast_data_add_password(data_user, "secret", auth);
14526
14527 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT);
14528
14529
14530 data_authmethods = ast_data_add_node(data_user, "authmethods");
14531 if (!data_authmethods) {
14532 ast_data_remove_node(data_root, data_user);
14533 continue;
14534 }
14535 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA);
14536 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5);
14537 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT);
14538
14539
14540 data_enum_node = ast_data_add_node(data_user, "amaflags");
14541 if (!data_enum_node) {
14542 ast_data_remove_node(data_root, data_user);
14543 continue;
14544 }
14545 ast_data_add_int(data_enum_node, "value", user->amaflags);
14546 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags));
14547
14548 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0);
14549
14550 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) {
14551 pstr = "REQ only";
14552 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) {
14553 pstr = "disabled";
14554 } else {
14555 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host";
14556 }
14557 ast_data_add_str(data_user, "codec-preferences", pstr);
14558
14559 user_unref(user);
14560
14561 if (!ast_data_search_match(search, data_user)) {
14562 ast_data_remove_node(data_root, data_user);
14563 }
14564 }
14565 ao2_iterator_destroy(&i);
14566
14567 return 0;
14568 }
14569
14570 static const struct ast_data_handler peers_data_provider = {
14571 .version = AST_DATA_HANDLER_VERSION,
14572 .get = peers_data_provider_get
14573 };
14574
14575 static const struct ast_data_handler users_data_provider = {
14576 .version = AST_DATA_HANDLER_VERSION,
14577 .get = users_data_provider_get
14578 };
14579
14580 static const struct ast_data_entry iax2_data_providers[] = {
14581 AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
14582 AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
14583 };
14584
14585
14586 static int load_module(void)
14587 {
14588 static const char config[] = "iax.conf";
14589 int x = 0;
14590 struct iax2_registry *reg = NULL;
14591
14592 if (load_objects()) {
14593 return AST_MODULE_LOAD_FAILURE;
14594 }
14595
14596 memset(iaxs, 0, sizeof(iaxs));
14597
14598 for (x = 0; x < ARRAY_LEN(iaxsl); x++) {
14599 ast_mutex_init(&iaxsl[x]);
14600 }
14601
14602 if (!(sched = ast_sched_thread_create())) {
14603 ast_log(LOG_ERROR, "Failed to create scheduler thread\n");
14604 return AST_MODULE_LOAD_FAILURE;
14605 }
14606
14607 if (!(io = io_context_create())) {
14608 ast_log(LOG_ERROR, "Failed to create I/O context\n");
14609 sched = ast_sched_thread_destroy(sched);
14610 return AST_MODULE_LOAD_FAILURE;
14611 }
14612
14613 if (!(netsock = ast_netsock_list_alloc())) {
14614 ast_log(LOG_ERROR, "Failed to create netsock list\n");
14615 io_context_destroy(io);
14616 sched = ast_sched_thread_destroy(sched);
14617 return AST_MODULE_LOAD_FAILURE;
14618 }
14619 ast_netsock_init(netsock);
14620
14621 outsock = ast_netsock_list_alloc();
14622 if (!outsock) {
14623 ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
14624 io_context_destroy(io);
14625 sched = ast_sched_thread_destroy(sched);
14626 return AST_MODULE_LOAD_FAILURE;
14627 }
14628 ast_netsock_init(outsock);
14629
14630 randomcalltokendata = ast_random();
14631
14632 iax_set_output(iax_debug_output);
14633 iax_set_error(iax_error_output);
14634 jb_setoutput(jb_error_output, jb_warning_output, NULL);
14635
14636 if ((timer = ast_timer_open())) {
14637 ast_timer_set_rate(timer, trunkfreq);
14638 }
14639
14640 if (set_config(config, 0) == -1) {
14641 if (timer) {
14642 ast_timer_close(timer);
14643 }
14644 return AST_MODULE_LOAD_DECLINE;
14645 }
14646
14647 #ifdef TEST_FRAMEWORK
14648 AST_TEST_REGISTER(test_iax2_peers_get);
14649 AST_TEST_REGISTER(test_iax2_users_get);
14650 #endif
14651
14652
14653 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers));
14654 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2));
14655
14656 ast_register_application_xml(papp, iax2_prov_app);
14657
14658 ast_custom_function_register(&iaxpeer_function);
14659 ast_custom_function_register(&iaxvar_function);
14660
14661 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers);
14662 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list);
14663 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats);
14664 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry);
14665
14666 if (ast_channel_register(&iax2_tech)) {
14667 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2");
14668 __unload_module();
14669 return AST_MODULE_LOAD_FAILURE;
14670 }
14671
14672 if (ast_register_switch(&iax2_switch)) {
14673 ast_log(LOG_ERROR, "Unable to register IAX switch\n");
14674 }
14675
14676 if (start_network_thread()) {
14677 ast_log(LOG_ERROR, "Unable to start network thread\n");
14678 __unload_module();
14679 return AST_MODULE_LOAD_FAILURE;
14680 } else {
14681 ast_verb(2, "IAX Ready and Listening\n");
14682 }
14683
14684 AST_LIST_LOCK(®istrations);
14685 AST_LIST_TRAVERSE(®istrations, reg, entry)
14686 iax2_do_register(reg);
14687 AST_LIST_UNLOCK(®istrations);
14688
14689 ao2_callback(peers, 0, peer_set_sock_cb, NULL);
14690 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL);
14691
14692
14693 reload_firmware(0);
14694 iax_provision_reload(0);
14695
14696 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL);
14697
14698 network_change_event_subscribe();
14699
14700 return AST_MODULE_LOAD_SUCCESS;
14701 }
14702
14703 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Inter Asterisk eXchange (Ver 2)",
14704 .load = load_module,
14705 .unload = unload_module,
14706 .reload = reload,
14707 .load_pri = AST_MODPRI_CHANNEL_DRIVER,
14708 .nonoptreq = "res_crypto",
14709 );