Implementation of Inter-Asterisk eXchange Version 2 as specified in RFC 5456. More...
#include "asterisk.h"#include <sys/mman.h>#include <dirent.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <sys/time.h>#include <sys/signal.h>#include <signal.h>#include <strings.h>#include <netdb.h>#include <fcntl.h>#include <sys/stat.h>#include <regex.h>#include "asterisk/paths.h"#include "asterisk/lock.h"#include "asterisk/frame.h"#include "asterisk/channel.h"#include "asterisk/module.h"#include "asterisk/pbx.h"#include "asterisk/sched.h"#include "asterisk/io.h"#include "asterisk/config.h"#include "asterisk/cli.h"#include "asterisk/translate.h"#include "asterisk/md5.h"#include "asterisk/cdr.h"#include "asterisk/crypto.h"#include "asterisk/acl.h"#include "asterisk/manager.h"#include "asterisk/callerid.h"#include "asterisk/app.h"#include "asterisk/astdb.h"#include "asterisk/musiconhold.h"#include "asterisk/features.h"#include "asterisk/utils.h"#include "asterisk/causes.h"#include "asterisk/localtime.h"#include "asterisk/dnsmgr.h"#include "asterisk/devicestate.h"#include "asterisk/netsock.h"#include "asterisk/stringfields.h"#include "asterisk/linkedlists.h"#include "asterisk/event.h"#include "asterisk/astobj2.h"#include "asterisk/timing.h"#include "asterisk/taskprocessor.h"#include "asterisk/test.h"#include "asterisk/data.h"#include "asterisk/netsock2.h"#include "iax2.h"#include "iax2-parser.h"#include "iax2-provision.h"#include "jitterbuf.h"Go to the source code of this file.
Data Structures | |
| struct | addr_range |
| struct | callno_entry |
| struct | chan_iax2_pvt |
| struct | create_addr_info |
| struct | dpreq_data |
| struct | iax2_context |
| struct | iax2_dpcache |
| struct | iax2_peer |
| struct | iax2_pkt_buf |
| struct | iax2_registry |
| struct | iax2_thread |
| struct | iax2_trunk_peer |
| struct | iax2_user |
| struct | iax_dual |
| struct | iax_firmware |
| struct | iax_rr |
| struct | parsed_dial_string |
| struct | signaling_queue_entry |
Defines | |
| #define | ACN_FORMAT1 "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
| #define | ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
| #define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
| #define | CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
| #define | CALLTOKEN_IE_FORMAT "%u?%s" |
| #define | DATA_EXPORT_IAX2_PEER(MEMBER) |
| #define | DATA_EXPORT_IAX2_USER(MEMBER) |
| #define | DEBUG_SCHED_MULTITHREAD |
| #define | DEBUG_SUPPORT |
| #define | DEFAULT_CONTEXT "default" |
| #define | DEFAULT_DROP 3 |
| #define | DEFAULT_FREQ_NOTOK 10 * 1000 |
| #define | DEFAULT_FREQ_OK 60 * 1000 |
| #define | DEFAULT_MAX_THREAD_COUNT 100 |
| #define | DEFAULT_MAXMS 2000 |
| #define | DEFAULT_RETRY_TIME 1000 |
| #define | DEFAULT_THREAD_COUNT 10 |
| #define | DEFAULT_TRUNKDATA 640 * 10 |
| #define | DONT_RESCHEDULE -2 |
| #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" |
| #define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
| #define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" |
| #define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
| #define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
| #define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
| #define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" |
| #define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
| #define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
| #define | GAMMA (0.01) |
| #define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
| #define | IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26) |
| #define | IAX_ALREADYGONE (uint64_t)(1 << 9) |
| #define | IAX_CALLENCRYPTED(pvt) (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED)) |
| #define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
| #define | IAX_CAPABILITY_LOWBANDWIDTH |
| #define | IAX_CAPABILITY_LOWFREE |
| #define | IAX_CAPABILITY_MEDBANDWIDTH |
| #define | IAX_CODEC_NOCAP (uint64_t)(1 << 16) |
| #define | IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
| #define | IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
| #define | IAX_DEBUGDIGEST(msg, key) |
| #define | IAX_DELAYPBXSTART (uint64_t)(1 << 25) |
| #define | IAX_DELME (uint64_t)(1 << 1) |
| #define | IAX_DYNAMIC (uint64_t)(1 << 6) |
| #define | IAX_ENCRYPTED (uint64_t)(1 << 12) |
| #define | IAX_FORCE_ENCRYPT (uint64_t)(1 << 30) |
| #define | IAX_FORCEJITTERBUF (uint64_t)(1 << 20) |
| #define | IAX_HASCALLERID (uint64_t)(1 << 0) |
| #define | IAX_IMMEDIATE (uint64_t)(1 << 27) |
| #define | IAX_KEYPOPULATED (uint64_t)(1 << 13) |
| #define | IAX_MAXAUTHREQ (uint64_t)(1 << 24) |
| #define | IAX_NOTRANSFER (uint64_t)(1 << 4) |
| #define | IAX_PROVISION (uint64_t)(1 << 10) |
| #define | IAX_QUELCH (uint64_t)(1 << 11) |
| #define | IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29) |
| #define | IAX_RTAUTOCLEAR (uint64_t)(1 << 19) |
| #define | IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
| #define | IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
| #define | IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
| #define | IAX_RTUPDATE (uint64_t)(1 << 18) |
| #define | IAX_SENDANI (uint64_t)(1 << 7) |
| #define | IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28) |
| #define | IAX_SHRINKCALLERID (uint64_t)(1 << 31) |
| #define | IAX_TEMPONLY (uint64_t)(1 << 2) |
| #define | IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
| #define | IAX_TRUNK (uint64_t)(1 << 3) |
| #define | IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
| #define | IAX_USEJITTERBUF (uint64_t)(1 << 5) |
| #define | MARK_IAX_SUBCLASS_TX 0x8000 |
| #define | MAX_JITTER_BUFFER 50 |
| #define | MAX_PEER_BUCKETS 563 |
| #define | MAX_RETRY_TIME 10000 |
| #define | MAX_TIMESTAMP_SKEW 160 |
| #define | MAX_TRUNK_MTU 1240 |
| Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240. | |
| #define | MAX_TRUNKDATA 640 * 200 |
| #define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
| #define | MEMORY_SIZE 100 |
| #define | MIN_JITTER_BUFFER 10 |
| #define | MIN_RETRY_TIME 100 |
| #define | MIN_REUSE_TIME 60 |
| #define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
| #define | SCHED_MULTITHREADED |
| #define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
| #define | TRUNK_CALL_START (IAX_MAX_CALLS / 2) |
| #define | TS_GAP_FOR_JB_RESYNC 5000 |
| #define | update_max_nontrunk() do { } while (0) |
| #define | update_max_trunk() do { } while (0) |
Enumerations | |
| enum | { CACHE_FLAG_EXISTS = (1 << 0), CACHE_FLAG_NONEXISTENT = (1 << 1), CACHE_FLAG_CANEXIST = (1 << 2), CACHE_FLAG_PENDING = (1 << 3), CACHE_FLAG_TIMEOUT = (1 << 4), CACHE_FLAG_TRANSMITTED = (1 << 5), CACHE_FLAG_UNKNOWN = (1 << 6), CACHE_FLAG_MATCHMORE = (1 << 7) } |
| enum | { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 } |
| enum | calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 } |
Call token validation settings. More... | |
| enum | iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
| enum | iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY } |
| enum | iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC } |
| enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
| enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
| static void | __attempt_transmit (const void *data) |
| static void | __auth_reject (const void *nothing) |
| static void | __auto_congest (const void *nothing) |
| static void | __auto_hangup (const void *nothing) |
| static int | __do_deliver (void *data) |
| static void | __expire_registry (const void *data) |
| static int | __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno) |
| static void | __get_from_jb (const void *p) |
| static void | __iax2_do_register_s (const void *data) |
| static void | __iax2_poke_noanswer (const void *data) |
| static void | __iax2_poke_peer_s (const void *data) |
| static int | __iax2_show_peers (int fd, int *total, struct mansession *s, const int argc, const char *const argv[]) |
| static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
| static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
| static void | __send_lagrq (const void *data) |
| static void | __send_ping (const void *data) |
| static int | __unload_module (void) |
| static int | acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen) |
| static int | acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| static int | acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
| static int | add_calltoken_ignore (const char *addr) |
| static void | add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied) |
| static int | addr_range_cmp_cb (void *obj, void *arg, int flags) |
| static int | addr_range_delme_cb (void *obj, void *arg, int flags) |
| static int | addr_range_hash_cb (const void *obj, const int flags) |
| static int | addr_range_match_address_cb (void *obj, void *arg, int flags) |
| static int | apply_context (struct iax2_context *con, const char *context) |
| static int | ast_cli_netstats (struct mansession *s, int fd, int limit_fmt) |
| AST_DATA_STRUCTURE (iax2_user, DATA_EXPORT_IAX2_USER) | |
| AST_DATA_STRUCTURE (iax2_peer, DATA_EXPORT_IAX2_PEER) | |
| static struct ast_channel * | ast_iax2_new (int callno, int state, format_t capability, const char *linkedid, unsigned int cachable) |
| Create new call, interface with the PBX core. | |
| static | AST_LIST_HEAD_NOLOCK (iax_frame) |
| a list of frames that may need to be retransmitted | |
| static | AST_LIST_HEAD_STATIC (dynamic_list, iax2_thread) |
| static | AST_LIST_HEAD_STATIC (active_list, iax2_thread) |
| static | AST_LIST_HEAD_STATIC (idle_list, iax2_thread) |
| static | AST_LIST_HEAD_STATIC (dpcache, iax2_dpcache) |
| static | AST_LIST_HEAD_STATIC (firmwares, iax_firmware) |
| static | AST_LIST_HEAD_STATIC (registrations, iax2_registry) |
| static | AST_LIST_HEAD_STATIC (tpeers, iax2_trunk_peer) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DRIVER,.nonoptreq="res_crypto",) | |
| static int | attempt_transmit (const void *data) |
| static int | auth_fail (int callno, int failcode) |
| static int | auth_reject (const void *data) |
| 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) |
| static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
| static int | authenticate_request (int call_num) |
| static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
| static int | auto_congest (const void *data) |
| static int | auto_hangup (const void *data) |
| static void | build_callno_limits (struct ast_variable *v) |
| static struct iax2_context * | build_context (const char *context) |
| static void | build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
| static void | build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
| static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
| Create peer structure based on configuration. | |
| static void | build_rand_pad (unsigned char *buf, ssize_t len) |
| static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
| Create in-memory user structure from configuration. | |
| static int | cache_get_callno_locked (const char *data) |
| static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
| static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
| static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now) |
| static int | callno_hash (const void *obj, const int flags) |
| static int | calltoken_required (struct sockaddr_in *sin, const char *name, int subclass) |
| static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
| static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
| static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
| Check if address can be used as packet source. | |
| static void | cleanup_thread_list (void *head) |
| static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
| static char * | complete_iax2_peers (const char *line, const char *word, int pos, int state, uint64_t flags) |
| static char * | complete_iax2_unregister (const char *line, const char *word, int pos, int state) |
| static int | complete_transfer (int callno, struct iax_ies *ies) |
| static unsigned char | compress_subclass (format_t subclass) |
| static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
| static int | create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai) |
| static int | create_callno_pools (void) |
| static int | decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
| static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
| static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
| Queue the last read full frame for processing by a certain thread. | |
| static void | delete_users (void) |
| static void | destroy_firmware (struct iax_firmware *cur) |
| static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
| static void * | dp_lookup_thread (void *data) |
| static void | encmethods_to_str (int e, struct ast_str **buf) |
| static int | encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
| static int | expire_registry (const void *data) |
| static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
| static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
| static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
| static struct iax2_thread * | find_idle_thread (void) |
| static struct iax2_peer * | find_peer (const char *name, int realtime) |
| static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
| static struct iax2_user * | find_user (const char *name) |
| static unsigned int | fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts) |
| static void | free_context (struct iax2_context *con) |
| static void | free_signaling_queue_entry (struct signaling_queue_entry *s) |
| static int | function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| static int | get_auth_methods (const char *value) |
| static int | get_encrypt_methods (const char *s) |
| static int | get_from_jb (const void *p) |
| static struct callno_entry * | get_unused_callno (int trunk, int validated) |
| static int | handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd) |
| static char * | handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Set trunk MTU from CLI. | |
| static char * | handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show one peer in detail. | |
| static char * | handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static void | handle_deferred_full_frames (struct iax2_thread *thread) |
| Handle any deferred full frames for this thread. | |
| static int | handle_error (void) |
| static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
| Acknowledgment received for OUR registration. | |
| static int attribute_pure | iax2_allow_new (int frametype, int subclass, int inbound) |
| static void | iax2_ami_channelupdate (struct chan_iax2_pvt *pvt) |
| Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers. | |
| static int | iax2_answer (struct ast_channel *c) |
| static int | iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta) |
| 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) |
| static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
| static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| part of the IAX2 dial plan switch interface | |
| static unsigned int | iax2_datetime (const char *tz) |
| static void | iax2_destroy (int callno) |
| static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
| static int | iax2_devicestate (void *data) |
| Part of the device state notification system ---. | |
| static int | iax2_digit_begin (struct ast_channel *c, char digit) |
| static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
| static int | iax2_do_register (struct iax2_registry *reg) |
| static int | iax2_do_register_s (const void *data) |
| static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
| static void * | iax2_dup_variable_datastore (void *) |
| static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| Execute IAX2 dialplan switch. | |
| static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| Part of the IAX2 switch interface. | |
| static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
| static void | iax2_frame_free (struct iax_frame *fr) |
| static void | iax2_free_variable_datastore (void *) |
| static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
| static int | iax2_getpeertrunk (struct sockaddr_in sin) |
| static int | iax2_hangup (struct ast_channel *c) |
| static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
| static int | iax2_is_control_frame_allowed (int subtype) |
| static int | iax2_key_rotate (const void *vpvt) |
| static void | iax2_lock_owner (int callno) |
| static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| Part of the IAX2 Switch interface. | |
| static int | iax2_poke_noanswer (const void *data) |
| static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
| static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
| static int | iax2_poke_peer_s (const void *data) |
| static int | iax2_predestroy (int callno) |
| static void * | iax2_process_thread (void *data) |
| static void | iax2_process_thread_cleanup (void *data) |
| static int | iax2_prov_app (struct ast_channel *chan, const char *data) |
| static int | iax2_provision (struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force) |
| static int | iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen) |
| static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
| Queue a control frame on the ast_channel owner. | |
| static int | iax2_queue_frame (int callno, struct ast_frame *f) |
| Queue a frame to a call's owning asterisk channel. | |
| static int | iax2_queue_hangup (int callno) |
| Queue a hangup frame on the ast_channel owner. | |
| static struct ast_frame * | iax2_read (struct ast_channel *c) |
| static int | iax2_register (const char *value, int lineno) |
| static struct ast_channel * | iax2_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
| static int | iax2_sched_add (struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
| static int | iax2_sched_replace (int id, struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
| static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
| static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
| static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
| static int | iax2_sendtext (struct ast_channel *c, const char *text) |
| static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
| static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
| static int | iax2_transfer (struct ast_channel *c, const char *dest) |
| static int | iax2_transmit (struct iax_frame *fr) |
| static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
| static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
| static int | iax2_vnak (int callno) |
| static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
| static int | iax_check_version (char *dev) |
| static void | iax_debug_output (const char *data) |
| static void | iax_error_output (const char *data) |
| static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
| static void | iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen) |
| static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context) |
| static void * | iax_park_thread (void *stuff) |
| static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
| static void | insert_idle_thread (struct iax2_thread *thread) |
| static void | jb_debug_output (const char *fmt,...) |
| static void | jb_error_output (const char *fmt,...) |
| static void | jb_warning_output (const char *fmt,...) |
| static int | load_module (void) |
| Load IAX2 module, load configuraiton ---. | |
| static int | load_objects (void) |
| static void | lock_both (unsigned short callno0, unsigned short callno1) |
| static void | log_jitterstats (unsigned short callno) |
| static int | make_trunk (unsigned short callno, int locked) |
| static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
| static int | manager_iax2_show_peer_list (struct mansession *s, const struct message *m) |
| callback to display iax peers in manager format | |
| static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
| callback to display iax peers in manager | |
| static int | manager_iax2_show_registry (struct mansession *s, const struct message *m) |
| static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno) |
| static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx) |
| static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx) |
| static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
| static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
| static void | network_change_event_cb (const struct ast_event *, void *) |
| static int | network_change_event_sched_cb (const void *data) |
| static void | network_change_event_subscribe (void) |
| static void | network_change_event_unsubscribe (void) |
| static void * | network_thread (void *ignore) |
| static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
| static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
| Parses an IAX dial string into its component parts. | |
| static int | peer_cmp_cb (void *obj, void *arg, int flags) |
| static int | peer_delme_cb (void *obj, void *arg, int flags) |
| static void | peer_destructor (void *obj) |
| static int | peer_hash_cb (const void *obj, const int flags) |
| static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
| static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
| static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
| Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
| static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
| peer_status: Report Peer status in character string | |
| static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
| static int | peercnt_add (struct sockaddr_in *sin) |
| static int | peercnt_cmp_cb (void *obj, void *arg, int flags) |
| static int | peercnt_hash_cb (const void *obj, const int flags) |
| static void | peercnt_modify (unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr) |
| static void | peercnt_remove (struct peercnt *peercnt) |
| static int | peercnt_remove_by_addr (struct sockaddr_in *sin) |
| static int | peercnt_remove_cb (const void *obj) |
| static int | peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
| static void | poke_all_peers (void) |
| static int | prune_addr_range_cb (void *obj, void *arg, int flags) |
| static void | prune_peers (void) |
| static void | prune_users (void) |
| static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
| static void | pvt_destructor (void *obj) |
| static int | pvt_hash_cb (const void *obj, const int flags) |
| static int | queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f) |
| All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number. | |
| static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
| static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
| static void | realtime_update_peer (const char *peername, struct ast_sockaddr *sockaddr, time_t regtime) |
| static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
| static void | reg_source_db (struct iax2_peer *p) |
| static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
| static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
| Verify inbound registration. | |
| static int | registry_authrequest (int callno) |
| static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
| static char * | regstate2str (int regstate) |
| static int | reload (void) |
| static int | reload_config (void) |
| static void | reload_firmware (int unload) |
| static void | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
| static void | remove_by_transfercallno (struct chan_iax2_pvt *pvt) |
| static int | replace_callno (const void *obj) |
| static void | requirecalltoken_mark_auto (const char *name, int subclass) |
| static void | resend_with_token (int callno, struct iax_frame *f, const char *newtoken) |
| static void | save_osptoken (struct iax_frame *fr, struct iax_ies *ies) |
| static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
| static void | sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry) |
| static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
| static int | scheduled_destroy (const void *vid) |
| static int | send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied) |
| static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
| static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
| static int | send_lagrq (const void *data) |
| static int | send_packet (struct iax_frame *f) |
| static int | send_ping (const void *data) |
| static void | send_signaling (struct chan_iax2_pvt *pvt) |
| This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point. | |
| static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
| static int | set_config (const char *config_file, int reload) |
| Load configuration. | |
| static void | set_config_destroy (void) |
| static void | set_hangup_source_and_cause (int callno, unsigned char causecode) |
| static void | set_peercnt_limit (struct peercnt *peercnt) |
| static int | set_peercnt_limit_all_cb (void *obj, void *arg, int flags) |
| static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
| static int | socket_process (struct iax2_thread *thread) |
| static int | socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr) |
| static int | socket_read (int *id, int fd, short events, void *cbdata) |
| static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
| static int | start_network_thread (void) |
| static void | stop_stuff (int callno) |
| static void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
| static void | store_by_transfercallno (struct chan_iax2_pvt *pvt) |
| static int | timing_read (int *id, int fd, short events, void *cbdata) |
| static int | transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags) |
| static int | transfercallno_pvt_hash_cb (const void *obj, const int flags) |
| static int | transmit_frame (void *data) |
| static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
| static int | try_firmware (char *s) |
| static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
| static format_t | uncompress_subclass (unsigned char csub) |
| static void | unlink_peer (struct iax2_peer *peer) |
| static int | unload_module (void) |
| static void | unlock_both (unsigned short callno0, unsigned short callno1) |
| static void | unwrap_timestamp (struct iax_frame *fr) |
| static void | update_jbsched (struct chan_iax2_pvt *pvt) |
| static int | update_packet (struct iax_frame *f) |
| static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
| static int | user_cmp_cb (void *obj, void *arg, int flags) |
| static int | user_delme_cb (void *obj, void *arg, int flags) |
| static void | user_destructor (void *obj) |
| static int | user_hash_cb (const void *obj, const int flags) |
| static struct iax2_user * | user_ref (struct iax2_user *user) |
| static struct iax2_user * | user_unref (struct iax2_user *user) |
| static int | users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
| static void | vnak_retransmit (int callno, int last) |
| static int | wait_for_peercallno (struct chan_iax2_pvt *pvt) |
Variables | |
| static char | accountcode [AST_MAX_ACCOUNT_CODE] |
| static int | adsi = 0 |
| static int | amaflags = 0 |
| static int | authdebug = 1 |
| static int | autokill = 0 |
| static struct ao2_container * | callno_pool |
| static const unsigned int | CALLNO_POOL_BUCKETS = 2699 |
| static struct ao2_container * | callno_pool_trunk |
| static struct ast_cli_entry | cli_iax2 [] |
| static struct sockaddr_in | debugaddr |
| static char | default_parkinglot [AST_MAX_CONTEXT] |
| static int | defaultsockfd = -1 |
| static int | delayreject = 0 |
| static int | global_max_trunk_mtu |
| static int | global_rtautoclear = 120 |
| static struct ast_flags64 | globalflags = { 0 } |
| static format_t | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
| static struct ast_data_entry | iax2_data_providers [] |
| static int | iax2_encryption = 0 |
| static int(* | iax2_regfunk )(const char *username, int onoff) = NULL |
| static struct ast_switch | iax2_switch |
| static struct ast_channel_tech | iax2_tech |
| static struct ast_datastore_info | iax2_variable_datastore_info |
| static struct ao2_container * | iax_peercallno_pvts |
| Another container of iax2_pvt structures. | |
| static struct ao2_container * | iax_transfercallno_pvts |
| Another container of iax2_pvt structures. | |
| static int | iaxactivethreadcount = 0 |
| static int | iaxcompat = 0 |
| static int | iaxdebug = 0 |
| static int | iaxdefaultdpcache = 10 * 60 |
| static int | iaxdefaulttimeout = 5 |
| static int | iaxdynamicthreadcount = 0 |
| static int | iaxdynamicthreadnum = 0 |
| static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
| static struct ast_custom_function | iaxpeer_function |
| static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
| an array of iax2 pvt structures | |
| static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
| chan_iax2_pvt structure locks | |
| static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
| static int | iaxtrunkdebug = 0 |
| static struct ast_custom_function | iaxvar_function |
| static struct io_context * | io |
| static int | jittertargetextra = 40 |
| static int | lagrq_time = 10 |
| static char | language [MAX_LANGUAGE] = "" |
| static int | last_authmethod = 0 |
| static int | max_reg_expire |
| static int | max_retries = 4 |
| static int | maxauthreq = 3 |
| static int | maxjitterbuffer = 1000 |
| static int | maxjitterinterps = 10 |
| static int | min_reg_expire |
| static char | mohinterpret [MAX_MUSICCLASS] |
| static char | mohsuggest [MAX_MUSICCLASS] |
| static struct ast_netsock_list * | netsock |
| static pthread_t | netthreadid = AST_PTHREADT_NULL |
| static int | network_change_event_sched_id = -1 |
| static struct ast_event_sub * | network_change_event_subscription |
| static struct ast_netsock_list * | outsock |
| static char * | papp = "IAX2Provision" |
| static struct ast_data_handler | peers_data_provider |
| static int | ping_time = 21 |
| static struct ast_codec_pref | prefs |
| struct { | |
| unsigned int cos | |
| unsigned int tos | |
| } | qos |
| static char | regcontext [AST_MAX_CONTEXT] = "" |
| static int | resyncthreshold = 1000 |
| static struct ast_sched_thread * | sched |
| static int | srvlookup = 0 |
| static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
| static int | test_losspct = 0 |
| static struct ast_timer * | timer |
| static int | trunk_maxmtu |
| static int | trunk_nmaxmtu |
| static int | trunk_timed |
| static int | trunk_untimed |
| static int | trunkfreq = 20 |
| static int | trunkmaxsize = MAX_TRUNKDATA |
| static struct ast_data_handler | users_data_provider |
Implementation of Inter-Asterisk eXchange Version 2 as specified in RFC 5456.
Definition in file chan_iax2.c.
| #define ACN_FORMAT1 "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
Referenced by ast_cli_netstats().
| #define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
Referenced by ast_cli_netstats().
| #define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 243 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), iax2_hangup(), and update_jbsched().
| #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
Referenced by handle_call_token().
| #define CALLTOKEN_IE_FORMAT "%u?%s" |
Referenced by handle_call_token().
| #define DATA_EXPORT_IAX2_PEER | ( | MEMBER | ) |
Definition at line 14764 of file chan_iax2.c.
| #define DATA_EXPORT_IAX2_USER | ( | MEMBER | ) |
Definition at line 14841 of file chan_iax2.c.
| #define DEBUG_SCHED_MULTITHREAD |
Definition at line 235 of file chan_iax2.c.
| #define DEBUG_SUPPORT |
Definition at line 251 of file chan_iax2.c.
| #define DEFAULT_CONTEXT "default" |
Definition at line 270 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), reload_config(), and users_data_provider_get().
| #define DEFAULT_DROP 3 |
Definition at line 249 of file chan_iax2.c.
| #define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 345 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
| #define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 344 of file chan_iax2.c.
Referenced by build_peer().
| #define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 246 of file chan_iax2.c.
| #define DEFAULT_MAXMS 2000 |
Definition at line 343 of file chan_iax2.c.
Referenced by build_peer(), iax2_poke_peer(), reload_config(), and set_config().
| #define DEFAULT_RETRY_TIME 1000 |
Definition at line 247 of file chan_iax2.c.
Referenced by __find_callno(), and complete_transfer().
| #define DEFAULT_THREAD_COUNT 10 |
Definition at line 245 of file chan_iax2.c.
| #define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 624 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
| #define DONT_RESCHEDULE -2 |
Definition at line 367 of file chan_iax2.c.
Referenced by __send_lagrq(), __send_ping(), iax2_destroy_helper(), send_lagrq(), and send_ping().
| #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" |
| #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
| #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" |
| #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
| #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
| #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
| #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" |
| #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
| #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
| #define GAMMA (0.01) |
Definition at line 256 of file chan_iax2.c.
| #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
Definition at line 545 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
| #define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26) |
Allow the FWDOWNL command?
Definition at line 433 of file chan_iax2.c.
Referenced by set_config(), and socket_process().
| #define IAX_ALREADYGONE (uint64_t)(1 << 9) |
Already disconnected
Definition at line 416 of file chan_iax2.c.
Referenced by __do_deliver(), __get_from_jb(), iax2_hangup(), iax2_predestroy(), iax2_write(), pvt_destructor(), and socket_process().
| #define IAX_CALLENCRYPTED | ( | pvt | ) | (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED)) |
Definition at line 348 of file chan_iax2.c.
Referenced by acf_channel_read(), iax2_send(), iax2_start_transfer(), and socket_process().
| #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 322 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
| #define IAX_CAPABILITY_LOWBANDWIDTH |
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 334 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_CAPABILITY_LOWFREE |
Definition at line 339 of file chan_iax2.c.
| #define IAX_CAPABILITY_MEDBANDWIDTH |
Definition at line 324 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_CODEC_NOCAP (uint64_t)(1 << 16) |
only consider requested format and ignore capabilities
Definition at line 423 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
| #define IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
Force old behaviour by turning off prefs
Definition at line 422 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
| #define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
are we willing to let the other guy choose the codec?
Definition at line 421 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
| #define IAX_DEBUGDIGEST | ( | msg, | |||
| key | ) |
Definition at line 351 of file chan_iax2.c.
Referenced by iax2_key_rotate(), and socket_process().
| #define IAX_DELAYPBXSTART (uint64_t)(1 << 25) |
Don't start a PBX on the channel until the peer sends us a response, so that we've achieved a three-way handshake with them before sending voice or anything else
Definition at line 432 of file chan_iax2.c.
Referenced by socket_process().
| #define IAX_DELME (uint64_t)(1 << 1) |
Needs to be deleted
Definition at line 408 of file chan_iax2.c.
Referenced by build_peer(), build_user(), peer_delme_cb(), prune_peers(), prune_users(), and user_delme_cb().
| #define IAX_DYNAMIC (uint64_t)(1 << 6) |
dynamic peer
Definition at line 413 of file chan_iax2.c.
Referenced by __iax2_show_peers(), build_peer(), function_iaxpeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), realtime_peer(), register_verify(), and set_config().
| #define IAX_ENCRYPTED (uint64_t)(1 << 12) |
Whether we should assume encrypted tx/rx
Definition at line 419 of file chan_iax2.c.
Referenced by authenticate_reply(), authenticate_request(), iax2_send(), and socket_process().
| #define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30) |
Forces call encryption, if encryption not possible hangup
Definition at line 437 of file chan_iax2.c.
Referenced by __find_callno(), authenticate_reply(), authenticate_verify(), build_peer(), build_user(), check_access(), create_addr(), iax2_call(), iax2_queryoption(), iax2_setoption(), set_config(), and socket_process().
| #define IAX_FORCEJITTERBUF (uint64_t)(1 << 20) |
Force jitterbuffer, even when bridged to a channel that can take jitter
Definition at line 427 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), schedule_delivery(), set_config(), and set_config_destroy().
| #define IAX_HASCALLERID (uint64_t)(1 << 0) |
CallerID has been specified
Definition at line 407 of file chan_iax2.c.
Referenced by build_peer(), build_user(), check_access(), and update_registry().
| #define IAX_IMMEDIATE (uint64_t)(1 << 27) |
Allow immediate off-hook to extension s
Definition at line 434 of file chan_iax2.c.
Referenced by build_user(), check_access(), and socket_process().
| #define IAX_KEYPOPULATED (uint64_t)(1 << 13) |
Whether we have a key populated
Definition at line 420 of file chan_iax2.c.
Referenced by authenticate_reply(), decrypt_frame(), and iax2_send().
| #define IAX_MAXAUTHREQ (uint64_t)(1 << 24) |
Maximum outstanding AUTHREQ restriction is in place
Definition at line 431 of file chan_iax2.c.
Referenced by authenticate_request(), authenticate_verify(), check_access(), and iax2_destroy_helper().
| #define IAX_NOTRANSFER (uint64_t)(1 << 4) |
Don't native bridge
Definition at line 411 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_bridge(), iax2_request(), iax2_start_transfer(), set_config(), and set_config_destroy().
| #define IAX_PROVISION (uint64_t)(1 << 10) |
This is a provisioning request
Definition at line 417 of file chan_iax2.c.
Referenced by iax2_provision(), and socket_process().
| #define IAX_QUELCH (uint64_t)(1 << 11) |
Whether or not we quelch audio
Definition at line 418 of file chan_iax2.c.
Referenced by iax2_write(), and socket_process().
| #define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29) |
Allow receiving of connected line updates
Definition at line 436 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), set_config(), set_config_destroy(), and socket_process().
| #define IAX_RTAUTOCLEAR (uint64_t)(1 << 19) |
erase me on expire
Definition at line 426 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), realtime_peer(), and set_config().
| #define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
let realtime stay till your reload
Definition at line 424 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), prune_peers(), prune_users(), realtime_peer(), realtime_user(), set_config(), and update_registry().
| #define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
When using realtime, ignore registration expiration
Definition at line 428 of file chan_iax2.c.
Referenced by realtime_peer(), and set_config().
| #define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
Save Systname on Realtime Updates
Definition at line 415 of file chan_iax2.c.
Referenced by realtime_update_peer(), and set_config().
| #define IAX_RTUPDATE (uint64_t)(1 << 18) |
Send a realtime update
Definition at line 425 of file chan_iax2.c.
Referenced by __expire_registry(), set_config(), and update_registry().
| #define IAX_SENDANI (uint64_t)(1 << 7) |
Send ANI along with CallerID
Definition at line 414 of file chan_iax2.c.
Referenced by build_peer(), create_addr(), iax2_call(), and iax2_request().
| #define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28) |
Allow sending of connected line updates
Definition at line 435 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_indicate(), iax2_request(), set_config(), and set_config_destroy().
| #define IAX_SHRINKCALLERID (uint64_t)(1 << 31) |
Turn on and off caller id shrinking
Definition at line 438 of file chan_iax2.c.
Referenced by check_access(), and set_config().
| #define IAX_TEMPONLY (uint64_t)(1 << 2) |
Temporary (realtime)
Definition at line 409 of file chan_iax2.c.
Referenced by __expire_registry(), realtime_peer(), realtime_user(), reg_source_db(), and update_registry().
| #define IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
When doing IAX2 transfers, transfer media only
Definition at line 430 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_bridge(), iax2_request(), set_config(), and set_config_destroy().
| #define IAX_TRUNK (uint64_t)(1 << 3) |
Treat as a trunk
Definition at line 410 of file chan_iax2.c.
Referenced by __iax2_show_peers(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_peer(), iax2_getpeertrunk(), iax2_request(), iax2_send(), manager_iax2_show_peer_list(), peers_data_provider_get(), and socket_process().
| #define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
Send trunk timestamps
Definition at line 429 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), send_trunk(), and set_config().
| #define IAX_USEJITTERBUF (uint64_t)(1 << 5) |
Use jitter buffer
Definition at line 412 of file chan_iax2.c.
Referenced by __find_callno(), ast_cli_netstats(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_channels(), iax2_request(), log_jitterstats(), schedule_delivery(), set_config(), and set_config_destroy().
| #define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 632 of file chan_iax2.c.
Referenced by ast_cli_netstats(), handle_cli_iax2_show_channels(), and iax2_send().
| #define MAX_JITTER_BUFFER 50 |
Definition at line 621 of file chan_iax2.c.
| #define MAX_PEER_BUCKETS 563 |
Referenced by load_objects().
| #define MAX_RETRY_TIME 10000 |
Definition at line 619 of file chan_iax2.c.
Referenced by __attempt_transmit(), and iax2_send().
| #define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 626 of file chan_iax2.c.
Referenced by ast_rtp_raw_write(), calc_timestamp(), and calc_txpeerstamp().
| #define MAX_TRUNK_MTU 1240 |
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.
Definition at line 265 of file chan_iax2.c.
Referenced by handle_cli_iax2_set_mtu(), and set_config().
| #define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 289 of file chan_iax2.c.
Referenced by set_config(), and set_config_destroy().
| #define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
Referenced by load_module(), and load_objects().
| #define MEMORY_SIZE 100 |
Definition at line 248 of file chan_iax2.c.
| #define MIN_JITTER_BUFFER 10 |
Definition at line 622 of file chan_iax2.c.
| #define MIN_RETRY_TIME 100 |
Definition at line 618 of file chan_iax2.c.
Referenced by iax2_send().
| #define MIN_REUSE_TIME 60 |
Definition at line 253 of file chan_iax2.c.
Referenced by make_trunk(), and sched_delay_remove().
| #define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 242 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), acf_channel_read(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_queryoption(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
| #define SCHED_MULTITHREADED |
Definition at line 231 of file chan_iax2.c.
| #define schedule_action | ( | func, | |||
| data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1569 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
| #define TRUNK_CALL_START (IAX_MAX_CALLS / 2) |
Definition at line 1098 of file chan_iax2.c.
| #define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 629 of file chan_iax2.c.
| #define update_max_nontrunk | ( | ) | do { } while (0) |
Definition at line 2131 of file chan_iax2.c.
Referenced by __find_callno(), and make_trunk().
| #define update_max_trunk | ( | ) | do { } while (0) |
Definition at line 2130 of file chan_iax2.c.
Referenced by iax2_destroy(), and make_trunk().
| anonymous enum |
Definition at line 943 of file chan_iax2.c.
00943 { 00944 /*! Extension exists */ 00945 CACHE_FLAG_EXISTS = (1 << 0), 00946 /*! Extension is nonexistent */ 00947 CACHE_FLAG_NONEXISTENT = (1 << 1), 00948 /*! Extension can exist */ 00949 CACHE_FLAG_CANEXIST = (1 << 2), 00950 /*! Waiting to hear back response */ 00951 CACHE_FLAG_PENDING = (1 << 3), 00952 /*! Timed out */ 00953 CACHE_FLAG_TIMEOUT = (1 << 4), 00954 /*! Request transmitted */ 00955 CACHE_FLAG_TRANSMITTED = (1 << 5), 00956 /*! Timeout */ 00957 CACHE_FLAG_UNKNOWN = (1 << 6), 00958 /*! Matchmore */ 00959 CACHE_FLAG_MATCHMORE = (1 << 7), 00960 };
| anonymous enum |
Definition at line 2057 of file chan_iax2.c.
02057 { 02058 /* do not allow a new call number, only search ones in use for match */ 02059 NEW_PREVENT = 0, 02060 /* search for match first, then allow a new one to be allocated */ 02061 NEW_ALLOW = 1, 02062 /* do not search for match, force a new call number */ 02063 NEW_FORCE = 2, 02064 /* do not search for match, force a new call number. Signifies call number 02065 * has been calltoken validated */ 02066 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 02067 };
| enum calltoken_peer_enum |
Call token validation settings.
Definition at line 446 of file chan_iax2.c.
00446 { 00447 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00448 CALLTOKEN_DEFAULT = 0, 00449 /*! \brief Require call token validation. */ 00450 CALLTOKEN_YES = 1, 00451 /*! \brief Require call token validation after a successful registration 00452 * using call token validation occurs. */ 00453 CALLTOKEN_AUTO = 2, 00454 /*! \brief Do not require call token validation. */ 00455 CALLTOKEN_NO = 3, 00456 };
| enum iax2_state |
Definition at line 395 of file chan_iax2.c.
00395 { 00396 IAX_STATE_STARTED = (1 << 0), 00397 IAX_STATE_AUTHENTICATED = (1 << 1), 00398 IAX_STATE_TBD = (1 << 2), 00399 };
| enum iax2_thread_iostate |
Definition at line 984 of file chan_iax2.c.
00984 { 00985 IAX_IOSTATE_IDLE, 00986 IAX_IOSTATE_READY, 00987 IAX_IOSTATE_PROCESSING, 00988 IAX_IOSTATE_SCHEDREADY, 00989 };
| enum iax2_thread_type |
Definition at line 991 of file chan_iax2.c.
00991 { 00992 IAX_THREAD_TYPE_POOL, 00993 IAX_THREAD_TYPE_DYNAMIC, 00994 };
| enum iax_reg_state |
| REG_STATE_UNREGISTERED | |
| REG_STATE_REGSENT | |
| REG_STATE_AUTHSENT | |
| REG_STATE_REGISTERED | |
| REG_STATE_REJECTED | |
| REG_STATE_TIMEOUT | |
| REG_STATE_NOAUTH |
Definition at line 577 of file chan_iax2.c.
00577 { 00578 REG_STATE_UNREGISTERED = 0, 00579 REG_STATE_REGSENT, 00580 REG_STATE_AUTHSENT, 00581 REG_STATE_REGISTERED, 00582 REG_STATE_REJECTED, 00583 REG_STATE_TIMEOUT, 00584 REG_STATE_NOAUTH 00585 };
| enum iax_transfer_state |
| TRANSFER_NONE | |
| TRANSFER_BEGIN | |
| TRANSFER_READY | |
| TRANSFER_RELEASED | |
| TRANSFER_PASSTHROUGH | |
| TRANSFER_MBEGIN | |
| TRANSFER_MREADY | |
| TRANSFER_MRELEASED | |
| TRANSFER_MPASSTHROUGH | |
| TRANSFER_MEDIA | |
| TRANSFER_MEDIAPASS |
Definition at line 587 of file chan_iax2.c.
00587 { 00588 TRANSFER_NONE = 0, 00589 TRANSFER_BEGIN, 00590 TRANSFER_READY, 00591 TRANSFER_RELEASED, 00592 TRANSFER_PASSTHROUGH, 00593 TRANSFER_MBEGIN, 00594 TRANSFER_MREADY, 00595 TRANSFER_MRELEASED, 00596 TRANSFER_MPASSTHROUGH, 00597 TRANSFER_MEDIA, 00598 TRANSFER_MEDIAPASS 00599 };
| static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3568 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_REMOVE, ast_log(), ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxs, iaxsl, ast_frame_subclass::integer, LOG_WARNING, MAX_RETRY_TIME, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
03569 { 03570 /* Attempt to transmit the frame to the remote peer... 03571 Called without iaxsl held. */ 03572 struct iax_frame *f = (struct iax_frame *)data; 03573 int freeme = 0; 03574 int callno = f->callno; 03575 03576 /* Make sure this call is still active */ 03577 if (callno) 03578 ast_mutex_lock(&iaxsl[callno]); 03579 if (callno && iaxs[callno]) { 03580 if (f->retries < 0) { 03581 /* Already ACK'd */ 03582 freeme = 1; 03583 } else if (f->retries >= max_retries) { 03584 /* Too many attempts. Record an error. */ 03585 if (f->transfer) { 03586 /* Transfer timeout */ 03587 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03588 } else if (f->final) { 03589 iax2_destroy(callno); 03590 } else { 03591 if (iaxs[callno]->owner) { 03592 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %u, subclass = %d, ts=%u, seqno=%d)\n", 03593 ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr), 03594 iaxs[f->callno]->owner->name, 03595 f->af.frametype, 03596 f->af.subclass.integer, 03597 f->ts, 03598 f->oseqno); 03599 } 03600 iaxs[callno]->error = ETIMEDOUT; 03601 if (iaxs[callno]->owner) { 03602 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03603 /* Hangup the fd */ 03604 iax2_queue_frame(callno, &fr); /* XXX */ 03605 /* Remember, owner could disappear */ 03606 if (iaxs[callno] && iaxs[callno]->owner) 03607 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03608 } else { 03609 if (iaxs[callno]->reg) { 03610 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03611 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03612 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03613 } 03614 iax2_destroy(callno); 03615 } 03616 } 03617 freeme = 1; 03618 } else { 03619 /* Update it if it needs it */ 03620 update_packet(f); 03621 /* Attempt transmission */ 03622 send_packet(f); 03623 f->retries++; 03624 /* Try again later after 10 times as long */ 03625 f->retrytime *= 10; 03626 if (f->retrytime > MAX_RETRY_TIME) 03627 f->retrytime = MAX_RETRY_TIME; 03628 /* Transfer messages max out at one second */ 03629 if (f->transfer && (f->retrytime > 1000)) 03630 f->retrytime = 1000; 03631 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03632 } 03633 } else { 03634 /* Make sure it gets freed */ 03635 f->retries = -1; 03636 freeme = 1; 03637 } 03638 03639 if (freeme) { 03640 /* Don't attempt delivery, just remove it from the queue */ 03641 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03642 ast_mutex_unlock(&iaxsl[callno]); 03643 f->retrans = -1; /* this is safe because this is the scheduled function */ 03644 /* Free the IAX frame */ 03645 iax2_frame_free(f); 03646 } else if (callno) { 03647 ast_mutex_unlock(&iaxsl[callno]); 03648 } 03649 }
| static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 9106 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax_ie_data::buf, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().
Referenced by auth_reject().
09107 { 09108 /* Called from IAX thread only, without iaxs lock */ 09109 int callno = (int)(long)(nothing); 09110 struct iax_ie_data ied; 09111 ast_mutex_lock(&iaxsl[callno]); 09112 if (iaxs[callno]) { 09113 memset(&ied, 0, sizeof(ied)); 09114 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 09115 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 09116 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 09117 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 09118 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 09119 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 09120 } 09121 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 09122 } 09123 ast_mutex_unlock(&iaxsl[callno]); 09124 }
| static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4758 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
04759 { 04760 int callno = PTR_TO_CALLNO(nothing); 04761 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } }; 04762 ast_mutex_lock(&iaxsl[callno]); 04763 if (iaxs[callno]) { 04764 iaxs[callno]->initid = -1; 04765 iax2_queue_frame(callno, &f); 04766 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04767 } 04768 ast_mutex_unlock(&iaxsl[callno]); 04769 }
| static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 9155 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax_ie_data::buf, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, iax_ie_data::pos, and send_command_final().
Referenced by auto_hangup().
09156 { 09157 /* Called from IAX thread only, without iaxs lock */ 09158 int callno = (int)(long)(nothing); 09159 struct iax_ie_data ied; 09160 ast_mutex_lock(&iaxsl[callno]); 09161 if (iaxs[callno]) { 09162 memset(&ied, 0, sizeof(ied)); 09163 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 09164 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 09165 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 09166 } 09167 ast_mutex_unlock(&iaxsl[callno]); 09168 }
| static int __do_deliver | ( | void * | data | ) | [static] |
Definition at line 3356 of file chan_iax2.c.
References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag64, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
03357 { 03358 /* Just deliver the packet by using queueing. This is called by 03359 the IAX thread with the iaxsl lock held. */ 03360 struct iax_frame *fr = data; 03361 fr->retrans = -1; 03362 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03363 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE)) 03364 iax2_queue_frame(fr->callno, &fr->af); 03365 /* Free our iax frame */ 03366 iax2_frame_free(fr); 03367 /* And don't run again */ 03368 return 0; 03369 }
| static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8731 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_debug, AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_test_flag64, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event, peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
08732 { 08733 struct iax2_peer *peer = (struct iax2_peer *) data; 08734 08735 if (!peer) 08736 return; 08737 if (peer->expire == -1) { 08738 /* Removed already (possibly through CLI), ignore */ 08739 return; 08740 } 08741 08742 peer->expire = -1; 08743 08744 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08745 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08746 realtime_update_peer(peer->name, &peer->addr, 0); 08747 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08748 /* modify entry in peercnts table as _not_ registered */ 08749 peercnt_modify((unsigned char) 0, 0, &peer->addr); 08750 /* Reset the address */ 08751 memset(&peer->addr, 0, sizeof(peer->addr)); 08752 /* Reset expiry value */ 08753 peer->expiry = min_reg_expire; 08754 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08755 ast_db_del("IAX/Registry", peer->name); 08756 register_peer_exten(peer, 0); 08757 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 08758 if (iax2_regfunk) 08759 iax2_regfunk(peer->name, 0); 08760 08761 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08762 unlink_peer(peer); 08763 08764 peer_unref(peer); 08765 }
| static int __find_callno | ( | unsigned short | callno, | |
| unsigned short | dcallno, | |||
| struct sockaddr_in * | sin, | |||
| int | new, | |||
| int | sockfd, | |||
| int | return_locked, | |||
| int | check_dcallno | |||
| ) | [static] |
Definition at line 2862 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find, ao2_ref, ast_copy_flags64, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, callno_entry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), iax2_getpeername(), iax2_sched_add(), IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, iax_transfercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, match(), NEW_ALLOW, new_iax(), OBJ_POINTER, parkinglot, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, and update_max_nontrunk.
Referenced by find_callno(), and find_callno_locked().
02863 { 02864 int res = 0; 02865 int x; 02866 /* this call is calltoken validated as long as it is either NEW_FORCE 02867 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02868 int validated = (new > NEW_ALLOW) ? 1 : 0; 02869 char host[80]; 02870 02871 if (new <= NEW_ALLOW) { 02872 if (callno) { 02873 struct chan_iax2_pvt *pvt; 02874 struct chan_iax2_pvt tmp_pvt = { 02875 .callno = dcallno, 02876 .peercallno = callno, 02877 .transfercallno = callno, 02878 /* hack!! */ 02879 .frames_received = check_dcallno, 02880 }; 02881 02882 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02883 /* this works for finding normal call numbers not involving transfering */ 02884 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02885 if (return_locked) { 02886 ast_mutex_lock(&iaxsl[pvt->callno]); 02887 } 02888 res = pvt->callno; 02889 ao2_ref(pvt, -1); 02890 pvt = NULL; 02891 return res; 02892 } 02893 /* this searches for transfer call numbers that might not get caught otherwise */ 02894 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02895 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02896 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02897 if (return_locked) { 02898 ast_mutex_lock(&iaxsl[pvt->callno]); 02899 } 02900 res = pvt->callno; 02901 ao2_ref(pvt, -1); 02902 pvt = NULL; 02903 return res; 02904 } 02905 } 02906 /* This will occur on the first response to a message that we initiated, 02907 * such as a PING. */ 02908 if (dcallno) { 02909 ast_mutex_lock(&iaxsl[dcallno]); 02910 } 02911 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02912 iaxs[dcallno]->peercallno = callno; 02913 res = dcallno; 02914 store_by_peercallno(iaxs[dcallno]); 02915 if (!res || !return_locked) { 02916 ast_mutex_unlock(&iaxsl[dcallno]); 02917 } 02918 return res; 02919 } 02920 if (dcallno) { 02921 ast_mutex_unlock(&iaxsl[dcallno]); 02922 } 02923 #ifdef IAX_OLD_FIND 02924 /* If we get here, we SHOULD NOT find a call structure for this 02925 callno; if we do, it means that there is a call structure that 02926 has a peer callno but did NOT get entered into the hash table, 02927 which is bad. 02928 02929 If we find a call structure using this old, slow method, output a log 02930 message so we'll know about it. After a few months of leaving this in 02931 place, if we don't hear about people seeing these messages, we can 02932 remove this code for good. 02933 */ 02934 02935 for (x = 1; !res && x < maxnontrunkcall; x++) { 02936 ast_mutex_lock(&iaxsl[x]); 02937 if (iaxs[x]) { 02938 /* Look for an exact match */ 02939 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02940 res = x; 02941 } 02942 } 02943 if (!res || !return_locked) 02944 ast_mutex_unlock(&iaxsl[x]); 02945 } 02946 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02947 ast_mutex_lock(&iaxsl[x]); 02948 if (iaxs[x]) { 02949 /* Look for an exact match */ 02950 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02951 res = x; 02952 } 02953 } 02954 if (!res || !return_locked) 02955 ast_mutex_unlock(&iaxsl[x]); 02956 } 02957 #endif 02958 } 02959 if (!res && (new >= NEW_ALLOW)) { 02960 struct callno_entry *callno_entry; 02961 /* It may seem odd that we look through the peer list for a name for 02962 * this *incoming* call. Well, it is weird. However, users don't 02963 * have an IP address/port number that we can match against. So, 02964 * this is just checking for a peer that has that IP/port and 02965 * assuming that we have a user of the same name. This isn't always 02966 * correct, but it will be changed if needed after authentication. */ 02967 if (!iax2_getpeername(*sin, host, sizeof(host))) 02968 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02969 02970 if (peercnt_add(sin)) { 02971 /* This address has hit its callnumber limit. When the limit 02972 * is reached, the connection is not added to the peercnts table.*/ 02973 return 0; 02974 } 02975 02976 if (!(callno_entry = get_unused_callno(0, validated))) { 02977 /* since we ran out of space, remove the peercnt 02978 * entry we added earlier */ 02979 peercnt_remove_by_addr(sin); 02980 ast_log(LOG_WARNING, "No more space\n"); 02981 return 0; 02982 } 02983 x = callno_entry->callno; 02984 ast_mutex_lock(&iaxsl[x]); 02985 02986 iaxs[x] = new_iax(sin, host); 02987 update_max_nontrunk(); 02988 if (iaxs[x]) { 02989 if (iaxdebug) 02990 ast_debug(1, "Creating new call structure %d\n", x); 02991 iaxs[x]->callno_entry = callno_entry; 02992 iaxs[x]->sockfd = sockfd; 02993 iaxs[x]->addr.sin_port = sin->sin_port; 02994 iaxs[x]->addr.sin_family = sin->sin_family; 02995 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02996 iaxs[x]->peercallno = callno; 02997 iaxs[x]->callno = x; 02998 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02999 iaxs[x]->expiry = min_reg_expire; 03000 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 03001 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 03002 iaxs[x]->amaflags = amaflags; 03003 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 03004 ast_string_field_set(iaxs[x], accountcode, accountcode); 03005 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 03006 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 03007 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 03008 03009 if (iaxs[x]->peercallno) { 03010 store_by_peercallno(iaxs[x]); 03011 } 03012 } else { 03013 ast_log(LOG_WARNING, "Out of resources\n"); 03014 ast_mutex_unlock(&iaxsl[x]); 03015 replace_callno(callno_entry); 03016 return 0; 03017 } 03018 if (!return_locked) 03019 ast_mutex_unlock(&iaxsl[x]); 03020 res = x; 03021 } 03022 return res; 03023 }
| static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4152 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), ast_format_rate(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_test_flag64, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_frame_subclass::codec, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
04153 { 04154 int callno = PTR_TO_CALLNO(p); 04155 struct chan_iax2_pvt *pvt = NULL; 04156 struct iax_frame *fr; 04157 jb_frame frame; 04158 int ret; 04159 long ms; 04160 long next; 04161 struct timeval now = ast_tvnow(); 04162 04163 /* Make sure we have a valid private structure before going on */ 04164 ast_mutex_lock(&iaxsl[callno]); 04165 pvt = iaxs[callno]; 04166 if (!pvt) { 04167 /* No go! */ 04168 ast_mutex_unlock(&iaxsl[callno]); 04169 return; 04170 } 04171 04172 pvt->jbid = -1; 04173 04174 /* round up a millisecond since ast_sched_runq does; */ 04175 /* prevents us from spinning while waiting for our now */ 04176 /* to catch up with runq's now */ 04177 now.tv_usec += 1000; 04178 04179 ms = ast_tvdiff_ms(now, pvt->rxcore); 04180 04181 if(ms >= (next = jb_next(pvt->jb))) { 04182 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 04183 switch(ret) { 04184 case JB_OK: 04185 fr = frame.data; 04186 __do_deliver(fr); 04187 /* __do_deliver() can cause the call to disappear */ 04188 pvt = iaxs[callno]; 04189 break; 04190 case JB_INTERP: 04191 { 04192 struct ast_frame af = { 0, }; 04193 04194 /* create an interpolation frame */ 04195 af.frametype = AST_FRAME_VOICE; 04196 af.subclass.codec = pvt->voiceformat; 04197 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 04198 af.src = "IAX2 JB interpolation"; 04199 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 04200 af.offset = AST_FRIENDLY_OFFSET; 04201 04202 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 04203 * which we'd need to malloc, and then it would free it. That seems like a drag */ 04204 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 04205 iax2_queue_frame(callno, &af); 04206 /* iax2_queue_frame() could cause the call to disappear */ 04207 pvt = iaxs[callno]; 04208 } 04209 } 04210 break; 04211 case JB_DROP: 04212 iax2_frame_free(frame.data); 04213 break; 04214 case JB_NOFRAME: 04215 case JB_EMPTY: 04216 /* do nothing */ 04217 break; 04218 default: 04219 /* shouldn't happen */ 04220 break; 04221 } 04222 } 04223 if (pvt) 04224 update_jbsched(pvt); 04225 ast_mutex_unlock(&iaxsl[callno]); 04226 }
| static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8402 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08403 { 08404 struct iax2_registry *reg = (struct iax2_registry *)data; 08405 reg->expire = -1; 08406 iax2_do_register(reg); 08407 }
| static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12199 of file chan_iax2.c.
References AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_peer::callno, EVENT_FLAG_SYSTEM, iax2_destroy(), iax2_poke_peer_s(), iax2_sched_add(), iaxsl, iax2_peer::lastms, LOG_NOTICE, manager_event, peer_ref(), peer_unref(), iax2_peer::pokeexpire, and iax2_peer::pokefreqnotok.
Referenced by iax2_poke_noanswer().
12200 { 12201 struct iax2_peer *peer = (struct iax2_peer *)data; 12202 int callno; 12203 12204 if (peer->lastms > -1) { 12205 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 12206 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 12207 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 12208 } 12209 if ((callno = peer->callno) > 0) { 12210 ast_mutex_lock(&iaxsl[callno]); 12211 iax2_destroy(callno); 12212 ast_mutex_unlock(&iaxsl[callno]); 12213 } 12214 peer->callno = 0; 12215 peer->lastms = -1; 12216 /* Try again quickly */ 12217 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 12218 if (peer->pokeexpire == -1) 12219 peer_unref(peer); 12220 }
| static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9215 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
09216 { 09217 struct iax2_peer *peer = (struct iax2_peer *)data; 09218 iax2_poke_peer(peer, 0); 09219 peer_unref(peer); 09220 }
| static int __iax2_show_peers | ( | int | fd, | |
| int * | total, | |||
| struct mansession * | s, | |||
| const int | argc, | |||
| const char *const | argv[] | |||
| ) | [static] |
Definition at line 6760 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), iax2_peer::encmethods, encmethods_to_str(), FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), peer_unref(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and status.
Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().
06761 { 06762 regex_t regexbuf; 06763 int havepattern = 0; 06764 int total_peers = 0; 06765 int online_peers = 0; 06766 int offline_peers = 0; 06767 int unmonitored_peers = 0; 06768 struct ao2_iterator i; 06769 06770 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" 06771 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" 06772 06773 struct iax2_peer *peer = NULL; 06774 char name[256]; 06775 struct ast_str *encmethods = ast_str_alloca(256); 06776 int registeredonly=0; 06777 char idtext[256] = ""; 06778 switch (argc) { 06779 case 6: 06780 if (!strcasecmp(argv[3], "registered")) 06781 registeredonly = 1; 06782 else 06783 return RESULT_SHOWUSAGE; 06784 if (!strcasecmp(argv[4], "like")) { 06785 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06786 return RESULT_SHOWUSAGE; 06787 havepattern = 1; 06788 } else 06789 return RESULT_SHOWUSAGE; 06790 break; 06791 case 5: 06792 if (!strcasecmp(argv[3], "like")) { 06793 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06794 return RESULT_SHOWUSAGE; 06795 havepattern = 1; 06796 } else 06797 return RESULT_SHOWUSAGE; 06798 break; 06799 case 4: 06800 if (!strcasecmp(argv[3], "registered")) 06801 registeredonly = 1; 06802 else 06803 return RESULT_SHOWUSAGE; 06804 break; 06805 case 3: 06806 break; 06807 default: 06808 return RESULT_SHOWUSAGE; 06809 } 06810 06811 06812 if (!s) 06813 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status"); 06814 06815 i = ao2_iterator_init(peers, 0); 06816 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 06817 char nm[20]; 06818 char status[20]; 06819 int retstatus; 06820 struct sockaddr_in peer_addr; 06821 06822 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 06823 06824 if (registeredonly && !peer_addr.sin_addr.s_addr) { 06825 continue; 06826 } 06827 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 06828 continue; 06829 } 06830 06831 if (!ast_strlen_zero(peer->username)) 06832 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06833 else 06834 ast_copy_string(name, peer->name, sizeof(name)); 06835 06836 encmethods_to_str(peer->encmethods, &encmethods); 06837 retstatus = peer_status(peer, status, sizeof(status)); 06838 if (retstatus > 0) 06839 online_peers++; 06840 else if (!retstatus) 06841 offline_peers++; 06842 else 06843 unmonitored_peers++; 06844 06845 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06846 06847 if (s) { 06848 astman_append(s, 06849 "Event: PeerEntry\r\n%s" 06850 "Channeltype: IAX2\r\n" 06851 "ObjectName: %s\r\n" 06852 "ChanObjectType: peer\r\n" 06853 "IPaddress: %s\r\n" 06854 "IPport: %d\r\n" 06855 "Dynamic: %s\r\n" 06856 "Trunk: %s\r\n" 06857 "Encryption: %s\r\n" 06858 "Status: %s\r\n\r\n", 06859 idtext, 06860 name, 06861 ast_sockaddr_stringify_addr(&peer->addr), 06862 ast_sockaddr_port(&peer->addr), 06863 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06864 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06865 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06866 status); 06867 } else { 06868 ast_cli(fd, FORMAT, name, 06869 ast_sockaddr_stringify_addr(&peer->addr), 06870 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06871 nm, 06872 ast_sockaddr_port(&peer->addr), 06873 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06874 peer->encmethods ? "(E)" : " ", 06875 status); 06876 } 06877 total_peers++; 06878 } 06879 ao2_iterator_destroy(&i); 06880 06881 if (!s) 06882 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n", 06883 total_peers, online_peers, offline_peers, unmonitored_peers); 06884 06885 if (havepattern) 06886 regfree(®exbuf); 06887 06888 if (total) 06889 *total = total_peers; 06890 06891 return RESULT_SUCCESS; 06892 #undef FORMAT 06893 #undef FORMAT2 06894 }
| static int __schedule_action | ( | void(*)(const void *data) | func, | |
| const void * | data, | |||
| const char * | funcname | |||
| ) | [static] |
Definition at line 1544 of file chan_iax2.c.
References ast_copy_string(), ast_debug, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, signal_condition(), and thread.
01545 { 01546 struct iax2_thread *thread; 01547 static time_t lasterror; 01548 time_t t; 01549 01550 thread = find_idle_thread(); 01551 if (thread != NULL) { 01552 thread->schedfunc = func; 01553 thread->scheddata = data; 01554 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01555 #ifdef DEBUG_SCHED_MULTITHREAD 01556 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01557 #endif 01558 signal_condition(&thread->lock, &thread->cond); 01559 return 0; 01560 } 01561 time(&t); 01562 if (t != lasterror) { 01563 lasterror = t; 01564 ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname); 01565 } 01566 01567 return -1; 01568 }
| static int __send_command | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno, | |||
| int | now, | |||
| int | transfer, | |||
| int | final | |||
| ) | [static] |
Definition at line 7587 of file chan_iax2.c.
References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame_subclass::integer, ast_frame::ptr, queue_signalling(), ast_frame::src, and ast_frame::subclass.
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
07589 { 07590 struct ast_frame f = { 0, }; 07591 int res = 0; 07592 07593 f.frametype = type; 07594 f.subclass.integer = command; 07595 f.datalen = datalen; 07596 f.src = __FUNCTION__; 07597 f.data.ptr = (void *) data; 07598 07599 if ((res = queue_signalling(i, &f)) <= 0) { 07600 return res; 07601 } 07602 07603 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07604 }
| static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1655 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, send_command(), and send_lagrq().
Referenced by send_lagrq().
01656 { 01657 int callno = (long) data; 01658 01659 ast_mutex_lock(&iaxsl[callno]); 01660 01661 if (iaxs[callno]) { 01662 if (iaxs[callno]->peercallno) { 01663 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01664 if (iaxs[callno]->lagid != DONT_RESCHEDULE) { 01665 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01666 } 01667 } 01668 } else { 01669 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01670 } 01671 01672 ast_mutex_unlock(&iaxsl[callno]); 01673 }
| static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1588 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, send_command(), and send_ping().
Referenced by send_ping().
01589 { 01590 int callno = (long) data; 01591 01592 ast_mutex_lock(&iaxsl[callno]); 01593 01594 if (iaxs[callno]) { 01595 if (iaxs[callno]->peercallno) { 01596 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01597 if (iaxs[callno]->pingid != DONT_RESCHEDULE) { 01598 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01599 } 01600 } 01601 } else { 01602 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01603 } 01604 01605 ast_mutex_unlock(&iaxsl[callno]); 01606 }
| static int __unload_module | ( | void | ) | [static] |
Definition at line 14568 of file chan_iax2.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_data_unregister, ast_manager_unregister(), ast_mutex_destroy, ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_thread_destroy(), ast_taskprocessor_unreference(), AST_TEST_UNREGISTER, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), cleanup_thread_list(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxs, iaxsl, network_change_event_unsubscribe(), papp, and reload_firmware().
Referenced by load_module(), and unload_module().
14569 { 14570 struct ast_context *con; 14571 int x; 14572 14573 network_change_event_unsubscribe(); 14574 14575 ast_manager_unregister("IAXpeers"); 14576 ast_manager_unregister("IAXpeerlist"); 14577 ast_manager_unregister("IAXnetstats"); 14578 ast_manager_unregister("IAXregistry"); 14579 ast_unregister_application(papp); 14580 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14581 ast_unregister_switch(&iax2_switch); 14582 ast_channel_unregister(&iax2_tech); 14583 14584 if (netthreadid != AST_PTHREADT_NULL) { 14585 pthread_cancel(netthreadid); 14586 pthread_kill(netthreadid, SIGURG); 14587 pthread_join(netthreadid, NULL); 14588 } 14589 14590 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14591 if (iaxs[x]) { 14592 iax2_destroy(x); 14593 } 14594 } 14595 14596 /* Call for all threads to halt */ 14597 cleanup_thread_list(&active_list); 14598 cleanup_thread_list(&dynamic_list); 14599 cleanup_thread_list(&idle_list); 14600 14601 ast_netsock_release(netsock); 14602 ast_netsock_release(outsock); 14603 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14604 if (iaxs[x]) { 14605 iax2_destroy(x); 14606 } 14607 } 14608 ast_manager_unregister( "IAXpeers" ); 14609 ast_manager_unregister( "IAXpeerlist" ); 14610 ast_manager_unregister( "IAXnetstats" ); 14611 ast_manager_unregister( "IAXregistry" ); 14612 ast_unregister_application(papp); 14613 #ifdef TEST_FRAMEWORK 14614 AST_TEST_UNREGISTER(test_iax2_peers_get); 14615 AST_TEST_UNREGISTER(test_iax2_users_get); 14616 #endif 14617 ast_data_unregister(NULL); 14618 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14619 ast_unregister_switch(&iax2_switch); 14620 ast_channel_unregister(&iax2_tech); 14621 delete_users(); 14622 iax_provision_unload(); 14623 reload_firmware(1); 14624 14625 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14626 ast_mutex_destroy(&iaxsl[x]); 14627 } 14628 14629 ao2_ref(peers, -1); 14630 ao2_ref(users, -1); 14631 ao2_ref(iax_peercallno_pvts, -1); 14632 ao2_ref(iax_transfercallno_pvts, -1); 14633 ao2_ref(peercnts, -1); 14634 ao2_ref(callno_limits, -1); 14635 ao2_ref(calltoken_ignores, -1); 14636 ao2_ref(callno_pool, -1); 14637 ao2_ref(callno_pool_trunk, -1); 14638 if (timer) { 14639 ast_timer_close(timer); 14640 timer = NULL; 14641 } 14642 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 14643 sched = ast_sched_thread_destroy(sched); 14644 14645 con = ast_context_find(regcontext); 14646 if (con) 14647 ast_context_destroy(con, "IAX2"); 14648 ast_unload_realtime("iaxpeers"); 14649 return 0; 14650 }
| static int acf_channel_read | ( | struct ast_channel * | chan, | |
| const char * | funcname, | |||
| char * | preparse, | |||
| char * | buf, | |||
| size_t | buflen | |||
| ) | [static] |
Definition at line 14208 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::callno, iax2_tech, IAX_CALLENCRYPTED, iaxs, iaxsl, LOG_ERROR, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
14209 { 14210 struct chan_iax2_pvt *pvt; 14211 unsigned int callno; 14212 int res = 0; 14213 14214 if (!chan || chan->tech != &iax2_tech) { 14215 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 14216 return -1; 14217 } 14218 14219 callno = PTR_TO_CALLNO(chan->tech_pvt); 14220 ast_mutex_lock(&iaxsl[callno]); 14221 if (!(pvt = iaxs[callno])) { 14222 ast_mutex_unlock(&iaxsl[callno]); 14223 return -1; 14224 } 14225 14226 if (!strcasecmp(args, "osptoken")) { 14227 ast_copy_string(buf, pvt->osptoken, buflen); 14228 } else if (!strcasecmp(args, "peerip")) { 14229 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 14230 } else if (!strcasecmp(args, "peername")) { 14231 ast_copy_string(buf, pvt->username, buflen); 14232 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) { 14233 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : ""); 14234 } else { 14235 res = -1; 14236 } 14237 14238 ast_mutex_unlock(&iaxsl[callno]); 14239 14240 return res; 14241 }
| static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 9937 of file chan_iax2.c.
References ast_channel_datastore_find(), ast_copy_string(), AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_datastore::data, iax2_variable_datastore_info, LOG_WARNING, ast_var_t::name, ast_var_t::value, and var.
09938 { 09939 struct ast_datastore *variablestore; 09940 AST_LIST_HEAD(, ast_var_t) *varlist; 09941 struct ast_var_t *var; 09942 09943 if (!chan) { 09944 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); 09945 return -1; 09946 } 09947 09948 variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09949 09950 if (!variablestore) { 09951 *buf = '\0'; 09952 return 0; 09953 } 09954 varlist = variablestore->data; 09955 09956 AST_LIST_LOCK(varlist); 09957 AST_LIST_TRAVERSE(varlist, var, entries) { 09958 if (strcmp(var->name, data) == 0) { 09959 ast_copy_string(buf, var->value, len); 09960 break; 09961 } 09962 } 09963 AST_LIST_UNLOCK(varlist); 09964 return 0; 09965 }
| static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 9967 of file chan_iax2.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_delete(), ast_datastore::data, DATASTORE_INHERIT_FOREVER, iax2_variable_datastore_info, ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_var_t::name, and var.
09968 { 09969 struct ast_datastore *variablestore; 09970 AST_LIST_HEAD(, ast_var_t) *varlist; 09971 struct ast_var_t *var; 09972 09973 if (!chan) { 09974 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); 09975 return -1; 09976 } 09977 09978 variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09979 09980 if (!variablestore) { 09981 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09982 if (!variablestore) { 09983 ast_log(LOG_ERROR, "Memory allocation error\n"); 09984 return -1; 09985 } 09986 varlist = ast_calloc(1, sizeof(*varlist)); 09987 if (!varlist) { 09988 ast_datastore_free(variablestore); 09989 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09990 return -1; 09991 } 09992 09993 AST_LIST_HEAD_INIT(varlist); 09994 variablestore->data = varlist; 09995 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09996 ast_channel_datastore_add(chan, variablestore); 09997 } else 09998 varlist = variablestore->data; 09999 10000 AST_LIST_LOCK(varlist); 10001 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 10002 if (strcmp(var->name, data) == 0) { 10003 AST_LIST_REMOVE_CURRENT(entries); 10004 ast_var_delete(var); 10005 break; 10006 } 10007 } 10008 AST_LIST_TRAVERSE_SAFE_END; 10009 var = ast_var_assign(data, value); 10010 if (var) 10011 AST_LIST_INSERT_TAIL(varlist, var, entries); 10012 else 10013 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 10014 AST_LIST_UNLOCK(varlist); 10015 return 0; 10016 }
| static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2597 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), ast_strlen_zero(), addr_range::delme, addr_range::ha, LOG_WARNING, and OBJ_POINTER.
Referenced by set_config().
02598 { 02599 struct addr_range tmp; 02600 struct addr_range *addr_range = NULL; 02601 struct ast_ha *ha = NULL; 02602 int error = 0; 02603 02604 if (ast_strlen_zero(addr)) { 02605 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02606 return -1; 02607 } 02608 02609 ha = ast_append_ha("permit", addr, NULL, &error); 02610 02611 /* check for valid config information */ 02612 if (error) { 02613 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02614 return -1; 02615 } 02616 02617 ast_copy_ha(ha, &tmp.ha); 02618 /* find or create the addr_range */ 02619 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02620 ao2_lock(addr_range); 02621 addr_range->delme = 0; 02622 ao2_unlock(addr_range); 02623 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02624 /* copy over config data into addr_range object */ 02625 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02626 ao2_link(calltoken_ignores, addr_range); 02627 } else { 02628 ast_free_ha(ha); 02629 return -1; 02630 } 02631 02632 ast_free_ha(ha); 02633 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02634 02635 return 0; 02636 }
| static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | ied | |||
| ) | [static] |
Definition at line 4834 of file chan_iax2.c.
References iax_ie_data::buf, IAX_IE_CALLTOKEN, and iax_ie_data::pos.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_do_register(), iax2_poke_peer(), and registry_rerequest().
04835 { 04836 /* first make sure their are two empty bytes left in ied->buf */ 04837 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04838 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04839 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04840 pvt->calltoken_ie_len = 2; 04841 } 04842 }
| static int addr_range_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2248 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_cmp_addr(), CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.
Referenced by load_objects().
02249 { 02250 struct addr_range *lim1 = obj, *lim2 = arg; 02251 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) && 02252 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ? 02253 CMP_MATCH | CMP_STOP : 0; 02254 }
| static int addr_range_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2233 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
02234 { 02235 struct addr_range *lim = obj; 02236 lim->delme = 1; 02237 return 0; 02238 }
| static int addr_range_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2240 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, and addr_range::ha.
Referenced by load_objects().
02241 { 02242 const struct addr_range *lim = obj; 02243 struct sockaddr_in sin; 02244 ast_sockaddr_to_sin(&lim->ha.addr, &sin); 02245 return abs((int) sin.sin_addr.s_addr); 02246 }
| static int addr_range_match_address_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2268 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.
Referenced by calltoken_required(), and set_peercnt_limit().
02269 { 02270 struct addr_range *addr_range = obj; 02271 struct sockaddr_in *sin = arg; 02272 struct sockaddr_in ha_netmask_sin; 02273 struct sockaddr_in ha_addr_sin; 02274 02275 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin); 02276 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin); 02277 02278 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) { 02279 return CMP_MATCH | CMP_STOP; 02280 } 02281 return 0; 02282 }
| static int apply_context | ( | struct iax2_context * | con, | |
| const char * | context | |||
| ) | [static] |
Definition at line 7651 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
| static int ast_cli_netstats | ( | struct mansession * | s, | |
| int | fd, | |||
| int | limit_fmt | |||
| ) | [static] |
Definition at line 7346 of file chan_iax2.c.
References ACN_FORMAT1, ACN_FORMAT2, ARRAY_LEN, ast_cli(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, astman_append(), jb_info::current, chan_iax2_pvt::first_iax_message, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, chan_iax2_pvt::last_iax_message, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, and chan_iax2_pvt::pingtime.
Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().
07347 { 07348 int x; 07349 int numchans = 0; 07350 char first_message[10] = { 0, }; 07351 char last_message[10] = { 0, }; 07352 #define ACN_FORMAT1 "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" 07353 #define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 07354 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07355 ast_mutex_lock(&iaxsl[x]); 07356 if (iaxs[x]) { 07357 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 07358 jb_info jbinfo; 07359 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07360 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07361 07362 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07363 jb_getinfo(iaxs[x]->jb, &jbinfo); 07364 localjitter = jbinfo.jitter; 07365 localdelay = jbinfo.current - jbinfo.min; 07366 locallost = jbinfo.frames_lost; 07367 locallosspct = jbinfo.losspct/1000; 07368 localdropped = jbinfo.frames_dropped; 07369 localooo = jbinfo.frames_ooo; 07370 } else { 07371 localjitter = -1; 07372 localdelay = 0; 07373 locallost = -1; 07374 locallosspct = -1; 07375 localdropped = 0; 07376 localooo = -1; 07377 } 07378 if (s) 07379 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07380 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07381 iaxs[x]->pingtime, 07382 localjitter, 07383 localdelay, 07384 locallost, 07385 locallosspct, 07386 localdropped, 07387 localooo, 07388 iaxs[x]->frames_received/1000, 07389 iaxs[x]->remote_rr.jitter, 07390 iaxs[x]->remote_rr.delay, 07391 iaxs[x]->remote_rr.losscnt, 07392 iaxs[x]->remote_rr.losspct, 07393 iaxs[x]->remote_rr.dropped, 07394 iaxs[x]->remote_rr.ooo, 07395 iaxs[x]->remote_rr.packets/1000, 07396 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07397 first_message, 07398 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07399 last_message); 07400 else 07401 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07402 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07403 iaxs[x]->pingtime, 07404 localjitter, 07405 localdelay, 07406 locallost, 07407 locallosspct, 07408 localdropped, 07409 localooo, 07410 iaxs[x]->frames_received/1000, 07411 iaxs[x]->remote_rr.jitter, 07412 iaxs[x]->remote_rr.delay, 07413 iaxs[x]->remote_rr.losscnt, 07414 iaxs[x]->remote_rr.losspct, 07415 iaxs[x]->remote_rr.dropped, 07416 iaxs[x]->remote_rr.ooo, 07417 iaxs[x]->remote_rr.packets/1000, 07418 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07419 first_message, 07420 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07421 last_message); 07422 numchans++; 07423 } 07424 ast_mutex_unlock(&iaxsl[x]); 07425 } 07426 07427 return numchans; 07428 }
| AST_DATA_STRUCTURE | ( | iax2_user | , | |
| DATA_EXPORT_IAX2_USER | ||||
| ) |
| AST_DATA_STRUCTURE | ( | iax2_peer | , | |
| DATA_EXPORT_IAX2_PEER | ||||
| ) |
| static struct ast_channel* ast_iax2_new | ( | int | callno, | |
| int | state, | |||
| format_t | capability, | |||
| const char * | linkedid, | |||
| unsigned int | cachable | |||
| ) | [static, read] |
Create new call, interface with the PBX core.
Definition at line 5838 of file chan_iax2.c.
References chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, ast_party_caller::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_release(), ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_FLAG_DISABLE_DEVSTATE_CACHE, ast_free, ast_hangup(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_module_ref(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), ast_channel::caller, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::dialed, ast_channel::exten, ast_channel::flags, ast_party_redirecting::from, iax2_ami_channelupdate(), iax2_tech, iax2_variable_datastore_info, iaxs, iaxsl, ast_party_caller::id, ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, chan_iax2_pvt::owner, parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::redirecting, ast_party_dialed::str, ast_party_number::str, ast_channel::tech, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, ast_party_number::valid, ast_variable::value, var, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
05839 { 05840 struct ast_channel *tmp; 05841 struct chan_iax2_pvt *i; 05842 struct ast_variable *v = NULL; 05843 05844 if (!(i = iaxs[callno])) { 05845 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05846 return NULL; 05847 } 05848 05849 /* Don't hold call lock */ 05850 ast_mutex_unlock(&iaxsl[callno]); 05851 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); 05852 ast_mutex_lock(&iaxsl[callno]); 05853 if (i != iaxs[callno]) { 05854 if (tmp) { 05855 /* unlock and relock iaxsl[callno] to preserve locking order */ 05856 ast_mutex_unlock(&iaxsl[callno]); 05857 tmp = ast_channel_release(tmp); 05858 ast_mutex_lock(&iaxsl[callno]); 05859 } 05860 return NULL; 05861 } 05862 iax2_ami_channelupdate(i); 05863 if (!tmp) 05864 return NULL; 05865 tmp->tech = &iax2_tech; 05866 /* We can support any format by default, until we get restricted */ 05867 tmp->nativeformats = capability; 05868 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05869 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05870 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05871 05872 if (!ast_strlen_zero(i->parkinglot)) 05873 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05874 /* Don't use ast_set_callerid() here because it will 05875 * generate a NewCallerID event before the NewChannel event */ 05876 if (!ast_strlen_zero(i->ani)) { 05877 tmp->caller.ani.number.valid = 1; 05878 tmp->caller.ani.number.str = ast_strdup(i->ani); 05879 } else if (!ast_strlen_zero(i->cid_num)) { 05880 tmp->caller.ani.number.valid = 1; 05881 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 05882 } 05883 tmp->dialed.number.str = ast_strdup(i->dnid); 05884 if (!ast_strlen_zero(i->rdnis)) { 05885 tmp->redirecting.from.number.valid = 1; 05886 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 05887 } 05888 tmp->caller.id.name.presentation = i->calling_pres; 05889 tmp->caller.id.number.presentation = i->calling_pres; 05890 tmp->caller.id.number.plan = i->calling_ton; 05891 tmp->dialed.transit_network_select = i->calling_tns; 05892 if (!ast_strlen_zero(i->language)) 05893 ast_string_field_set(tmp, language, i->language); 05894 if (!ast_strlen_zero(i->accountcode)) 05895 ast_string_field_set(tmp, accountcode, i->accountcode); 05896 if (i->amaflags) 05897 tmp->amaflags = i->amaflags; 05898 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05899 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05900 if (i->adsi) 05901 tmp->adsicpe = i->peeradsicpe; 05902 else 05903 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05904 i->owner = tmp; 05905 i->capability = capability; 05906 05907 if (!cachable) { 05908 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE; 05909 } 05910 05911 /* Set inherited variables */ 05912 if (i->vars) { 05913 for (v = i->vars ; v ; v = v->next) 05914 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05915 } 05916 if (i->iaxvars) { 05917 struct ast_datastore *variablestore; 05918 struct ast_variable *var, *prev = NULL; 05919 AST_LIST_HEAD(, ast_var_t) *varlist; 05920 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05921 varlist = ast_calloc(1, sizeof(*varlist)); 05922 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05923 if (variablestore && varlist) { 05924 variablestore->data = varlist; 05925 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05926 AST_LIST_HEAD_INIT(varlist); 05927 for (var = i->iaxvars; var; var = var->next) { 05928 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05929 if (prev) 05930 ast_free(prev); 05931 prev = var; 05932 if (!newvar) { 05933 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05934 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05935 } else { 05936 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05937 } 05938 } 05939 if (prev) 05940 ast_free(prev); 05941 i->iaxvars = NULL; 05942 ast_channel_datastore_add(i->owner, variablestore); 05943 } else { 05944 if (variablestore) { 05945 ast_datastore_free(variablestore); 05946 } 05947 if (varlist) { 05948 ast_free(varlist); 05949 } 05950 } 05951 } 05952 05953 if (state != AST_STATE_DOWN) { 05954 if (ast_pbx_start(tmp)) { 05955 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05956 ast_hangup(tmp); 05957 i->owner = NULL; 05958 return NULL; 05959 } 05960 } 05961 05962 ast_module_ref(ast_module_info->self); 05963 return tmp; 05964 }
| static AST_LIST_HEAD_NOLOCK | ( | iax_frame | ) | [static] |
a list of frames that may need to be retransmitted
peer connection private, keeps track of all the call numbers consumed by a single ip address
ip address consuming call numbers
Number of call numbers currently used by this ip address
Max call numbers allowed for this ip address
Specifies whether limit is set by a registration or not, if so normal limit setting rules do not apply to this address.
Definition at line 865 of file chan_iax2.c.
References iax2_trunk_peer::addr.
00912 { 00913 /*! ip address consuming call numbers */ 00914 unsigned long addr; 00915 /*! Number of call numbers currently used by this ip address */ 00916 uint16_t cur; 00917 /*! Max call numbers allowed for this ip address */ 00918 uint16_t limit; 00919 /*! Specifies whether limit is set by a registration or not, if so normal 00920 * limit setting rules do not apply to this address. */ 00921 unsigned char reg; 00922 };
| static AST_LIST_HEAD_STATIC | ( | dynamic_list | , | |
| iax2_thread | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | active_list | , | |
| iax2_thread | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | idle_list | , | |
| iax2_thread | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | dpcache | , | |
| iax2_dpcache | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | firmwares | , | |
| iax_firmware | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | registrations | , | |
| iax2_registry | ||||
| ) | [static] |
| static AST_LIST_HEAD_STATIC | ( | tpeers | , | |
| iax2_trunk_peer | ||||
| ) | [static] |
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_LOAD_ORDER | , | |||
| "Inter Asterisk eXchange (Ver 2)" | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload, |
|||
| . | load_pri = AST_MODPRI_CHANNEL_DRIVER, |
|||
| . | nonoptreq = "res_crypto" | |||
| ) |
| static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3651 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03652 { 03653 #ifdef SCHED_MULTITHREADED 03654 if (schedule_action(__attempt_transmit, data)) 03655 #endif 03656 __attempt_transmit(data); 03657 return 0; 03658 }
| static int auth_fail | ( | int | callno, | |
| int | failcode | |||
| ) | [static] |
Definition at line 9140 of file chan_iax2.c.
References auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_replace(), and iaxs.
Referenced by socket_process().
09141 { 09142 /* Schedule sending the authentication failure in one second, to prevent 09143 guessing */ 09144 if (iaxs[callno]) { 09145 iaxs[callno]->authfail = failcode; 09146 if (delayreject) { 09147 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 09148 sched, 1000, auth_reject, (void *)(long)callno); 09149 } else 09150 auth_reject((void *)(long)callno); 09151 } 09152 return 0; 09153 }
| static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 9126 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::authid, iaxs, iaxsl, and schedule_action.
Referenced by auth_fail().
09127 { 09128 int callno = (int)(long)(data); 09129 ast_mutex_lock(&iaxsl[callno]); 09130 if (iaxs[callno]) 09131 iaxs[callno]->authid = -1; 09132 ast_mutex_unlock(&iaxsl[callno]); 09133 #ifdef SCHED_MULTITHREADED 09134 if (schedule_action(__auth_reject, data)) 09135 #endif 09136 __auth_reject(data); 09137 return 0; 09138 }
| 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 | |||
| ) | [static] |
Definition at line 8224 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get(), AST_KEY_PRIVATE, ast_log(), ast_sign(), ast_strlen_zero(), build_encryption_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update().
Referenced by authenticate_reply(), and registry_rerequest().
08225 { 08226 int res = -1; 08227 int x; 08228 if (!ast_strlen_zero(keyn)) { 08229 if (!(authmethods & IAX_AUTH_RSA)) { 08230 if (ast_strlen_zero(secret)) 08231 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)); 08232 } else if (ast_strlen_zero(challenge)) { 08233 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 08234 } else { 08235 char sig[256]; 08236 struct ast_key *key; 08237 key = ast_key_get(keyn, AST_KEY_PRIVATE); 08238 if (!key) { 08239 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 08240 } else { 08241 if (ast_sign(key, (char*)challenge, sig)) { 08242 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 08243 res = -1; 08244 } else { 08245 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 08246 res = 0; 08247 } 08248 } 08249 } 08250 } 08251 /* Fall back */ 08252 if (res && !ast_strlen_zero(secret)) { 08253 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 08254 struct MD5Context md5; 08255 unsigned char digest[16]; 08256 char digres[128]; 08257 MD5Init(&md5); 08258 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 08259 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 08260 MD5Final(digest, &md5); 08261 /* If they support md5, authenticate with it. */ 08262 for (x=0;x<16;x++) 08263 sprintf(digres + (x << 1), "%2.2x", (unsigned)digest[x]); /* safe */ 08264 if (pvt) { 08265 build_encryption_keys(digest, pvt); 08266 } 08267 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 08268 res = 0; 08269 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 08270 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 08271 res = 0; 08272 } else 08273 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 08274 } 08275 return res; 08276 }
| static int authenticate_reply | ( | struct chan_iax2_pvt * | p, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies, | |||
| const char * | override, | |||
| const char * | okey | |||
| ) | [static] |
Definition at line 8282 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_calloc, ast_channel_datastore_add(), ast_datastore_alloc, ast_datastore_free(), AST_FRAME_IAX, ast_free, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_sockaddr_to_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::encmethods, iax_ies::encmethods, iax2_variable_datastore_info, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, iaxs, iaxsl, ast_datastore::inheritance, LOG_ERROR, LOG_NOTICE, iax2_peer::mask, merge_encryption(), ast_variable::name, ast_variable::next, chan_iax2_pvt::owner, peer_unref(), iax_ie_data::pos, realtime_peer(), send_command(), iax_ies::username, ast_variable::value, var, and iax_ies::vars.
Referenced by socket_process().
08283 { 08284 struct iax2_peer *peer = NULL; 08285 /* Start pessimistic */ 08286 int res = -1; 08287 int authmethods = 0; 08288 struct iax_ie_data ied; 08289 uint16_t callno = p->callno; 08290 08291 memset(&ied, 0, sizeof(ied)); 08292 08293 if (ies->username) 08294 ast_string_field_set(p, username, ies->username); 08295 if (ies->challenge) 08296 ast_string_field_set(p, challenge, ies->challenge); 08297 if (ies->authmethods) 08298 authmethods = ies->authmethods; 08299 if (authmethods & IAX_AUTH_MD5) 08300 merge_encryption(p, ies->encmethods); 08301 else 08302 p->encmethods = 0; 08303 08304 /* Check for override RSA authentication first */ 08305 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 08306 /* Normal password authentication */ 08307 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 08308 } else { 08309 struct ao2_iterator i = ao2_iterator_init(peers, 0); 08310 while ((peer = ao2_iterator_next(&i))) { 08311 struct sockaddr_in peer_addr; 08312 08313 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 08314 08315 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 08316 /* No peer specified at our end, or this is the peer */ 08317 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 08318 /* No username specified in peer rule, or this is the right username */ 08319 && (!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))) 08320 /* No specified host, or this is our host */ 08321 ) { 08322 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 08323 if (!res) { 08324 peer_unref(peer); 08325 break; 08326 } 08327 } 08328 peer_unref(peer); 08329 } 08330 ao2_iterator_destroy(&i); 08331 if (!peer) { 08332 /* We checked our list and didn't find one. It's unlikely, but possible, 08333 that we're trying to authenticate *to* a realtime peer */ 08334 const char *peer_name = ast_strdupa(p->peer); 08335 ast_mutex_unlock(&iaxsl[callno]); 08336 if ((peer = realtime_peer(peer_name, NULL))) { 08337 ast_mutex_lock(&iaxsl[callno]); 08338 if (!(p = iaxs[callno])) { 08339 peer_unref(peer); 08340 return -1; 08341 } 08342 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 08343 peer_unref(peer); 08344 } 08345 if (!peer) { 08346 ast_mutex_lock(&iaxsl[callno]); 08347 if (!(p = iaxs[callno])) 08348 return -1; 08349 } 08350 } 08351 } 08352 08353 if (ies->encmethods) { 08354 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 08355 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 08356 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n"); 08357 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 08358 } 08359 if (!res) { 08360 struct ast_datastore *variablestore; 08361 struct ast_variable *var, *prev = NULL; 08362 AST_LIST_HEAD(, ast_var_t) *varlist; 08363 varlist = ast_calloc(1, sizeof(*varlist)); 08364 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 08365 if (variablestore && varlist && p->owner) { 08366 variablestore->data = varlist; 08367 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 08368 AST_LIST_HEAD_INIT(varlist); 08369 for (var = ies->vars; var; var = var->next) { 08370 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 08371 if (prev) 08372 ast_free(prev); 08373 prev = var; 08374 if (!newvar) { 08375 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 08376 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08377 } else { 08378 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 08379 } 08380 } 08381 if (prev) 08382 ast_free(prev); 08383 ies->vars = NULL; 08384 ast_channel_datastore_add(p->owner, variablestore); 08385 } else { 08386 if (p->owner) 08387 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08388 if (variablestore) 08389 ast_datastore_free(variablestore); 08390 if (varlist) 08391 ast_free(varlist); 08392 } 08393 } 08394 08395 if (!res) 08396 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08397 return res; 08398 }
| static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7930 of file chan_iax2.c.
References ao2_find, AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag64, ast_string_field_set, ast_test_flag64, chan_iax2_pvt::authmethods, iax_ie_data::buf, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iaxs, iax2_user::maxauthreq, OBJ_POINTER, iax_ie_data::pos, send_command(), send_command_final(), and user_unref().
Referenced by socket_process().
07931 { 07932 struct iax_ie_data ied; 07933 int res = -1, authreq_restrict = 0; 07934 char challenge[10]; 07935 struct chan_iax2_pvt *p = iaxs[call_num]; 07936 07937 memset(&ied, 0, sizeof(ied)); 07938 07939 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07940 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07941 struct iax2_user *user, tmp_user = { 07942 .name = p->username, 07943 }; 07944 07945 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07946 if (user) { 07947 if (user->curauthreq == user->maxauthreq) 07948 authreq_restrict = 1; 07949 else 07950 user->curauthreq++; 07951 user = user_unref(user); 07952 } 07953 } 07954 07955 /* If the AUTHREQ limit test failed, send back an error */ 07956 if (authreq_restrict) { 07957 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07958 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07959 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07960 return 0; 07961 } 07962 07963 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07964 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07965 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07966 ast_string_field_set(p, challenge, challenge); 07967 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07968 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07969 } 07970 if (p->encmethods) 07971 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07972 07973 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07974 07975 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07976 07977 if (p->encmethods) 07978 ast_set_flag64(p, IAX_ENCRYPTED); 07979 07980 return res; 07981 }
| static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7983 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_check_signature(), ast_clear_flag64, ast_copy_string(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_FORCE_ENCRYPT, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, secret, chan_iax2_pvt::state, and user_unref().
Referenced by socket_process().
07984 { 07985 char requeststr[256]; 07986 char md5secret[256] = ""; 07987 char secret[256] = ""; 07988 char rsasecret[256] = ""; 07989 int res = -1; 07990 int x; 07991 struct iax2_user *user, tmp_user = { 07992 .name = p->username, 07993 }; 07994 07995 if (p->authrej) { 07996 return res; 07997 } 07998 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07999 if (user) { 08000 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 08001 ast_atomic_fetchadd_int(&user->curauthreq, -1); 08002 ast_clear_flag64(p, IAX_MAXAUTHREQ); 08003 } 08004 ast_string_field_set(p, host, user->name); 08005 user = user_unref(user); 08006 } 08007 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 08008 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n"); 08009 return res; 08010 } 08011 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 08012 return res; 08013 if (ies->password) 08014 ast_copy_string(secret, ies->password, sizeof(secret)); 08015 if (ies->md5_result) 08016 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 08017 if (ies->rsa_result) 08018 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 08019 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 08020 struct ast_key *key; 08021 char *keyn; 08022 char tmpkey[256]; 08023 char *stringp=NULL; 08024 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 08025 stringp=tmpkey; 08026 keyn = strsep(&stringp, ":"); 08027 while(keyn) { 08028 key = ast_key_get(keyn, AST_KEY_PUBLIC); 08029 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 08030 res = 0; 08031 break; 08032 } else if (!key) 08033 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 08034 keyn = strsep(&stringp, ":"); 08035 } 08036 } else if (p->authmethods & IAX_AUTH_MD5) { 08037 struct MD5Context md5; 08038 unsigned char digest[16]; 08039 char *tmppw, *stringp; 08040 08041 tmppw = ast_strdupa(p->secret); 08042 stringp = tmppw; 08043 while((tmppw = strsep(&stringp, ";"))) { 08044 MD5Init(&md5); 08045 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 08046 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08047 MD5Final(digest, &md5); 08048 /* If they support md5, authenticate with it. */ 08049 for (x=0;x<16;x++) 08050 sprintf(requeststr + (x << 1), "%2.2x", (unsigned)digest[x]); /* safe */ 08051 if (!strcasecmp(requeststr, md5secret)) { 08052 res = 0; 08053 break; 08054 } 08055 } 08056 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 08057 if (!strcmp(secret, p->secret)) 08058 res = 0; 08059 } 08060 return res; 08061 }
| static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4771 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call().
04772 { 04773 #ifdef SCHED_MULTITHREADED 04774 if (schedule_action(__auto_congest, data)) 04775 #endif 04776 __auto_congest(data); 04777 return 0; 04778 }
| static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 9170 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock, ast_mutex_unlock, chan_iax2_pvt::autoid, iaxs, iaxsl, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
09171 { 09172 int callno = (int)(long)(data); 09173 ast_mutex_lock(&iaxsl[callno]); 09174 if (iaxs[callno]) { 09175 iaxs[callno]->autoid = -1; 09176 } 09177 ast_mutex_unlock(&iaxsl[callno]); 09178 #ifdef SCHED_MULTITHREADED 09179 if (schedule_action(__auto_hangup, data)) 09180 #endif 09181 __auto_hangup(data); 09182 return 0; 09183 }
| static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2542 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), addr_range::delme, addr_range::ha, addr_range::limit, LOG_ERROR, ast_variable::name, ast_variable::next, OBJ_POINTER, and ast_variable::value.
Referenced by set_config().
02543 { 02544 struct addr_range *addr_range = NULL; 02545 struct addr_range tmp; 02546 struct ast_ha *ha; 02547 int limit; 02548 int error; 02549 int found; 02550 02551 for (; v; v = v->next) { 02552 limit = -1; 02553 error = 0; 02554 found = 0; 02555 ha = ast_append_ha("permit", v->name, NULL, &error); 02556 02557 /* check for valid config information */ 02558 if (error) { 02559 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02560 continue; 02561 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02562 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02563 ast_free_ha(ha); 02564 continue; 02565 } 02566 02567 ast_copy_ha(ha, &tmp.ha); 02568 /* find or create the addr_range */ 02569 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02570 ao2_lock(addr_range); 02571 found = 1; 02572 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02573 ast_free_ha(ha); 02574 return; /* out of memory */ 02575 } 02576 02577 /* copy over config data into addr_range object */ 02578 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02579 ast_free_ha(ha); /* cleanup the tmp ha */ 02580 addr_range->limit = limit; 02581 addr_range->delme = 0; 02582 02583 /* cleanup */ 02584 if (found) { 02585 ao2_unlock(addr_range); 02586 } else { 02587 ao2_link(callno_limits, addr_range); 02588 } 02589 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02590 } 02591 }
| static struct iax2_context* build_context | ( | const char * | context | ) | [static, read] |
Definition at line 12468 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), and iax2_context::context.
Referenced by build_user().
12469 { 12470 struct iax2_context *con; 12471 12472 if ((con = ast_calloc(1, sizeof(*con)))) 12473 ast_copy_string(con->context, context, sizeof(con->context)); 12474 12475 return con; 12476 }
| static void build_ecx_key | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 6305 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), ast_aes_set_encrypt_key(), build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.
Referenced by build_encryption_keys(), and iax2_key_rotate().
06306 { 06307 /* it is required to hold the corresponding decrypt key to our encrypt key 06308 * in the pvt struct because queued frames occasionally need to be decrypted and 06309 * re-encrypted when updated for a retransmission */ 06310 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 06311 ast_aes_set_encrypt_key(digest, &pvt->ecx); 06312 ast_aes_set_decrypt_key(digest, &pvt->mydcx); 06313 }
| static void build_encryption_keys | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 6299 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
06300 { 06301 build_ecx_key(digest, pvt); 06302 ast_aes_set_decrypt_key(digest, &pvt->dcx); 06303 }
| static struct iax2_peer * build_peer | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | temponly | |||
| ) | [static, read] |
Create peer structure based on configuration.
Definition at line 12617 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, ao2_alloc, ao2_find, ast_append_ha(), ast_callerid_split(), ast_clear_flag64, ast_copy_flags64, ast_dnsmgr_lookup(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), ast_false(), ast_free_ha(), ast_get_ip(), ast_log(), ast_parse_allow_disallow(), ast_sched_thread_del, ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_setnull(), ast_sockaddr_to_sin, ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), iax2_peer::authmethods, CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, cid_name, cid_num, context, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_sockaddr::len, ast_variable::lineno, LOG_WARNING, mailbox, iax2_peer::mask, iax2_peer::maxcallno, iax2_peer::maxms, mwi_event_cb(), iax2_peer::mwi_event_sub, ast_variable::name, ast_variable::next, OBJ_POINTER, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, S_OR, secret, iax2_peer::smoothing, iax2_peer::sockfd, ast_sockaddr::ss, unlink_peer(), ast_variable::value, and zonetag.
Referenced by realtime_peer(), and set_config().
12618 { 12619 struct iax2_peer *peer = NULL; 12620 struct ast_ha *oldha = NULL; 12621 int maskfound = 0; 12622 int found = 0; 12623 int firstpass = 1; 12624 struct iax2_peer tmp_peer = { 12625 .name = name, 12626 }; 12627 12628 if (!temponly) { 12629 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 12630 if (peer && !ast_test_flag64(peer, IAX_DELME)) 12631 firstpass = 0; 12632 } 12633 12634 if (peer) { 12635 found++; 12636 if (firstpass) { 12637 oldha = peer->ha; 12638 peer->ha = NULL; 12639 } 12640 unlink_peer(peer); 12641 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 12642 peer->expire = -1; 12643 peer->pokeexpire = -1; 12644 peer->sockfd = defaultsockfd; 12645 peer->addr.ss.ss_family = AF_INET; 12646 peer->addr.len = sizeof(struct sockaddr_in); 12647 if (ast_string_field_init(peer, 32)) 12648 peer = peer_unref(peer); 12649 } 12650 12651 if (peer) { 12652 if (firstpass) { 12653 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12654 peer->encmethods = iax2_encryption; 12655 peer->adsi = adsi; 12656 ast_string_field_set(peer,secret,""); 12657 if (!found) { 12658 ast_string_field_set(peer, name, name); 12659 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12660 peer->expiry = min_reg_expire; 12661 } 12662 peer->prefs = prefs; 12663 peer->capability = iax2_capability; 12664 peer->smoothing = 0; 12665 peer->pokefreqok = DEFAULT_FREQ_OK; 12666 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 12667 peer->maxcallno = 0; 12668 peercnt_modify((unsigned char) 0, 0, &peer->addr); 12669 peer->calltoken_required = CALLTOKEN_DEFAULT; 12670 ast_string_field_set(peer,context,""); 12671 ast_string_field_set(peer,peercontext,""); 12672 ast_clear_flag64(peer, IAX_HASCALLERID); 12673 ast_string_field_set(peer, cid_name, ""); 12674 ast_string_field_set(peer, cid_num, ""); 12675 ast_string_field_set(peer, mohinterpret, mohinterpret); 12676 ast_string_field_set(peer, mohsuggest, mohsuggest); 12677 } 12678 12679 if (!v) { 12680 v = alt; 12681 alt = NULL; 12682 } 12683 while(v) { 12684 if (!strcasecmp(v->name, "secret")) { 12685 ast_string_field_set(peer, secret, v->value); 12686 } else if (!strcasecmp(v->name, "mailbox")) { 12687 ast_string_field_set(peer, mailbox, v->value); 12688 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12689 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12690 ast_string_field_set(peer, mailbox, name); 12691 } 12692 } else if (!strcasecmp(v->name, "mohinterpret")) { 12693 ast_string_field_set(peer, mohinterpret, v->value); 12694 } else if (!strcasecmp(v->name, "mohsuggest")) { 12695 ast_string_field_set(peer, mohsuggest, v->value); 12696 } else if (!strcasecmp(v->name, "dbsecret")) { 12697 ast_string_field_set(peer, dbsecret, v->value); 12698 } else if (!strcasecmp(v->name, "trunk")) { 12699 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12700 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12701 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12702 ast_clear_flag64(peer, IAX_TRUNK); 12703 } 12704 } else if (!strcasecmp(v->name, "auth")) { 12705 peer->authmethods = get_auth_methods(v->value); 12706 } else if (!strcasecmp(v->name, "encryption")) { 12707 peer->encmethods |= get_encrypt_methods(v->value); 12708 if (!peer->encmethods) { 12709 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12710 } 12711 } else if (!strcasecmp(v->name, "forceencryption")) { 12712 if (ast_false(v->value)) { 12713 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12714 } else { 12715 peer->encmethods |= get_encrypt_methods(v->value); 12716 if (peer->encmethods) { 12717 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12718 } 12719 } 12720 } else if (!strcasecmp(v->name, "transfer")) { 12721 if (!strcasecmp(v->value, "mediaonly")) { 12722 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12723 } else if (ast_true(v->value)) { 12724 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12725 } else 12726 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12727 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12728 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12729 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12730 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12731 } else if (!strcasecmp(v->name, "host")) { 12732 if (!strcasecmp(v->value, "dynamic")) { 12733 /* They'll register with us */ 12734 ast_set_flag64(peer, IAX_DYNAMIC); 12735 if (!found) { 12736 /* Initialize stuff iff we're not found, otherwise 12737 we keep going with what we had */ 12738 if (ast_sockaddr_port(&peer->addr)) { 12739 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr)); 12740 } 12741 ast_sockaddr_setnull(&peer->addr); 12742 } 12743 } else { 12744 /* Non-dynamic. Make sure we become that way if we're not */ 12745 ast_sched_thread_del(sched, peer->expire); 12746 ast_clear_flag64(peer, IAX_DYNAMIC); 12747 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12748 return peer_unref(peer); 12749 if (!ast_sockaddr_port(&peer->addr)) { 12750 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12751 } 12752 } 12753 if (!maskfound) 12754 inet_aton("255.255.255.255", &peer->mask); 12755 } else if (!strcasecmp(v->name, "defaultip")) { 12756 struct ast_sockaddr peer_defaddr_tmp; 12757 12758 peer_defaddr_tmp.ss.ss_family = AF_INET; 12759 if (ast_get_ip(&peer_defaddr_tmp, v->value)) { 12760 return peer_unref(peer); 12761 } 12762 ast_sockaddr_to_sin(&peer_defaddr_tmp, 12763 &peer->defaddr); 12764 } else if (!strcasecmp(v->name, "sourceaddress")) { 12765 peer_set_srcaddr(peer, v->value); 12766 } else if (!strcasecmp(v->name, "permit") || 12767 !strcasecmp(v->name, "deny")) { 12768 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12769 } else if (!strcasecmp(v->name, "mask")) { 12770 maskfound++; 12771 inet_aton(v->value, &peer->mask); 12772 } else if (!strcasecmp(v->name, "context")) { 12773 ast_string_field_set(peer, context, v->value); 12774 } else if (!strcasecmp(v->name, "regexten")) { 12775 ast_string_field_set(peer, regexten, v->value); 12776 } else if (!strcasecmp(v->name, "peercontext")) { 12777 ast_string_field_set(peer, peercontext, v->value); 12778 } else if (!strcasecmp(v->name, "port")) { 12779 if (ast_test_flag64(peer, IAX_DYNAMIC)) { 12780 peer->defaddr.sin_port = htons(atoi(v->value)); 12781 } else { 12782 ast_sockaddr_set_port(&peer->addr, atoi(v->value)); 12783 } 12784 } else if (!strcasecmp(v->name, "username")) { 12785 ast_string_field_set(peer, username, v->value); 12786 } else if (!strcasecmp(v->name, "allow")) { 12787 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12788 } else if (!strcasecmp(v->name, "disallow")) { 12789 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12790 } else if (!strcasecmp(v->name, "callerid")) { 12791 if (!ast_strlen_zero(v->value)) { 12792 char name2[80]; 12793 char num2[80]; 12794 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12795 ast_string_field_set(peer, cid_name, name2); 12796 ast_string_field_set(peer, cid_num, num2); 12797 } else { 12798 ast_string_field_set(peer, cid_name, ""); 12799 ast_string_field_set(peer, cid_num, ""); 12800 } 12801 ast_set_flag64(peer, IAX_HASCALLERID); 12802 } else if (!strcasecmp(v->name, "fullname")) { 12803 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12804 ast_set_flag64(peer, IAX_HASCALLERID); 12805 } else if (!strcasecmp(v->name, "cid_number")) { 12806 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12807 ast_set_flag64(peer, IAX_HASCALLERID); 12808 } else if (!strcasecmp(v->name, "sendani")) { 12809 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12810 } else if (!strcasecmp(v->name, "inkeys")) { 12811 ast_string_field_set(peer, inkeys, v->value); 12812 } else if (!strcasecmp(v->name, "outkey")) { 12813 ast_string_field_set(peer, outkey, v->value); 12814 } else if (!strcasecmp(v->name, "qualify")) { 12815 if (!strcasecmp(v->value, "no")) { 12816 peer->maxms = 0; 12817 } else if (!strcasecmp(v->value, "yes")) { 12818 peer->maxms = DEFAULT_MAXMS; 12819 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12820 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); 12821 peer->maxms = 0; 12822 } 12823 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12824 peer->smoothing = ast_true(v->value); 12825 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12826 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12827 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); 12828 } 12829 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12830 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12831 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); 12832 } 12833 } else if (!strcasecmp(v->name, "timezone")) { 12834 ast_string_field_set(peer, zonetag, v->value); 12835 } else if (!strcasecmp(v->name, "adsi")) { 12836 peer->adsi = ast_true(v->value); 12837 } else if (!strcasecmp(v->name, "connectedline")) { 12838 if (ast_true(v->value)) { 12839 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12840 } else if (!strcasecmp(v->value, "send")) { 12841 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12842 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12843 } else if (!strcasecmp(v->value, "receive")) { 12844 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12845 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12846 } else { 12847 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12848 } 12849 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12850 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12851 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12852 } else { 12853 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr); 12854 } 12855 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12856 /* default is required unless in optional ip list */ 12857 if (ast_false(v->value)) { 12858 peer->calltoken_required = CALLTOKEN_NO; 12859 } else if (!strcasecmp(v->value, "auto")) { 12860 peer->calltoken_required = CALLTOKEN_AUTO; 12861 } else if (ast_true(v->value)) { 12862 peer->calltoken_required = CALLTOKEN_YES; 12863 } else { 12864 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12865 } 12866 } /* else if (strcasecmp(v->name,"type")) */ 12867 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12868 v = v->next; 12869 if (!v) { 12870 v = alt; 12871 alt = NULL; 12872 } 12873 } 12874 if (!peer->authmethods) 12875 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12876 ast_clear_flag64(peer, IAX_DELME); 12877 } 12878 12879 if (oldha) 12880 ast_free_ha(oldha); 12881 12882 if (!ast_strlen_zero(peer->mailbox)) { 12883 char *mailbox, *context; 12884 context = mailbox = ast_strdupa(peer->mailbox); 12885 strsep(&context, "@"); 12886 if (ast_strlen_zero(context)) 12887 context = "default"; 12888 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12889 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12890 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12891 AST_EVENT_IE_END); 12892 } 12893 12894 return peer; 12895 }
| static void build_rand_pad | ( | unsigned char * | buf, | |
| ssize_t | len | |||
| ) | [static] |
Definition at line 6289 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
06290 { 06291 long tmp; 06292 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 06293 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 06294 buf += sizeof(tmp); 06295 len -= sizeof(tmp); 06296 } 06297 }
| static struct iax2_user * build_user | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | temponly | |||
| ) | [static, read] |
Create in-memory user structure from configuration.
Definition at line 12911 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ao2_alloc, ao2_find, ao2_unlink, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag64, ast_copy_flags64, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_user::calltoken_required, CALLTOKEN_YES, iax2_user::capability, cid_name, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, ast_variable::lineno, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, iax2_context::next, OBJ_POINTER, parkinglot, prefs, iax2_user::prefs, secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.
Referenced by realtime_user(), and set_config().
12912 { 12913 struct iax2_user *user = NULL; 12914 struct iax2_context *con, *conl = NULL; 12915 struct ast_ha *oldha = NULL; 12916 struct iax2_context *oldcon = NULL; 12917 int format; 12918 int firstpass=1; 12919 int oldcurauthreq = 0; 12920 char *varname = NULL, *varval = NULL; 12921 struct ast_variable *tmpvar = NULL; 12922 struct iax2_user tmp_user = { 12923 .name = name, 12924 }; 12925 12926 if (!temponly) { 12927 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12928 if (user && !ast_test_flag64(user, IAX_DELME)) 12929 firstpass = 0; 12930 } 12931 12932 if (user) { 12933 if (firstpass) { 12934 oldcurauthreq = user->curauthreq; 12935 oldha = user->ha; 12936 oldcon = user->contexts; 12937 user->ha = NULL; 12938 user->contexts = NULL; 12939 } 12940 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12941 ao2_unlink(users, user); 12942 } else { 12943 user = ao2_alloc(sizeof(*user), user_destructor); 12944 } 12945 12946 if (user) { 12947 if (firstpass) { 12948 ast_string_field_free_memory(user); 12949 memset(user, 0, sizeof(struct iax2_user)); 12950 if (ast_string_field_init(user, 32)) { 12951 user = user_unref(user); 12952 goto cleanup; 12953 } 12954 user->maxauthreq = maxauthreq; 12955 user->curauthreq = oldcurauthreq; 12956 user->prefs = prefs; 12957 user->capability = iax2_capability; 12958 user->encmethods = iax2_encryption; 12959 user->adsi = adsi; 12960 user->calltoken_required = CALLTOKEN_DEFAULT; 12961 ast_string_field_set(user, name, name); 12962 ast_string_field_set(user, language, language); 12963 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); 12964 ast_clear_flag64(user, IAX_HASCALLERID); 12965 ast_string_field_set(user, cid_name, ""); 12966 ast_string_field_set(user, cid_num, ""); 12967 ast_string_field_set(user, accountcode, accountcode); 12968 ast_string_field_set(user, mohinterpret, mohinterpret); 12969 ast_string_field_set(user, mohsuggest, mohsuggest); 12970 } 12971 if (!v) { 12972 v = alt; 12973 alt = NULL; 12974 } 12975 while(v) { 12976 if (!strcasecmp(v->name, "context")) { 12977 con = build_context(v->value); 12978 if (con) { 12979 if (conl) 12980 conl->next = con; 12981 else 12982 user->contexts = con; 12983 conl = con; 12984 } 12985 } else if (!strcasecmp(v->name, "permit") || 12986 !strcasecmp(v->name, "deny")) { 12987 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12988 } else if (!strcasecmp(v->name, "setvar")) { 12989 varname = ast_strdupa(v->value); 12990 if ((varval = strchr(varname, '='))) { 12991 *varval = '\0'; 12992 varval++; 12993 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12994 tmpvar->next = user->vars; 12995 user->vars = tmpvar; 12996 } 12997 } 12998 } else if (!strcasecmp(v->name, "allow")) { 12999 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 13000 } else if (!strcasecmp(v->name, "disallow")) { 13001 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 13002 } else if (!strcasecmp(v->name, "trunk")) { 13003 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 13004 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 13005 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 13006 ast_clear_flag64(user, IAX_TRUNK); 13007 } 13008 } else if (!strcasecmp(v->name, "auth")) { 13009 user->authmethods = get_auth_methods(v->value); 13010 } else if (!strcasecmp(v->name, "encryption")) { 13011 user->encmethods |= get_encrypt_methods(v->value); 13012 if (!user->encmethods) { 13013 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 13014 } 13015 } else if (!strcasecmp(v->name, "forceencryption")) { 13016 if (ast_false(v->value)) { 13017 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 13018 } else { 13019 user->encmethods |= get_encrypt_methods(v->value); 13020 if (user->encmethods) { 13021 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 13022 } 13023 } 13024 } else if (!strcasecmp(v->name, "transfer")) { 13025 if (!strcasecmp(v->value, "mediaonly")) { 13026 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13027 } else if (ast_true(v->value)) { 13028 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13029 } else 13030 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13031 } else if (!strcasecmp(v->name, "codecpriority")) { 13032 if(!strcasecmp(v->value, "caller")) 13033 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 13034 else if(!strcasecmp(v->value, "disabled")) 13035 ast_set_flag64(user, IAX_CODEC_NOPREFS); 13036 else if(!strcasecmp(v->value, "reqonly")) { 13037 ast_set_flag64(user, IAX_CODEC_NOCAP); 13038 ast_set_flag64(user, IAX_CODEC_NOPREFS); 13039 } 13040 } else if (!strcasecmp(v->name, "immediate")) { 13041 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 13042 } else if (!strcasecmp(v->name, "jitterbuffer")) { 13043 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 13044 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 13045 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 13046 } else if (!strcasecmp(v->name, "dbsecret")) { 13047 ast_string_field_set(user, dbsecret, v->value); 13048 } else if (!strcasecmp(v->name, "secret")) { 13049 if (!ast_strlen_zero(user->secret)) { 13050 char *old = ast_strdupa(user->secret); 13051 13052 ast_string_field_build(user, secret, "%s;%s", old, v->value); 13053 } else 13054 ast_string_field_set(user, secret, v->value); 13055 } else if (!strcasecmp(v->name, "callerid")) { 13056 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 13057 char name2[80]; 13058 char num2[80]; 13059 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 13060 ast_string_field_set(user, cid_name, name2); 13061 ast_string_field_set(user, cid_num, num2); 13062 ast_set_flag64(user, IAX_HASCALLERID); 13063 } else { 13064 ast_clear_flag64(user, IAX_HASCALLERID); 13065 ast_string_field_set(user, cid_name, ""); 13066 ast_string_field_set(user, cid_num, ""); 13067 } 13068 } else if (!strcasecmp(v->name, "fullname")) { 13069 if (!ast_strlen_zero(v->value)) { 13070 ast_string_field_set(user, cid_name, v->value); 13071 ast_set_flag64(user, IAX_HASCALLERID); 13072 } else { 13073 ast_string_field_set(user, cid_name, ""); 13074 if (ast_strlen_zero(user->cid_num)) 13075 ast_clear_flag64(user, IAX_HASCALLERID); 13076 } 13077 } else if (!strcasecmp(v->name, "cid_number")) { 13078 if (!ast_strlen_zero(v->value)) { 13079 ast_string_field_set(user, cid_num, v->value); 13080 ast_set_flag64(user, IAX_HASCALLERID); 13081 } else { 13082 ast_string_field_set(user, cid_num, ""); 13083 if (ast_strlen_zero(user->cid_name)) 13084 ast_clear_flag64(user, IAX_HASCALLERID); 13085 } 13086 } else if (!strcasecmp(v->name, "accountcode")) { 13087 ast_string_field_set(user, accountcode, v->value); 13088 } else if (!strcasecmp(v->name, "mohinterpret")) { 13089 ast_string_field_set(user, mohinterpret, v->value); 13090 } else if (!strcasecmp(v->name, "mohsuggest")) { 13091 ast_string_field_set(user, mohsuggest, v->value); 13092 } else if (!strcasecmp(v->name, "parkinglot")) { 13093 ast_string_field_set(user, parkinglot, v->value); 13094 } else if (!strcasecmp(v->name, "language")) { 13095 ast_string_field_set(user, language, v->value); 13096 } else if (!strcasecmp(v->name, "amaflags")) { 13097 format = ast_cdr_amaflags2int(v->value); 13098 if (format < 0) { 13099 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13100 } else { 13101 user->amaflags = format; 13102 } 13103 } else if (!strcasecmp(v->name, "inkeys")) { 13104 ast_string_field_set(user, inkeys, v->value); 13105 } else if (!strcasecmp(v->name, "maxauthreq")) { 13106 user->maxauthreq = atoi(v->value); 13107 if (user->maxauthreq < 0) 13108 user->maxauthreq = 0; 13109 } else if (!strcasecmp(v->name, "adsi")) { 13110 user->adsi = ast_true(v->value); 13111 } else if (!strcasecmp(v->name, "connectedline")) { 13112 if (ast_true(v->value)) { 13113 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13114 } else if (!strcasecmp(v->value, "send")) { 13115 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 13116 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 13117 } else if (!strcasecmp(v->value, "receive")) { 13118 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 13119 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 13120 } else { 13121 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13122 } 13123 } else if (!strcasecmp(v->name, "requirecalltoken")) { 13124 /* default is required unless in optional ip list */ 13125 if (ast_false(v->value)) { 13126 user->calltoken_required = CALLTOKEN_NO; 13127 } else if (!strcasecmp(v->value, "auto")) { 13128 user->calltoken_required = CALLTOKEN_AUTO; 13129 } else if (ast_true(v->value)) { 13130 user->calltoken_required = CALLTOKEN_YES; 13131 } else { 13132 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 13133 } 13134 } /* else if (strcasecmp(v->name,"type")) */ 13135 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13136 v = v->next; 13137 if (!v) { 13138 v = alt; 13139 alt = NULL; 13140 } 13141 } 13142 if (!user->authmethods) { 13143 if (!ast_strlen_zero(user->secret)) { 13144 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 13145 if (!ast_strlen_zero(user->inkeys)) 13146 user->authmethods |= IAX_AUTH_RSA; 13147 } else if (!ast_strlen_zero(user->inkeys)) { 13148 user->authmethods = IAX_AUTH_RSA; 13149 } else { 13150 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 13151 } 13152 } 13153 ast_clear_flag64(user, IAX_DELME); 13154 } 13155 cleanup: 13156 if (oldha) 13157 ast_free_ha(oldha); 13158 if (oldcon) 13159 free_context(oldcon); 13160 return user; 13161 }
| static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13808 of file chan_iax2.c.
References add_empty_calltoken_ie(), ARRAY_LEN, ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_trylock, ast_mutex_unlock, ast_strdupa, ast_string_field_set, ast_strlen_zero(), iax_ie_data::buf, chan_iax2_pvt::capability, parsed_dial_string::context, create_addr(), parsed_dial_string::exten, find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, iaxs, iaxsl, parsed_dial_string::key, LOG_WARNING, NEW_FORCE, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, iax_ie_data::pos, secret, send_command(), create_addr_info::sockfd, and parsed_dial_string::username.
Referenced by find_cache().
13809 { 13810 struct sockaddr_in sin; 13811 int x; 13812 int callno; 13813 struct iax_ie_data ied; 13814 struct create_addr_info cai; 13815 struct parsed_dial_string pds; 13816 char *tmpstr; 13817 13818 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13819 /* Look for an *exact match* call. Once a call is negotiated, it can only 13820 look up entries for a single context */ 13821 if (!ast_mutex_trylock(&iaxsl[x])) { 13822 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13823 return x; 13824 ast_mutex_unlock(&iaxsl[x]); 13825 } 13826 } 13827 13828 /* No match found, we need to create a new one */ 13829 13830 memset(&cai, 0, sizeof(cai)); 13831 memset(&ied, 0, sizeof(ied)); 13832 memset(&pds, 0, sizeof(pds)); 13833 13834 tmpstr = ast_strdupa(data); 13835 parse_dial_string(tmpstr, &pds); 13836 13837 if (ast_strlen_zero(pds.peer)) { 13838 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13839 return -1; 13840 } 13841 13842 /* Populate our address from the given */ 13843 if (create_addr(pds.peer, NULL, &sin, &cai)) 13844 return -1; 13845 13846 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13847 pds.peer, pds.username, pds.password, pds.context); 13848 13849 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13850 if (callno < 1) { 13851 ast_log(LOG_WARNING, "Unable to create call\n"); 13852 return -1; 13853 } 13854 13855 ast_string_field_set(iaxs[callno], dproot, data); 13856 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13857 13858 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13859 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13860 /* the string format is slightly different from a standard dial string, 13861 because the context appears in the 'exten' position 13862 */ 13863 if (pds.exten) 13864 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13865 if (pds.username) 13866 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13867 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13868 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13869 /* Keep password handy */ 13870 if (pds.password) 13871 ast_string_field_set(iaxs[callno], secret, pds.password); 13872 if (pds.key) 13873 ast_string_field_set(iaxs[callno], outkey, pds.key); 13874 /* Start the call going */ 13875 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13876 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13877 13878 return callno; 13879 }
| static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | offset | |||
| ) | [static] |
Definition at line 6142 of file chan_iax2.c.
References ast_debug, ast_random(), ast_samp2tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, and chan_iax2_pvt::rxcore.
Referenced by schedule_delivery().
06143 { 06144 /* Returns where in "receive time" we are. That is, how many ms 06145 since we received (or would have received) the frame with timestamp 0 */ 06146 int ms; 06147 #ifdef IAXTESTS 06148 int jit; 06149 #endif /* IAXTESTS */ 06150 /* Setup rxcore if necessary */ 06151 if (ast_tvzero(p->rxcore)) { 06152 p->rxcore = ast_tvnow(); 06153 if (iaxdebug) 06154 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %ums\n", 06155 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 06156 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 06157 #if 1 06158 if (iaxdebug) 06159 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 06160 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 06161 #endif 06162 } 06163 06164 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 06165 #ifdef IAXTESTS 06166 if (test_jit) { 06167 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 06168 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 06169 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 06170 jit = -jit; 06171 ms += jit; 06172 } 06173 } 06174 if (test_late) { 06175 ms += test_late; 06176 test_late = 0; 06177 } 06178 #endif /* IAXTESTS */ 06179 return ms; 06180 }
| static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | ts, | |||
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 6010 of file chan_iax2.c.
References ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, ast_frame_subclass::codec, ast_frame::delivery, ast_frame::frametype, iaxs, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, chan_iax2_pvt::peercallno, ast_frame::samples, and ast_frame::subclass.
Referenced by iax2_send(), and socket_process().
06011 { 06012 int ms; 06013 int voice = 0; 06014 int genuine = 0; 06015 int adjust; 06016 int rate = ast_format_rate(f->subclass.codec) / 1000; 06017 struct timeval *delivery = NULL; 06018 06019 06020 /* What sort of frame do we have?: voice is self-explanatory 06021 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 06022 non-genuine frames are CONTROL frames [ringing etc], DTMF 06023 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 06024 the others need a timestamp slaved to the voice frames so that they go in sequence 06025 */ 06026 if (f->frametype == AST_FRAME_VOICE) { 06027 voice = 1; 06028 delivery = &f->delivery; 06029 } else if (f->frametype == AST_FRAME_IAX) { 06030 genuine = 1; 06031 } else if (f->frametype == AST_FRAME_CNG) { 06032 p->notsilenttx = 0; 06033 } 06034 06035 if (ast_tvzero(p->offset)) { 06036 p->offset = ast_tvnow(); 06037 /* Round to nearest 20ms for nice looking traces */ 06038 p->offset.tv_usec -= p->offset.tv_usec % 20000; 06039 } 06040 /* If the timestamp is specified, just send it as is */ 06041 if (ts) 06042 return ts; 06043 /* If we have a time that the frame arrived, always use it to make our timestamp */ 06044 if (delivery && !ast_tvzero(*delivery)) { 06045 ms = ast_tvdiff_ms(*delivery, p->offset); 06046 if (ms < 0) { 06047 ms = 0; 06048 } 06049 if (iaxdebug) 06050 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 06051 } else { 06052 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 06053 if (ms < 0) 06054 ms = 0; 06055 if (voice) { 06056 /* On a voice frame, use predicted values if appropriate */ 06057 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 06058 /* Adjust our txcore, keeping voice and non-voice synchronized */ 06059 /* AN EXPLANATION: 06060 When we send voice, we usually send "calculated" timestamps worked out 06061 on the basis of the number of samples sent. When we send other frames, 06062 we usually send timestamps worked out from the real clock. 06063 The problem is that they can tend to drift out of step because the 06064 source channel's clock and our clock may not be exactly at the same rate. 06065 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 06066 for this call. Moving it adjusts timestamps for non-voice frames. 06067 We make the adjustment in the style of a moving average. Each time we 06068 adjust p->offset by 10% of the difference between our clock-derived 06069 timestamp and the predicted timestamp. That's why you see "10000" 06070 below even though IAX2 timestamps are in milliseconds. 06071 The use of a moving average avoids offset moving too radically. 06072 Generally, "adjust" roams back and forth around 0, with offset hardly 06073 changing at all. But if a consistent different starts to develop it 06074 will be eliminated over the course of 10 frames (200-300msecs) 06075 */ 06076 adjust = (ms - p->nextpred); 06077 if (adjust < 0) 06078 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 06079 else if (adjust > 0) 06080 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 06081 06082 if (!p->nextpred) { 06083 p->nextpred = ms; /*f->samples / rate;*/ 06084 if (p->nextpred <= p->lastsent) 06085 p->nextpred = p->lastsent + 3; 06086 } 06087 ms = p->nextpred; 06088 } else { 06089 /* in this case, just use the actual 06090 * time, since we're either way off 06091 * (shouldn't happen), or we're ending a 06092 * silent period -- and seed the next 06093 * predicted time. Also, round ms to the 06094 * next multiple of frame size (so our 06095 * silent periods are multiples of 06096 * frame size too) */ 06097 06098 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 06099 ast_debug(1, "predicted timestamp skew (%d) > max (%d), using real ts instead.\n", 06100 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 06101 06102 if (f->samples >= rate) /* check to make sure we don't core dump */ 06103 { 06104 int diff = ms % (f->samples / rate); 06105 if (diff) 06106 ms += f->samples/rate - diff; 06107 } 06108 06109 p->nextpred = ms; 06110 p->notsilenttx = 1; 06111 } 06112 } else if ( f->frametype == AST_FRAME_VIDEO ) { 06113 /* 06114 * IAX2 draft 03 says that timestamps MUST be in order. 06115 * It does not say anything about several frames having the same timestamp 06116 * When transporting video, we can have a frame that spans multiple iax packets 06117 * (so called slices), so it would make sense to use the same timestamp for all of 06118 * them 06119 * We do want to make sure that frames don't go backwards though 06120 */ 06121 if ( (unsigned int)ms < p->lastsent ) 06122 ms = p->lastsent; 06123 } else { 06124 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 06125 it's a genuine frame */ 06126 if (genuine) { 06127 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 06128 if (ms <= p->lastsent) 06129 ms = p->lastsent + 3; 06130 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 06131 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 06132 ms = p->lastsent + 3; 06133 } 06134 } 06135 } 06136 p->lastsent = ms; 06137 if (voice) 06138 p->nextpred = p->nextpred + f->samples / rate; 06139 return ms; 06140 }
| static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
| int | sampms, | |||
| struct timeval * | now | |||
| ) | [static] |
Definition at line 5966 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.
Referenced by send_trunk().
05967 { 05968 unsigned long int mssincetx; /* unsigned to handle overflows */ 05969 long int ms, pred; 05970 05971 tpeer->trunkact = *now; 05972 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05973 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05974 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05975 tpeer->txtrunktime = *now; 05976 tpeer->lastsent = 999999; 05977 } 05978 /* Update last transmit time now */ 05979 tpeer->lasttxtime = *now; 05980 05981 /* Calculate ms offset */ 05982 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05983 /* Predict from last value */ 05984 pred = tpeer->lastsent + sampms; 05985 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05986 ms = pred; 05987 05988 /* We never send the same timestamp twice, so fudge a little if we must */ 05989 if (ms == tpeer->lastsent) 05990 ms = tpeer->lastsent + 1; 05991 tpeer->lastsent = ms; 05992 return ms; 05993 }
| static int callno_hash | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2765 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02766 { 02767 return abs(ast_random()); 02768 }
| static int calltoken_required | ( | struct sockaddr_in * | sin, | |
| const char * | name, | |||
| int | subclass | |||
| ) | [static] |
Definition at line 2289 of file chan_iax2.c.
References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, iax2_user::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), realtime_peer(), realtime_user(), S_OR, and user_unref().
Referenced by handle_call_token().
02290 { 02291 struct addr_range *addr_range; 02292 struct iax2_peer *peer = NULL; 02293 struct iax2_user *user = NULL; 02294 /* if no username is given, check for guest accounts */ 02295 const char *find = S_OR(name, "guest"); 02296 int res = 1; /* required by default */ 02297 int optional = 0; 02298 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 02299 /* There are only two cases in which calltoken validation is not required. 02300 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 02301 * the peer definition has not set the requirecalltoken option. 02302 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 02303 */ 02304 02305 /* ----- Case 1 ----- */ 02306 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 02307 ao2_ref(addr_range, -1); 02308 optional = 1; 02309 } 02310 02311 /* ----- Case 2 ----- */ 02312 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 02313 calltoken_required = user->calltoken_required; 02314 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 02315 calltoken_required = user->calltoken_required; 02316 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 02317 calltoken_required = peer->calltoken_required; 02318 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 02319 calltoken_required = peer->calltoken_required; 02320 } 02321 02322 if (peer) { 02323 peer_unref(peer); 02324 } 02325 if (user) { 02326 user_unref(user); 02327 } 02328 02329 ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %u\n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required); 02330 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 02331 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 02332 res = 0; 02333 } 02334 02335 return res; 02336 }
| static int check_access | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7662 of file chan_iax2.c.
References iax2_user::adsi, chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags64, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_SENSE_ALLOW, AST_SENSE_DENY, ast_set2_flag64, ast_set_flag64, ast_shrink_phone_number(), ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, iax2_context::context, context, iax2_user::contexts, DEFAULT_CONTEXT, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iax_ies::language, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, ast_variable::next, parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, user_unref(), iax_ies::username, ast_variable::value, iax2_user::vars, iax_ies::version, and version.
Referenced by socket_process().
07663 { 07664 /* Start pessimistic */ 07665 int res = -1; 07666 int version = 2; 07667 struct iax2_user *user = NULL, *best = NULL; 07668 int bestscore = 0; 07669 int gotcapability = 0; 07670 struct ast_variable *v = NULL, *tmpvar = NULL; 07671 struct ao2_iterator i; 07672 struct ast_sockaddr addr; 07673 07674 if (!iaxs[callno]) 07675 return res; 07676 if (ies->called_number) 07677 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07678 if (ies->calling_number) { 07679 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07680 ast_shrink_phone_number(ies->calling_number); 07681 } 07682 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07683 } 07684 if (ies->calling_name) 07685 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07686 if (ies->calling_ani) 07687 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07688 if (ies->dnid) 07689 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07690 if (ies->rdnis) 07691 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07692 if (ies->called_context) 07693 ast_string_field_set(iaxs[callno], context, ies->called_context); 07694 if (ies->language) 07695 ast_string_field_set(iaxs[callno], language, ies->language); 07696 if (ies->username) 07697 ast_string_field_set(iaxs[callno], username, ies->username); 07698 if (ies->calling_ton > -1) 07699 iaxs[callno]->calling_ton = ies->calling_ton; 07700 if (ies->calling_tns > -1) 07701 iaxs[callno]->calling_tns = ies->calling_tns; 07702 if (ies->calling_pres > -1) 07703 iaxs[callno]->calling_pres = ies->calling_pres; 07704 if (ies->format) 07705 iaxs[callno]->peerformat = ies->format; 07706 if (ies->adsicpe) 07707 iaxs[callno]->peeradsicpe = ies->adsicpe; 07708 if (ies->capability) { 07709 gotcapability = 1; 07710 iaxs[callno]->peercapability = ies->capability; 07711 } 07712 if (ies->version) 07713 version = ies->version; 07714 07715 /* Use provided preferences until told otherwise for actual preferences */ 07716 if (ies->codec_prefs) { 07717 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07718 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07719 } 07720 07721 if (!gotcapability) 07722 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07723 if (version > IAX_PROTO_VERSION) { 07724 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07725 ast_inet_ntoa(sin->sin_addr), version); 07726 return res; 07727 } 07728 /* Search the userlist for a compatible entry, and fill in the rest */ 07729 ast_sockaddr_from_sin(&addr, sin); 07730 i = ao2_iterator_init(users, 0); 07731 while ((user = ao2_iterator_next(&i))) { 07732 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07733 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07734 && ast_apply_ha(user->ha, &addr) == AST_SENSE_ALLOW /* Access is permitted from this IP */ 07735 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07736 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07737 if (!ast_strlen_zero(iaxs[callno]->username)) { 07738 /* Exact match, stop right now. */ 07739 if (best) 07740 user_unref(best); 07741 best = user; 07742 break; 07743 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07744 /* No required authentication */ 07745 if (user->ha) { 07746 /* There was host authentication and we passed, bonus! */ 07747 if (bestscore < 4) { 07748 bestscore = 4; 07749 if (best) 07750 user_unref(best); 07751 best = user; 07752 continue; 07753 } 07754 } else { 07755 /* No host access, but no secret, either, not bad */ 07756 if (bestscore < 3) { 07757 bestscore = 3; 07758 if (best) 07759 user_unref(best); 07760 best = user; 07761 continue; 07762 } 07763 } 07764 } else { 07765 if (user->ha) { 07766 /* Authentication, but host access too, eh, it's something.. */ 07767 if (bestscore < 2) { 07768 bestscore = 2; 07769 if (best) 07770 user_unref(best); 07771 best = user; 07772 continue; 07773 } 07774 } else { 07775 /* Authentication and no host access... This is our baseline */ 07776 if (bestscore < 1) { 07777 bestscore = 1; 07778 if (best) 07779 user_unref(best); 07780 best = user; 07781 continue; 07782 } 07783 } 07784 } 07785 } 07786 user_unref(user); 07787 } 07788 ao2_iterator_destroy(&i); 07789 user = best; 07790 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07791 user = realtime_user(iaxs[callno]->username, sin); 07792 if (user && (ast_apply_ha(user->ha, &addr) == AST_SENSE_DENY /* Access is denied from this IP */ 07793 || (!ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07794 !apply_context(user->contexts, iaxs[callno]->context)))) { /* Context is permitted */ 07795 user = user_unref(user); 07796 } 07797 } 07798 if (user) { 07799 /* We found our match (use the first) */ 07800 /* copy vars */ 07801 for (v = user->vars ; v ; v = v->next) { 07802 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07803 tmpvar->next = iaxs[callno]->vars; 07804 iaxs[callno]->vars = tmpvar; 07805 } 07806 } 07807 /* If a max AUTHREQ restriction is in place, activate it */ 07808 if (user->maxauthreq > 0) 07809 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07810 iaxs[callno]->prefs = user->prefs; 07811 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07812 iaxs[callno]->encmethods = user->encmethods; 07813 /* Store the requested username if not specified */ 07814 if (ast_strlen_zero(iaxs[callno]->username)) 07815 ast_string_field_set(iaxs[callno], username, user->name); 07816 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07817 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07818 iaxs[callno]->capability = user->capability; 07819 /* And use the default context */ 07820 if (ast_strlen_zero(iaxs[callno]->context)) { 07821 if (user->contexts) 07822 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07823 else 07824 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07825 } 07826 /* And any input keys */ 07827 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07828 /* And the permitted authentication methods */ 07829 iaxs[callno]->authmethods = user->authmethods; 07830 iaxs[callno]->adsi = user->adsi; 07831 /* If the user has callerid, override the remote caller id. */ 07832 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07833 iaxs[callno]->calling_tns = 0; 07834 iaxs[callno]->calling_ton = 0; 07835 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07836 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07837 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07838 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07839 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07840 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07841 } /* else user is allowed to set their own CID settings */ 07842 if (!ast_strlen_zero(user->accountcode)) 07843 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07844 if (!ast_strlen_zero(user->mohinterpret)) 07845 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07846 if (!ast_strlen_zero(user->mohsuggest)) 07847 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07848 if (!ast_strlen_zero(user->parkinglot)) 07849 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07850 if (user->amaflags) 07851 iaxs[callno]->amaflags = user->amaflags; 07852 if (!ast_strlen_zero(user->language)) 07853 ast_string_field_set(iaxs[callno], language, user->language); 07854 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07855 /* Keep this check last */ 07856 if (!ast_strlen_zero(user->dbsecret)) { 07857 char *family, *key=NULL; 07858 char buf[80]; 07859 family = ast_strdupa(user->dbsecret); 07860 key = strchr(family, '/'); 07861 if (key) { 07862 *key = '\0'; 07863 key++; 07864 } 07865 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07866 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07867 else 07868 ast_string_field_set(iaxs[callno], secret, buf); 07869 } else 07870 ast_string_field_set(iaxs[callno], secret, user->secret); 07871 res = 0; 07872 user = user_unref(user); 07873 } else { 07874 /* user was not found, but we should still fake an AUTHREQ. 07875 * Set authmethods to the last known authmethod used by the system 07876 * Set a fake secret, it's not looked at, just required to attempt authentication. 07877 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07878 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07879 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07880 iaxs[callno]->authrej = 1; 07881 if (!ast_strlen_zero(iaxs[callno]->username)) { 07882 /* only send the AUTHREQ if a username was specified. */ 07883 res = 0; 07884 } 07885 } 07886 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07887 return res; 07888 }
| static int check_provisioning | ( | struct sockaddr_in * | sin, | |
| int | sockfd, | |||
| char * | si, | |||
| unsigned int | ver | |||
| ) | [static] |
Definition at line 9540 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09541 { 09542 unsigned int ourver; 09543 char rsi[80]; 09544 snprintf(rsi, sizeof(rsi), "si-%s", si); 09545 if (iax_provision_version(&ourver, rsi, 1)) 09546 return 0; 09547 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09548 if (ourver != ver) 09549 iax2_provision(sin, sockfd, NULL, rsi, 1); 09550 return 0; 09551 }
| static int check_srcaddr | ( | struct sockaddr * | sa, | |
| socklen_t | salen | |||
| ) | [static] |
Check if address can be used as packet source.
Definition at line 12494 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
12495 { 12496 int sd; 12497 int res; 12498 12499 sd = socket(AF_INET, SOCK_DGRAM, 0); 12500 if (sd < 0) { 12501 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 12502 return -1; 12503 } 12504 12505 res = bind(sd, sa, salen); 12506 if (res < 0) { 12507 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 12508 close(sd); 12509 return 1; 12510 } 12511 12512 close(sd); 12513 return 0; 12514 }
| static void cleanup_thread_list | ( | void * | head | ) | [static] |
Definition at line 14548 of file chan_iax2.c.
References AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, signal_condition(), and thread.
Referenced by __unload_module().
14549 { 14550 AST_LIST_HEAD(iax2_thread_list, iax2_thread); 14551 struct iax2_thread_list *list_head = head; 14552 struct iax2_thread *thread; 14553 14554 AST_LIST_LOCK(list_head); 14555 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) { 14556 pthread_t thread_id = thread->threadid; 14557 14558 thread->stop = 1; 14559 signal_condition(&thread->lock, &thread->cond); 14560 14561 AST_LIST_UNLOCK(list_head); 14562 pthread_join(thread_id, NULL); 14563 AST_LIST_LOCK(list_head); 14564 } 14565 AST_LIST_UNLOCK(list_head); 14566 }
| static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8452 of file chan_iax2.c.
References ARRAY_LEN, ast_copy_string(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_UNKNOWN, iax_ies::called_number, iax2_dpcache::callno, iax_ies::dpstatus, iax2_dpcache::expiry, iax2_dpcache::exten, exten, iax2_dpcache::flags, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, matchmore(), iax2_dpcache::orig, iax_ies::refresh, status, and iax2_dpcache::waiters.
Referenced by socket_process().
08453 { 08454 char exten[256] = ""; 08455 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08456 struct iax2_dpcache *dp = NULL; 08457 08458 if (ies->called_number) 08459 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08460 08461 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08462 status = CACHE_FLAG_EXISTS; 08463 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08464 status = CACHE_FLAG_CANEXIST; 08465 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08466 status = CACHE_FLAG_NONEXISTENT; 08467 08468 if (ies->refresh) 08469 expiry = ies->refresh; 08470 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08471 matchmore = CACHE_FLAG_MATCHMORE; 08472 08473 AST_LIST_LOCK(&dpcache); 08474 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08475 if (strcmp(dp->exten, exten)) 08476 continue; 08477 AST_LIST_REMOVE_CURRENT(peer_list); 08478 dp->callno = 0; 08479 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08480 if (dp->flags & CACHE_FLAG_PENDING) { 08481 dp->flags &= ~CACHE_FLAG_PENDING; 08482 dp->flags |= status; 08483 dp->flags |= matchmore; 08484 } 08485 /* Wake up waiters */ 08486 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08487 if (dp->waiters[x] > -1) { 08488 if (write(dp->waiters[x], "asdf", 4) < 0) { 08489 } 08490 } 08491 } 08492 } 08493 AST_LIST_TRAVERSE_SAFE_END; 08494 AST_LIST_UNLOCK(&dpcache); 08495 08496 return 0; 08497 }
| static char * complete_iax2_peers | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state, | |||
| uint64_t | flags | |||
| ) | [static] |
Definition at line 3918 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_test_flag64, and peer_unref().
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), and handle_cli_iax2_show_peer().
03919 { 03920 int which = 0; 03921 struct iax2_peer *peer; 03922 char *res = NULL; 03923 int wordlen = strlen(word); 03924 struct ao2_iterator i; 03925 03926 i = ao2_iterator_init(peers, 0); 03927 while ((peer = ao2_iterator_next(&i))) { 03928 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03929 && (!flags || ast_test_flag64(peer, flags))) { 03930 res = ast_strdup(peer->name); 03931 peer_unref(peer); 03932 break; 03933 } 03934 peer_unref(peer); 03935 } 03936 ao2_iterator_destroy(&i); 03937 03938 return res; 03939 }
| static char * complete_iax2_unregister | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 7009 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::expire, and peer_unref().
Referenced by handle_cli_iax2_unregister().
07010 { 07011 int which = 0; 07012 struct iax2_peer *p = NULL; 07013 char *res = NULL; 07014 int wordlen = strlen(word); 07015 07016 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 07017 if (pos == 2) { 07018 struct ao2_iterator i = ao2_iterator_init(peers, 0); 07019 while ((p = ao2_iterator_next(&i))) { 07020 if (!strncasecmp(p->name, word, wordlen) && 07021 ++which > state && p->expire > 0) { 07022 res = ast_strdup(p->name); 07023 peer_unref(p); 07024 break; 07025 } 07026 peer_unref(p); 07027 } 07028 ao2_iterator_destroy(&i); 07029 } 07030 07031 return res; 07032 }
| static int complete_transfer | ( | int | callno, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8499 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_TRAVERSE, ast_log(), iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingtime, remove_by_peercallno(), remove_by_transfercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
08500 { 08501 int peercallno = 0; 08502 struct chan_iax2_pvt *pvt = iaxs[callno]; 08503 struct iax_frame *cur; 08504 jb_frame frame; 08505 08506 if (ies->callno) 08507 peercallno = ies->callno; 08508 08509 if (peercallno < 1) { 08510 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08511 return -1; 08512 } 08513 remove_by_transfercallno(pvt); 08514 /* since a transfer has taken place, the address will change. 08515 * This must be accounted for in the peercnts table. Remove 08516 * the old address and add the new one */ 08517 peercnt_remove_by_addr(&pvt->addr); 08518 peercnt_add(&pvt->transfer); 08519 /* now copy over the new address */ 08520 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08521 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08522 /* Reset sequence numbers */ 08523 pvt->oseqno = 0; 08524 pvt->rseqno = 0; 08525 pvt->iseqno = 0; 08526 pvt->aseqno = 0; 08527 08528 if (pvt->peercallno) { 08529 remove_by_peercallno(pvt); 08530 } 08531 pvt->peercallno = peercallno; 08532 /*this is where the transfering call swiches hash tables */ 08533 store_by_peercallno(pvt); 08534 pvt->transferring = TRANSFER_NONE; 08535 pvt->svoiceformat = -1; 08536 pvt->voiceformat = 0; 08537 pvt->svideoformat = -1; 08538 pvt->videoformat = 0; 08539 pvt->transfercallno = 0; 08540 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08541 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08542 /* reset jitterbuffer */ 08543 while(jb_getall(pvt->jb,&frame) == JB_OK) 08544 iax2_frame_free(frame.data); 08545 jb_reset(pvt->jb); 08546 pvt->lag = 0; 08547 pvt->last = 0; 08548 pvt->lastsent = 0; 08549 pvt->nextpred = 0; 08550 pvt->pingtime = DEFAULT_RETRY_TIME; 08551 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08552 /* We must cancel any packets that would have been transmitted 08553 because now we're talking to someone new. It's okay, they 08554 were transmitted to someone that didn't care anyway. */ 08555 cur->retries = -1; 08556 } 08557 return 0; 08558 }
| static unsigned char compress_subclass | ( | format_t | subclass | ) | [static] |
Definition at line 1691 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), raw_hangup(), and send_apathetic_reply().
01692 { 01693 int x; 01694 int power=-1; 01695 /* If it's 64 or smaller, just return it */ 01696 if (subclass < IAX_FLAG_SC_LOG) 01697 return subclass; 01698 /* Otherwise find its power */ 01699 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01700 if (subclass & (1LL << x)) { 01701 if (power > -1) { 01702 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass); 01703 return 0; 01704 } else 01705 power = x; 01706 } 01707 } 01708 return power | IAX_FLAG_SC_LOG; 01709 }
| static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | iep | |||
| ) | [static] |
Definition at line 9553 of file chan_iax2.c.
References jb_info::current, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, iax_ie_append_int(), iax_ie_append_short(), IAX_IE_RR_DELAY, IAX_IE_RR_DROPPED, IAX_IE_RR_JITTER, IAX_IE_RR_LOSS, IAX_IE_RR_OOO, IAX_IE_RR_PKTS, chan_iax2_pvt::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, and jb_info::min.
Referenced by socket_process().
09554 { 09555 jb_info stats; 09556 jb_getinfo(pvt->jb, &stats); 09557 09558 memset(iep, 0, sizeof(*iep)); 09559 09560 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09561 if(stats.frames_in == 0) stats.frames_in = 1; 09562 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09563 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09564 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09565 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09566 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09567 }
| static int create_addr | ( | const char * | peername, | |
| struct ast_channel * | c, | |||
| struct sockaddr_in * | sin, | |||
| struct create_addr_info * | cai | |||
| ) | [static] |
Definition at line 4657 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag64, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags64, ast_copy_string(), ast_db_get(), ast_debug, ast_get_ip_or_srv(), ast_log(), ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, create_addr_info::cid_name, create_addr_info::cid_num, create_addr_info::context, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, IAX_DEFAULT_PORTNO, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, create_addr_info::outkey, peer_unref(), create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, ast_sockaddr::ss, create_addr_info::timezone, and create_addr_info::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_provision(), and iax2_request().
04658 { 04659 struct iax2_peer *peer; 04660 int res = -1; 04661 struct ast_codec_pref ourprefs; 04662 struct sockaddr_in peer_addr; 04663 04664 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04665 cai->sockfd = defaultsockfd; 04666 cai->maxtime = 0; 04667 sin->sin_family = AF_INET; 04668 04669 if (!(peer = find_peer(peername, 1))) { 04670 struct ast_sockaddr sin_tmp; 04671 04672 cai->found = 0; 04673 sin_tmp.ss.ss_family = AF_INET; 04674 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) { 04675 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04676 return -1; 04677 } 04678 ast_sockaddr_to_sin(&sin_tmp, sin); 04679 if (sin->sin_port == 0) { 04680 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04681 } 04682 /* use global iax prefs for unknown peer/user */ 04683 /* But move the calling channel's native codec to the top of the preference list */ 04684 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04685 if (c) 04686 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04687 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04688 return 0; 04689 } 04690 04691 cai->found = 1; 04692 04693 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 04694 04695 /* if the peer has no address (current or default), return failure */ 04696 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 04697 goto return_unref; 04698 } 04699 04700 /* if the peer is being monitored and is currently unreachable, return failure */ 04701 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04702 goto return_unref; 04703 04704 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04705 cai->maxtime = peer->maxms; 04706 cai->capability = peer->capability; 04707 cai->encmethods = peer->encmethods; 04708 cai->sockfd = peer->sockfd; 04709 cai->adsi = peer->adsi; 04710 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04711 /* Move the calling channel's native codec to the top of the preference list */ 04712 if (c) { 04713 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats); 04714 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04715 } 04716 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04717 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04718 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04719 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04720 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04721 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04722 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04723 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04724 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04725 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04726 if (ast_strlen_zero(peer->dbsecret)) { 04727 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04728 } else { 04729 char *family; 04730 char *key = NULL; 04731 04732 family = ast_strdupa(peer->dbsecret); 04733 key = strchr(family, '/'); 04734 if (key) 04735 *key++ = '\0'; 04736 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04737 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04738 goto return_unref; 04739 } 04740 } 04741 04742 if (peer_addr.sin_addr.s_addr) { 04743 sin->sin_addr = peer_addr.sin_addr; 04744 sin->sin_port = peer_addr.sin_port; 04745 } else { 04746 sin->sin_addr = peer->defaddr.sin_addr; 04747 sin->sin_port = peer->defaddr.sin_port; 04748 } 04749 04750 res = 0; 04751 04752 return_unref: 04753 peer_unref(peer); 04754 04755 return res; 04756 }
| static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2770 of file chan_iax2.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, callno_entry::callno, and callno_hash().
Referenced by load_objects().
02771 { 02772 uint16_t i; 02773 02774 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02775 return -1; 02776 } 02777 02778 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02779 return -1; 02780 } 02781 02782 /* start at 2, 0 and 1 are reserved */ 02783 for (i = 2; i < IAX_MAX_CALLS; i++) { 02784 struct callno_entry *callno_entry; 02785 02786 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02787 return -1; 02788 } 02789 02790 callno_entry->callno = i; 02791 02792 if (i < TRUNK_CALL_START) { 02793 ao2_link(callno_pool, callno_entry); 02794 } else { 02795 ao2_link(callno_pool_trunk, callno_entry); 02796 } 02797 02798 ao2_ref(callno_entry, -1); 02799 } 02800 02801 return 0; 02802 }
| static int decode_frame | ( | ast_aes_decrypt_key * | dcx, | |
| struct ast_iax2_full_hdr * | fh, | |||
| struct ast_frame * | f, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6363 of file chan_iax2.c.
References ast_alloca, ast_debug, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frame_subclass::codec, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame::frametype, IAX_FLAG_FULL, ast_frame_subclass::integer, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame(), and update_packet().
06364 { 06365 int padding; 06366 unsigned char *workspace; 06367 06368 workspace = ast_alloca(*datalen); 06369 memset(f, 0, sizeof(*f)); 06370 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06371 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06372 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06373 return -1; 06374 /* Decrypt */ 06375 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06376 06377 padding = 16 + (workspace[15] & 0x0f); 06378 if (iaxdebug) 06379 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, (unsigned)workspace[15]); 06380 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06381 return -1; 06382 06383 *datalen -= padding; 06384 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06385 f->frametype = fh->type; 06386 if (f->frametype == AST_FRAME_VIDEO) { 06387 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06388 } else if (f->frametype == AST_FRAME_VOICE) { 06389 f->subclass.codec = uncompress_subclass(fh->csub); 06390 } else { 06391 f->subclass.integer = uncompress_subclass(fh->csub); 06392 } 06393 } else { 06394 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06395 if (iaxdebug) 06396 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06397 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06398 return -1; 06399 /* Decrypt */ 06400 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06401 padding = 16 + (workspace[15] & 0x0f); 06402 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06403 return -1; 06404 *datalen -= padding; 06405 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06406 } 06407 return 0; 06408 }
| static int decrypt_frame | ( | int | callno, | |
| struct ast_iax2_full_hdr * | fh, | |||
| struct ast_frame * | f, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6449 of file chan_iax2.c.
References ast_set_flag64, ast_strdupa, ast_test_flag64, build_encryption_keys(), decode_frame(), IAX_KEYPOPULATED, iaxs, MD5Final(), MD5Init(), MD5Update(), and secret.
Referenced by socket_process().
06450 { 06451 int res=-1; 06452 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06453 /* Search for possible keys, given secrets */ 06454 struct MD5Context md5; 06455 unsigned char digest[16]; 06456 char *tmppw, *stringp; 06457 06458 tmppw = ast_strdupa(iaxs[callno]->secret); 06459 stringp = tmppw; 06460 while ((tmppw = strsep(&stringp, ";"))) { 06461 MD5Init(&md5); 06462 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06463 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06464 MD5Final(digest, &md5); 06465 build_encryption_keys(digest, iaxs[callno]); 06466 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06467 if (!res) { 06468 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06469 break; 06470 } 06471 } 06472 } else 06473 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06474 return res; 06475 }
| static void defer_full_frame | ( | struct iax2_thread * | from_here, | |
| struct iax2_thread * | to_here | |||
| ) | [static] |
Queue the last read full frame for processing by a certain thread.
If there are already any full frames queued, they are sorted by sequence number.
Definition at line 9700 of file chan_iax2.c.
References ast_calloc, ast_cond_signal, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock, ast_mutex_unlock, IAX_IOSTATE_READY, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
09701 { 09702 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09703 struct ast_iax2_full_hdr *fh, *cur_fh; 09704 09705 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09706 return; 09707 09708 pkt_buf->len = from_here->buf_len; 09709 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09710 09711 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09712 ast_mutex_lock(&to_here->lock); 09713 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09714 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09715 if (fh->oseqno < cur_fh->oseqno) { 09716 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09717 break; 09718 } 09719 } 09720 AST_LIST_TRAVERSE_SAFE_END 09721 09722 if (!cur_pkt_buf) 09723 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09724 09725 to_here->iostate = IAX_IOSTATE_READY; 09726 ast_cond_signal(&to_here->cond); 09727 09728 ast_mutex_unlock(&to_here->lock); 09729 }
| static void delete_users | ( | void | ) | [static] |
Definition at line 13181 of file chan_iax2.c.
References ao2_callback, ast_dnsmgr_release(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), chan_iax2_pvt::reg, and user_delme_cb().
Referenced by __unload_module(), and set_config_destroy().
13182 { 13183 struct iax2_registry *reg; 13184 13185 ao2_callback(users, 0, user_delme_cb, NULL); 13186 13187 AST_LIST_LOCK(®istrations); 13188 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 13189 if (sched) { 13190 ast_sched_thread_del(sched, reg->expire); 13191 } 13192 if (reg->callno) { 13193 int callno = reg->callno; 13194 ast_mutex_lock(&iaxsl[callno]); 13195 if (iaxs[callno]) { 13196 iaxs[callno]->reg = NULL; 13197 iax2_destroy(callno); 13198 } 13199 ast_mutex_unlock(&iaxsl[callno]); 13200 } 13201 if (reg->dnsmgr) 13202 ast_dnsmgr_release(reg->dnsmgr); 13203 ast_free(reg); 13204 } 13205 AST_LIST_UNLOCK(®istrations); 13206 13207 ao2_callback(peers, 0, peer_delme_cb, NULL); 13208 }
| static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 3100 of file chan_iax2.c.
References ast_free.
Referenced by reload_firmware().
03101 { 03102 /* Close firmware */ 03103 if (cur->fwh) { 03104 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 03105 } 03106 close(cur->fd); 03107 ast_free(cur); 03108 }
| static void dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid, | |||
| int | skiplock | |||
| ) | [static] |
Definition at line 9355 of file chan_iax2.c.
References ast_canmatch_extension(), ast_exists_extension(), AST_FRAME_IAX, ast_ignore_pattern(), ast_matchmore_extension(), ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), iax_ie_data::buf, IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iaxs, iaxsl, iax_ie_data::pos, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
09356 { 09357 unsigned short dpstatus = 0; 09358 struct iax_ie_data ied1; 09359 int mm; 09360 09361 memset(&ied1, 0, sizeof(ied1)); 09362 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 09363 /* Must be started */ 09364 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 09365 dpstatus = IAX_DPSTATUS_EXISTS; 09366 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 09367 dpstatus = IAX_DPSTATUS_CANEXIST; 09368 } else { 09369 dpstatus = IAX_DPSTATUS_NONEXISTENT; 09370 } 09371 if (ast_ignore_pattern(context, callednum)) 09372 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 09373 if (mm) 09374 dpstatus |= IAX_DPSTATUS_MATCHMORE; 09375 if (!skiplock) 09376 ast_mutex_lock(&iaxsl[callno]); 09377 if (iaxs[callno]) { 09378 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 09379 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 09380 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 09381 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 09382 } 09383 if (!skiplock) 09384 ast_mutex_unlock(&iaxsl[callno]); 09385 }
| static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 9387 of file chan_iax2.c.
References ast_free, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, and dp_lookup().
Referenced by spawn_dp_lookup().
| static void encmethods_to_str | ( | int | e, | |
| struct ast_str ** | buf | |||
| ) | [static] |
Definition at line 1625 of file chan_iax2.c.
References ast_str_append(), ast_str_set(), ast_str_strlen(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by __iax2_show_peers(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().
01626 { 01627 ast_str_set(buf, 0, "("); 01628 if (e & IAX_ENCRYPT_AES128) { 01629 ast_str_append(buf, 0, "aes128"); 01630 } 01631 if (e & IAX_ENCRYPT_KEYROTATE) { 01632 ast_str_append(buf, 0, ",keyrotate"); 01633 } 01634 if (ast_str_strlen(*buf) > 1) { 01635 ast_str_append(buf, 0, ")"); 01636 } else { 01637 ast_str_set(buf, 0, "No"); 01638 } 01639 }
| static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
| struct ast_iax2_full_hdr * | fh, | |||
| unsigned char * | poo, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6410 of file chan_iax2.c.
References ast_alloca, ast_debug, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send(), and update_packet().
06411 { 06412 int padding; 06413 unsigned char *workspace; 06414 workspace = ast_alloca(*datalen + 32); 06415 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06416 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06417 if (iaxdebug) 06418 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06419 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06420 padding = 16 + (padding & 0xf); 06421 memcpy(workspace, poo, padding); 06422 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06423 workspace[15] &= 0xf0; 06424 workspace[15] |= (padding & 0xf); 06425 if (iaxdebug) 06426 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, (unsigned)workspace[15]); 06427 *datalen += padding; 06428 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06429 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06430 memcpy(poo, workspace + *datalen - 32, 32); 06431 } else { 06432 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06433 if (iaxdebug) 06434 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06435 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06436 padding = 16 + (padding & 0xf); 06437 memcpy(workspace, poo, padding); 06438 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06439 workspace[15] &= 0xf0; 06440 workspace[15] |= (padding & 0x0f); 06441 *datalen += padding; 06442 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06443 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06444 memcpy(poo, workspace + *datalen - 32, 32); 06445 } 06446 return 0; 06447 }
| static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8767 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), realtime_peer(), reg_source_db(), and update_registry().
08768 { 08769 #ifdef SCHED_MULTITHREADED 08770 if (schedule_action(__expire_registry, data)) 08771 #endif 08772 __expire_registry(data); 08773 return 0; 08774 }
| static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
| const char * | data, | |||
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) | [static, read] |
Definition at line 13881 of file chan_iax2.c.
References ARRAY_LEN, ast_calloc, ast_channel_defer_dtmf(), ast_channel_undefer_dtmf(), ast_copy_string(), ast_free, ast_frfree, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_unlock, ast_read(), ast_remaining_ms(), ast_test_flag, ast_tvcmp(), ast_tvnow(), ast_waitfor_nandfds(), CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, cache_get_callno_locked(), iax2_dpcache::callno, errno, iax2_dpcache::expiry, iax2_dpcache::exten, f, iax2_dpcache::flags, iax2_dprequest(), IAX_STATE_STARTED, iaxs, iaxsl, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peercontext, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
13882 { 13883 struct iax2_dpcache *dp = NULL; 13884 struct timeval now = ast_tvnow(); 13885 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13886 struct ast_channel *c = NULL; 13887 struct ast_frame *f = NULL; 13888 13889 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13890 if (ast_tvcmp(now, dp->expiry) > 0) { 13891 AST_LIST_REMOVE_CURRENT(cache_list); 13892 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13893 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13894 else 13895 ast_free(dp); 13896 continue; 13897 } 13898 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13899 break; 13900 } 13901 AST_LIST_TRAVERSE_SAFE_END; 13902 13903 if (!dp) { 13904 /* No matching entry. Create a new one. */ 13905 /* First, can we make a callno? */ 13906 if ((callno = cache_get_callno_locked(data)) < 0) { 13907 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13908 return NULL; 13909 } 13910 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13911 ast_mutex_unlock(&iaxsl[callno]); 13912 return NULL; 13913 } 13914 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13915 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13916 dp->expiry = ast_tvnow(); 13917 dp->orig = dp->expiry; 13918 /* Expires in 30 mins by default */ 13919 dp->expiry.tv_sec += iaxdefaultdpcache; 13920 dp->flags = CACHE_FLAG_PENDING; 13921 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13922 dp->waiters[x] = -1; 13923 /* Insert into the lists */ 13924 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13925 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13926 /* Send the request if we're already up */ 13927 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13928 iax2_dprequest(dp, callno); 13929 ast_mutex_unlock(&iaxsl[callno]); 13930 } 13931 13932 /* By here we must have a dp */ 13933 if (dp->flags & CACHE_FLAG_PENDING) { 13934 struct timeval start; 13935 int ms; 13936 /* Okay, here it starts to get nasty. We need a pipe now to wait 13937 for a reply to come back so long as it's pending */ 13938 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13939 /* Find an empty slot */ 13940 if (dp->waiters[x] < 0) 13941 break; 13942 } 13943 if (x >= ARRAY_LEN(dp->waiters)) { 13944 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13945 return NULL; 13946 } 13947 if (pipe(com)) { 13948 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13949 return NULL; 13950 } 13951 dp->waiters[x] = com[1]; 13952 /* Okay, now we wait */ 13953 timeout = iaxdefaulttimeout * 1000; 13954 /* Temporarily unlock */ 13955 AST_LIST_UNLOCK(&dpcache); 13956 /* Defer any dtmf */ 13957 if (chan) 13958 old = ast_channel_defer_dtmf(chan); 13959 doabort = 0; 13960 start = ast_tvnow(); 13961 while ((ms = ast_remaining_ms(start, timeout))) { 13962 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms); 13963 if (outfd > -1) 13964 break; 13965 if (!c) 13966 continue; 13967 if (!(f = ast_read(c))) { 13968 doabort = 1; 13969 break; 13970 } 13971 ast_frfree(f); 13972 } 13973 if (!ms) { 13974 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13975 } 13976 AST_LIST_LOCK(&dpcache); 13977 dp->waiters[x] = -1; 13978 close(com[1]); 13979 close(com[0]); 13980 if (doabort) { 13981 /* Don't interpret anything, just abort. Not sure what th epoint 13982 of undeferring dtmf on a hung up channel is but hey whatever */ 13983 if (!old && chan) 13984 ast_channel_undefer_dtmf(chan); 13985 return NULL; 13986 } 13987 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13988 /* Now to do non-independent analysis the results of our wait */ 13989 if (dp->flags & CACHE_FLAG_PENDING) { 13990 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13991 pending. Don't let it take as long to timeout. */ 13992 dp->flags &= ~CACHE_FLAG_PENDING; 13993 dp->flags |= CACHE_FLAG_TIMEOUT; 13994 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 13995 systems without leaving it unavailable once the server comes back online */ 13996 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 13997 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13998 if (dp->waiters[x] > -1) { 13999 if (write(dp->waiters[x], "asdf", 4) < 0) { 14000 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 14001 } 14002 } 14003 } 14004 } 14005 } 14006 /* Our caller will obtain the rest */ 14007 if (!old && chan) 14008 ast_channel_undefer_dtmf(chan); 14009 } 14010 return dp; 14011 }
| static int find_callno | ( | unsigned short | callno, | |
| unsigned short | dcallno, | |||
| struct sockaddr_in * | sin, | |||
| int | new, | |||
| int | sockfd, | |||
| int | full_frame | |||
| ) | [static] |
Definition at line 3025 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
03025 { 03026 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 03027 }
| static int find_callno_locked | ( | unsigned short | callno, | |
| unsigned short | dcallno, | |||
| struct sockaddr_in * | sin, | |||
| int | new, | |||
| int | sockfd, | |||
| int | full_frame | |||
| ) | [static] |
Definition at line 3029 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process_meta().
03029 { 03030 03031 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 03032 }
| static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 1477 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, iax2_thread::ffinfo, iax2_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
01478 { 01479 struct iax2_thread *thread = NULL; 01480 01481 /* Pop the head of the idle list off */ 01482 AST_LIST_LOCK(&idle_list); 01483 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01484 AST_LIST_UNLOCK(&idle_list); 01485 01486 /* If we popped a thread off the idle list, just return it */ 01487 if (thread) { 01488 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01489 return thread; 01490 } 01491 01492 /* Pop the head of the dynamic list off */ 01493 AST_LIST_LOCK(&dynamic_list); 01494 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01495 AST_LIST_UNLOCK(&dynamic_list); 01496 01497 /* If we popped a thread off the dynamic list, just return it */ 01498 if (thread) { 01499 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01500 return thread; 01501 } 01502 01503 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01504 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01505 return NULL; 01506 01507 /* Set default values */ 01508 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01509 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01510 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01511 01512 /* Initialize lock and condition */ 01513 ast_mutex_init(&thread->lock); 01514 ast_cond_init(&thread->cond, NULL); 01515 ast_mutex_init(&thread->init_lock); 01516 ast_cond_init(&thread->init_cond, NULL); 01517 ast_mutex_lock(&thread->init_lock); 01518 01519 /* Create thread and send it on it's way */ 01520 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01521 ast_cond_destroy(&thread->cond); 01522 ast_mutex_destroy(&thread->lock); 01523 ast_mutex_unlock(&thread->init_lock); 01524 ast_cond_destroy(&thread->init_cond); 01525 ast_mutex_destroy(&thread->init_lock); 01526 ast_free(thread); 01527 return NULL; 01528 } 01529 01530 /* this thread is not processing a full frame (since it is idle), 01531 so ensure that the field for the full frame call number is empty */ 01532 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01533 01534 /* Wait for the thread to be ready before returning it to the caller */ 01535 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01536 01537 /* Done with init_lock */ 01538 ast_mutex_unlock(&thread->init_lock); 01539 01540 return thread; 01541 }
| static struct iax2_peer* find_peer | ( | const char * | name, | |
| int | realtime | |||
| ) | [static, read] |
Definition at line 1769 of file chan_iax2.c.
References ao2_find, OBJ_POINTER, and realtime_peer().
Referenced by calltoken_required(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), and update_registry().
01770 { 01771 struct iax2_peer *peer = NULL; 01772 struct iax2_peer tmp_peer = { 01773 .name = name, 01774 }; 01775 01776 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01777 01778 /* Now go for realtime if applicable */ 01779 if(!peer && realtime) 01780 peer = realtime_peer(name, NULL); 01781 01782 return peer; 01783 }
| static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
| int | fd | |||
| ) | [static, read] |
Definition at line 6182 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_calloc, ast_debug, ast_inet_ntoa(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_init, ast_mutex_lock, ast_tvnow(), inaddrcmp(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lock, iax2_trunk_peer::sockfd, and iax2_trunk_peer::trunkact.
Referenced by iax2_trunk_queue(), and socket_process_meta().
06183 { 06184 struct iax2_trunk_peer *tpeer = NULL; 06185 06186 /* Finds and locks trunk peer */ 06187 AST_LIST_LOCK(&tpeers); 06188 06189 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 06190 if (!inaddrcmp(&tpeer->addr, sin)) { 06191 ast_mutex_lock(&tpeer->lock); 06192 break; 06193 } 06194 } 06195 06196 if (!tpeer) { 06197 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 06198 ast_mutex_init(&tpeer->lock); 06199 tpeer->lastsent = 9999; 06200 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 06201 tpeer->trunkact = ast_tvnow(); 06202 ast_mutex_lock(&tpeer->lock); 06203 tpeer->sockfd = fd; 06204 #ifdef SO_NO_CHECK 06205 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 06206 #endif 06207 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06208 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 06209 } 06210 } 06211 06212 AST_LIST_UNLOCK(&tpeers); 06213 06214 return tpeer; 06215 }
| static struct iax2_user* find_user | ( | const char * | name | ) | [static, read] |
Definition at line 1797 of file chan_iax2.c.
References ao2_find, and OBJ_POINTER.
Referenced by calltoken_required(), handle_cli_iax2_prune_realtime(), and requirecalltoken_mark_auto().
01798 { 01799 struct iax2_user tmp_user = { 01800 .name = name, 01801 }; 01802 01803 return ao2_find(users, &tmp_user, OBJ_POINTER); 01804 }
| static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
| int | callno, | |||
| unsigned int | ts | |||
| ) | [static] |
Definition at line 5995 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05996 { 05997 long ms; /* NOT unsigned */ 05998 if (ast_tvzero(iaxs[callno]->rxcore)) { 05999 /* Initialize rxcore time if appropriate */ 06000 iaxs[callno]->rxcore = ast_tvnow(); 06001 /* Round to nearest 20ms so traces look pretty */ 06002 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 06003 } 06004 /* Calculate difference between trunk and channel */ 06005 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 06006 /* Return as the sum of trunk time and the difference between trunk and real time */ 06007 return ms + ts; 06008 }
| static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 12313 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
12314 { 12315 struct iax2_context *conl; 12316 while(con) { 12317 conl = con; 12318 con = con->next; 12319 ast_free(conl); 12320 } 12321 }
| static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1903 of file chan_iax2.c.
References ast_free, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, and ast_frame::ptr.
Referenced by pvt_destructor(), queue_signalling(), and send_signaling().
| static int function_iaxpeer | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 14134 of file chan_iax2.c.
References iax2_peer::addr, iax2_trunk_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sockaddr_stringify_addr(), ast_strdupa, ast_test_flag64, iax2_peer::callno, iax2_peer::capability, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
14135 { 14136 struct iax2_peer *peer; 14137 char *peername, *colname; 14138 14139 peername = ast_strdupa(data); 14140 14141 /* if our channel, return the IP address of the endpoint of current channel */ 14142 if (!strcmp(peername,"CURRENTCHANNEL")) { 14143 unsigned short callno; 14144 if (!chan || chan->tech != &iax2_tech) { 14145 return -1; 14146 } 14147 callno = PTR_TO_CALLNO(chan->tech_pvt); 14148 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 14149 return 0; 14150 } 14151 14152 if ((colname = strchr(peername, ','))) 14153 *colname++ = '\0'; 14154 else 14155 colname = "ip"; 14156 14157 if (!(peer = find_peer(peername, 1))) 14158 return -1; 14159 14160 if (!strcasecmp(colname, "ip")) { 14161 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 14162 } else if (!strcasecmp(colname, "status")) { 14163 peer_status(peer, buf, len); 14164 } else if (!strcasecmp(colname, "mailbox")) { 14165 ast_copy_string(buf, peer->mailbox, len); 14166 } else if (!strcasecmp(colname, "context")) { 14167 ast_copy_string(buf, peer->context, len); 14168 } else if (!strcasecmp(colname, "expire")) { 14169 snprintf(buf, len, "%d", peer->expire); 14170 } else if (!strcasecmp(colname, "dynamic")) { 14171 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 14172 } else if (!strcasecmp(colname, "callerid_name")) { 14173 ast_copy_string(buf, peer->cid_name, len); 14174 } else if (!strcasecmp(colname, "callerid_num")) { 14175 ast_copy_string(buf, peer->cid_num, len); 14176 } else if (!strcasecmp(colname, "codecs")) { 14177 ast_getformatname_multiple(buf, len -1, peer->capability); 14178 } else if (!strncasecmp(colname, "codec[", 6)) { 14179 char *codecnum, *ptr; 14180 int codec = 0; 14181 14182 /* skip over "codec" to the '[' */ 14183 codecnum = colname + 5; 14184 *codecnum = '\0'; 14185 codecnum++; 14186 if ((ptr = strchr(codecnum, ']'))) { 14187 *ptr = '\0'; 14188 } 14189 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 14190 ast_copy_string(buf, ast_getformatname(codec), len); 14191 } else { 14192 buf[0] = '\0'; 14193 } 14194 } else { 14195 buf[0] = '\0'; 14196 } 14197 14198 peer_unref(peer); 14199 14200 return 0; 14201 }
| static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 12478 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
12479 { 12480 int methods = 0; 12481 if (strstr(value, "rsa")) 12482 methods |= IAX_AUTH_RSA; 12483 if (strstr(value, "md5")) 12484 methods |= IAX_AUTH_MD5; 12485 if (strstr(value, "plaintext")) 12486 methods |= IAX_AUTH_PLAINTEXT; 12487 return methods; 12488 }
| static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1641 of file chan_iax2.c.
References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by build_peer(), build_user(), and set_config().
01642 { 01643 int e; 01644 if (!strcasecmp(s, "aes128")) 01645 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01646 else if (ast_true(s)) 01647 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01648 else 01649 e = 0; 01650 return e; 01651 }
| static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4228 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
04229 { 04230 #ifdef SCHED_MULTITHREADED 04231 if (schedule_action(__get_from_jb, data)) 04232 #endif 04233 __get_from_jb(data); 04234 return 0; 04235 }
| static struct callno_entry * get_unused_callno | ( | int | trunk, | |
| int | validated | |||
| ) | [static, read] |
Definition at line 2703 of file chan_iax2.c.
References ao2_container_count(), ao2_find, ao2_lock, ao2_unlock, ast_log(), LOG_WARNING, OBJ_CONTINUE, OBJ_POINTER, OBJ_UNLINK, and callno_entry::validated.
Referenced by __find_callno(), and make_trunk().
02704 { 02705 struct callno_entry *callno_entry = NULL; 02706 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02707 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02708 /* Minor optimization for the extreme case. */ 02709 return NULL; 02710 } 02711 02712 /* the callno_pool container is locked here primarily to ensure thread 02713 * safety of the total_nonval_callno_used check and increment */ 02714 ao2_lock(callno_pool); 02715 02716 /* only a certain number of nonvalidated call numbers should be allocated. 02717 * If there ever is an attack, this separates the calltoken validating 02718 * users from the non calltoken validating users. */ 02719 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02720 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02721 ao2_unlock(callno_pool); 02722 return NULL; 02723 } 02724 02725 /* unlink the object from the container, taking over ownership 02726 * of the reference the container had to the object */ 02727 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02728 02729 if (callno_entry) { 02730 callno_entry->validated = validated; 02731 if (!validated) { 02732 total_nonval_callno_used++; 02733 } 02734 } 02735 02736 ao2_unlock(callno_pool); 02737 return callno_entry; 02738 }
| static int handle_call_token | ( | struct ast_iax2_full_hdr * | fh, | |
| struct iax_ies * | ies, | |||
| struct sockaddr_in * | sin, | |||
| int | fd | |||
| ) | [static] |
Definition at line 4966 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), ast_str_alloca, ast_str_buffer(), ast_str_set(), iax_ie_data::buf, iax_ies::calltoken, CALLTOKEN_HASH_FORMAT, CALLTOKEN_IE_FORMAT, calltoken_required(), iax_ies::calltokendata, ast_iax2_full_hdr::csub, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, iax_ie_append_str(), IAX_IE_CALLTOKEN, ast_iax2_full_hdr::iseqno, LOG_ERROR, LOG_WARNING, requirecalltoken_mark_auto(), S_OR, ast_iax2_full_hdr::scallno, send_apathetic_reply(), ast_iax2_full_hdr::ts, uncompress_subclass(), and iax_ies::username.
Referenced by socket_process().
04968 { 04969 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04970 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04971 struct ast_str *buf = ast_str_alloca(256); 04972 time_t t = time(NULL); 04973 char hash[41]; /* 40 char sha1 hash */ 04974 int subclass = uncompress_subclass(fh->csub); 04975 04976 /* ----- Case 1 ----- */ 04977 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04978 struct iax_ie_data ied = { 04979 .buf = { 0 }, 04980 .pos = 0, 04981 }; 04982 04983 /* create the hash with their address data and our timestamp */ 04984 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04985 ast_sha1_hash(hash, ast_str_buffer(buf)); 04986 04987 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04988 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04989 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04990 04991 return 1; 04992 04993 /* ----- Case 2 ----- */ 04994 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04995 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04996 char *rec_ts = NULL; /* received timestamp */ 04997 unsigned int rec_time; /* received time_t */ 04998 04999 /* split the timestamp from the hash data */ 05000 rec_hash = strchr((char *) ies->calltokendata, '?'); 05001 if (rec_hash) { 05002 *rec_hash++ = '\0'; 05003 rec_ts = (char *) ies->calltokendata; 05004 } 05005 05006 /* check that we have valid data before we do any comparisons */ 05007 if (!rec_hash || !rec_ts) { 05008 goto reject; 05009 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 05010 goto reject; 05011 } 05012 05013 /* create a hash with their address and the _TOKEN'S_ timestamp */ 05014 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 05015 ast_sha1_hash(hash, ast_str_buffer(buf)); 05016 05017 /* compare hashes and then check timestamp delay */ 05018 if (strcmp(hash, rec_hash)) { 05019 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 05020 goto reject; /* received hash does not match ours, reject */ 05021 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 05022 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 05023 goto reject; /* too much delay, reject */ 05024 } 05025 05026 /* at this point the call token is valid, returning 0 05027 * will allow socket_process to continue as usual */ 05028 requirecalltoken_mark_auto(ies->username, subclass); 05029 return 0; 05030 05031 /* ----- Case 3 ----- */ 05032 } else { /* calltokens are not supported for this client, how do we respond? */ 05033 if (calltoken_required(sin, ies->username, subclass)) { 05034 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")); 05035 goto reject; 05036 } 05037 return 0; /* calltoken is not required for this addr, so permit it. */ 05038 } 05039 05040 reject: 05041 /* received frame has failed calltoken inspection, send apathetic reject messages */ 05042 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 05043 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 05044 } else { 05045 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 05046 } 05047 05048 return 1; 05049 }
| static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 12160 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax2_provision(), iax_prov_complete_template(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
12161 { 12162 int force = 0; 12163 int res; 12164 12165 switch (cmd) { 12166 case CLI_INIT: 12167 e->command = "iax2 provision"; 12168 e->usage = 12169 "Usage: iax2 provision <host> <template> [forced]\n" 12170 " Provisions the given peer or IP address using a template\n" 12171 " matching either 'template' or '*' if the template is not\n" 12172 " found. If 'forced' is specified, even empty provisioning\n" 12173 " fields will be provisioned as empty fields.\n"; 12174 return NULL; 12175 case CLI_GENERATE: 12176 if (a->pos == 3) 12177 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 12178 return NULL; 12179 } 12180 12181 if (a->argc < 4) 12182 return CLI_SHOWUSAGE; 12183 if (a->argc > 4) { 12184 if (!strcasecmp(a->argv[4], "forced")) 12185 force = 1; 12186 else 12187 return CLI_SHOWUSAGE; 12188 } 12189 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 12190 if (res < 0) 12191 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 12192 else if (res < 1) 12193 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 12194 else 12195 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 12196 return CLI_SUCCESS; 12197 }
| static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3660 of file chan_iax2.c.
References ao2_unlink, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_set_flag64, ast_test_flag64, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), expire_registry(), ast_cli_args::fd, find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, ast_cli_args::line, ast_cli_args::n, peer_ref(), peer_unref(), ast_cli_args::pos, prune_peers(), prune_users(), ast_cli_entry::usage, user_unref(), and ast_cli_args::word.
03661 { 03662 struct iax2_peer *peer = NULL; 03663 struct iax2_user *user = NULL; 03664 static const char * const choices[] = { "all", NULL }; 03665 char *cmplt; 03666 03667 switch (cmd) { 03668 case CLI_INIT: 03669 e->command = "iax2 prune realtime"; 03670 e->usage = 03671 "Usage: iax2 prune realtime [<peername>|all]\n" 03672 " Prunes object(s) from the cache\n"; 03673 return NULL; 03674 case CLI_GENERATE: 03675 if (a->pos == 3) { 03676 cmplt = ast_cli_complete(a->word, choices, a->n); 03677 if (!cmplt) 03678 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03679 return cmplt; 03680 } 03681 return NULL; 03682 } 03683 if (a->argc != 4) 03684 return CLI_SHOWUSAGE; 03685 if (!strcmp(a->argv[3], "all")) { 03686 prune_users(); 03687 prune_peers(); 03688 ast_cli(a->fd, "Cache flushed successfully.\n"); 03689 return CLI_SUCCESS; 03690 } 03691 peer = find_peer(a->argv[3], 0); 03692 user = find_user(a->argv[3]); 03693 if (peer || user) { 03694 if (peer) { 03695 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 03696 ast_set_flag64(peer, IAX_RTAUTOCLEAR); 03697 expire_registry(peer_ref(peer)); 03698 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03699 } else { 03700 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03701 } 03702 peer_unref(peer); 03703 } 03704 if (user) { 03705 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 03706 ast_set_flag64(user, IAX_RTAUTOCLEAR); 03707 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03708 } else { 03709 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03710 } 03711 ao2_unlink(users,user); 03712 user_unref(user); 03713 } 03714 } else { 03715 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03716 } 03717 03718 return CLI_SUCCESS; 03719 }
| static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 13785 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
13786 { 13787 switch (cmd) { 13788 case CLI_INIT: 13789 e->command = "iax2 reload"; 13790 e->usage = 13791 "Usage: iax2 reload\n" 13792 " Reloads IAX configuration from iax.conf\n"; 13793 return NULL; 13794 case CLI_GENERATE: 13795 return NULL; 13796 } 13797 13798 reload_config(); 13799 13800 return CLI_SUCCESS; 13801 }
| static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7453 of file chan_iax2.c.
References iax2_peer::addr, ao2_ref, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), ast_sockaddr_to_sin, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), debugaddr, ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
07454 { 07455 switch (cmd) { 07456 case CLI_INIT: 07457 e->command = "iax2 set debug {on|off|peer}"; 07458 e->usage = 07459 "Usage: iax2 set debug {on|off|peer peername}\n" 07460 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07461 return NULL; 07462 case CLI_GENERATE: 07463 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07464 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07465 return NULL; 07466 } 07467 07468 if (a->argc < e->args || a->argc > e->args + 1) 07469 return CLI_SHOWUSAGE; 07470 07471 if (!strcasecmp(a->argv[3], "peer")) { 07472 struct iax2_peer *peer; 07473 struct sockaddr_in peer_addr; 07474 07475 07476 if (a->argc != e->args + 1) 07477 return CLI_SHOWUSAGE; 07478 07479 peer = find_peer(a->argv[4], 1); 07480 07481 if (!peer) { 07482 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07483 return CLI_FAILURE; 07484 } 07485 07486 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 07487 07488 debugaddr.sin_addr = peer_addr.sin_addr; 07489 debugaddr.sin_port = peer_addr.sin_port; 07490 07491 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07492 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07493 07494 ao2_ref(peer, -1); 07495 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07496 iaxdebug = 1; 07497 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07498 } else { 07499 iaxdebug = 0; 07500 memset(&debugaddr, 0, sizeof(debugaddr)); 07501 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07502 } 07503 return CLI_SUCCESS; 07504 }
| static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7532 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, jb_debug_output(), jb_error_output(), jb_setoutput(), jb_warning_output(), and ast_cli_entry::usage.
07533 { 07534 switch (cmd) { 07535 case CLI_INIT: 07536 e->command = "iax2 set debug jb {on|off}"; 07537 e->usage = 07538 "Usage: iax2 set debug jb {on|off}\n" 07539 " Enables/Disables jitterbuffer debugging information\n"; 07540 return NULL; 07541 case CLI_GENERATE: 07542 return NULL; 07543 } 07544 07545 if (a->argc != e->args) 07546 return CLI_SHOWUSAGE; 07547 07548 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07549 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07550 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07551 } else { 07552 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07553 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07554 } 07555 return CLI_SUCCESS; 07556 }
| static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7506 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
07507 { 07508 switch (cmd) { 07509 case CLI_INIT: 07510 e->command = "iax2 set debug trunk {on|off}"; 07511 e->usage = 07512 "Usage: iax2 set debug trunk {on|off}\n" 07513 " Enables/Disables debugging of IAX trunking\n"; 07514 return NULL; 07515 case CLI_GENERATE: 07516 return NULL; 07517 } 07518 07519 if (a->argc != e->args) 07520 return CLI_SHOWUSAGE; 07521 07522 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07523 iaxtrunkdebug = 1; 07524 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07525 } else { 07526 iaxtrunkdebug = 0; 07527 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07528 } 07529 return CLI_SUCCESS; 07530 }
| static char* handle_cli_iax2_set_mtu | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Set trunk MTU from CLI.
Definition at line 3987 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MAX_TRUNK_MTU, and ast_cli_entry::usage.
03988 { 03989 int mtuv; 03990 03991 switch (cmd) { 03992 case CLI_INIT: 03993 e->command = "iax2 set mtu"; 03994 e->usage = 03995 "Usage: iax2 set mtu <value>\n" 03996 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03997 " zero to disable. Disabling means that the operating system\n" 03998 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03999 " packet exceeds the UDP payload size. This is substantially\n" 04000 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 04001 " greater for G.711 samples.\n"; 04002 return NULL; 04003 case CLI_GENERATE: 04004 return NULL; 04005 } 04006 04007 if (a->argc != 4) 04008 return CLI_SHOWUSAGE; 04009 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 04010 mtuv = MAX_TRUNK_MTU; 04011 else 04012 mtuv = atoi(a->argv[3]); 04013 04014 if (mtuv == 0) { 04015 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 04016 global_max_trunk_mtu = 0; 04017 return CLI_SUCCESS; 04018 } 04019 if (mtuv < 172 || mtuv > 4000) { 04020 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 04021 return CLI_SHOWUSAGE; 04022 } 04023 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 04024 global_max_trunk_mtu = mtuv; 04025 return CLI_SUCCESS; 04026 }
| static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 4028 of file chan_iax2.c.
References ARRAY_LEN, ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_tvnow(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, iax2_dpcache::expiry, iax2_dpcache::exten, ast_cli_args::fd, iax2_dpcache::flags, iax2_dpcache::peercontext, ast_cli_entry::usage, and iax2_dpcache::waiters.
04029 { 04030 struct iax2_dpcache *dp = NULL; 04031 char tmp[1024], *pc = NULL; 04032 int s, x, y; 04033 struct timeval now = ast_tvnow(); 04034 04035 switch (cmd) { 04036 case CLI_INIT: 04037 e->command = "iax2 show cache"; 04038 e->usage = 04039 "Usage: iax2 show cache\n" 04040 " Display currently cached IAX Dialplan results.\n"; 04041 return NULL; 04042 case CLI_GENERATE: 04043 return NULL; 04044 } 04045 04046 AST_LIST_LOCK(&dpcache); 04047 04048 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 04049 04050 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 04051 s = dp->expiry.tv_sec - now.tv_sec; 04052 tmp[0] = '\0'; 04053 if (dp->flags & CACHE_FLAG_EXISTS) 04054 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 04055 if (dp->flags & CACHE_FLAG_NONEXISTENT) 04056 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 04057 if (dp->flags & CACHE_FLAG_CANEXIST) 04058 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 04059 if (dp->flags & CACHE_FLAG_PENDING) 04060 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 04061 if (dp->flags & CACHE_FLAG_TIMEOUT) 04062 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 04063 if (dp->flags & CACHE_FLAG_TRANSMITTED) 04064 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 04065 if (dp->flags & CACHE_FLAG_MATCHMORE) 04066 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 04067 if (dp->flags & CACHE_FLAG_UNKNOWN) 04068 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 04069 /* Trim trailing pipe */ 04070 if (!ast_strlen_zero(tmp)) { 04071 tmp[strlen(tmp) - 1] = '\0'; 04072 } else { 04073 ast_copy_string(tmp, "(none)", sizeof(tmp)); 04074 } 04075 y = 0; 04076 pc = strchr(dp->peercontext, '@'); 04077 if (!pc) { 04078 pc = dp->peercontext; 04079 } else { 04080 pc++; 04081 } 04082 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 04083 if (dp->waiters[x] > -1) 04084 y++; 04085 } 04086 if (s > 0) { 04087 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 04088 } else { 04089 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 04090 } 04091 } 04092 04093 AST_LIST_UNLOCK(&dpcache); 04094 04095 return CLI_SUCCESS; 04096 }
| static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 2638 of file chan_iax2.c.
References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
02639 { 02640 struct ao2_iterator i; 02641 struct peercnt *peercnt; 02642 struct sockaddr_in sin; 02643 int found = 0; 02644 02645 switch (cmd) { 02646 case CLI_INIT: 02647 e->command = "iax2 show callnumber usage"; 02648 e->usage = 02649 "Usage: iax2 show callnumber usage [IP address]\n" 02650 " Shows current IP addresses which are consuming iax2 call numbers\n"; 02651 return NULL; 02652 case CLI_GENERATE: 02653 return NULL; 02654 case CLI_HANDLER: 02655 if (a->argc < 4 || a->argc > 5) 02656 return CLI_SHOWUSAGE; 02657 02658 if (a->argc == 4) { 02659 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02660 } 02661 02662 i = ao2_iterator_init(peercnts, 0); 02663 while ((peercnt = ao2_iterator_next(&i))) { 02664 sin.sin_addr.s_addr = peercnt->addr; 02665 if (a->argc == 5) { 02666 if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) { 02667 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02668 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02669 ao2_ref(peercnt, -1); 02670 found = 1; 02671 break; 02672 } 02673 } else { 02674 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02675 } 02676 ao2_ref(peercnt, -1); 02677 } 02678 ao2_iterator_destroy(&i); 02679 02680 if (a->argc == 4) { 02681 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n" 02682 "Non-CallToken Validated Callno Used: %d\n", 02683 global_maxcallno_nonval, 02684 total_nonval_callno_used); 02685 02686 ast_cli(a->fd, "Total Available Callno: %d\n" 02687 "Regular Callno Available: %d\n" 02688 "Trunk Callno Available: %d\n", 02689 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk), 02690 ao2_container_count(callno_pool), 02691 ao2_container_count(callno_pool_trunk)); 02692 } else if (a->argc == 5 && !found) { 02693 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] ); 02694 } 02695 02696 02697 return CLI_SUCCESS; 02698 default: 02699 return NULL; 02700 } 02701 }
| static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7280 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_cli_args::argc, ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, iax2_registry::callno, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, jb_info::current, ast_cli_args::fd, FORMAT, FORMAT2, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, chan_iax2_pvt::owner, S_OR, and ast_cli_entry::usage.
07281 { 07282 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 07283 #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" 07284 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 07285 int x; 07286 int numchans = 0; 07287 char first_message[10] = { 0, }; 07288 char last_message[10] = { 0, }; 07289 07290 switch (cmd) { 07291 case CLI_INIT: 07292 e->command = "iax2 show channels"; 07293 e->usage = 07294 "Usage: iax2 show channels\n" 07295 " Lists all currently active IAX channels.\n"; 07296 return NULL; 07297 case CLI_GENERATE: 07298 return NULL; 07299 } 07300 07301 if (a->argc != 3) 07302 return CLI_SHOWUSAGE; 07303 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 07304 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07305 ast_mutex_lock(&iaxsl[x]); 07306 if (iaxs[x]) { 07307 int lag, jitter, localdelay; 07308 jb_info jbinfo; 07309 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07310 jb_getinfo(iaxs[x]->jb, &jbinfo); 07311 jitter = jbinfo.jitter; 07312 localdelay = jbinfo.current - jbinfo.min; 07313 } else { 07314 jitter = -1; 07315 localdelay = 0; 07316 } 07317 07318 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07319 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07320 lag = iaxs[x]->remote_rr.delay; 07321 ast_cli(a->fd, FORMAT, 07322 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07323 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 07324 S_OR(iaxs[x]->username, "(None)"), 07325 iaxs[x]->callno, iaxs[x]->peercallno, 07326 iaxs[x]->oseqno, iaxs[x]->iseqno, 07327 lag, 07328 jitter, 07329 localdelay, 07330 ast_getformatname(iaxs[x]->voiceformat), 07331 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07332 first_message, 07333 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07334 last_message); 07335 numchans++; 07336 } 07337 ast_mutex_unlock(&iaxsl[x]); 07338 } 07339 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07340 return CLI_SUCCESS; 07341 #undef FORMAT 07342 #undef FORMAT2 07343 #undef FORMATB 07344 }
| static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7066 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
07067 { 07068 struct iax_firmware *cur = NULL; 07069 07070 switch (cmd) { 07071 case CLI_INIT: 07072 e->command = "iax2 show firmware"; 07073 e->usage = 07074 "Usage: iax2 show firmware\n" 07075 " Lists all known IAX firmware images.\n"; 07076 return NULL; 07077 case CLI_GENERATE: 07078 return NULL; 07079 } 07080 07081 if (a->argc != 3 && a->argc != 4) 07082 return CLI_SHOWUSAGE; 07083 07084 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 07085 AST_LIST_LOCK(&firmwares); 07086 AST_LIST_TRAVERSE(&firmwares, cur, list) { 07087 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 07088 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 07089 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 07090 } 07091 } 07092 AST_LIST_UNLOCK(&firmwares); 07093 07094 return CLI_SUCCESS; 07095 }
| static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7430 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli(), ast_cli_netstats(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
07431 { 07432 int numchans = 0; 07433 07434 switch (cmd) { 07435 case CLI_INIT: 07436 e->command = "iax2 show netstats"; 07437 e->usage = 07438 "Usage: iax2 show netstats\n" 07439 " Lists network status for all currently active IAX channels.\n"; 07440 return NULL; 07441 case CLI_GENERATE: 07442 return NULL; 07443 } 07444 if (a->argc != 3) 07445 return CLI_SHOWUSAGE; 07446 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 07447 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 07448 numchans = ast_cli_netstats(NULL, a->fd, 1); 07449 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07450 return CLI_SUCCESS; 07451 }
| static char* handle_cli_iax2_show_peer | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Show one peer in detail.
Definition at line 3835 of file chan_iax2.c.
References iax2_peer::addr, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), iax2_peer::defaddr, iax2_peer::encmethods, encmethods_to_str(), iax2_peer::expire, ast_cli_args::fd, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, ast_cli_args::line, iax2_peer::maxcallno, ast_cli_args::n, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::smoothing, status, ast_cli_entry::usage, and ast_cli_args::word.
03836 { 03837 char status[30]; 03838 char cbuf[256]; 03839 struct iax2_peer *peer; 03840 char codec_buf[512]; 03841 struct ast_str *encmethods = ast_str_alloca(256); 03842 int x = 0, codec = 0, load_realtime = 0; 03843 03844 switch (cmd) { 03845 case CLI_INIT: 03846 e->command = "iax2 show peer"; 03847 e->usage = 03848 "Usage: iax2 show peer <name>\n" 03849 " Display details on specific IAX peer\n"; 03850 return NULL; 03851 case CLI_GENERATE: 03852 if (a->pos == 3) 03853 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03854 return NULL; 03855 } 03856 03857 if (a->argc < 4) 03858 return CLI_SHOWUSAGE; 03859 03860 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03861 03862 peer = find_peer(a->argv[3], load_realtime); 03863 if (peer) { 03864 struct sockaddr_in peer_addr; 03865 03866 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 03867 03868 encmethods_to_str(peer->encmethods, &encmethods); 03869 ast_cli(a->fd, "\n\n"); 03870 ast_cli(a->fd, " * Name : %s\n", peer->name); 03871 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03872 ast_cli(a->fd, " Context : %s\n", peer->context); 03873 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03874 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03875 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03876 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03877 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03878 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 03879 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03880 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03881 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03882 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03883 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)); 03884 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03885 ast_cli(a->fd, " Username : %s\n", peer->username); 03886 ast_cli(a->fd, " Codecs : "); 03887 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03888 ast_cli(a->fd, "%s\n", codec_buf); 03889 03890 ast_cli(a->fd, " Codec Order : ("); 03891 for(x = 0; x < 32 ; x++) { 03892 codec = ast_codec_pref_index(&peer->prefs,x); 03893 if(!codec) 03894 break; 03895 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03896 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03897 ast_cli(a->fd, "|"); 03898 } 03899 03900 if (!x) 03901 ast_cli(a->fd, "none"); 03902 ast_cli(a->fd, ")\n"); 03903 03904 ast_cli(a->fd, " Status : "); 03905 peer_status(peer, status, sizeof(status)); 03906 ast_cli(a->fd, "%s\n",status); 03907 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"); 03908 ast_cli(a->fd, "\n"); 03909 peer_unref(peer); 03910 } else { 03911 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03912 ast_cli(a->fd, "\n"); 03913 } 03914 03915 return CLI_SUCCESS; 03916 }
| static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7034 of file chan_iax2.c.
References __iax2_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, RESULT_FAILURE, RESULT_SHOWUSAGE, and ast_cli_entry::usage.
07035 { 07036 switch (cmd) { 07037 case CLI_INIT: 07038 e->command = "iax2 show peers"; 07039 e->usage = 07040 "Usage: iax2 show peers [registered] [like <pattern>]\n" 07041 " Lists all known IAX2 peers.\n" 07042 " Optional 'registered' argument lists only peers with known addresses.\n" 07043 " Optional regular expression pattern is used to filter the peer list.\n"; 07044 return NULL; 07045 case CLI_GENERATE: 07046 return NULL; 07047 } 07048 07049 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) { 07050 case RESULT_SHOWUSAGE: 07051 return CLI_SHOWUSAGE; 07052 case RESULT_FAILURE: 07053 return CLI_FAILURE; 07054 default: 07055 return CLI_SUCCESS; 07056 } 07057 }
| static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7189 of file chan_iax2.c.
References iax2_registry::addr, ast_cli_args::argc, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.
07190 { 07191 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 07192 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 07193 struct iax2_registry *reg = NULL; 07194 char host[80]; 07195 char perceived[80]; 07196 int counter = 0; 07197 07198 switch (cmd) { 07199 case CLI_INIT: 07200 e->command = "iax2 show registry"; 07201 e->usage = 07202 "Usage: iax2 show registry\n" 07203 " Lists all registration requests and status.\n"; 07204 return NULL; 07205 case CLI_GENERATE: 07206 return NULL; 07207 } 07208 if (a->argc != 3) 07209 return CLI_SHOWUSAGE; 07210 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 07211 AST_LIST_LOCK(®istrations); 07212 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07213 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07214 if (reg->us.sin_addr.s_addr) 07215 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07216 else 07217 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07218 ast_cli(a->fd, FORMAT, host, 07219 (reg->dnsmgr) ? "Y" : "N", 07220 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 07221 counter++; 07222 } 07223 AST_LIST_UNLOCK(®istrations); 07224 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 07225 return CLI_SUCCESS; 07226 #undef FORMAT 07227 #undef FORMAT2 07228 }
| static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3941 of file chan_iax2.c.
References ast_cli_args::argc, ARRAY_LEN, ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxsl, iax_frame::retries, and ast_cli_entry::usage.
03942 { 03943 struct iax_frame *cur; 03944 int cnt = 0, dead = 0, final = 0, i = 0; 03945 03946 switch (cmd) { 03947 case CLI_INIT: 03948 e->command = "iax2 show stats"; 03949 e->usage = 03950 "Usage: iax2 show stats\n" 03951 " Display statistics on IAX channel driver.\n"; 03952 return NULL; 03953 case CLI_GENERATE: 03954 return NULL; 03955 } 03956 03957 if (a->argc != 3) 03958 return CLI_SHOWUSAGE; 03959 03960 for (i = 0; i < ARRAY_LEN(frame_queue); i++) { 03961 ast_mutex_lock(&iaxsl[i]); 03962 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) { 03963 if (cur->retries < 0) 03964 dead++; 03965 if (cur->final) 03966 final++; 03967 cnt++; 03968 } 03969 ast_mutex_unlock(&iaxsl[i]); 03970 } 03971 03972 ast_cli(a->fd, " IAX Statistics\n"); 03973 ast_cli(a->fd, "---------------------\n"); 03974 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03975 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03976 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03977 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03978 03979 trunk_timed = trunk_untimed = 0; 03980 if (trunk_maxmtu > trunk_nmaxmtu) 03981 trunk_nmaxmtu = trunk_maxmtu; 03982 03983 return CLI_SUCCESS; 03984 }
| static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6896 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, thread, and ast_cli_entry::usage.
06897 { 06898 struct iax2_thread *thread = NULL; 06899 time_t t; 06900 int threadcount = 0, dynamiccount = 0; 06901 char type; 06902 06903 switch (cmd) { 06904 case CLI_INIT: 06905 e->command = "iax2 show threads"; 06906 e->usage = 06907 "Usage: iax2 show threads\n" 06908 " Lists status of IAX helper threads\n"; 06909 return NULL; 06910 case CLI_GENERATE: 06911 return NULL; 06912 } 06913 if (a->argc != 3) 06914 return CLI_SHOWUSAGE; 06915 06916 ast_cli(a->fd, "IAX2 Thread Information\n"); 06917 time(&t); 06918 ast_cli(a->fd, "Idle Threads:\n"); 06919 AST_LIST_LOCK(&idle_list); 06920 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06921 #ifdef DEBUG_SCHED_MULTITHREAD 06922 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n", 06923 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06924 #else 06925 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n", 06926 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06927 #endif 06928 threadcount++; 06929 } 06930 AST_LIST_UNLOCK(&idle_list); 06931 ast_cli(a->fd, "Active Threads:\n"); 06932 AST_LIST_LOCK(&active_list); 06933 AST_LIST_TRAVERSE(&active_list, thread, list) { 06934 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06935 type = 'D'; 06936 else 06937 type = 'P'; 06938 #ifdef DEBUG_SCHED_MULTITHREAD 06939 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d, func='%s'\n", 06940 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06941 #else 06942 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d\n", 06943 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06944 #endif 06945 threadcount++; 06946 } 06947 AST_LIST_UNLOCK(&active_list); 06948 ast_cli(a->fd, "Dynamic Threads:\n"); 06949 AST_LIST_LOCK(&dynamic_list); 06950 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06951 #ifdef DEBUG_SCHED_MULTITHREAD 06952 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n", 06953 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06954 #else 06955 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n", 06956 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06957 #endif 06958 dynamiccount++; 06959 } 06960 AST_LIST_UNLOCK(&dynamic_list); 06961 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06962 return CLI_SUCCESS; 06963 }
| static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6687 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_strlen_zero(), ast_test_flag64, iax2_user::authmethods, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, ast_cli_entry::usage, and user_unref().
06688 { 06689 regex_t regexbuf; 06690 int havepattern = 0; 06691 06692 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06693 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06694 06695 struct iax2_user *user = NULL; 06696 char auth[90]; 06697 char *pstr = ""; 06698 struct ao2_iterator i; 06699 06700 switch (cmd) { 06701 case CLI_INIT: 06702 e->command = "iax2 show users [like]"; 06703 e->usage = 06704 "Usage: iax2 show users [like <pattern>]\n" 06705 " Lists all known IAX2 users.\n" 06706 " Optional regular expression pattern is used to filter the user list.\n"; 06707 return NULL; 06708 case CLI_GENERATE: 06709 return NULL; 06710 } 06711 06712 switch (a->argc) { 06713 case 5: 06714 if (!strcasecmp(a->argv[3], "like")) { 06715 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06716 return CLI_SHOWUSAGE; 06717 havepattern = 1; 06718 } else 06719 return CLI_SHOWUSAGE; 06720 case 3: 06721 break; 06722 default: 06723 return CLI_SHOWUSAGE; 06724 } 06725 06726 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06727 i = ao2_iterator_init(users, 0); 06728 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 06729 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06730 continue; 06731 06732 if (!ast_strlen_zero(user->secret)) { 06733 ast_copy_string(auth,user->secret, sizeof(auth)); 06734 } else if (!ast_strlen_zero(user->inkeys)) { 06735 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06736 } else 06737 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06738 06739 if(ast_test_flag64(user, IAX_CODEC_NOCAP)) 06740 pstr = "REQ Only"; 06741 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS)) 06742 pstr = "Disabled"; 06743 else 06744 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06745 06746 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06747 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06748 user->ha ? "Yes" : "No", pstr); 06749 } 06750 ao2_iterator_destroy(&i); 06751 06752 if (havepattern) 06753 regfree(®exbuf); 06754 06755 return CLI_SUCCESS; 06756 #undef FORMAT 06757 #undef FORMAT2 06758 }
| static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3721 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
03722 { 03723 switch (cmd) { 03724 case CLI_INIT: 03725 e->command = "iax2 test losspct"; 03726 e->usage = 03727 "Usage: iax2 test losspct <percentage>\n" 03728 " For testing, throws away <percentage> percent of incoming packets\n"; 03729 return NULL; 03730 case CLI_GENERATE: 03731 return NULL; 03732 } 03733 if (a->argc != 4) 03734 return CLI_SHOWUSAGE; 03735 03736 test_losspct = atoi(a->argv[3]); 03737 03738 return CLI_SUCCESS; 03739 }
| static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6965 of file chan_iax2.c.
References ao2_find, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_unregister(), iax2_peer::expire, expire_registry(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, OBJ_POINTER, peer_ref(), peer_unref(), ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
06966 { 06967 struct iax2_peer *p; 06968 06969 switch (cmd) { 06970 case CLI_INIT: 06971 e->command = "iax2 unregister"; 06972 e->usage = 06973 "Usage: iax2 unregister <peername>\n" 06974 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06975 return NULL; 06976 case CLI_GENERATE: 06977 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06978 } 06979 06980 if (a->argc != 3) 06981 return CLI_SHOWUSAGE; 06982 06983 p = find_peer(a->argv[2], 1); 06984 if (p) { 06985 if (p->expire > 0) { 06986 struct iax2_peer tmp_peer = { 06987 .name = a->argv[2], 06988 }; 06989 struct iax2_peer *peer; 06990 06991 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06992 if (peer) { 06993 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06994 peer_unref(peer); /* ref from ao2_find() */ 06995 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06996 } else { 06997 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06998 } 06999 } else { 07000 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 07001 } 07002 peer_unref(p); 07003 } else { 07004 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 07005 } 07006 return CLI_SUCCESS; 07007 }
| static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9670 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, and socket_process().
Referenced by iax2_process_thread().
09671 { 09672 struct iax2_pkt_buf *pkt_buf; 09673 09674 ast_mutex_lock(&thread->lock); 09675 09676 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09677 ast_mutex_unlock(&thread->lock); 09678 09679 thread->buf = pkt_buf->buf; 09680 thread->buf_len = pkt_buf->len; 09681 thread->buf_size = pkt_buf->len + 1; 09682 09683 socket_process(thread); 09684 09685 thread->buf = NULL; 09686 ast_free(pkt_buf); 09687 09688 ast_mutex_lock(&thread->lock); 09689 } 09690 09691 ast_mutex_unlock(&thread->lock); 09692 }
| static int handle_error | ( | void | ) | [static] |
Definition at line 3371 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
03372 { 03373 /* XXX Ideally we should figure out why an error occurred and then abort those 03374 rather than continuing to try. Unfortunately, the published interface does 03375 not seem to work XXX */ 03376 #if 0 03377 struct sockaddr_in *sin; 03378 int res; 03379 struct msghdr m; 03380 struct sock_extended_err e; 03381 m.msg_name = NULL; 03382 m.msg_namelen = 0; 03383 m.msg_iov = NULL; 03384 m.msg_control = &e; 03385 m.msg_controllen = sizeof(e); 03386 m.msg_flags = 0; 03387 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03388 if (res < 0) 03389 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03390 else { 03391 if (m.msg_controllen) { 03392 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03393 if (sin) 03394 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03395 else 03396 ast_log(LOG_WARNING, "No address detected??\n"); 03397 } else { 03398 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03399 } 03400 } 03401 #endif 03402 return 0; 03403 }
| static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
| struct sockaddr_in * | sin, | |||
| int | callno | |||
| ) | [static] |
Acknowledgment received for OUR registration.
Definition at line 8561 of file chan_iax2.c.
References iax2_registry::addr, iax_ies::apparent_addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_verb, iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_replace(), iaxs, inaddrcmp(), LOG_WARNING, manager_event, iax2_registry::messages, iax_ies::msgcount, iax2_registry::refresh, iax_ies::refresh, refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, and iax_ies::username.
Referenced by socket_process().
08562 { 08563 struct iax2_registry *reg; 08564 /* Start pessimistic */ 08565 char peer[256] = ""; 08566 char msgstatus[60]; 08567 int refresh = 60; 08568 char ourip[256] = "<Unspecified>"; 08569 struct sockaddr_in oldus; 08570 struct sockaddr_in us; 08571 int oldmsgs; 08572 struct sockaddr_in reg_addr; 08573 08574 memset(&us, 0, sizeof(us)); 08575 if (ies->apparent_addr) { 08576 memmove(&us, ies->apparent_addr, sizeof(us)); 08577 } 08578 if (ies->username) { 08579 ast_copy_string(peer, ies->username, sizeof(peer)); 08580 } 08581 if (ies->refresh) { 08582 refresh = ies->refresh; 08583 } 08584 if (ies->calling_number) { 08585 /* We don't do anything with it really, but maybe we should */ 08586 } 08587 reg = iaxs[callno]->reg; 08588 if (!reg) { 08589 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08590 return -1; 08591 } 08592 memcpy(&oldus, ®->us, sizeof(oldus)); 08593 oldmsgs = reg->messages; 08594 ast_sockaddr_to_sin(®->addr, ®_addr); 08595 if (inaddrcmp(®_addr, sin)) { 08596 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08597 return -1; 08598 } 08599 memcpy(®->us, &us, sizeof(reg->us)); 08600 if (ies->msgcount >= 0) { 08601 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08602 } 08603 /* always refresh the registration at the interval requested by the server 08604 we are registering to 08605 */ 08606 reg->refresh = refresh; 08607 reg->expire = iax2_sched_replace(reg->expire, sched, 08608 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08609 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08610 if (reg->messages > 255) { 08611 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08612 } else if (reg->messages > 1) { 08613 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages); 08614 } else if (reg->messages > 0) { 08615 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus)); 08616 } else { 08617 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus)); 08618 } 08619 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08620 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08621 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08622 } 08623 reg->regstate = REG_STATE_REGISTERED; 08624 return 0; 08625 }
| static int attribute_pure iax2_allow_new | ( | int | frametype, | |
| int | subclass, | |||
| int | inbound | |||
| ) | [inline, static] |
Definition at line 2839 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_FWDOWNL, IAX_COMMAND_NEW, IAX_COMMAND_POKE, IAX_COMMAND_REGREL, and IAX_COMMAND_REGREQ.
Referenced by resend_with_token(), and socket_process().
02840 { 02841 if (frametype != AST_FRAME_IAX) { 02842 return 0; 02843 } 02844 switch (subclass) { 02845 case IAX_COMMAND_NEW: 02846 case IAX_COMMAND_REGREQ: 02847 case IAX_COMMAND_FWDOWNL: 02848 case IAX_COMMAND_REGREL: 02849 return 1; 02850 case IAX_COMMAND_POKE: 02851 if (!inbound) { 02852 return 1; 02853 } 02854 break; 02855 } 02856 return 0; 02857 }
| static void iax2_ami_channelupdate | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.
Definition at line 1406 of file chan_iax2.c.
References chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, chan_iax2_pvt::owner, and chan_iax2_pvt::peercallno.
Referenced by ast_iax2_new(), and iax2_answer().
01407 { 01408 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01409 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01410 pvt->owner ? pvt->owner->name : "", 01411 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01412 }
| static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5732 of file chan_iax2.c.
References AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, ast_mutex_lock, ast_mutex_unlock, iax2_ami_channelupdate(), iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05733 { 05734 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05735 ast_debug(1, "Answering IAX2 call\n"); 05736 ast_mutex_lock(&iaxsl[callno]); 05737 if (iaxs[callno]) 05738 iax2_ami_channelupdate(iaxs[callno]); 05739 ast_mutex_unlock(&iaxsl[callno]); 05740 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05741 }
| static int iax2_append_register | ( | const char * | hostname, | |
| const char * | username, | |||
| const char * | secret, | |||
| const char * | porta | |||
| ) | [static] |
Definition at line 8627 of file chan_iax2.c.
References iax2_registry::addr, ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_sockaddr_set_port, iax2_registry::dnsmgr, iax2_registry::expire, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, iax2_registry::refresh, iax2_registry::secret, ast_sockaddr::ss, and iax2_registry::username.
Referenced by iax2_register().
08629 { 08630 struct iax2_registry *reg; 08631 08632 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08633 return -1; 08634 08635 reg->addr.ss.ss_family = AF_INET; 08636 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08637 ast_free(reg); 08638 return -1; 08639 } 08640 08641 ast_copy_string(reg->username, username, sizeof(reg->username)); 08642 08643 if (secret) 08644 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08645 08646 reg->expire = -1; 08647 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08648 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); 08649 08650 AST_LIST_LOCK(®istrations); 08651 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08652 AST_LIST_UNLOCK(®istrations); 08653 08654 return 0; 08655 }
| 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 | |||
| ) | [static] |
Definition at line 5561 of file chan_iax2.c.
References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag64, ast_tvnow(), ast_tvzero(), ast_verb, ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, f, ast_frame::frametype, iax2_start_transfer(), iax2_tech, IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, iaxs, iaxsl, ast_frame_subclass::integer, lock_both(), LOG_WARNING, ast_channel::nativeformats, PTR_TO_CALLNO, ast_frame::subclass, ast_channel::tech, ast_channel::tech_pvt, TRANSFER_RELEASED, and unlock_both().
05562 { 05563 struct ast_channel *cs[3]; 05564 struct ast_channel *who, *other; 05565 int to = -1; 05566 int res = -1; 05567 int transferstarted=0; 05568 struct ast_frame *f; 05569 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05570 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05571 struct timeval waittimer = {0, 0}; 05572 05573 /* We currently do not support native bridging if a timeoutms value has been provided */ 05574 if (timeoutms > 0) { 05575 return AST_BRIDGE_FAILED; 05576 } 05577 05578 timeoutms = -1; 05579 05580 lock_both(callno0, callno1); 05581 if (!iaxs[callno0] || !iaxs[callno1]) { 05582 unlock_both(callno0, callno1); 05583 return AST_BRIDGE_FAILED; 05584 } 05585 /* Put them in native bridge mode */ 05586 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05587 iaxs[callno0]->bridgecallno = callno1; 05588 iaxs[callno1]->bridgecallno = callno0; 05589 } 05590 unlock_both(callno0, callno1); 05591 05592 /* If not, try to bridge until we can execute a transfer, if we can */ 05593 cs[0] = c0; 05594 cs[1] = c1; 05595 for (/* ever */;;) { 05596 /* Check in case we got masqueraded into */ 05597 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05598 ast_verb(3, "Can't masquerade, we're different...\n"); 05599 /* Remove from native mode */ 05600 if (c0->tech == &iax2_tech) { 05601 ast_mutex_lock(&iaxsl[callno0]); 05602 iaxs[callno0]->bridgecallno = 0; 05603 ast_mutex_unlock(&iaxsl[callno0]); 05604 } 05605 if (c1->tech == &iax2_tech) { 05606 ast_mutex_lock(&iaxsl[callno1]); 05607 iaxs[callno1]->bridgecallno = 0; 05608 ast_mutex_unlock(&iaxsl[callno1]); 05609 } 05610 return AST_BRIDGE_FAILED_NOWARN; 05611 } 05612 if (c0->nativeformats != c1->nativeformats) { 05613 char buf0[256]; 05614 char buf1[256]; 05615 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats); 05616 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats); 05617 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1); 05618 /* Remove from native mode */ 05619 lock_both(callno0, callno1); 05620 if (iaxs[callno0]) 05621 iaxs[callno0]->bridgecallno = 0; 05622 if (iaxs[callno1]) 05623 iaxs[callno1]->bridgecallno = 0; 05624 unlock_both(callno0, callno1); 05625 return AST_BRIDGE_FAILED_NOWARN; 05626 } 05627 /* check if transferred and if we really want native bridging */ 05628 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) { 05629 /* Try the transfer */ 05630 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05631 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA))) 05632 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05633 transferstarted = 1; 05634 } 05635 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05636 /* Call has been transferred. We're no longer involved */ 05637 struct timeval now = ast_tvnow(); 05638 if (ast_tvzero(waittimer)) { 05639 waittimer = now; 05640 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05641 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05642 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05643 *fo = NULL; 05644 *rc = c0; 05645 res = AST_BRIDGE_COMPLETE; 05646 break; 05647 } 05648 } 05649 to = 1000; 05650 who = ast_waitfor_n(cs, 2, &to); 05651 /* XXX This will need to be updated to calculate 05652 * timeout correctly once timeoutms is allowed to be 05653 * > 0. Right now, this can go badly if the waitfor 05654 * times out in less than a millisecond 05655 */ 05656 if (timeoutms > -1) { 05657 timeoutms -= (1000 - to); 05658 if (timeoutms < 0) 05659 timeoutms = 0; 05660 } 05661 if (!who) { 05662 if (!timeoutms) { 05663 res = AST_BRIDGE_RETRY; 05664 break; 05665 } 05666 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05667 res = AST_BRIDGE_FAILED; 05668 break; 05669 } 05670 continue; 05671 } 05672 f = ast_read(who); 05673 if (!f) { 05674 *fo = NULL; 05675 *rc = who; 05676 res = AST_BRIDGE_COMPLETE; 05677 break; 05678 } 05679 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05680 if (f->frametype == AST_FRAME_CONTROL && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 05681 switch (f->subclass.integer) { 05682 case AST_CONTROL_VIDUPDATE: 05683 case AST_CONTROL_SRCUPDATE: 05684 case AST_CONTROL_SRCCHANGE: 05685 case AST_CONTROL_T38_PARAMETERS: 05686 ast_write(other, f); 05687 break; 05688 default: 05689 *fo = f; 05690 *rc = who; 05691 res = AST_BRIDGE_COMPLETE; 05692 break; 05693 } 05694 if (res == AST_BRIDGE_COMPLETE) { 05695 break; 05696 } 05697 } else if (f->frametype == AST_FRAME_VOICE 05698 || f->frametype == AST_FRAME_TEXT 05699 || f->frametype == AST_FRAME_VIDEO 05700 || f->frametype == AST_FRAME_IMAGE) { 05701 ast_write(other, f); 05702 } else if (f->frametype == AST_FRAME_DTMF) { 05703 /* monitored dtmf take out of the bridge. 05704 * check if we monitor the specific source. 05705 */ 05706 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05707 05708 if (flags & monitored_source) { 05709 *rc = who; 05710 *fo = f; 05711 res = AST_BRIDGE_COMPLETE; 05712 /* Remove from native mode */ 05713 break; 05714 } 05715 ast_write(other, f); 05716 } 05717 ast_frfree(f); 05718 /* Swap who gets priority */ 05719 cs[2] = cs[0]; 05720 cs[0] = cs[1]; 05721 cs[1] = cs[2]; 05722 } 05723 lock_both(callno0, callno1); 05724 if(iaxs[callno0]) 05725 iaxs[callno0]->bridgecallno = 0; 05726 if(iaxs[callno1]) 05727 iaxs[callno1]->bridgecallno = 0; 05728 unlock_both(callno0, callno1); 05729 return res; 05730 }
| static int iax2_call | ( | struct ast_channel * | c, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 5109 of file chan_iax2.c.
References ast_channel::_state, add_empty_calltoken_ie(), create_addr_info::adsi, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_party_connected_line::ani, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, ast_channel_datastore_find(), ast_copy_string(), ast_debug, AST_FRAME_IAX, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_party_id_presentation(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_name(), ast_var_value(), auto_congest(), iax_ie_data::buf, CALLNO_TO_PTR, capability, ast_channel::connected, context, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), ast_datastore::data, ast_channel::dialed, chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, ast_party_redirecting::from, ast_channel::hangupcause, iax2_datetime(), iax2_sched_add(), iax2_variable_datastore_info, IAX_COMMAND_NEW, IAX_FORCE_ENCRYPT, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_raw(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CAPABILITY2, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_LANGUAGE, IAX_IE_OSPTOKEN, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPTOKEN_SIZE, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, ast_party_connected_line::id, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_party_id::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, pbx_builtin_getvar_helper(), parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, ast_party_number::plan, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, ast_channel::redirecting, secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, create_addr_info::timezone, ast_party_dialed::transit_network_select, create_addr_info::username, parsed_dial_string::username, ast_party_name::valid, ast_party_number::valid, and var.
05110 { 05111 struct sockaddr_in sin; 05112 char *l=NULL, *n=NULL, *tmpstr; 05113 struct iax_ie_data ied; 05114 char *defaultrdest = "s"; 05115 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05116 struct parsed_dial_string pds; 05117 struct create_addr_info cai; 05118 struct ast_var_t *var; 05119 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 05120 const char* osp_token_ptr; 05121 unsigned int osp_token_length; 05122 unsigned char osp_block_index; 05123 unsigned int osp_block_length; 05124 unsigned char osp_buffer[256]; 05125 05126 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 05127 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 05128 return -1; 05129 } 05130 05131 memset(&cai, 0, sizeof(cai)); 05132 cai.encmethods = iax2_encryption; 05133 05134 memset(&pds, 0, sizeof(pds)); 05135 tmpstr = ast_strdupa(dest); 05136 parse_dial_string(tmpstr, &pds); 05137 05138 if (ast_strlen_zero(pds.peer)) { 05139 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 05140 return -1; 05141 } 05142 if (!pds.exten) { 05143 pds.exten = defaultrdest; 05144 } 05145 if (create_addr(pds.peer, c, &sin, &cai)) { 05146 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 05147 return -1; 05148 } 05149 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) { 05150 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n"); 05151 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05152 return -1; 05153 } 05154 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 05155 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 05156 return -1; 05157 } 05158 if (!pds.username && !ast_strlen_zero(cai.username)) 05159 pds.username = cai.username; 05160 if (!pds.password && !ast_strlen_zero(cai.secret)) 05161 pds.password = cai.secret; 05162 if (!pds.key && !ast_strlen_zero(cai.outkey)) 05163 pds.key = cai.outkey; 05164 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 05165 pds.context = cai.peercontext; 05166 05167 /* Keep track of the context for outgoing calls too */ 05168 ast_copy_string(c->context, cai.context, sizeof(c->context)); 05169 05170 if (pds.port) 05171 sin.sin_port = htons(atoi(pds.port)); 05172 05173 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL; 05174 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL; 05175 05176 /* Now build request */ 05177 memset(&ied, 0, sizeof(ied)); 05178 05179 /* On new call, first IE MUST be IAX version of caller */ 05180 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 05181 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 05182 if (pds.options && strchr(pds.options, 'a')) { 05183 /* Request auto answer */ 05184 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 05185 } 05186 05187 /* WARNING: this breaks down at 190 bits! */ 05188 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 05189 05190 if (l) { 05191 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 05192 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05193 ast_party_id_presentation(&c->connected.id)); 05194 } else if (n) { 05195 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05196 ast_party_id_presentation(&c->connected.id)); 05197 } else { 05198 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 05199 } 05200 05201 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan); 05202 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select); 05203 05204 if (n) 05205 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 05206 if (ast_test_flag64(iaxs[callno], IAX_SENDANI) 05207 && c->connected.ani.number.valid 05208 && c->connected.ani.number.str) { 05209 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str); 05210 } 05211 05212 if (!ast_strlen_zero(c->language)) 05213 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 05214 if (!ast_strlen_zero(c->dialed.number.str)) { 05215 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str); 05216 } 05217 if (c->redirecting.from.number.valid 05218 && !ast_strlen_zero(c->redirecting.from.number.str)) { 05219 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str); 05220 } 05221 05222 if (pds.context) 05223 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 05224 05225 if (pds.username) 05226 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 05227 05228 if (cai.encmethods) 05229 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 05230 05231 ast_mutex_lock(&iaxsl[callno]); 05232 05233 if (!ast_strlen_zero(c->context)) 05234 ast_string_field_set(iaxs[callno], context, c->context); 05235 05236 if (pds.username) 05237 ast_string_field_set(iaxs[callno], username, pds.username); 05238 05239 iaxs[callno]->encmethods = cai.encmethods; 05240 05241 iaxs[callno]->adsi = cai.adsi; 05242 05243 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 05244 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 05245 05246 if (pds.key) 05247 ast_string_field_set(iaxs[callno], outkey, pds.key); 05248 if (pds.password) 05249 ast_string_field_set(iaxs[callno], secret, pds.password); 05250 05251 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats); 05252 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats); 05253 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability); 05254 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability); 05255 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 05256 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 05257 05258 if (iaxs[callno]->maxtime) { 05259 /* Initialize pingtime and auto-congest time */ 05260 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 05261 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 05262 } else if (autokill) { 05263 iaxs[callno]->pingtime = autokill / 2; 05264 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 05265 } 05266 05267 /* Check if there is an OSP token */ 05268 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 05269 if (!ast_strlen_zero(osp_token_ptr)) { 05270 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 05271 osp_block_index = 0; 05272 while (osp_token_length > 0) { 05273 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 05274 osp_buffer[0] = osp_block_index; 05275 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 05276 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 05277 osp_block_index++; 05278 osp_token_ptr += osp_block_length; 05279 osp_token_length -= osp_block_length; 05280 } 05281 } else 05282 ast_log(LOG_WARNING, "OSP token is too long\n"); 05283 } else if (iaxdebug) 05284 ast_debug(1, "OSP token is undefined\n"); 05285 05286 /* send the command using the appropriate socket for this peer */ 05287 iaxs[callno]->sockfd = cai.sockfd; 05288 05289 /* Add remote vars */ 05290 if (variablestore) { 05291 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 05292 ast_debug(1, "Found an IAX variable store on this channel\n"); 05293 AST_LIST_LOCK(variablelist); 05294 AST_LIST_TRAVERSE(variablelist, var, entries) { 05295 char tmp[256]; 05296 int i; 05297 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 05298 /* Automatically divide the value up into sized chunks */ 05299 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 05300 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 05301 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 05302 } 05303 } 05304 AST_LIST_UNLOCK(variablelist); 05305 } 05306 05307 /* Transmit the string in a "NEW" request */ 05308 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 05309 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 05310 05311 ast_mutex_unlock(&iaxsl[callno]); 05312 ast_setstate(c, AST_STATE_RINGING); 05313 05314 return 0; 05315 }
| static int iax2_canmatch | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid, | |||
| const char * | data | |||
| ) | [static] |
part of the IAX2 dial plan switch interface
Definition at line 14037 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_CANEXIST, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
14038 { 14039 int res = 0; 14040 struct iax2_dpcache *dp = NULL; 14041 #if 0 14042 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 14043 #endif 14044 if ((priority != 1) && (priority != 2)) 14045 return 0; 14046 14047 AST_LIST_LOCK(&dpcache); 14048 if ((dp = find_cache(chan, data, context, exten, priority))) { 14049 if (dp->flags & CACHE_FLAG_CANEXIST) 14050 res = 1; 14051 } else { 14052 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 14053 } 14054 AST_LIST_UNLOCK(&dpcache); 14055 14056 return res; 14057 }
| static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4780 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), ast_tvnow(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, and ast_tm::tm_year.
Referenced by iax2_call(), and update_registry().
04781 { 04782 struct timeval t = ast_tvnow(); 04783 struct ast_tm tm; 04784 unsigned int tmp; 04785 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04786 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04787 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04788 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04789 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04790 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04791 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04792 return tmp; 04793 }
| static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3475 of file chan_iax2.c.
References ao2_ref, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iax2_destroy_helper(), iaxs, iaxsl, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), remove_by_transfercallno(), chan_iax2_pvt::transfercallno, and update_max_trunk.
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), scheduled_destroy(), and socket_process().
03476 { 03477 struct chan_iax2_pvt *pvt = NULL; 03478 struct ast_channel *owner = NULL; 03479 03480 retry: 03481 if ((pvt = iaxs[callno])) { 03482 #if 0 03483 /* iax2_destroy_helper gets called from this function later on. When 03484 * called twice, we get the (previously) familiar FRACK! errors in 03485 * devmode, from the scheduler. An alternative to this approach is to 03486 * reset the scheduler entries to -1 when they're deleted in 03487 * iax2_destroy_helper(). That approach was previously decided to be 03488 * "wrong" because "the memory is going to be deallocated anyway. Why 03489 * should we be resetting those values?" */ 03490 iax2_destroy_helper(pvt); 03491 #endif 03492 } 03493 03494 owner = pvt ? pvt->owner : NULL; 03495 03496 if (owner) { 03497 if (ast_channel_trylock(owner)) { 03498 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03499 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03500 goto retry; 03501 } 03502 } 03503 03504 if (!owner) { 03505 iaxs[callno] = NULL; 03506 } 03507 03508 if (pvt) { 03509 if (!owner) { 03510 pvt->owner = NULL; 03511 } else { 03512 /* If there's an owner, prod it to give up */ 03513 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03514 * because we already hold the owner channel lock. */ 03515 ast_queue_hangup(owner); 03516 } 03517 03518 if (pvt->peercallno) { 03519 remove_by_peercallno(pvt); 03520 } 03521 03522 if (pvt->transfercallno) { 03523 remove_by_transfercallno(pvt); 03524 } 03525 03526 if (!owner) { 03527 ao2_ref(pvt, -1); 03528 pvt = NULL; 03529 } 03530 } 03531 03532 if (owner) { 03533 ast_channel_unlock(owner); 03534 } 03535 03536 if (callno & TRUNK_CALL_START) { 03537 update_max_trunk(); 03538 } 03539 }
| static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1854 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag64, AST_SCHED_DEL_SPINLOCK, ast_sched_thread_del, ast_sched_thread_get_context(), ast_test_flag64, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, iax2_user::curauthreq, DONT_RESCHEDULE, IAX_MAXAUTHREQ, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, OBJ_POINTER, chan_iax2_pvt::pingid, and user_unref().
Referenced by iax2_destroy(), iax2_predestroy(), pvt_destructor(), and stop_stuff().
01855 { 01856 /* Decrement AUTHREQ count if needed */ 01857 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) { 01858 struct iax2_user *user; 01859 struct iax2_user tmp_user = { 01860 .name = pvt->username, 01861 }; 01862 01863 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01864 if (user) { 01865 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01866 user_unref(user); 01867 } 01868 01869 ast_clear_flag64(pvt, IAX_MAXAUTHREQ); 01870 } 01871 /* No more pings or lagrq's */ 01872 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]); 01873 pvt->pingid = DONT_RESCHEDULE; 01874 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]); 01875 pvt->lagid = DONT_RESCHEDULE; 01876 ast_sched_thread_del(sched, pvt->autoid); 01877 ast_sched_thread_del(sched, pvt->authid); 01878 ast_sched_thread_del(sched, pvt->initid); 01879 ast_sched_thread_del(sched, pvt->jbid); 01880 ast_sched_thread_del(sched, pvt->keyrotateid); 01881 }
| static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 14244 of file chan_iax2.c.
References iax2_peer::addr, ast_debug, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_sockaddr_ipv4(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, parse_dial_string(), parsed_dial_string::peer, and peer_unref().
14245 { 14246 struct parsed_dial_string pds; 14247 char *tmp = ast_strdupa(data); 14248 struct iax2_peer *p; 14249 int res = AST_DEVICE_INVALID; 14250 14251 memset(&pds, 0, sizeof(pds)); 14252 parse_dial_string(tmp, &pds); 14253 14254 if (ast_strlen_zero(pds.peer)) { 14255 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 14256 return res; 14257 } 14258 14259 ast_debug(3, "Checking device state for device %s\n", pds.peer); 14260 14261 /* SLD: FIXME: second call to find_peer during registration */ 14262 if (!(p = find_peer(pds.peer, 1))) 14263 return res; 14264 14265 res = AST_DEVICE_UNAVAILABLE; 14266 ast_debug(3, "Found peer. What's device state of %s? addr=%u, defaddr=%u maxms=%d, lastms=%d\n", 14267 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 14268 14269 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) && 14270 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 14271 /* Peer is registered, or have default IP address 14272 and a valid registration */ 14273 if (p->historicms == 0 || p->historicms <= p->maxms) 14274 /* let the core figure out whether it is in use or not */ 14275 res = AST_DEVICE_UNKNOWN; 14276 } 14277 14278 peer_unref(p); 14279 14280 return res; 14281 }
| static int iax2_digit_begin | ( | struct ast_channel * | c, | |
| char | digit | |||
| ) | [static] |
Definition at line 4381 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04382 { 04383 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04384 }
| static int iax2_digit_end | ( | struct ast_channel * | c, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 4386 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04387 { 04388 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04389 }
| static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 12018 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_registry::addr, ast_debug, ast_dnsmgr_changed(), ast_dnsmgr_refresh(), AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax_ie_data::buf, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_replace(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, iaxsl, LOG_WARNING, NEW_FORCE, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), network_change_event_sched_cb(), and reload_config().
12019 { 12020 struct iax_ie_data ied; 12021 if (iaxdebug) 12022 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 12023 12024 if (reg->dnsmgr && 12025 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) { 12026 /* Maybe the IP has changed, force DNS refresh */ 12027 ast_dnsmgr_refresh(reg->dnsmgr); 12028 } 12029 12030 /* 12031 * if IP has Changed, free allocated call to create a new one with new IP 12032 * call has the pointer to IP and must be updated to the new one 12033 */ 12034 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 12035 int callno = reg->callno; 12036 ast_mutex_lock(&iaxsl[callno]); 12037 iax2_destroy(callno); 12038 ast_mutex_unlock(&iaxsl[callno]); 12039 reg->callno = 0; 12040 } 12041 if (!ast_sockaddr_ipv4(®->addr)) { 12042 if (iaxdebug) 12043 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 12044 /* Setup the next registration attempt */ 12045 reg->expire = iax2_sched_replace(reg->expire, sched, 12046 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 12047 return -1; 12048 } 12049 12050 if (!reg->callno) { 12051 struct sockaddr_in reg_addr; 12052 12053 ast_debug(3, "Allocate call number\n"); 12054 12055 ast_sockaddr_to_sin(®->addr, ®_addr); 12056 12057 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0); 12058 if (reg->callno < 1) { 12059 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 12060 return -1; 12061 } else 12062 ast_debug(3, "Registration created on call %d\n", reg->callno); 12063 iaxs[reg->callno]->reg = reg; 12064 ast_mutex_unlock(&iaxsl[reg->callno]); 12065 } 12066 /* Setup the next registration a little early */ 12067 reg->expire = iax2_sched_replace(reg->expire, sched, 12068 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 12069 /* Send the request */ 12070 memset(&ied, 0, sizeof(ied)); 12071 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 12072 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 12073 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 12074 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 12075 reg->regstate = REG_STATE_REGSENT; 12076 return 0; 12077 }
| static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8409 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
08410 { 08411 #ifdef SCHED_MULTITHREADED 08412 if (schedule_action(__iax2_do_register_s, data)) 08413 #endif 08414 __iax2_do_register_s(data); 08415 return 0; 08416 }
| static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
| int | callno | |||
| ) | [static] |
Definition at line 9185 of file chan_iax2.c.
References AST_FRAME_IAX, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_replace(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, iax_ie_data::pos, and send_command().
Referenced by find_cache(), and socket_process().
09186 { 09187 struct iax_ie_data ied; 09188 /* Auto-hangup with 30 seconds of inactivity */ 09189 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 09190 sched, 30000, auto_hangup, (void *)(long)callno); 09191 memset(&ied, 0, sizeof(ied)); 09192 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 09193 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 09194 dp->flags |= CACHE_FLAG_TRANSMITTED; 09195 }
| static void * iax2_dup_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1420 of file chan_iax2.c.
References ast_calloc, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_name(), ast_var_value(), and LOG_ERROR.
01421 { 01422 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01423 struct ast_var_t *oldvar, *newvar; 01424 01425 newlist = ast_calloc(sizeof(*newlist), 1); 01426 if (!newlist) { 01427 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01428 return NULL; 01429 } 01430 01431 AST_LIST_HEAD_INIT(newlist); 01432 AST_LIST_LOCK(oldlist); 01433 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01434 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01435 if (newvar) 01436 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01437 else 01438 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01439 } 01440 AST_LIST_UNLOCK(oldlist); 01441 return newlist; 01442 }
| static int iax2_exec | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid, | |||
| const char * | data | |||
| ) | [static] |
Execute IAX2 dialplan switch.
Definition at line 14083 of file chan_iax2.c.
References ast_copy_string(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_verb, CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, LOG_WARNING, pbx_builtin_getvar_helper(), pbx_exec(), and pbx_findapp().
14084 { 14085 char odata[256]; 14086 char req[256]; 14087 char *ncontext; 14088 struct iax2_dpcache *dp = NULL; 14089 struct ast_app *dial = NULL; 14090 #if 0 14091 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); 14092 #endif 14093 if (priority == 2) { 14094 /* Indicate status, can be overridden in dialplan */ 14095 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 14096 if (dialstatus) { 14097 dial = pbx_findapp(dialstatus); 14098 if (dial) 14099 pbx_exec(chan, dial, ""); 14100 } 14101 return -1; 14102 } else if (priority != 1) 14103 return -1; 14104 14105 AST_LIST_LOCK(&dpcache); 14106 if ((dp = find_cache(chan, data, context, exten, priority))) { 14107 if (dp->flags & CACHE_FLAG_EXISTS) { 14108 ast_copy_string(odata, data, sizeof(odata)); 14109 ncontext = strchr(odata, '/'); 14110 if (ncontext) { 14111 *ncontext = '\0'; 14112 ncontext++; 14113 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 14114 } else { 14115 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 14116 } 14117 ast_verb(3, "Executing Dial('%s')\n", req); 14118 } else { 14119 AST_LIST_UNLOCK(&dpcache); 14120 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 14121 return -1; 14122 } 14123 } 14124 AST_LIST_UNLOCK(&dpcache); 14125 14126 if ((dial = pbx_findapp("Dial"))) 14127 return pbx_exec(chan, dial, req); 14128 else 14129 ast_log(LOG_WARNING, "No dial application registered\n"); 14130 14131 return -1; 14132 }
| static int iax2_exists | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid, | |||
| const char * | data | |||
| ) | [static] |
Part of the IAX2 switch interface.
Definition at line 14014 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_EXISTS, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
14015 { 14016 int res = 0; 14017 struct iax2_dpcache *dp = NULL; 14018 #if 0 14019 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 14020 #endif 14021 if ((priority != 1) && (priority != 2)) 14022 return 0; 14023 14024 AST_LIST_LOCK(&dpcache); 14025 if ((dp = find_cache(chan, data, context, exten, priority))) { 14026 if (dp->flags & CACHE_FLAG_EXISTS) 14027 res = 1; 14028 } else { 14029 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 14030 } 14031 AST_LIST_UNLOCK(&dpcache); 14032 14033 return res; 14034 }
| static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 4408 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax_frame::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04409 { 04410 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04411 ast_mutex_lock(&iaxsl[callno]); 04412 if (iaxs[callno]) 04413 iaxs[callno]->owner = newchan; 04414 else 04415 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04416 ast_mutex_unlock(&iaxsl[callno]); 04417 return 0; 04418 }
| static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1883 of file chan_iax2.c.
References ast_sched_thread_del, iax_frame_free(), and iax_frame::retrans.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), resend_with_token(), and schedule_delivery().
01884 { 01885 ast_sched_thread_del(sched, fr->retrans); 01886 iax_frame_free(fr); 01887 }
| static void iax2_free_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1444 of file chan_iax2.c.
References ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
01445 { 01446 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01447 struct ast_var_t *oldvar; 01448 01449 AST_LIST_LOCK(oldlist); 01450 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01451 ast_free(oldvar); 01452 } 01453 AST_LIST_UNLOCK(oldlist); 01454 AST_LIST_HEAD_DESTROY(oldlist); 01455 ast_free(oldlist); 01456 }
| static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
| char * | host, | |||
| int | len | |||
| ) | [static] |
Definition at line 1817 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_sockaddr_to_sin, peer_unref(), and realtime_peer().
Referenced by __find_callno().
01818 { 01819 struct iax2_peer *peer = NULL; 01820 int res = 0; 01821 struct ao2_iterator i; 01822 01823 i = ao2_iterator_init(peers, 0); 01824 while ((peer = ao2_iterator_next(&i))) { 01825 struct sockaddr_in peer_addr; 01826 01827 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 01828 01829 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01830 (peer_addr.sin_port == sin.sin_port)) { 01831 ast_copy_string(host, peer->name, len); 01832 peer_unref(peer); 01833 res = 1; 01834 break; 01835 } 01836 peer_unref(peer); 01837 } 01838 ao2_iterator_destroy(&i); 01839 01840 if (!peer) { 01841 peer = realtime_peer(NULL, &sin); 01842 if (peer) { 01843 ast_copy_string(host, peer->name, len); 01844 peer_unref(peer); 01845 res = 1; 01846 } 01847 } 01848 01849 return res; 01850 }
| static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5812 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_sockaddr_to_sin, ast_test_flag64, IAX_TRUNK, and peer_unref().
Referenced by check_access().
05813 { 05814 struct iax2_peer *peer; 05815 int res = 0; 05816 struct ao2_iterator i; 05817 05818 i = ao2_iterator_init(peers, 0); 05819 while ((peer = ao2_iterator_next(&i))) { 05820 struct sockaddr_in peer_addr; 05821 05822 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 05823 05824 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05825 (peer_addr.sin_port == sin.sin_port)) { 05826 res = ast_test_flag64(peer, IAX_TRUNK); 05827 peer_unref(peer); 05828 break; 05829 } 05830 peer_unref(peer); 05831 } 05832 ao2_iterator_destroy(&i); 05833 05834 return res; 05835 }
| static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5317 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_add(), ast_test_flag64, ast_verb, iax_ie_data::buf, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_ERROR, LOG_WARNING, iax_ie_data::pos, PTR_TO_CALLNO, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.
05318 { 05319 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05320 struct iax_ie_data ied; 05321 int alreadygone; 05322 memset(&ied, 0, sizeof(ied)); 05323 ast_mutex_lock(&iaxsl[callno]); 05324 if (callno && iaxs[callno]) { 05325 ast_debug(1, "We're hanging up %s now...\n", c->name); 05326 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE); 05327 /* Send the hangup unless we have had a transmission error or are already gone */ 05328 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 05329 if (!iaxs[callno]->error && !alreadygone) { 05330 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 05331 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 05332 } 05333 if (!iaxs[callno]) { 05334 ast_mutex_unlock(&iaxsl[callno]); 05335 return 0; 05336 } 05337 } 05338 /* Explicitly predestroy it */ 05339 iax2_predestroy(callno); 05340 /* If we were already gone to begin with, destroy us now */ 05341 if (iaxs[callno] && alreadygone) { 05342 ast_debug(1, "Really destroying %s now...\n", c->name); 05343 iax2_destroy(callno); 05344 } else if (iaxs[callno]) { 05345 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 05346 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05347 iax2_destroy(callno); 05348 } 05349 } 05350 } else if (c->tech_pvt) { 05351 /* If this call no longer exists, but the channel still 05352 * references it we need to set the channel's tech_pvt to null 05353 * to avoid ast_channel_free() trying to free it. 05354 */ 05355 c->tech_pvt = NULL; 05356 } 05357 ast_mutex_unlock(&iaxsl[callno]); 05358 ast_verb(3, "Hungup '%s'\n", c->name); 05359 return 0; 05360 }
| static int iax2_indicate | ( | struct ast_channel * | c, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 5743 of file chan_iax2.c.
References AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, IAX_SENDCONNECTEDLINE, iaxs, iaxsl, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
05744 { 05745 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05746 struct chan_iax2_pvt *pvt; 05747 int res = 0; 05748 05749 if (iaxdebug) 05750 ast_debug(1, "Indicating condition %d\n", condition); 05751 05752 ast_mutex_lock(&iaxsl[callno]); 05753 pvt = iaxs[callno]; 05754 05755 if (wait_for_peercallno(pvt)) { 05756 res = -1; 05757 goto done; 05758 } 05759 05760 switch (condition) { 05761 case AST_CONTROL_HOLD: 05762 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05763 ast_moh_start(c, data, pvt->mohinterpret); 05764 goto done; 05765 } 05766 break; 05767 case AST_CONTROL_UNHOLD: 05768 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05769 ast_moh_stop(c); 05770 goto done; 05771 } 05772 break; 05773 case AST_CONTROL_CONNECTED_LINE: 05774 case AST_CONTROL_REDIRECTING: 05775 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) { 05776 /* We are not configured to allow sending these updates. */ 05777 ast_debug(2, "Callno %d: Config blocked sending control frame %d.\n", 05778 callno, condition); 05779 goto done; 05780 } 05781 break; 05782 } 05783 05784 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05785 05786 done: 05787 ast_mutex_unlock(&iaxsl[callno]); 05788 05789 return res; 05790 }
| static int iax2_is_control_frame_allowed | ( | int | subtype | ) | [static] |
Definition at line 1284 of file chan_iax2.c.
References _XXX_AST_CONTROL_T38, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, and AST_CONTROL_WINK.
Referenced by send_command(), and socket_process().
01285 { 01286 enum ast_control_frame_type control = subtype; 01287 int is_allowed; 01288 01289 /* 01290 * Note: If we compare the enumeration type, which does not have any 01291 * negative constants, the compiler may optimize this code away. 01292 * Therefore, we must perform an integer comparison here. 01293 */ 01294 if (subtype == -1) { 01295 return -1; 01296 } 01297 01298 /* Default to not allowing control frames to pass. */ 01299 is_allowed = 0; 01300 01301 /* 01302 * The switch default is not present in order to take advantage 01303 * of the compiler complaining of a missing enum case. 01304 */ 01305 switch (control) { 01306 /* 01307 * These control frames make sense to send/receive across the link. 01308 */ 01309 case AST_CONTROL_HANGUP: 01310 case AST_CONTROL_RING: 01311 case AST_CONTROL_RINGING: 01312 case AST_CONTROL_ANSWER: 01313 case AST_CONTROL_BUSY: 01314 case AST_CONTROL_TAKEOFFHOOK: 01315 case AST_CONTROL_OFFHOOK: 01316 case AST_CONTROL_CONGESTION: 01317 case AST_CONTROL_FLASH: 01318 case AST_CONTROL_WINK: 01319 case AST_CONTROL_OPTION: 01320 case AST_CONTROL_RADIO_KEY: 01321 case AST_CONTROL_RADIO_UNKEY: 01322 case AST_CONTROL_PROGRESS: 01323 case AST_CONTROL_PROCEEDING: 01324 case AST_CONTROL_HOLD: 01325 case AST_CONTROL_UNHOLD: 01326 case AST_CONTROL_VIDUPDATE: 01327 case AST_CONTROL_CONNECTED_LINE: 01328 case AST_CONTROL_REDIRECTING: 01329 case AST_CONTROL_T38_PARAMETERS: 01330 case AST_CONTROL_AOC: 01331 case AST_CONTROL_INCOMPLETE: 01332 is_allowed = -1; 01333 break; 01334 01335 /* 01336 * These control frames do not make sense to send/receive across the link. 01337 */ 01338 case _XXX_AST_CONTROL_T38: 01339 /* The control value is deprecated in favor of AST_CONTROL_T38_PARAMETERS. */ 01340 case AST_CONTROL_SRCUPDATE: 01341 /* Across an IAX link the source is still the same. */ 01342 case AST_CONTROL_TRANSFER: 01343 /* A success/fail status report from calling ast_transfer() on this machine. */ 01344 case AST_CONTROL_CC: 01345 /* The payload contains pointers that are valid for the sending machine only. */ 01346 case AST_CONTROL_SRCCHANGE: 01347 /* Across an IAX link the source is still the same. */ 01348 case AST_CONTROL_READ_ACTION: 01349 /* The action can only be done by the sending machine. */ 01350 case AST_CONTROL_END_OF_Q: 01351 /* This frame would cause the call to unexpectedly hangup. */ 01352 case AST_CONTROL_UPDATE_RTP_PEER: 01353 /* Only meaningful across a bridge on this machine for direct-media exchange. */ 01354 break; 01355 } 01356 return is_allowed; 01357 }
| static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5479 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sched_thread_add(), iax_ie_data::buf, build_ecx_key(), chan_iax2_pvt::callno, IAX_COMMAND_RTKEY, IAX_DEBUGDIGEST, iax_ie_append_raw(), IAX_IE_CHALLENGE, iaxsl, chan_iax2_pvt::keyrotateid, MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, and send_command().
Referenced by iax2_send().
05480 { 05481 int res = 0; 05482 struct chan_iax2_pvt *pvt = (void *) vpvt; 05483 struct MD5Context md5; 05484 char key[17] = ""; 05485 struct iax_ie_data ied = { 05486 .pos = 0, 05487 }; 05488 05489 ast_mutex_lock(&iaxsl[pvt->callno]); 05490 pvt->keyrotateid = 05491 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05492 05493 snprintf(key, sizeof(key), "%lX", (unsigned long)ast_random()); 05494 05495 MD5Init(&md5); 05496 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05497 MD5Final((unsigned char *) key, &md5); 05498 05499 IAX_DEBUGDIGEST("Sending", key); 05500 05501 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05502 05503 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05504 05505 build_ecx_key((unsigned char *) key, pvt); 05506 05507 ast_mutex_unlock(&iaxsl[pvt->callno]); 05508 05509 return res; 05510 }
| static void iax2_lock_owner | ( | int | callno | ) | [static] |
Definition at line 1260 of file chan_iax2.c.
References ast_channel_trylock, DEADLOCK_AVOIDANCE, iaxs, and iaxsl.
Referenced by iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), schedule_delivery(), set_hangup_source_and_cause(), and socket_process().
01261 { 01262 for (;;) { 01263 if (!iaxs[callno] || !iaxs[callno]->owner) { 01264 /* There is no owner lock to get. */ 01265 break; 01266 } 01267 if (!ast_channel_trylock(iaxs[callno]->owner)) { 01268 /* We got the lock */ 01269 break; 01270 } 01271 /* Avoid deadlock by pausing and trying again */ 01272 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01273 } 01274 }
| static int iax2_matchmore | ( | struct ast_channel * | chan, | |
| const char * | context, | |||
| const char * | exten, | |||
| int | priority, | |||
| const char * | callerid, | |||
| const char * | data | |||
| ) | [static] |
Part of the IAX2 Switch interface.
Definition at line 14060 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), CACHE_FLAG_MATCHMORE, find_cache(), iax2_dpcache::flags, LOG_NOTICE, and LOG_WARNING.
14061 { 14062 int res = 0; 14063 struct iax2_dpcache *dp = NULL; 14064 #if 0 14065 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 14066 #endif 14067 if ((priority != 1) && (priority != 2)) 14068 return 0; 14069 14070 AST_LIST_LOCK(&dpcache); 14071 if ((dp = find_cache(chan, data, context, exten, priority))) { 14072 if (dp->flags & CACHE_FLAG_MATCHMORE) 14073 res = 1; 14074 } else { 14075 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 14076 } 14077 AST_LIST_UNLOCK(&dpcache); 14078 14079 return res; 14080 }
| static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12222 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
12223 { 12224 struct iax2_peer *peer = (struct iax2_peer *)data; 12225 peer->pokeexpire = -1; 12226 #ifdef SCHED_MULTITHREADED 12227 if (schedule_action(__iax2_poke_noanswer, data)) 12228 #endif 12229 __iax2_poke_noanswer(data); 12230 peer_unref(peer); 12231 return 0; 12232 }
| static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
| int | heldcall | |||
| ) | [static] |
Definition at line 12243 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, ast_sockaddr_ipv4(), ast_sockaddr_to_sin, iax_ie_data::buf, iax2_peer::callno, DEFAULT_MAXMS, iax2_peer::dnsmgr, find_callno(), iax2_peer::historicms, iax2_destroy(), iax2_poke_noanswer(), iax2_sched_add(), IAX_COMMAND_POKE, iaxs, iaxsl, iax2_peer::lastms, LOG_NOTICE, LOG_WARNING, iax2_peer::maxms, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, send_command(), and iax2_peer::sockfd.
Referenced by __iax2_poke_peer_s(), iax2_poke_peer_cb(), poke_all_peers(), reg_source_db(), and update_registry().
12244 { 12245 int callno; 12246 struct sockaddr_in peer_addr; 12247 12248 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) { 12249 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 12250 immediately after clearing things out */ 12251 peer->lastms = 0; 12252 peer->historicms = 0; 12253 peer->pokeexpire = -1; 12254 peer->callno = 0; 12255 return 0; 12256 } 12257 12258 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 12259 12260 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 12261 if ((callno = peer->callno) > 0) { 12262 ast_log(LOG_NOTICE, "Still have a callno...\n"); 12263 ast_mutex_lock(&iaxsl[callno]); 12264 iax2_destroy(callno); 12265 ast_mutex_unlock(&iaxsl[callno]); 12266 } 12267 if (heldcall) 12268 ast_mutex_unlock(&iaxsl[heldcall]); 12269 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0); 12270 if (heldcall) 12271 ast_mutex_lock(&iaxsl[heldcall]); 12272 if (peer->callno < 1) { 12273 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 12274 return -1; 12275 } 12276 12277 /* Speed up retransmission times for this qualify call */ 12278 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 12279 iaxs[peer->callno]->peerpoke = peer; 12280 12281 if (peer->pokeexpire > -1) { 12282 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 12283 peer->pokeexpire = -1; 12284 peer_unref(peer); 12285 } 12286 } 12287 12288 /* Queue up a new task to handle no reply */ 12289 /* If the host is already unreachable then use the unreachable interval instead */ 12290 if (peer->lastms < 0) 12291 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 12292 else 12293 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 12294 12295 if (peer->pokeexpire == -1) 12296 peer_unref(peer); 12297 12298 /* And send the poke */ 12299 ast_mutex_lock(&iaxsl[callno]); 12300 if (iaxs[callno]) { 12301 struct iax_ie_data ied = { 12302 .buf = { 0 }, 12303 .pos = 0, 12304 }; 12305 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 12306 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 12307 } 12308 ast_mutex_unlock(&iaxsl[callno]); 12309 12310 return 0; 12311 }
| static int iax2_poke_peer_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 12234 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
12235 { 12236 struct iax2_peer *peer = obj; 12237 12238 iax2_poke_peer(peer, 0); 12239 12240 return 0; 12241 }
| static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9222 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
09223 { 09224 struct iax2_peer *peer = (struct iax2_peer *)data; 09225 peer->pokeexpire = -1; 09226 #ifdef SCHED_MULTITHREADED 09227 if (schedule_action(__iax2_poke_peer_s, data)) 09228 #endif 09229 __iax2_poke_peer_s(data); 09230 return 0; 09231 }
| static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3452 of file chan_iax2.c.
References ast_module_unref(), ast_set_flag64, ast_test_flag64, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
03453 { 03454 struct ast_channel *c = NULL; 03455 struct chan_iax2_pvt *pvt = iaxs[callno]; 03456 03457 if (!pvt) 03458 return -1; 03459 03460 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) { 03461 iax2_destroy_helper(pvt); 03462 ast_set_flag64(pvt, IAX_ALREADYGONE); 03463 } 03464 03465 if ((c = pvt->owner)) { 03466 c->tech_pvt = NULL; 03467 iax2_queue_hangup(callno); 03468 pvt->owner = NULL; 03469 ast_module_unref(ast_module_info->self); 03470 } 03471 03472 return 0; 03473 }
| static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 11872 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_cond_timedwait, ast_cond_wait, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, insert_idle_thread(), signal_condition(), socket_process(), and thread.
Referenced by find_idle_thread(), and start_network_thread().
11873 { 11874 struct iax2_thread *thread = data; 11875 struct timeval wait; 11876 struct timespec ts; 11877 int put_into_idle = 0; 11878 int first_time = 1; 11879 int old_state; 11880 11881 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1); 11882 11883 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); 11884 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11885 11886 for (;;) { 11887 /* Wait for something to signal us to be awake */ 11888 ast_mutex_lock(&thread->lock); 11889 11890 if (thread->stop) { 11891 ast_mutex_unlock(&thread->lock); 11892 break; 11893 } 11894 11895 /* Flag that we're ready to accept signals */ 11896 if (first_time) { 11897 signal_condition(&thread->init_lock, &thread->init_cond); 11898 first_time = 0; 11899 } 11900 11901 /* Put into idle list if applicable */ 11902 if (put_into_idle) { 11903 insert_idle_thread(thread); 11904 } 11905 11906 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11907 struct iax2_thread *t = NULL; 11908 /* Wait to be signalled or time out */ 11909 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11910 ts.tv_sec = wait.tv_sec; 11911 ts.tv_nsec = wait.tv_usec * 1000; 11912 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11913 /* This thread was never put back into the available dynamic 11914 * thread list, so just go away. */ 11915 if (!put_into_idle || thread->stop) { 11916 ast_mutex_unlock(&thread->lock); 11917 break; 11918 } 11919 AST_LIST_LOCK(&dynamic_list); 11920 /* Account for the case where this thread is acquired *right* after a timeout */ 11921 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11922 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11923 AST_LIST_UNLOCK(&dynamic_list); 11924 if (t) { 11925 /* This dynamic thread timed out waiting for a task and was 11926 * not acquired immediately after the timeout, 11927 * so it's time to go away. */ 11928 ast_mutex_unlock(&thread->lock); 11929 break; 11930 } 11931 /* Someone grabbed our thread *right* after we timed out. 11932 * Wait for them to set us up with something to do and signal 11933 * us to continue. */ 11934 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11935 ts.tv_sec = wait.tv_sec; 11936 ts.tv_nsec = wait.tv_usec * 1000; 11937 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11938 ast_mutex_unlock(&thread->lock); 11939 break; 11940 } 11941 } 11942 } else { 11943 ast_cond_wait(&thread->cond, &thread->lock); 11944 } 11945 11946 /* Go back into our respective list */ 11947 put_into_idle = 1; 11948 11949 ast_mutex_unlock(&thread->lock); 11950 11951 if (thread->stop) { 11952 break; 11953 } 11954 11955 /* See what we need to do */ 11956 switch (thread->iostate) { 11957 case IAX_IOSTATE_IDLE: 11958 continue; 11959 case IAX_IOSTATE_READY: 11960 thread->actions++; 11961 thread->iostate = IAX_IOSTATE_PROCESSING; 11962 socket_process(thread); 11963 handle_deferred_full_frames(thread); 11964 break; 11965 case IAX_IOSTATE_SCHEDREADY: 11966 thread->actions++; 11967 thread->iostate = IAX_IOSTATE_PROCESSING; 11968 #ifdef SCHED_MULTITHREADED 11969 thread->schedfunc(thread->scheddata); 11970 #endif 11971 break; 11972 default: 11973 break; 11974 } 11975 11976 /* The network thread added us to the active_thread list when we were given 11977 * frames to process, Now that we are done, we must remove ourselves from 11978 * the active list, and return to the idle list */ 11979 AST_LIST_LOCK(&active_list); 11980 AST_LIST_REMOVE(&active_list, thread, list); 11981 AST_LIST_UNLOCK(&active_list); 11982 11983 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11984 handle_deferred_full_frames(thread); 11985 11986 time(&thread->checktime); 11987 thread->iostate = IAX_IOSTATE_IDLE; 11988 #ifdef DEBUG_SCHED_MULTITHREAD 11989 thread->curfunc[0]='\0'; 11990 #endif 11991 } 11992 11993 /*! 11994 * \note For some reason, idle threads are exiting without being 11995 * removed from an idle list, which is causing memory 11996 * corruption. Forcibly remove it from the list, if it's there. 11997 */ 11998 AST_LIST_LOCK(&idle_list); 11999 AST_LIST_REMOVE(&idle_list, thread, list); 12000 AST_LIST_UNLOCK(&idle_list); 12001 12002 AST_LIST_LOCK(&dynamic_list); 12003 AST_LIST_REMOVE(&dynamic_list, thread, list); 12004 AST_LIST_UNLOCK(&dynamic_list); 12005 12006 if (!thread->stop) { 12007 /* Nobody asked me to stop so nobody is waiting to join me. */ 12008 pthread_detach(pthread_self()); 12009 } 12010 12011 /* I am exiting here on my own volition, I need to clean up my own data structures 12012 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 12013 */ 12014 pthread_cleanup_pop(1); 12015 return NULL; 12016 }
| static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11860 of file chan_iax2.c.
References ast_atomic_dec_and_test(), ast_cond_destroy, ast_free, ast_mutex_destroy, iaxactivethreadcount, and thread.
Referenced by iax2_process_thread().
11861 { 11862 struct iax2_thread *thread = data; 11863 ast_mutex_destroy(&thread->lock); 11864 ast_cond_destroy(&thread->cond); 11865 ast_mutex_destroy(&thread->init_lock); 11866 ast_cond_destroy(&thread->init_cond); 11867 ast_free(thread); 11868 /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */ 11869 ast_atomic_dec_and_test(&iaxactivethreadcount); 11870 }
| static int iax2_provision | ( | struct sockaddr_in * | end, | |
| int | sockfd, | |||
| const char * | dest, | |||
| const char * | template, | |||
| int | force | |||
| ) | [static] |
Definition at line 12079 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_unlock, ast_set_flag64, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, create_addr(), find_callno_locked(), iax2_sched_replace(), IAX_COMMAND_PROVISION, iax_ie_append_raw(), IAX_IE_PROVISIONING, IAX_PROVISION, iax_provision_build(), iaxs, iaxsl, NEW_FORCE, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.
Referenced by check_provisioning(), handle_cli_iax2_provision(), and iax2_prov_app().
12080 { 12081 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 12082 is found for template */ 12083 struct iax_ie_data provdata; 12084 struct iax_ie_data ied; 12085 unsigned int sig; 12086 struct sockaddr_in sin; 12087 int callno; 12088 struct create_addr_info cai; 12089 12090 memset(&cai, 0, sizeof(cai)); 12091 12092 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 12093 12094 if (iax_provision_build(&provdata, &sig, template, force)) { 12095 ast_debug(1, "No provisioning found for template '%s'\n", template); 12096 return 0; 12097 } 12098 12099 if (end) { 12100 memcpy(&sin, end, sizeof(sin)); 12101 cai.sockfd = sockfd; 12102 } else if (create_addr(dest, NULL, &sin, &cai)) 12103 return -1; 12104 12105 /* Build the rest of the message */ 12106 memset(&ied, 0, sizeof(ied)); 12107 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 12108 12109 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12110 if (!callno) 12111 return -1; 12112 12113 if (iaxs[callno]) { 12114 /* Schedule autodestruct in case they don't ever give us anything back */ 12115 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 12116 sched, 15000, auto_hangup, (void *)(long)callno); 12117 ast_set_flag64(iaxs[callno], IAX_PROVISION); 12118 /* Got a call number now, so go ahead and send the provisioning information */ 12119 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 12120 } 12121 ast_mutex_unlock(&iaxsl[callno]); 12122 12123 return 1; 12124 }
| static int iax2_queryoption | ( | struct ast_channel * | c, | |
| int | option, | |||
| void * | data, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 5456 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_unlock, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_test_flag64, chan_iax2_pvt::callno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.
05457 { 05458 switch (option) { 05459 case AST_OPTION_SECURE_SIGNALING: 05460 case AST_OPTION_SECURE_MEDIA: 05461 { 05462 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05463 ast_mutex_lock(&iaxsl[callno]); 05464 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0; 05465 ast_mutex_unlock(&iaxsl[callno]); 05466 return 0; 05467 } 05468 default: 05469 return -1; 05470 } 05471 }
| static int iax2_queue_control_data | ( | int | callno, | |
| enum ast_control_frame_type | control, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Queue a control frame on the ast_channel owner.
This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 3090 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_control_data(), iax2_lock_owner(), and iaxs.
Referenced by socket_process().
03092 { 03093 iax2_lock_owner(callno); 03094 if (iaxs[callno] && iaxs[callno]->owner) { 03095 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 03096 ast_channel_unlock(iaxs[callno]->owner); 03097 } 03098 return 0; 03099 }
| static int iax2_queue_frame | ( | int | callno, | |
| struct ast_frame * | f | |||
| ) | [static] |
Queue a frame to a call's owning asterisk channel.
Definition at line 3044 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_frame(), iax2_lock_owner(), and iaxs.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
03045 { 03046 iax2_lock_owner(callno); 03047 if (iaxs[callno] && iaxs[callno]->owner) { 03048 ast_queue_frame(iaxs[callno]->owner, f); 03049 ast_channel_unlock(iaxs[callno]->owner); 03050 } 03051 return 0; 03052 }
| static int iax2_queue_hangup | ( | int | callno | ) | [static] |
Queue a hangup frame on the ast_channel owner.
This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 3067 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_hangup(), iax2_lock_owner(), and iaxs.
Referenced by iax2_predestroy().
03068 { 03069 iax2_lock_owner(callno); 03070 if (iaxs[callno] && iaxs[callno]->owner) { 03071 ast_queue_hangup(iaxs[callno]->owner); 03072 ast_channel_unlock(iaxs[callno]->owner); 03073 } 03074 return 0; 03075 }
| static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 5473 of file chan_iax2.c.
References ast_debug, and ast_null_frame.
05474 { 05475 ast_debug(1, "I should never be called!\n"); 05476 return &ast_null_frame; 05477 }
| static int iax2_register | ( | const char * | value, | |
| int | lineno | |||
| ) | [static] |
Definition at line 8657 of file chan_iax2.c.
References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, and secret.
Referenced by set_config().
08658 { 08659 char copy[256]; 08660 char *username, *hostname, *secret; 08661 char *porta; 08662 char *stringp=NULL; 08663 08664 if (!value) 08665 return -1; 08666 08667 ast_copy_string(copy, value, sizeof(copy)); 08668 stringp = copy; 08669 username = strsep(&stringp, "@"); 08670 hostname = strsep(&stringp, "@"); 08671 08672 if (!hostname) { 08673 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08674 return -1; 08675 } 08676 08677 stringp = username; 08678 username = strsep(&stringp, ":"); 08679 secret = strsep(&stringp, ":"); 08680 stringp = hostname; 08681 hostname = strsep(&stringp, ":"); 08682 porta = strsep(&stringp, ":"); 08683 08684 if (porta && !atoi(porta)) { 08685 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08686 return -1; 08687 } 08688 08689 return iax2_append_register(hostname, username, secret, porta); 08690 }
| static struct ast_channel * iax2_request | ( | const char * | type, | |
| format_t | format, | |||
| const struct ast_channel * | requestor, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Definition at line 12323 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags64, ast_getformatname(), ast_hangup(), ast_iax2_new(), ast_log(), ast_mutex_unlock, AST_STATE_DOWN, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_translator_best_choice(), create_addr_info::capability, create_addr(), find_callno_locked(), create_addr_info::found, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, LOG_WARNING, make_trunk(), create_addr_info::maxtime, chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), parsed_dial_string::peer, parsed_dial_string::port, ast_channel::readformat, create_addr_info::sockfd, and ast_channel::writeformat.
12324 { 12325 int callno; 12326 int res; 12327 format_t fmt, native; 12328 struct sockaddr_in sin; 12329 struct ast_channel *c; 12330 struct parsed_dial_string pds; 12331 struct create_addr_info cai; 12332 char *tmpstr; 12333 12334 memset(&pds, 0, sizeof(pds)); 12335 tmpstr = ast_strdupa(data); 12336 parse_dial_string(tmpstr, &pds); 12337 12338 if (ast_strlen_zero(pds.peer)) { 12339 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12340 return NULL; 12341 } 12342 12343 memset(&cai, 0, sizeof(cai)); 12344 cai.capability = iax2_capability; 12345 12346 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12347 12348 /* Populate our address from the given */ 12349 if (create_addr(pds.peer, NULL, &sin, &cai)) { 12350 *cause = AST_CAUSE_UNREGISTERED; 12351 return NULL; 12352 } 12353 12354 if (pds.port) 12355 sin.sin_port = htons(atoi(pds.port)); 12356 12357 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12358 if (callno < 1) { 12359 ast_log(LOG_WARNING, "Unable to create call\n"); 12360 *cause = AST_CAUSE_CONGESTION; 12361 return NULL; 12362 } 12363 12364 /* If this is a trunk, update it now */ 12365 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12366 if (ast_test_flag64(&cai, IAX_TRUNK)) { 12367 int new_callno; 12368 if ((new_callno = make_trunk(callno, 1)) != -1) 12369 callno = new_callno; 12370 } 12371 iaxs[callno]->maxtime = cai.maxtime; 12372 if (cai.found) 12373 ast_string_field_set(iaxs[callno], host, pds.peer); 12374 12375 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found); 12376 12377 ast_mutex_unlock(&iaxsl[callno]); 12378 12379 if (c) { 12380 /* Choose a format we can live with */ 12381 if (c->nativeformats & format) 12382 c->nativeformats &= format; 12383 else { 12384 native = c->nativeformats; 12385 fmt = format; 12386 res = ast_translator_best_choice(&fmt, &native); 12387 if (res < 0) { 12388 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 12389 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 12390 ast_hangup(c); 12391 return NULL; 12392 } 12393 c->nativeformats = native; 12394 } 12395 c->readformat = ast_best_codec(c->nativeformats); 12396 c->writeformat = c->readformat; 12397 } 12398 12399 return c; 12400 }
| static int iax2_sched_add | ( | struct ast_sched_thread * | st, | |
| int | when, | |||
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 1580 of file chan_iax2.c.
References ast_sched_thread_add().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_poke_peer(), make_trunk(), network_change_event_cb(), realtime_peer(), reg_source_db(), sched_delay_remove(), socket_process(), transmit_frame(), and update_registry().
01582 { 01583 return ast_sched_thread_add(st, when, callback, data); 01584 }
| static int iax2_sched_replace | ( | int | id, | |
| struct ast_sched_thread * | st, | |||
| int | when, | |||
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 1572 of file chan_iax2.c.
References ast_sched_thread_add(), and ast_sched_thread_del.
Referenced by auth_fail(), iax2_ack_registry(), iax2_do_register(), iax2_dprequest(), iax2_provision(), and update_jbsched().
01574 { 01575 ast_sched_thread_del(st, id); 01576 01577 return ast_sched_thread_add(st, when, callback, data); 01578 }
| static int iax2_send | ( | struct chan_iax2_pvt * | pvt, | |
| struct ast_frame * | f, | |||
| unsigned int | ts, | |||
| int | seqno, | |||
| int | now, | |||
| int | transfer, | |||
| int | final | |||
| ) | [static] |
Definition at line 6477 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag64, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, ast_frame_subclass::codec, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::ecx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_frame::encmethods, encrypt_frame(), iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_frame_subclass::integer, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, chan_iax2_pvt::mydcx, iax_frame::mydcx, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_frame::ptr, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, iax_frame::semirand, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), send_signaling(), and socket_process().
06478 { 06479 /* Queue a packet for delivery on a given private structure. Use "ts" for 06480 timestamp, or calculate if ts is 0. Send immediately without retransmission 06481 or delayed, with retransmission */ 06482 struct ast_iax2_full_hdr *fh; 06483 struct ast_iax2_mini_hdr *mh; 06484 struct ast_iax2_video_hdr *vh; 06485 struct { 06486 struct iax_frame fr2; 06487 unsigned char buffer[4096]; 06488 } frb; 06489 struct iax_frame *fr; 06490 int res; 06491 int sendmini=0; 06492 unsigned int lastsent; 06493 unsigned int fts; 06494 06495 frb.fr2.afdatalen = sizeof(frb.buffer); 06496 06497 if (!pvt) { 06498 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06499 return -1; 06500 } 06501 06502 lastsent = pvt->lastsent; 06503 06504 /* Calculate actual timestamp */ 06505 fts = calc_timestamp(pvt, ts, f); 06506 06507 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06508 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06509 * increment the "predicted timestamps" for voice, if we're predicting */ 06510 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06511 return 0; 06512 #if 0 06513 ast_log(LOG_NOTICE, 06514 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06515 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06516 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06517 pvt->keyrotateid != -1 ? "" : "no " 06518 ); 06519 #endif 06520 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06521 iax2_key_rotate(pvt); 06522 } 06523 06524 if ((ast_test_flag64(pvt, IAX_TRUNK) || 06525 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06526 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06527 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06528 (f->frametype == AST_FRAME_VOICE) 06529 /* is a voice frame */ && 06530 (f->subclass.codec == pvt->svoiceformat) 06531 /* is the same type */ ) { 06532 /* Force immediate rather than delayed transmission */ 06533 now = 1; 06534 /* Mark that mini-style frame is appropriate */ 06535 sendmini = 1; 06536 } 06537 if ( f->frametype == AST_FRAME_VIDEO ) { 06538 /* 06539 * If the lower 15 bits of the timestamp roll over, or if 06540 * the video format changed then send a full frame. 06541 * Otherwise send a mini video frame 06542 */ 06543 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06544 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat) 06545 ) { 06546 now = 1; 06547 sendmini = 1; 06548 } else { 06549 now = 0; 06550 sendmini = 0; 06551 } 06552 pvt->lastvsent = fts; 06553 } 06554 if (f->frametype == AST_FRAME_IAX) { 06555 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06556 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX; 06557 if (!pvt->first_iax_message) { 06558 pvt->first_iax_message = pvt->last_iax_message; 06559 } 06560 } 06561 /* Allocate an iax_frame */ 06562 if (now) { 06563 fr = &frb.fr2; 06564 } else 06565 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)); 06566 if (!fr) { 06567 ast_log(LOG_WARNING, "Out of memory\n"); 06568 return -1; 06569 } 06570 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06571 iax_frame_wrap(fr, f); 06572 06573 fr->ts = fts; 06574 fr->callno = pvt->callno; 06575 fr->transfer = transfer; 06576 fr->final = final; 06577 fr->encmethods = 0; 06578 if (!sendmini) { 06579 /* We need a full frame */ 06580 if (seqno > -1) 06581 fr->oseqno = seqno; 06582 else 06583 fr->oseqno = pvt->oseqno++; 06584 fr->iseqno = pvt->iseqno; 06585 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06586 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06587 fh->ts = htonl(fr->ts); 06588 fh->oseqno = fr->oseqno; 06589 if (transfer) { 06590 fh->iseqno = 0; 06591 } else 06592 fh->iseqno = fr->iseqno; 06593 /* Keep track of the last thing we've acknowledged */ 06594 if (!transfer) 06595 pvt->aseqno = fr->iseqno; 06596 fh->type = fr->af.frametype & 0xFF; 06597 06598 if (fr->af.frametype == AST_FRAME_VIDEO) { 06599 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6); 06600 } else if (fr->af.frametype == AST_FRAME_VOICE) { 06601 fh->csub = compress_subclass(fr->af.subclass.codec); 06602 } else { 06603 fh->csub = compress_subclass(fr->af.subclass.integer); 06604 } 06605 06606 if (transfer) { 06607 fr->dcallno = pvt->transfercallno; 06608 } else 06609 fr->dcallno = pvt->peercallno; 06610 fh->dcallno = htons(fr->dcallno); 06611 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06612 fr->data = fh; 06613 fr->retries = 0; 06614 /* Retry after 2x the ping time has passed */ 06615 fr->retrytime = pvt->pingtime * 2; 06616 if (fr->retrytime < MIN_RETRY_TIME) 06617 fr->retrytime = MIN_RETRY_TIME; 06618 if (fr->retrytime > MAX_RETRY_TIME) 06619 fr->retrytime = MAX_RETRY_TIME; 06620 /* Acks' don't get retried */ 06621 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK)) 06622 fr->retries = -1; 06623 else if (f->frametype == AST_FRAME_VOICE) 06624 pvt->svoiceformat = f->subclass.codec; 06625 else if (f->frametype == AST_FRAME_VIDEO) 06626 pvt->svideoformat = f->subclass.codec & ~0x1LL; 06627 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06628 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06629 if (fr->transfer) 06630 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06631 else 06632 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06633 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06634 fr->encmethods = pvt->encmethods; 06635 fr->ecx = pvt->ecx; 06636 fr->mydcx = pvt->mydcx; 06637 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06638 } else 06639 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06640 } 06641 06642 if (now) { 06643 res = send_packet(fr); 06644 } else 06645 res = iax2_transmit(fr); 06646 } else { 06647 if (ast_test_flag64(pvt, IAX_TRUNK)) { 06648 iax2_trunk_queue(pvt, fr); 06649 res = 0; 06650 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06651 /* Video frame have no sequence number */ 06652 fr->oseqno = -1; 06653 fr->iseqno = -1; 06654 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06655 vh->zeros = 0; 06656 vh->callno = htons(0x8000 | fr->callno); 06657 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0)); 06658 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06659 fr->data = vh; 06660 fr->retries = -1; 06661 res = send_packet(fr); 06662 } else { 06663 /* Mini-frames have no sequence number */ 06664 fr->oseqno = -1; 06665 fr->iseqno = -1; 06666 /* Mini frame will do */ 06667 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06668 mh->callno = htons(fr->callno); 06669 mh->ts = htons(fr->ts & 0xFFFF); 06670 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06671 fr->data = mh; 06672 fr->retries = -1; 06673 if (pvt->transferring == TRANSFER_MEDIAPASS) 06674 fr->transfer = 1; 06675 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06676 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06677 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06678 } else 06679 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06680 } 06681 res = send_packet(fr); 06682 } 06683 } 06684 return res; 06685 }
| static int iax2_sendhtml | ( | struct ast_channel * | c, | |
| int | subclass, | |||
| const char * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 4403 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04404 { 04405 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04406 }
| static int iax2_sendimage | ( | struct ast_channel * | c, | |
| struct ast_frame * | img | |||
| ) | [static] |
Definition at line 4398 of file chan_iax2.c.
References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, ast_frame_subclass::integer, ast_frame::ptr, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.
04399 { 04400 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1); 04401 }
| static int iax2_sendtext | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 4391 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04392 { 04393 04394 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04395 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04396 }
| static int iax2_setoption | ( | struct ast_channel * | c, | |
| int | option, | |||
| void * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 5384 of file chan_iax2.c.
References ast_clear_flag64, AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, AST_OPTION_FLAG_REQUEST, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_set_flag64, ast_option_header::data, errno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
05385 { 05386 struct ast_option_header *h; 05387 int res; 05388 05389 switch (option) { 05390 case AST_OPTION_TXGAIN: 05391 case AST_OPTION_RXGAIN: 05392 /* these two cannot be sent, because they require a result */ 05393 errno = ENOSYS; 05394 return -1; 05395 case AST_OPTION_OPRMODE: 05396 errno = EINVAL; 05397 return -1; 05398 case AST_OPTION_SECURE_SIGNALING: 05399 case AST_OPTION_SECURE_MEDIA: 05400 { 05401 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05402 ast_mutex_lock(&iaxsl[callno]); 05403 if ((*(int *) data)) { 05404 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05405 } else { 05406 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05407 } 05408 ast_mutex_unlock(&iaxsl[callno]); 05409 return 0; 05410 } 05411 /* These options are sent to the other side across the network where 05412 * they will be passed to whatever channel is bridged there. Don't 05413 * do anything silly like pass an option that transmits pointers to 05414 * memory on this machine to a remote machine to use */ 05415 case AST_OPTION_TONE_VERIFY: 05416 case AST_OPTION_TDD: 05417 case AST_OPTION_RELAXDTMF: 05418 case AST_OPTION_AUDIO_MODE: 05419 case AST_OPTION_DIGIT_DETECT: 05420 case AST_OPTION_FAX_DETECT: 05421 { 05422 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05423 struct chan_iax2_pvt *pvt; 05424 05425 ast_mutex_lock(&iaxsl[callno]); 05426 pvt = iaxs[callno]; 05427 05428 if (wait_for_peercallno(pvt)) { 05429 ast_mutex_unlock(&iaxsl[callno]); 05430 return -1; 05431 } 05432 05433 ast_mutex_unlock(&iaxsl[callno]); 05434 05435 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05436 return -1; 05437 } 05438 05439 h->flag = AST_OPTION_FLAG_REQUEST; 05440 h->option = htons(option); 05441 memcpy(h->data, data, datalen); 05442 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05443 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05444 datalen + sizeof(*h), -1); 05445 ast_free(h); 05446 return res; 05447 } 05448 default: 05449 return -1; 05450 } 05451 05452 /* Just in case someone does a break instead of a return */ 05453 return -1; 05454 }
| static int iax2_start_transfer | ( | unsigned short | callno0, | |
| unsigned short | callno1, | |||
| int | mediaonly | |||
| ) | [static] |
Definition at line 5512 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag64, iax_ie_data::buf, IAX_CALLENCRYPTED, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, IAX_NOTRANSFER, iaxs, iax_ie_data::pos, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
Referenced by iax2_bridge().
05513 { 05514 int res; 05515 struct iax_ie_data ied0; 05516 struct iax_ie_data ied1; 05517 unsigned int transferid = (unsigned int)ast_random(); 05518 05519 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05520 ast_debug(1, "transfers are not supported for encrypted calls at this time\n"); 05521 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER); 05522 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER); 05523 return 0; 05524 } 05525 05526 memset(&ied0, 0, sizeof(ied0)); 05527 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05528 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05529 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05530 05531 memset(&ied1, 0, sizeof(ied1)); 05532 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05533 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05534 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05535 05536 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05537 if (res) 05538 return -1; 05539 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05540 if (res) 05541 return -1; 05542 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05543 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05544 return 0; 05545 }
| static int iax2_transfer | ( | struct ast_channel * | c, | |
| const char * | dest | |||
| ) | [static] |
Definition at line 5792 of file chan_iax2.c.
References AST_CONTROL_TRANSFER, ast_copy_string(), ast_debug, AST_FRAME_IAX, ast_queue_control_data(), AST_TRANSFER_SUCCESS, iax_ie_data::buf, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05793 { 05794 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05795 struct iax_ie_data ied = { "", }; 05796 char tmp[256], *context; 05797 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 05798 ast_copy_string(tmp, dest, sizeof(tmp)); 05799 context = strchr(tmp, '@'); 05800 if (context) { 05801 *context = '\0'; 05802 context++; 05803 } 05804 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05805 if (context) 05806 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05807 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05808 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message)); 05809 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05810 }
| static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4374 of file chan_iax2.c.
References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().
Referenced by iax2_send().
04375 { 04376 fr->sentyet = 0; 04377 04378 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr); 04379 }
| static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [inline, static] |
Definition at line 9276 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
09277 { 09278 /* Drop when trunk is about 5 seconds idle */ 09279 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 09280 return 1; 09281 return 0; 09282 }
| static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_frame * | fr | |||
| ) | [static] |
Definition at line 6217 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_realloc, ast_test_flag64, ast_tvnow(), ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, f, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, ast_frame::ptr, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
06218 { 06219 struct ast_frame *f; 06220 struct iax2_trunk_peer *tpeer; 06221 void *tmp, *ptr; 06222 struct timeval now; 06223 struct ast_iax2_meta_trunk_entry *met; 06224 struct ast_iax2_meta_trunk_mini *mtm; 06225 06226 f = &fr->af; 06227 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 06228 if (tpeer) { 06229 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 06230 /* Need to reallocate space */ 06231 if (tpeer->trunkdataalloc < trunkmaxsize) { 06232 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 06233 ast_mutex_unlock(&tpeer->lock); 06234 return -1; 06235 } 06236 06237 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 06238 tpeer->trunkdata = tmp; 06239 ast_debug(1, "Expanded trunk '%s:%d' to %u bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 06240 } else { 06241 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)); 06242 ast_mutex_unlock(&tpeer->lock); 06243 return -1; 06244 } 06245 } 06246 06247 /* Append to meta frame */ 06248 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 06249 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) { 06250 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06251 mtm->len = htons(f->datalen); 06252 mtm->mini.callno = htons(pvt->callno); 06253 mtm->mini.ts = htons(0xffff & fr->ts); 06254 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06255 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 06256 } else { 06257 met = (struct ast_iax2_meta_trunk_entry *)ptr; 06258 /* Store call number and length in meta header */ 06259 met->callno = htons(pvt->callno); 06260 met->len = htons(f->datalen); 06261 /* Advance pointers/decrease length past trunk entry header */ 06262 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06263 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 06264 } 06265 /* Copy actual trunk data */ 06266 memcpy(ptr, f->data.ptr, f->datalen); 06267 tpeer->trunkdatalen += f->datalen; 06268 06269 tpeer->calls++; 06270 06271 /* track the largest mtu we actually have sent */ 06272 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 06273 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 06274 06275 /* if we have enough for a full MTU, ship it now without waiting */ 06276 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 06277 now = ast_tvnow(); 06278 send_trunk(tpeer, &now); 06279 trunk_untimed ++; 06280 } 06281 06282 ast_mutex_unlock(&tpeer->lock); 06283 } 06284 return 0; 06285 }
| static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 9197 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, iaxs, and send_command_immediate().
Referenced by socket_process(), and socket_process_meta().
09198 { 09199 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 09200 }
| static int iax2_write | ( | struct ast_channel * | c, | |
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 7558 of file chan_iax2.c.
References ast_debug, AST_FRAME_NULL, AST_FRAME_VOICE, ast_mutex_lock, ast_mutex_unlock, ast_test_flag, ast_test_flag64, errno, ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.
07559 { 07560 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07561 int res = -1; 07562 ast_mutex_lock(&iaxsl[callno]); 07563 if (iaxs[callno]) { 07564 /* If there's an outstanding error, return failure now */ 07565 if (!iaxs[callno]->error) { 07566 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) 07567 res = 0; 07568 /* Don't waste bandwidth sending null frames */ 07569 else if (f->frametype == AST_FRAME_NULL) 07570 res = 0; 07571 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH)) 07572 res = 0; 07573 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07574 res = 0; 07575 else 07576 /* Simple, just queue for transmission */ 07577 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07578 } else { 07579 ast_debug(1, "Write error: %s\n", strerror(errno)); 07580 } 07581 } 07582 /* If it's already gone, just return */ 07583 ast_mutex_unlock(&iaxsl[callno]); 07584 return res; 07585 }
| static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 3246 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().
Referenced by update_registry().
03247 { 03248 int res = 0; 03249 struct iax_firmware *cur = NULL; 03250 03251 if (ast_strlen_zero(dev)) 03252 return 0; 03253 03254 AST_LIST_LOCK(&firmwares); 03255 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03256 if (!strcmp(dev, (char *)cur->fwh->devname)) { 03257 res = ntohs(cur->fwh->version); 03258 break; 03259 } 03260 } 03261 AST_LIST_UNLOCK(&firmwares); 03262 03263 return res; 03264 }
| static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 1120 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
01121 { 01122 if (iaxdebug) 01123 ast_verbose("%s", data); 01124 }
| static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 1126 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
01127 { 01128 ast_log(LOG_WARNING, "%s", data); 01129 }
| static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
| const unsigned char * | dev, | |||
| unsigned int | desc | |||
| ) | [static] |
Definition at line 3266 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, and IAX_IE_FWBLOCKDESC.
Referenced by socket_process().
03267 { 03268 int res = -1; 03269 unsigned int bs = desc & 0xff; 03270 unsigned int start = (desc >> 8) & 0xffffff; 03271 unsigned int bytes; 03272 struct iax_firmware *cur; 03273 03274 if (ast_strlen_zero((char *)dev) || !bs) 03275 return -1; 03276 03277 start *= bs; 03278 03279 AST_LIST_LOCK(&firmwares); 03280 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03281 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 03282 continue; 03283 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 03284 if (start < ntohl(cur->fwh->datalen)) { 03285 bytes = ntohl(cur->fwh->datalen) - start; 03286 if (bytes > bs) 03287 bytes = bs; 03288 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 03289 } else { 03290 bytes = 0; 03291 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 03292 } 03293 if (bytes == bs) 03294 res = 0; 03295 else 03296 res = 1; 03297 break; 03298 } 03299 AST_LIST_UNLOCK(&firmwares); 03300 03301 return res; 03302 }
| static void iax_outputframe | ( | struct iax_frame * | f, | |
| struct ast_iax2_full_hdr * | fhi, | |||
| int | rx, | |||
| struct sockaddr_in * | sin, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 1103 of file chan_iax2.c.
References debugaddr, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), send_apathetic_reply(), send_packet(), and socket_process().
01104 { 01105 if (iaxdebug || 01106 (sin && debugaddr.sin_addr.s_addr && 01107 (!ntohs(debugaddr.sin_port) || 01108 debugaddr.sin_port == sin->sin_port) && 01109 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 01110 if (iaxdebug) { 01111 iax_showframe(f, fhi, rx, sin, datalen); 01112 } else { 01113 iaxdebug = 1; 01114 iax_showframe(f, fhi, rx, sin, datalen); 01115 iaxdebug = 0; 01116 } 01117 } 01118 }
| static int iax_park | ( | struct ast_channel * | chan1, | |
| struct ast_channel * | chan2, | |||
| const char * | park_exten, | |||
| const char * | park_context | |||
| ) | [static] |
DO NOT hold any locks while calling iax_park
Definition at line 9450 of file chan_iax2.c.
References ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_strdup, ast_string_field_set, iax_dual::chan1, iax_dual::chan2, ast_channel::context, ast_channel::exten, iax_park_thread(), iax_dual::park_context, iax_dual::park_exten, parkinglot, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
09451 { 09452 struct iax_dual *d; 09453 struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */ 09454 pthread_t th; 09455 09456 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 09457 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name); 09458 d = ast_calloc(1, sizeof(*d)); 09459 if (!chan1m || !chan2m || !d) { 09460 if (chan1m) { 09461 ast_hangup(chan1m); 09462 } 09463 if (chan2m) { 09464 ast_hangup(chan2m); 09465 } 09466 ast_free(d); 09467 return -1; 09468 } 09469 d->park_exten = ast_strdup(park_exten); 09470 d->park_context = ast_strdup(park_context); 09471 if (!d->park_exten || !d->park_context) { 09472 ast_hangup(chan1m); 09473 ast_hangup(chan2m); 09474 ast_free(d->park_exten); 09475 ast_free(d->park_context); 09476 ast_free(d); 09477 return -1; 09478 } 09479 09480 /* Make formats okay */ 09481 chan1m->readformat = chan1->readformat; 09482 chan1m->writeformat = chan1->writeformat; 09483 09484 /* Prepare for taking over the channel */ 09485 if (ast_channel_masquerade(chan1m, chan1)) { 09486 ast_hangup(chan1m); 09487 ast_hangup(chan2m); 09488 ast_free(d->park_exten); 09489 ast_free(d->park_context); 09490 ast_free(d); 09491 return -1; 09492 } 09493 09494 /* Setup the extensions and such */ 09495 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 09496 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 09497 chan1m->priority = chan1->priority; 09498 09499 ast_do_masquerade(chan1m); 09500 09501 /* We make a clone of the peer channel too, so we can play 09502 back the announcement */ 09503 09504 /* Make formats okay */ 09505 chan2m->readformat = chan2->readformat; 09506 chan2m->writeformat = chan2->writeformat; 09507 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot); 09508 09509 /* Prepare for taking over the channel */ 09510 if (ast_channel_masquerade(chan2m, chan2)) { 09511 ast_hangup(chan1m); 09512 ast_hangup(chan2m); 09513 ast_free(d->park_exten); 09514 ast_free(d->park_context); 09515 ast_free(d); 09516 return -1; 09517 } 09518 09519 /* Setup the extensions and such */ 09520 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 09521 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 09522 chan2m->priority = chan2->priority; 09523 09524 ast_do_masquerade(chan2m); 09525 09526 d->chan1 = chan1m; /* Transferee */ 09527 d->chan2 = chan2m; /* Transferer */ 09528 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) { 09529 /* Could not start thread */ 09530 ast_hangup(chan1m); 09531 ast_hangup(chan2m); 09532 ast_free(d->park_exten); 09533 ast_free(d->park_context); 09534 ast_free(d); 09535 return -1; 09536 } 09537 return 0; 09538 }
| static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 9423 of file chan_iax2.c.
References ast_debug, ast_free, ast_hangup(), ast_log(), ast_park_call_exten(), iax_dual::chan1, iax_dual::chan2, ext, LOG_NOTICE, iax_dual::park_context, and iax_dual::park_exten.
Referenced by iax_park().
09424 { 09425 struct iax_dual *d; 09426 int res; 09427 int ext = 0; 09428 09429 d = stuff; 09430 09431 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n", 09432 d->chan2->name, d->chan1->name); 09433 09434 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext); 09435 if (res) { 09436 /* Parking failed. */ 09437 ast_hangup(d->chan1); 09438 } else { 09439 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 09440 } 09441 ast_hangup(d->chan2); 09442 09443 ast_free(d->park_exten); 09444 ast_free(d->park_context); 09445 ast_free(d); 09446 return NULL; 09447 }
Definition at line 2040 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().
Referenced by socket_process(), and socket_process_meta().
02041 { 02042 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 02043 if (new) { 02044 size_t afdatalen = new->afdatalen; 02045 memcpy(new, fr, sizeof(*new)); 02046 iax_frame_wrap(new, &fr->af); 02047 new->afdatalen = afdatalen; 02048 new->data = NULL; 02049 new->datalen = 0; 02050 new->direction = DIRECTION_INGRESS; 02051 new->retrans = -1; 02052 } 02053 return new; 02054 }
| static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1462 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, and IAX_THREAD_TYPE_DYNAMIC.
Referenced by iax2_process_thread().
01463 { 01464 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01465 AST_LIST_LOCK(&dynamic_list); 01466 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01467 AST_LIST_UNLOCK(&dynamic_list); 01468 } else { 01469 AST_LIST_LOCK(&idle_list); 01470 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01471 AST_LIST_UNLOCK(&idle_list); 01472 } 01473 01474 return; 01475 }
| static void jb_debug_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1155 of file chan_iax2.c.
References args, and ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01156 { 01157 va_list args; 01158 char buf[1024]; 01159 01160 va_start(args, fmt); 01161 vsnprintf(buf, sizeof(buf), fmt, args); 01162 va_end(args); 01163 01164 ast_verbose("%s", buf); 01165 }
| static void jb_error_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1131 of file chan_iax2.c.
References args, ast_log(), and LOG_ERROR.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
| static void jb_warning_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1143 of file chan_iax2.c.
References args, ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01144 { 01145 va_list args; 01146 char buf[1024]; 01147 01148 va_start(args, fmt); 01149 vsnprintf(buf, sizeof(buf), fmt, args); 01150 va_end(args); 01151 01152 ast_log(LOG_WARNING, "%s", buf); 01153 }
| static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 14943 of file chan_iax2.c.
References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_custom_function_register, ast_data_register_multiple, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register_xml, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_mutex_init, ast_netsock_init(), ast_netsock_list_alloc(), ast_random(), ast_realtime_require_field(), ast_register_application_xml, ast_register_switch(), ast_sched_thread_create(), ast_sched_thread_destroy(), AST_TEST_REGISTER, ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, cli_iax2, config, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_data_providers, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax2_switch, iax2_tech, iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), iaxpeer_function, iaxs, iaxsl, iaxvar_function, io_context_create(), io_context_destroy(), jb_error_output(), jb_setoutput(), jb_warning_output(), load_objects(), LOG_ERROR, manager_iax2_show_netstats(), manager_iax2_show_peer_list(), manager_iax2_show_peers(), manager_iax2_show_registry(), network_change_event_subscribe(), papp, peer_set_sock_cb(), reload_firmware(), RQ_CHAR, RQ_UINTEGER2, SENTINEL, set_config(), and start_network_thread().
14944 { 14945 static const char config[] = "iax.conf"; 14946 int x = 0; 14947 struct iax2_registry *reg = NULL; 14948 14949 if (load_objects()) { 14950 return AST_MODULE_LOAD_FAILURE; 14951 } 14952 14953 memset(iaxs, 0, sizeof(iaxs)); 14954 14955 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14956 ast_mutex_init(&iaxsl[x]); 14957 } 14958 14959 if (!(sched = ast_sched_thread_create())) { 14960 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 14961 return AST_MODULE_LOAD_FAILURE; 14962 } 14963 14964 if (!(io = io_context_create())) { 14965 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 14966 sched = ast_sched_thread_destroy(sched); 14967 return AST_MODULE_LOAD_FAILURE; 14968 } 14969 14970 if (!(netsock = ast_netsock_list_alloc())) { 14971 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 14972 io_context_destroy(io); 14973 sched = ast_sched_thread_destroy(sched); 14974 return AST_MODULE_LOAD_FAILURE; 14975 } 14976 ast_netsock_init(netsock); 14977 14978 outsock = ast_netsock_list_alloc(); 14979 if (!outsock) { 14980 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 14981 io_context_destroy(io); 14982 sched = ast_sched_thread_destroy(sched); 14983 return AST_MODULE_LOAD_FAILURE; 14984 } 14985 ast_netsock_init(outsock); 14986 14987 randomcalltokendata = ast_random(); 14988 14989 iax_set_output(iax_debug_output); 14990 iax_set_error(iax_error_output); 14991 jb_setoutput(jb_error_output, jb_warning_output, NULL); 14992 14993 if ((timer = ast_timer_open())) { 14994 ast_timer_set_rate(timer, 1000 / trunkfreq); 14995 } 14996 14997 if (set_config(config, 0) == -1) { 14998 if (timer) { 14999 ast_timer_close(timer); 15000 timer = NULL; 15001 } 15002 return AST_MODULE_LOAD_DECLINE; 15003 } 15004 15005 #ifdef TEST_FRAMEWORK 15006 AST_TEST_REGISTER(test_iax2_peers_get); 15007 AST_TEST_REGISTER(test_iax2_users_get); 15008 #endif 15009 15010 /* Register AstData providers */ 15011 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers)); 15012 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 15013 15014 ast_register_application_xml(papp, iax2_prov_app); 15015 15016 ast_custom_function_register(&iaxpeer_function); 15017 ast_custom_function_register(&iaxvar_function); 15018 15019 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers); 15020 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list); 15021 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats); 15022 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry); 15023 15024 if (ast_channel_register(&iax2_tech)) { 15025 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 15026 __unload_module(); 15027 return AST_MODULE_LOAD_FAILURE; 15028 } 15029 15030 if (ast_register_switch(&iax2_switch)) { 15031 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 15032 } 15033 15034 if (start_network_thread()) { 15035 ast_log(LOG_ERROR, "Unable to start network thread\n"); 15036 __unload_module(); 15037 return AST_MODULE_LOAD_FAILURE; 15038 } else { 15039 ast_verb(2, "IAX Ready and Listening\n"); 15040 } 15041 15042 AST_LIST_LOCK(®istrations); 15043 AST_LIST_TRAVERSE(®istrations, reg, entry) 15044 iax2_do_register(reg); 15045 AST_LIST_UNLOCK(®istrations); 15046 15047 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 15048 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 15049 15050 15051 reload_firmware(0); 15052 iax_provision_reload(0); 15053 15054 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 15055 15056 network_change_event_subscribe(); 15057 15058 return AST_MODULE_LOAD_SUCCESS; 15059 }
| static int load_objects | ( | void | ) | [static] |
Definition at line 14705 of file chan_iax2.c.
References addr_range_cmp_cb(), addr_range_hash_cb(), ao2_container_alloc, ao2_ref, AST_MODULE_LOAD_FAILURE, ast_taskprocessor_get(), create_callno_pools(), iax_peercallno_pvts, iax_transfercallno_pvts, MAX_PEER_BUCKETS, MAX_USER_BUCKETS, peer_cmp_cb(), peer_hash_cb(), peercnt_cmp_cb(), peercnt_hash_cb(), pvt_cmp_cb(), pvt_hash_cb(), TPS_REF_DEFAULT, transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), and user_hash_cb().
Referenced by load_module().
14706 { 14707 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 14708 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 14709 14710 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 14711 goto container_fail; 14712 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 14713 goto container_fail; 14714 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 14715 goto container_fail; 14716 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 14717 goto container_fail; 14718 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 14719 goto container_fail; 14720 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14721 goto container_fail; 14722 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14723 goto container_fail; 14724 } else if (create_callno_pools()) { 14725 goto container_fail; 14726 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) { 14727 goto container_fail; 14728 } 14729 14730 return 0; 14731 14732 container_fail: 14733 if (peers) { 14734 ao2_ref(peers, -1); 14735 } 14736 if (users) { 14737 ao2_ref(users, -1); 14738 } 14739 if (iax_peercallno_pvts) { 14740 ao2_ref(iax_peercallno_pvts, -1); 14741 } 14742 if (iax_transfercallno_pvts) { 14743 ao2_ref(iax_transfercallno_pvts, -1); 14744 } 14745 if (peercnts) { 14746 ao2_ref(peercnts, -1); 14747 } 14748 if (callno_limits) { 14749 ao2_ref(callno_limits, -1); 14750 } 14751 if (calltoken_ignores) { 14752 ao2_ref(calltoken_ignores, -1); 14753 } 14754 if (callno_pool) { 14755 ao2_ref(callno_pool, -1); 14756 } 14757 if (callno_pool_trunk) { 14758 ao2_ref(callno_pool_trunk, -1); 14759 } 14760 return AST_MODULE_LOAD_FAILURE; 14761 }
| static void lock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5547 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
05548 { 05549 ast_mutex_lock(&iaxsl[callno0]); 05550 while (ast_mutex_trylock(&iaxsl[callno1])) { 05551 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05552 } 05553 }
| static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9610 of file chan_iax2.c.
References ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, jb_info::current, EVENT_FLAG_REPORTING, jb_info::frames_dropped, jb_info::frames_in, jb_info::frames_lost, jb_info::frames_ooo, IAX_USEJITTERBUF, iaxs, iaxsl, ast_channel::jb, jb_getinfo(), jb_info::jitter, jb_info::losspct, manager_event, jb_info::min, and chan_iax2_pvt::pingtime.
Referenced by socket_process().
09611 { 09612 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09613 jb_info jbinfo; 09614 09615 ast_mutex_lock(&iaxsl[callno]); 09616 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 09617 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) { 09618 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09619 localjitter = jbinfo.jitter; 09620 localdelay = jbinfo.current - jbinfo.min; 09621 locallost = jbinfo.frames_lost; 09622 locallosspct = jbinfo.losspct/1000; 09623 localdropped = jbinfo.frames_dropped; 09624 localooo = jbinfo.frames_ooo; 09625 localpackets = jbinfo.frames_in; 09626 } 09627 ast_debug(3, "JB STATS:%s ping=%u 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", 09628 iaxs[callno]->owner->name, 09629 iaxs[callno]->pingtime, 09630 localjitter, 09631 localdelay, 09632 locallost, 09633 locallosspct, 09634 localdropped, 09635 localooo, 09636 localpackets, 09637 iaxs[callno]->remote_rr.jitter, 09638 iaxs[callno]->remote_rr.delay, 09639 iaxs[callno]->remote_rr.losscnt, 09640 iaxs[callno]->remote_rr.losspct/1000, 09641 iaxs[callno]->remote_rr.dropped, 09642 iaxs[callno]->remote_rr.ooo, 09643 iaxs[callno]->remote_rr.packets); 09644 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %u\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", 09645 iaxs[callno]->owner->name, 09646 iaxs[callno]->pingtime, 09647 localjitter, 09648 localdelay, 09649 locallost, 09650 locallosspct, 09651 localdropped, 09652 localooo, 09653 localpackets, 09654 iaxs[callno]->remote_rr.jitter, 09655 iaxs[callno]->remote_rr.delay, 09656 iaxs[callno]->remote_rr.losscnt, 09657 iaxs[callno]->remote_rr.losspct/1000, 09658 iaxs[callno]->remote_rr.dropped, 09659 iaxs[callno]->remote_rr.ooo, 09660 iaxs[callno]->remote_rr.packets); 09661 } 09662 ast_mutex_unlock(&iaxsl[callno]); 09663 }
| static int make_trunk | ( | unsigned short | callno, | |
| int | locked | |||
| ) | [static] |
Definition at line 2135 of file chan_iax2.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), iax2_sched_add(), iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, replace_callno(), send_lagrq(), send_ping(), update_max_nontrunk, update_max_trunk, and callno_entry::validated.
Referenced by iax2_request(), and socket_process().
02136 { 02137 int x; 02138 int res= 0; 02139 struct callno_entry *callno_entry; 02140 if (iaxs[callno]->oseqno) { 02141 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 02142 return -1; 02143 } 02144 if (callno >= TRUNK_CALL_START) { 02145 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 02146 return -1; 02147 } 02148 02149 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 02150 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 02151 return -1; 02152 } 02153 02154 x = callno_entry->callno; 02155 ast_mutex_lock(&iaxsl[x]); 02156 02157 /*! 02158 * \note We delete these before switching the slot, because if 02159 * they fire in the meantime, they will generate a warning. 02160 */ 02161 ast_sched_thread_del(sched, iaxs[callno]->pingid); 02162 ast_sched_thread_del(sched, iaxs[callno]->lagid); 02163 iaxs[callno]->lagid = iaxs[callno]->pingid = -1; 02164 iaxs[x] = iaxs[callno]; 02165 iaxs[x]->callno = x; 02166 02167 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 02168 * before assigning the new one */ 02169 if (iaxs[x]->callno_entry) { 02170 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 02171 } 02172 iaxs[x]->callno_entry = callno_entry; 02173 02174 iaxs[callno] = NULL; 02175 /* Update the two timers that should have been started */ 02176 iaxs[x]->pingid = iax2_sched_add(sched, 02177 ping_time * 1000, send_ping, (void *)(long)x); 02178 iaxs[x]->lagid = iax2_sched_add(sched, 02179 lagrq_time * 1000, send_lagrq, (void *)(long)x); 02180 02181 if (locked) 02182 ast_mutex_unlock(&iaxsl[callno]); 02183 res = x; 02184 if (!locked) 02185 ast_mutex_unlock(&iaxsl[x]); 02186 02187 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 02188 /* We move this call from a non-trunked to a trunked call */ 02189 update_max_trunk(); 02190 update_max_nontrunk(); 02191 return res; 02192 }
| static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 7059 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
07060 { 07061 ast_cli_netstats(s, -1, 0); 07062 astman_append(s, "\r\n"); 07063 return RESULT_SUCCESS; 07064 }
| static int manager_iax2_show_peer_list | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
callback to display iax peers in manager format
Definition at line 7122 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), astman_get_header(), iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, peer_status(), peer_unref(), RESULT_SUCCESS, and status.
Referenced by load_module().
07123 { 07124 struct iax2_peer *peer = NULL; 07125 int peer_count = 0; 07126 char nm[20]; 07127 char status[20]; 07128 const char *id = astman_get_header(m,"ActionID"); 07129 char idtext[256] = ""; 07130 struct ast_str *encmethods = ast_str_alloca(256); 07131 struct ao2_iterator i; 07132 07133 if (!ast_strlen_zero(id)) 07134 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07135 07136 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 07137 07138 07139 i = ao2_iterator_init(peers, 0); 07140 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 07141 encmethods_to_str(peer->encmethods, &encmethods); 07142 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 07143 if (!ast_strlen_zero(peer->username)) { 07144 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 07145 } else { 07146 astman_append(s, "ObjectName: %s\r\n", peer->name); 07147 } 07148 astman_append(s, "ChanObjectType: peer\r\n"); 07149 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr)); 07150 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 07151 astman_append(s, "Mask: %s\r\n", nm); 07152 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr)); 07153 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 07154 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 07155 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 07156 peer_status(peer, status, sizeof(status)); 07157 astman_append(s, "Status: %s\r\n\r\n", status); 07158 peer_count++; 07159 } 07160 ao2_iterator_destroy(&i); 07161 07162 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 07163 return RESULT_SUCCESS; 07164 }
| static int manager_iax2_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
callback to display iax peers in manager
Definition at line 7098 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.
Referenced by load_module().
07099 { 07100 static const char * const a[] = { "iax2", "show", "peers" }; 07101 const char *id = astman_get_header(m,"ActionID"); 07102 char idtext[256] = ""; 07103 int total = 0; 07104 07105 if (!ast_strlen_zero(id)) 07106 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07107 07108 astman_send_listack(s, m, "Peer status list will follow", "start"); 07109 /* List the peers in separate manager events */ 07110 __iax2_show_peers(-1, &total, s, 3, a); 07111 /* Send final confirmation */ 07112 astman_append(s, 07113 "Event: PeerlistComplete\r\n" 07114 "EventList: Complete\r\n" 07115 "ListItems: %d\r\n" 07116 "%s" 07117 "\r\n", total, idtext); 07118 return 0; 07119 }
| static int manager_iax2_show_registry | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 7230 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), iax2_registry::dnsmgr, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.
Referenced by load_module().
07231 { 07232 const char *id = astman_get_header(m, "ActionID"); 07233 struct iax2_registry *reg = NULL; 07234 char idtext[256] = ""; 07235 char host[80] = ""; 07236 char perceived[80] = ""; 07237 int total = 0; 07238 07239 if (!ast_strlen_zero(id)) 07240 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07241 07242 astman_send_listack(s, m, "Registrations will follow", "start"); 07243 07244 AST_LIST_LOCK(®istrations); 07245 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07246 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07247 07248 if (reg->us.sin_addr.s_addr) { 07249 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07250 } else { 07251 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07252 } 07253 07254 astman_append(s, 07255 "Event: RegistryEntry\r\n" 07256 "%s" 07257 "Host: %s\r\n" 07258 "DNSmanager: %s\r\n" 07259 "Username: %s\r\n" 07260 "Perceived: %s\r\n" 07261 "Refresh: %d\r\n" 07262 "State: %s\r\n" 07263 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 07264 reg->refresh, regstate2str(reg->regstate)); 07265 07266 total++; 07267 } 07268 AST_LIST_UNLOCK(®istrations); 07269 07270 astman_append(s, 07271 "Event: RegistrationsComplete\r\n" 07272 "EventList: Complete\r\n" 07273 "ListItems: %d\r\n" 07274 "%s" 07275 "\r\n", total, idtext); 07276 07277 return 0; 07278 }
| static int match | ( | struct sockaddr_in * | sin, | |
| unsigned short | callno, | |||
| unsigned short | dcallno, | |||
| const struct chan_iax2_pvt * | cur, | |||
| int | check_dcallno | |||
| ) | [static] |
Definition at line 2069 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), __get_header(), ast_parse_device_state(), ast_srtp_add_stream(), ast_srtp_change_source(), check_blacklist(), find_by_name(), find_command(), handle_updates(), internal_ao2_callback(), lua_find_extension(), misdn_update_redirecting(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), transfercallno_pvt_cmp_cb(), and xmldoc_attribute_match().
02070 { 02071 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 02072 (cur->addr.sin_port == sin->sin_port)) { 02073 /* This is the main host */ 02074 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 02075 (check_dcallno ? dcallno == cur->callno : 1) ) { 02076 /* That's us. Be sure we keep track of the peer call number */ 02077 return 1; 02078 } 02079 } 02080 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 02081 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 02082 /* We're transferring */ 02083 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 02084 return 1; 02085 } 02086 return 0; 02087 }
| static void memcpy_decrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_decrypt_key * | dcx | |||
| ) | [static] |
Definition at line 6315 of file chan_iax2.c.
References ast_aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
06316 { 06317 #if 0 06318 /* Debug with "fake encryption" */ 06319 int x; 06320 if (len % 16) 06321 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06322 for (x=0;x<len;x++) 06323 dst[x] = src[x] ^ 0xff; 06324 #else 06325 unsigned char lastblock[16] = { 0 }; 06326 int x; 06327 while(len > 0) { 06328 ast_aes_decrypt(src, dst, dcx); 06329 for (x=0;x<16;x++) 06330 dst[x] ^= lastblock[x]; 06331 memcpy(lastblock, src, sizeof(lastblock)); 06332 dst += 16; 06333 src += 16; 06334 len -= 16; 06335 } 06336 #endif 06337 }
| static void memcpy_encrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_encrypt_key * | ecx | |||
| ) | [static] |
Definition at line 6339 of file chan_iax2.c.
References ast_aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
06340 { 06341 #if 0 06342 /* Debug with "fake encryption" */ 06343 int x; 06344 if (len % 16) 06345 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06346 for (x=0;x<len;x++) 06347 dst[x] = src[x] ^ 0xff; 06348 #else 06349 unsigned char curblock[16] = { 0 }; 06350 int x; 06351 while(len > 0) { 06352 for (x=0;x<16;x++) 06353 curblock[x] ^= src[x]; 06354 ast_aes_encrypt(curblock, dst, ecx); 06355 memcpy(curblock, dst, sizeof(curblock)); 06356 dst += 16; 06357 src += 16; 06358 len -= 16; 06359 } 06360 #endif 06361 }
| static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | enc | |||
| ) | [static] |
Definition at line 7909 of file chan_iax2.c.
References chan_iax2_pvt::encmethods, IAX_ENCRYPT_AES128, IAX_ENCRYPT_KEYROTATE, and chan_iax2_pvt::keyrotateid.
Referenced by authenticate_reply(), and socket_process().
07910 { 07911 /* Select exactly one common encryption if there are any */ 07912 p->encmethods &= enc; 07913 if (p->encmethods) { 07914 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07915 p->keyrotateid = -2; 07916 } 07917 if (p->encmethods & IAX_ENCRYPT_AES128) 07918 p->encmethods = IAX_ENCRYPT_AES128; 07919 else 07920 p->encmethods = 0; 07921 } 07922 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 1359 of file chan_iax2.c.
Referenced by build_peer().
| static void network_change_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 1394 of file chan_iax2.c.
References ast_debug, iax2_sched_add(), and network_change_event_sched_cb().
Referenced by network_change_event_subscribe().
01395 { 01396 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n"); 01397 if (network_change_event_sched_id == -1) { 01398 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 01399 } 01400 01401 }
| static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 1381 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and iax2_do_register().
Referenced by network_change_event_cb().
01382 { 01383 struct iax2_registry *reg; 01384 network_change_event_sched_id = -1; 01385 AST_LIST_LOCK(®istrations); 01386 AST_LIST_TRAVERSE(®istrations, reg, entry) { 01387 iax2_do_register(reg); 01388 } 01389 AST_LIST_UNLOCK(®istrations); 01390 01391 return 0; 01392 }
| static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 1366 of file chan_iax2.c.
References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), and network_change_event_cb().
Referenced by load_module(), and set_config().
01367 { 01368 if (!network_change_event_subscription) { 01369 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 01370 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END); 01371 } 01372 }
| static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 1374 of file chan_iax2.c.
References ast_event_unsubscribe().
Referenced by __unload_module(), and set_config().
01375 { 01376 if (network_change_event_subscription) { 01377 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 01378 } 01379 }
| static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 12402 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_timer_fd(), and timing_read().
Referenced by start_network_thread().
12403 { 12404 if (timer) { 12405 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 12406 } 12407 12408 for (;;) { 12409 pthread_testcancel(); 12410 /* Wake up once a second just in case SIGURG was sent while 12411 * we weren't in poll(), to make sure we don't hang when trying 12412 * to unload. */ 12413 if (ast_io_wait(io, 1000) <= 0) { 12414 break; 12415 } 12416 } 12417 12418 return NULL; 12419 }
| static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
| const char * | host | |||
| ) | [static, read] |
Definition at line 1998 of file chan_iax2.c.
References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, exten, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, pvt_destructor(), jb_conf::resync_threshold, and jb_conf::target_extra.
Referenced by __find_callno().
01999 { 02000 struct chan_iax2_pvt *tmp; 02001 jb_conf jbconf; 02002 02003 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 02004 return NULL; 02005 } 02006 02007 if (ast_string_field_init(tmp, 32)) { 02008 ao2_ref(tmp, -1); 02009 tmp = NULL; 02010 return NULL; 02011 } 02012 02013 tmp->prefs = prefs; 02014 tmp->pingid = -1; 02015 tmp->lagid = -1; 02016 tmp->autoid = -1; 02017 tmp->authid = -1; 02018 tmp->initid = -1; 02019 tmp->keyrotateid = -1; 02020 02021 ast_string_field_set(tmp,exten, "s"); 02022 ast_string_field_set(tmp,host, host); 02023 02024 tmp->jb = jb_new(); 02025 tmp->jbid = -1; 02026 jbconf.max_jitterbuf = maxjitterbuffer; 02027 jbconf.resync_threshold = resyncthreshold; 02028 jbconf.max_contig_interp = maxjitterinterps; 02029 jbconf.target_extra = jittertargetextra; 02030 jb_setconf(tmp->jb,&jbconf); 02031 02032 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 02033 02034 tmp->hold_signaling = 1; 02035 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 02036 02037 return tmp; 02038 }
| static void parse_dial_string | ( | char * | data, | |
| struct parsed_dial_string * | pds | |||
| ) | [static] |
Parses an IAX dial string into its component parts.
| data | the string to be parsed | |
| pds | pointer to a struct parsed_dial_string to be filled in |
This function parses the string and fills the structure with pointers to its component parts. The input string will be modified.
Definition at line 5069 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
05070 { 05071 if (ast_strlen_zero(data)) 05072 return; 05073 05074 pds->peer = strsep(&data, "/"); 05075 pds->exten = strsep(&data, "/"); 05076 pds->options = data; 05077 05078 if (pds->exten) { 05079 data = pds->exten; 05080 pds->exten = strsep(&data, "@"); 05081 pds->context = data; 05082 } 05083 05084 if (strchr(pds->peer, '@')) { 05085 data = pds->peer; 05086 pds->username = strsep(&data, "@"); 05087 pds->peer = data; 05088 } 05089 05090 if (pds->username) { 05091 data = pds->username; 05092 pds->username = strsep(&data, ":"); 05093 pds->password = data; 05094 } 05095 05096 data = pds->peer; 05097 pds->peer = strsep(&data, ":"); 05098 pds->port = data; 05099 05100 /* check for a key name wrapped in [] in the secret position, if found, 05101 move it to the key field instead 05102 */ 05103 if (pds->password && (pds->password[0] == '[')) { 05104 pds->key = ast_strip_quoted(pds->password, "[", "]"); 05105 pds->password = NULL; 05106 } 05107 }
| static int peer_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1738 of file chan_iax2.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
| static int peer_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 13163 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
13164 { 13165 struct iax2_peer *peer = obj; 13166 13167 ast_set_flag64(peer, IAX_DELME); 13168 13169 return 0; 13170 }
| static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 12592 of file chan_iax2.c.
References ast_dnsmgr_release(), ast_event_unsubscribe(), ast_free_ha(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_free_memory, iax2_peer::callno, iax2_peer::dnsmgr, iax2_peer::ha, iax2_destroy(), iaxsl, iax2_peer::mwi_event_sub, and register_peer_exten().
Referenced by build_peer().
12593 { 12594 struct iax2_peer *peer = obj; 12595 int callno = peer->callno; 12596 12597 ast_free_ha(peer->ha); 12598 12599 if (callno > 0) { 12600 ast_mutex_lock(&iaxsl[callno]); 12601 iax2_destroy(callno); 12602 ast_mutex_unlock(&iaxsl[callno]); 12603 } 12604 12605 register_peer_exten(peer, 0); 12606 12607 if (peer->dnsmgr) 12608 ast_dnsmgr_release(peer->dnsmgr); 12609 12610 if (peer->mwi_event_sub) 12611 ast_event_unsubscribe(peer->mwi_event_sub); 12612 12613 ast_string_field_free_memory(peer); 12614 }
| static int peer_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1728 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_objects().
01729 { 01730 const struct iax2_peer *peer = obj; 01731 01732 return ast_str_hash(peer->name); 01733 }
Definition at line 1785 of file chan_iax2.c.
References ao2_ref.
Referenced by __iax2_poke_noanswer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), iax2_poke_peer(), realtime_peer(), reg_source_db(), socket_process(), and update_registry().
01786 { 01787 ao2_ref(peer, +1); 01788 return peer; 01789 }
| static int peer_set_sock_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 14659 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
14660 { 14661 struct iax2_peer *peer = obj; 14662 14663 if (peer->sockfd < 0) 14664 peer->sockfd = defaultsockfd; 14665 14666 return 0; 14667 }
| static int peer_set_srcaddr | ( | struct iax2_peer * | peer, | |
| const char * | srcaddr | |||
| ) | [static] |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found.
Definition at line 12519 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_sockaddr_to_sin, ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_WARNING, qos, socket_read(), iax2_peer::sockfd, iax2_trunk_peer::sockfd, and ast_sockaddr::ss.
Referenced by build_peer().
12520 { 12521 struct sockaddr_in sin; 12522 struct ast_sockaddr sin_tmp; 12523 int nonlocal = 1; 12524 int port = IAX_DEFAULT_PORTNO; 12525 int sockfd = defaultsockfd; 12526 char *tmp; 12527 char *addr; 12528 char *portstr; 12529 12530 tmp = ast_strdupa(srcaddr); 12531 addr = strsep(&tmp, ":"); 12532 portstr = tmp; 12533 12534 if (portstr) { 12535 port = atoi(portstr); 12536 if (port < 1) 12537 port = IAX_DEFAULT_PORTNO; 12538 } 12539 12540 sin_tmp.ss.ss_family = AF_INET; 12541 if (!ast_get_ip(&sin_tmp, addr)) { 12542 struct ast_netsock *sock; 12543 int res; 12544 12545 ast_sockaddr_to_sin(&sin_tmp, &sin); 12546 sin.sin_port = 0; 12547 sin.sin_family = AF_INET; 12548 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 12549 if (res == 0) { 12550 /* ip address valid. */ 12551 sin.sin_port = htons(port); 12552 if (!(sock = ast_netsock_find(netsock, &sin))) 12553 sock = ast_netsock_find(outsock, &sin); 12554 if (sock) { 12555 sockfd = ast_netsock_sockfd(sock); 12556 nonlocal = 0; 12557 } else { 12558 unsigned int orig_saddr = sin.sin_addr.s_addr; 12559 /* INADDR_ANY matches anyway! */ 12560 sin.sin_addr.s_addr = INADDR_ANY; 12561 if (ast_netsock_find(netsock, &sin)) { 12562 sin.sin_addr.s_addr = orig_saddr; 12563 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 12564 if (sock) { 12565 sockfd = ast_netsock_sockfd(sock); 12566 ast_netsock_unref(sock); 12567 nonlocal = 0; 12568 } else { 12569 nonlocal = 2; 12570 } 12571 } 12572 } 12573 } 12574 } 12575 12576 peer->sockfd = sockfd; 12577 12578 if (nonlocal == 1) { 12579 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 12580 srcaddr, peer->name); 12581 return -1; 12582 } else if (nonlocal == 2) { 12583 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 12584 srcaddr, peer->name); 12585 return -1; 12586 } else { 12587 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 12588 return 0; 12589 } 12590 }
| static int peer_status | ( | struct iax2_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
peer_status: Report Peer status in character string
Definition at line 3812 of file chan_iax2.c.
References ast_copy_string(), iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), function_iaxpeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().
03813 { 03814 int res = 0; 03815 if (peer->maxms) { 03816 if (peer->lastms < 0) { 03817 ast_copy_string(status, "UNREACHABLE", statuslen); 03818 } else if (peer->lastms > peer->maxms) { 03819 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03820 res = 1; 03821 } else if (peer->lastms) { 03822 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03823 res = 1; 03824 } else { 03825 ast_copy_string(status, "UNKNOWN", statuslen); 03826 } 03827 } else { 03828 ast_copy_string(status, "Unmonitored", statuslen); 03829 res = -1; 03830 } 03831 return res; 03832 }
Definition at line 1791 of file chan_iax2.c.
References ao2_ref.
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), calltoken_required(), complete_iax2_peers(), complete_iax2_unregister(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), poke_all_peers(), prune_peers(), realtime_peer(), reg_source_db(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().
01792 { 01793 ao2_ref(peer, -1); 01794 return NULL; 01795 }
| static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2432 of file chan_iax2.c.
References iax2_trunk_peer::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_inet_ntoa(), ast_log(), LOG_ERROR, OBJ_POINTER, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
02433 { 02434 struct peercnt *peercnt; 02435 unsigned long addr = sin->sin_addr.s_addr; 02436 int res = 0; 02437 struct peercnt tmp = { 02438 .addr = addr, 02439 }; 02440 02441 /* Reasoning for peercnts container lock: Two identical ip addresses 02442 * could be added by different threads at the "same time". Without the container 02443 * lock, both threads could alloc space for the same object and attempt 02444 * to link to table. With the lock, one would create the object and link 02445 * to table while the other would find the already created peercnt object 02446 * rather than creating a new one. */ 02447 ao2_lock(peercnts); 02448 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02449 ao2_lock(peercnt); 02450 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02451 ao2_lock(peercnt); 02452 /* create and set defaults */ 02453 peercnt->addr = addr; 02454 set_peercnt_limit(peercnt); 02455 /* guarantees it does not go away after unlocking table 02456 * ao2_find automatically adds this */ 02457 ao2_link(peercnts, peercnt); 02458 } else { 02459 ao2_unlock(peercnts); 02460 return -1; 02461 } 02462 02463 /* check to see if the address has hit its callno limit. If not increment cur. */ 02464 if (peercnt->limit > peercnt->cur) { 02465 peercnt->cur++; 02466 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02467 } else { /* max num call numbers for this peer has been reached! */ 02468 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02469 res = -1; 02470 } 02471 02472 /* clean up locks and ref count */ 02473 ao2_unlock(peercnt); 02474 ao2_unlock(peercnts); 02475 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02476 02477 return res; 02478 }
| static int peercnt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2262 of file chan_iax2.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
| static int peercnt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2256 of file chan_iax2.c.
Referenced by load_objects().
| static void peercnt_modify | ( | unsigned char | reg, | |
| uint16_t | limit, | |||
| struct ast_sockaddr * | sockaddr | |||
| ) | [static] |
Definition at line 2399 of file chan_iax2.c.
References ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), ast_sockaddr_to_sin, OBJ_POINTER, and set_peercnt_limit().
Referenced by __expire_registry(), build_peer(), and update_registry().
02400 { 02401 /* this function turns off and on custom callno limits set by peer registration */ 02402 struct peercnt *peercnt; 02403 struct peercnt tmp = { 02404 .addr = 0, 02405 }; 02406 struct sockaddr_in sin; 02407 02408 ast_sockaddr_to_sin(sockaddr, &sin); 02409 02410 tmp.addr = sin.sin_addr.s_addr; 02411 02412 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02413 peercnt->reg = reg; 02414 if (limit) { 02415 peercnt->limit = limit; 02416 } else { 02417 set_peercnt_limit(peercnt); 02418 } 02419 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg); 02420 ao2_ref(peercnt, -1); /* decrement ref from find */ 02421 } 02422 }
| static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2484 of file chan_iax2.c.
References ao2_lock, ao2_unlink, ao2_unlock, ast_debug, and ast_inet_ntoa().
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
02485 { 02486 struct sockaddr_in sin = { 02487 .sin_addr.s_addr = peercnt->addr, 02488 }; 02489 02490 /* 02491 * Container locked here since peercnt may be unlinked from 02492 * list. If left unlocked, peercnt_add could try and grab this 02493 * entry from the table and modify it at the "same time" this 02494 * thread attemps to unlink it. 02495 */ 02496 ao2_lock(peercnts); 02497 peercnt->cur--; 02498 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02499 /* if this was the last connection from the peer remove it from table */ 02500 if (peercnt->cur == 0) { 02501 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02502 } 02503 ao2_unlock(peercnts); 02504 }
| static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2524 of file chan_iax2.c.
References ao2_find, ao2_ref, OBJ_POINTER, and peercnt_remove().
Referenced by __find_callno(), and complete_transfer().
02525 { 02526 struct peercnt *peercnt; 02527 struct peercnt tmp = { 02528 .addr = sin->sin_addr.s_addr, 02529 }; 02530 02531 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02532 peercnt_remove(peercnt); 02533 ao2_ref(peercnt, -1); /* decrement ref from find */ 02534 } 02535 return 0; 02536 }
| static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2510 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02511 { 02512 struct peercnt *peercnt = (struct peercnt *) obj; 02513 02514 peercnt_remove(peercnt); 02515 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02516 02517 return 0; 02518 }
| static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 14793 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_host(), ast_str_alloca, ast_str_buffer(), ast_test_flag64, iax2_peer::capability, iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, peer_status(), peer_unref(), and status.
14795 { 14796 struct ast_data *data_peer; 14797 struct iax2_peer *peer; 14798 struct ao2_iterator i; 14799 char status[20]; 14800 struct ast_str *encmethods = ast_str_alloca(256); 14801 14802 i = ao2_iterator_init(peers, 0); 14803 while ((peer = ao2_iterator_next(&i))) { 14804 data_peer = ast_data_add_node(data_root, "peer"); 14805 if (!data_peer) { 14806 peer_unref(peer); 14807 continue; 14808 } 14809 14810 ast_data_add_structure(iax2_peer, data_peer, peer); 14811 14812 ast_data_add_codecs(data_peer, "codecs", peer->capability); 14813 14814 peer_status(peer, status, sizeof(status)); 14815 ast_data_add_str(data_peer, "status", status); 14816 14817 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr)); 14818 14819 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask)); 14820 14821 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr)); 14822 14823 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK)); 14824 14825 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC)); 14826 14827 encmethods_to_str(peer->encmethods, &encmethods); 14828 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no"); 14829 14830 peer_unref(peer); 14831 14832 if (!ast_data_search_match(search, data_peer)) { 14833 ast_data_remove_node(data_root, data_peer); 14834 } 14835 } 14836 ao2_iterator_destroy(&i); 14837 14838 return 0; 14839 }
| static void poke_all_peers | ( | void | ) | [static] |
Definition at line 13742 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, iax2_poke_peer(), and peer_unref().
Referenced by reload_config().
13743 { 13744 struct ao2_iterator i; 13745 struct iax2_peer *peer; 13746 13747 i = ao2_iterator_init(peers, 0); 13748 while ((peer = ao2_iterator_next(&i))) { 13749 iax2_poke_peer(peer, 0); 13750 peer_unref(peer); 13751 } 13752 ao2_iterator_destroy(&i); 13753 }
| static int prune_addr_range_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2388 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02389 { 02390 struct addr_range *addr_range = obj; 02391 02392 return addr_range->delme ? CMP_MATCH : 0; 02393 }
| static void prune_peers | ( | void | ) | [static] |
Definition at line 13226 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), and unlink_peer().
Referenced by handle_cli_iax2_prune_realtime(), and reload_config().
13227 { 13228 struct iax2_peer *peer; 13229 struct ao2_iterator i; 13230 13231 i = ao2_iterator_init(peers, 0); 13232 while ((peer = ao2_iterator_next(&i))) { 13233 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 13234 unlink_peer(peer); 13235 } 13236 peer_unref(peer); 13237 } 13238 ao2_iterator_destroy(&i); 13239 }
| static void prune_users | ( | void | ) | [static] |
Definition at line 13210 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, and user_unref().
Referenced by handle_cli_iax2_prune_realtime(), and reload_config().
13211 { 13212 struct iax2_user *user; 13213 struct ao2_iterator i; 13214 13215 i = ao2_iterator_init(users, 0); 13216 while ((user = ao2_iterator_next(&i))) { 13217 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 13218 ao2_unlink(users, user); 13219 } 13220 user_unref(user); 13221 } 13222 ao2_iterator_destroy(&i); 13223 }
| static int pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 14676 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by load_objects().
14677 { 14678 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14679 14680 /* The frames_received field is used to hold whether we're matching 14681 * against a full frame or not ... */ 14682 14683 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 14684 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14685 }
| static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1951 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, jb_frame::data, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, and sched_delay_remove().
Referenced by new_iax().
01952 { 01953 struct chan_iax2_pvt *pvt = obj; 01954 struct iax_frame *cur = NULL; 01955 struct signaling_queue_entry *s = NULL; 01956 01957 ast_mutex_lock(&iaxsl[pvt->callno]); 01958 01959 iax2_destroy_helper(pvt); 01960 01961 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01962 pvt->callno_entry = NULL; 01963 01964 /* Already gone */ 01965 ast_set_flag64(pvt, IAX_ALREADYGONE); 01966 01967 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) { 01968 /* Cancel any pending transmissions */ 01969 cur->retries = -1; 01970 } 01971 01972 ast_mutex_unlock(&iaxsl[pvt->callno]); 01973 01974 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01975 free_signaling_queue_entry(s); 01976 } 01977 01978 if (pvt->reg) { 01979 pvt->reg->callno = 0; 01980 } 01981 01982 if (!pvt->owner) { 01983 jb_frame frame; 01984 if (pvt->vars) { 01985 ast_variables_destroy(pvt->vars); 01986 pvt->vars = NULL; 01987 } 01988 01989 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01990 iax2_frame_free(frame.data); 01991 } 01992 01993 jb_destroy(pvt->jb); 01994 ast_string_field_free_memory(pvt); 01995 } 01996 }
| static int pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 14669 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_objects().
14670 { 14671 const struct chan_iax2_pvt *pvt = obj; 14672 14673 return pvt->peercallno; 14674 }
| static int queue_signalling | ( | struct chan_iax2_pvt * | pvt, | |
| struct ast_frame * | f | |||
| ) | [static] |
All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
Definition at line 1926 of file chan_iax2.c.
References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, ast_malloc, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, ast_frame::frametype, free_signaling_queue_entry(), and ast_frame::ptr.
Referenced by __send_command().
01927 { 01928 struct signaling_queue_entry *qe; 01929 01930 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01931 return 1; /* do not queue this frame */ 01932 } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01933 return -1; /* out of memory */ 01934 } 01935 01936 /* copy ast_frame into our queue entry */ 01937 qe->f = *f; 01938 if (qe->f.datalen) { 01939 /* if there is data in this frame copy it over as well */ 01940 if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) { 01941 free_signaling_queue_entry(qe); 01942 return -1; 01943 } 01944 memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen); 01945 } 01946 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, qe, next); 01947 01948 return 0; 01949 }
| static int raw_hangup | ( | struct sockaddr_in * | sin, | |
| unsigned short | src, | |||
| unsigned short | dst, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 7890 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_inet_ntoa(), compress_subclass(), ast_iax2_full_hdr::csub, ast_iax2_full_hdr::dcallno, IAX_COMMAND_INVAL, IAX_FLAG_FULL, iax_outputframe(), ast_iax2_full_hdr::iseqno, option_debug, ast_iax2_full_hdr::oseqno, ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::ts, and ast_iax2_full_hdr::type.
Referenced by socket_process().
07891 { 07892 struct ast_iax2_full_hdr fh; 07893 fh.scallno = htons(src | IAX_FLAG_FULL); 07894 fh.dcallno = htons(dst); 07895 fh.ts = 0; 07896 fh.oseqno = 0; 07897 fh.iseqno = 0; 07898 fh.type = AST_FRAME_IAX; 07899 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07900 iax_outputframe(NULL, &fh, 0, sin, 0); 07901 #if 0 07902 if (option_debug) 07903 #endif 07904 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07905 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07906 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07907 }
| static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4424 of file chan_iax2.c.
References iax2_peer::addr, ao2_link, ast_copy_flags64, ast_debug, ast_get_time_t(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_sched_thread_del, ast_set_flag64, ast_sockaddr_parse(), ast_sockaddr_set_port, ast_test_flag64, ast_variables_destroy(), build_peer(), iax2_peer::expire, expire_registry(), hp, iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, LOG_WARNING, ast_variable::name, ast_variable::next, PARSE_PORT_IGNORE, peer_ref(), peer_unref(), realtime_update_peer(), reg_source_db(), SENTINEL, ast_variable::value, and var.
Referenced by authenticate_reply(), calltoken_required(), find_peer(), and iax2_getpeername().
04425 { 04426 struct ast_variable *var = NULL; 04427 struct ast_variable *tmp; 04428 struct iax2_peer *peer=NULL; 04429 time_t regseconds = 0, nowtime; 04430 int dynamic=0; 04431 04432 if (peername) { 04433 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04434 if (!var && sin) 04435 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04436 } else if (sin) { 04437 char porta[25]; 04438 sprintf(porta, "%d", ntohs(sin->sin_port)); 04439 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04440 if (var) { 04441 /* We'll need the peer name in order to build the structure! */ 04442 for (tmp = var; tmp; tmp = tmp->next) { 04443 if (!strcasecmp(tmp->name, "name")) 04444 peername = tmp->value; 04445 } 04446 } 04447 } 04448 if (!var && peername) { /* Last ditch effort */ 04449 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04450 /*!\note 04451 * If this one loaded something, then we need to ensure that the host 04452 * field matched. The only reason why we can't have this as a criteria 04453 * is because we only have the IP address and the host field might be 04454 * set as a name (and the reverse PTR might not match). 04455 */ 04456 if (var && sin) { 04457 for (tmp = var; tmp; tmp = tmp->next) { 04458 if (!strcasecmp(tmp->name, "host")) { 04459 struct ast_hostent ahp; 04460 struct hostent *hp; 04461 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04462 /* No match */ 04463 ast_variables_destroy(var); 04464 var = NULL; 04465 } 04466 break; 04467 } 04468 } 04469 } 04470 } 04471 if (!var) 04472 return NULL; 04473 04474 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04475 04476 if (!peer) { 04477 ast_variables_destroy(var); 04478 return NULL; 04479 } 04480 04481 for (tmp = var; tmp; tmp = tmp->next) { 04482 /* Make sure it's not a user only... */ 04483 if (!strcasecmp(tmp->name, "type")) { 04484 if (strcasecmp(tmp->value, "friend") && 04485 strcasecmp(tmp->value, "peer")) { 04486 /* Whoops, we weren't supposed to exist! */ 04487 peer = peer_unref(peer); 04488 break; 04489 } 04490 } else if (!strcasecmp(tmp->name, "regseconds")) { 04491 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04492 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04493 if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) { 04494 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name); 04495 } 04496 } else if (!strcasecmp(tmp->name, "port")) { 04497 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value)); 04498 } else if (!strcasecmp(tmp->name, "host")) { 04499 if (!strcasecmp(tmp->value, "dynamic")) 04500 dynamic = 1; 04501 } 04502 } 04503 04504 ast_variables_destroy(var); 04505 04506 if (!peer) 04507 return NULL; 04508 04509 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04510 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04511 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) { 04512 if (peer->expire > -1) { 04513 if (!ast_sched_thread_del(sched, peer->expire)) { 04514 peer->expire = -1; 04515 peer_unref(peer); 04516 } 04517 } 04518 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04519 if (peer->expire == -1) 04520 peer_unref(peer); 04521 } 04522 ao2_link(peers, peer); 04523 if (ast_test_flag64(peer, IAX_DYNAMIC)) 04524 reg_source_db(peer); 04525 } else { 04526 ast_set_flag64(peer, IAX_TEMPONLY); 04527 } 04528 04529 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04530 time(&nowtime); 04531 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04532 memset(&peer->addr, 0, sizeof(peer->addr)); 04533 realtime_update_peer(peer->name, &peer->addr, 0); 04534 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04535 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04536 } 04537 else { 04538 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04539 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04540 } 04541 } 04542 04543 return peer; 04544 }
| static void realtime_update_peer | ( | const char * | peername, | |
| struct ast_sockaddr * | sockaddr, | |||
| time_t | regtime | |||
| ) | [static] |
Definition at line 4617 of file chan_iax2.c.
References ast_config_AST_SYSTEM_NAME, ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag64, ast_update_realtime(), IAX_RTSAVE_SYSNAME, and SENTINEL.
Referenced by __expire_registry(), realtime_peer(), and update_registry().
04618 { 04619 char port[10]; 04620 char regseconds[20]; 04621 const char *sysname = ast_config_AST_SYSTEM_NAME; 04622 char *syslabel = NULL; 04623 04624 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04625 sysname = NULL; 04626 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME)) 04627 syslabel = "regserver"; 04628 04629 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04630 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr)); 04631 ast_update_realtime("iaxpeers", "name", peername, 04632 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 04633 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */ 04634 }
| static struct iax2_user * realtime_user | ( | const char * | username, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4546 of file chan_iax2.c.
References ao2_link, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_set_flag64, ast_test_flag64, ast_variables_destroy(), build_user(), hp, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
Referenced by calltoken_required(), and check_access().
04547 { 04548 struct ast_variable *var; 04549 struct ast_variable *tmp; 04550 struct iax2_user *user=NULL; 04551 04552 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04553 if (!var) 04554 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04555 if (!var && sin) { 04556 char porta[6]; 04557 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04558 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04559 if (!var) 04560 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04561 } 04562 if (!var) { /* Last ditch effort */ 04563 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04564 /*!\note 04565 * If this one loaded something, then we need to ensure that the host 04566 * field matched. The only reason why we can't have this as a criteria 04567 * is because we only have the IP address and the host field might be 04568 * set as a name (and the reverse PTR might not match). 04569 */ 04570 if (var) { 04571 for (tmp = var; tmp; tmp = tmp->next) { 04572 if (!strcasecmp(tmp->name, "host")) { 04573 struct ast_hostent ahp; 04574 struct hostent *hp; 04575 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04576 /* No match */ 04577 ast_variables_destroy(var); 04578 var = NULL; 04579 } 04580 break; 04581 } 04582 } 04583 } 04584 } 04585 if (!var) 04586 return NULL; 04587 04588 tmp = var; 04589 while(tmp) { 04590 /* Make sure it's not a peer only... */ 04591 if (!strcasecmp(tmp->name, "type")) { 04592 if (strcasecmp(tmp->value, "friend") && 04593 strcasecmp(tmp->value, "user")) { 04594 return NULL; 04595 } 04596 } 04597 tmp = tmp->next; 04598 } 04599 04600 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)); 04601 04602 ast_variables_destroy(var); 04603 04604 if (!user) 04605 return NULL; 04606 04607 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04608 ast_set_flag64(user, IAX_RTCACHEFRIENDS); 04609 ao2_link(users, user); 04610 } else { 04611 ast_set_flag64(user, IAX_TEMPONLY); 04612 } 04613 04614 return user; 04615 }
| static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8776 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_log(), ast_sched_thread_del, ast_sockaddr_parse(), ast_sockaddr_stringify(), ast_test_flag64, ast_verb, iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, LOG_NOTICE, PARSE_PORT_REQUIRE, peer_ref(), peer_unref(), and register_peer_exten().
Referenced by realtime_peer(), and set_config().
08777 { 08778 char data[80]; 08779 char *expiry; 08780 08781 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) { 08782 return; 08783 } 08784 08785 expiry = strrchr(data, ':'); 08786 if (!expiry) { 08787 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data); 08788 return; 08789 } 08790 *expiry++ = '\0'; 08791 08792 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) { 08793 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data); 08794 return; 08795 } 08796 08797 p->expiry = atoi(expiry); 08798 08799 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name, 08800 ast_sockaddr_stringify(&p->addr), p->expiry); 08801 08802 iax2_poke_peer(p, 0); 08803 if (p->expire > -1) { 08804 if (!ast_sched_thread_del(sched, p->expire)) { 08805 p->expire = -1; 08806 peer_unref(p); 08807 } 08808 } 08809 08810 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08811 08812 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08813 if (p->expire == -1) { 08814 peer_unref(p); 08815 } 08816 08817 if (iax2_regfunk) { 08818 iax2_regfunk(p->name, 1); 08819 } 08820 08821 register_peer_exten(p, 1); 08822 }
| static void register_peer_exten | ( | struct iax2_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Definition at line 8693 of file chan_iax2.c.
References ast_add_extension(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr(), ast_strdup, ast_strlen_zero(), ext, and S_OR.
Referenced by __expire_registry(), peer_destructor(), reg_source_db(), and update_registry().
08694 { 08695 char multi[256]; 08696 char *stringp, *ext; 08697 if (!ast_strlen_zero(regcontext)) { 08698 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08699 stringp = multi; 08700 while((ext = strsep(&stringp, "&"))) { 08701 if (onoff) { 08702 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08703 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08704 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08705 } else 08706 ast_context_remove_extension(regcontext, ext, 1, NULL); 08707 } 08708 } 08709 }
| static int register_verify | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Verify inbound registration.
Definition at line 8064 of file chan_iax2.c.
References ast_apply_ha(), ast_check_signature(), ast_clear_flag, ast_copy_string(), AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_inet_ntoa(), ast_key_get(), AST_KEY_PUBLIC, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_set_flag, ast_sockaddr_from_sin, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, iax2_peer::authmethods, chan_iax2_pvt::expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iaxs, iaxsl, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax_ies::password, peer_unref(), iax_ies::refresh, iax_ies::rsa_result, secret, and iax_ies::username.
Referenced by socket_process().
08065 { 08066 char requeststr[256] = ""; 08067 char peer[256] = ""; 08068 char md5secret[256] = ""; 08069 char rsasecret[256] = ""; 08070 char secret[256] = ""; 08071 struct iax2_peer *p = NULL; 08072 struct ast_key *key; 08073 char *keyn; 08074 int x; 08075 int expire = 0; 08076 int res = -1; 08077 struct ast_sockaddr addr; 08078 08079 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08080 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 08081 if (ies->username) 08082 ast_copy_string(peer, ies->username, sizeof(peer)); 08083 if (ies->password) 08084 ast_copy_string(secret, ies->password, sizeof(secret)); 08085 if (ies->md5_result) 08086 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 08087 if (ies->rsa_result) 08088 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 08089 if (ies->refresh) 08090 expire = ies->refresh; 08091 08092 if (ast_strlen_zero(peer)) { 08093 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 08094 return -1; 08095 } 08096 08097 /* SLD: first call to lookup peer during registration */ 08098 ast_mutex_unlock(&iaxsl[callno]); 08099 p = find_peer(peer, 1); 08100 ast_mutex_lock(&iaxsl[callno]); 08101 if (!p || !iaxs[callno]) { 08102 if (iaxs[callno]) { 08103 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 08104 /* Anything, as long as it's non-blank */ 08105 ast_string_field_set(iaxs[callno], secret, "badsecret"); 08106 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 08107 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 08108 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 08109 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 08110 * to be plaintext, indicating it is an authmethod used by other peers on the system. 08111 * 08112 * If none of these cases exist, res will be returned as 0 without authentication indicating 08113 * an AUTHREQ needs to be sent out. */ 08114 08115 if (ast_strlen_zero(iaxs[callno]->challenge) && 08116 !(!ast_strlen_zero(secret) && plaintext)) { 08117 /* by setting res to 0, an REGAUTH will be sent */ 08118 res = 0; 08119 } 08120 } 08121 if (authdebug && !p) 08122 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08123 goto return_unref; 08124 } 08125 08126 if (!ast_test_flag64(p, IAX_DYNAMIC)) { 08127 if (authdebug) 08128 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08129 goto return_unref; 08130 } 08131 08132 ast_sockaddr_from_sin(&addr, sin); 08133 if (!ast_apply_ha(p->ha, &addr)) { 08134 if (authdebug) 08135 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08136 goto return_unref; 08137 } 08138 ast_string_field_set(iaxs[callno], secret, p->secret); 08139 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 08140 /* Check secret against what we have on file */ 08141 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08142 if (!ast_strlen_zero(p->inkeys)) { 08143 char tmpkeys[256]; 08144 char *stringp=NULL; 08145 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 08146 stringp=tmpkeys; 08147 keyn = strsep(&stringp, ":"); 08148 while(keyn) { 08149 key = ast_key_get(keyn, AST_KEY_PUBLIC); 08150 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 08151 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08152 break; 08153 } else if (!key) 08154 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 08155 keyn = strsep(&stringp, ":"); 08156 } 08157 if (!keyn) { 08158 if (authdebug) 08159 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 08160 goto return_unref; 08161 } 08162 } else { 08163 if (authdebug) 08164 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 08165 goto return_unref; 08166 } 08167 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08168 struct MD5Context md5; 08169 unsigned char digest[16]; 08170 char *tmppw, *stringp; 08171 08172 tmppw = ast_strdupa(p->secret); 08173 stringp = tmppw; 08174 while((tmppw = strsep(&stringp, ";"))) { 08175 MD5Init(&md5); 08176 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 08177 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08178 MD5Final(digest, &md5); 08179 for (x=0;x<16;x++) 08180 sprintf(requeststr + (x << 1), "%2.2x", (unsigned)digest[x]); /* safe */ 08181 if (!strcasecmp(requeststr, md5secret)) 08182 break; 08183 } 08184 if (tmppw) { 08185 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08186 } else { 08187 if (authdebug) 08188 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 08189 goto return_unref; 08190 } 08191 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 08192 /* They've provided a plain text password and we support that */ 08193 if (strcmp(secret, p->secret)) { 08194 if (authdebug) 08195 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08196 goto return_unref; 08197 } else 08198 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08199 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 08200 /* if challenge has been sent, but no challenge response if given, reject. */ 08201 goto return_unref; 08202 } 08203 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08204 08205 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 08206 res = 0; 08207 08208 return_unref: 08209 if (iaxs[callno]) { 08210 ast_string_field_set(iaxs[callno], peer, peer); 08211 08212 /* Choose lowest expiry number */ 08213 if (expire && (expire < iaxs[callno]->expiry)) { 08214 iaxs[callno]->expiry = expire; 08215 } 08216 } 08217 08218 if (p) { 08219 peer_unref(p); 08220 } 08221 return res; 08222 }
| static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 9001 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, iax_ie_data::buf, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, iaxs, iaxsl, peer_unref(), iax_ie_data::pos, and send_command().
Referenced by socket_process().
09002 { 09003 struct iax_ie_data ied; 09004 struct iax2_peer *p; 09005 char challenge[10]; 09006 const char *peer_name; 09007 int sentauthmethod; 09008 09009 peer_name = ast_strdupa(iaxs[callno]->peer); 09010 09011 /* SLD: third call to find_peer in registration */ 09012 ast_mutex_unlock(&iaxsl[callno]); 09013 if ((p = find_peer(peer_name, 1))) { 09014 last_authmethod = p->authmethods; 09015 } 09016 09017 ast_mutex_lock(&iaxsl[callno]); 09018 if (!iaxs[callno]) 09019 goto return_unref; 09020 09021 memset(&ied, 0, sizeof(ied)); 09022 /* The selection of which delayed reject is sent may leak information, 09023 * if it sets a static response. For example, if a host is known to only 09024 * use MD5 authentication, then an RSA response would indicate that the 09025 * peer does not exist, and vice-versa. 09026 * Therefore, we use whatever the last peer used (which may vary over the 09027 * course of a server, which should leak minimal information). */ 09028 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 09029 if (!p) { 09030 iaxs[callno]->authmethods = sentauthmethod; 09031 } 09032 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 09033 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 09034 /* Build the challenge */ 09035 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 09036 ast_string_field_set(iaxs[callno], challenge, challenge); 09037 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 09038 } 09039 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 09040 09041 return_unref: 09042 if (p) { 09043 peer_unref(p); 09044 } 09045 09046 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 09047 }
| static int registry_rerequest | ( | struct iax_ies * | ies, | |
| int | callno, | |||
| struct sockaddr_in * | sin | |||
| ) | [static] |
Definition at line 9049 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_registry::addr, ast_copy_string(), AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_sockaddr_to_sin, ast_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ie_data::buf, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, iaxs, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.
Referenced by socket_process().
09050 { 09051 struct iax2_registry *reg; 09052 /* Start pessimistic */ 09053 struct iax_ie_data ied; 09054 char peer[256] = ""; 09055 char challenge[256] = ""; 09056 int res; 09057 int authmethods = 0; 09058 if (ies->authmethods) 09059 authmethods = ies->authmethods; 09060 if (ies->username) 09061 ast_copy_string(peer, ies->username, sizeof(peer)); 09062 if (ies->challenge) 09063 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 09064 memset(&ied, 0, sizeof(ied)); 09065 reg = iaxs[callno]->reg; 09066 if (reg) { 09067 struct sockaddr_in reg_addr; 09068 09069 ast_sockaddr_to_sin(®->addr, ®_addr); 09070 09071 if (inaddrcmp(®_addr, sin)) { 09072 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 09073 return -1; 09074 } 09075 if (ast_strlen_zero(reg->secret)) { 09076 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 09077 reg->regstate = REG_STATE_NOAUTH; 09078 return -1; 09079 } 09080 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 09081 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 09082 if (reg->secret[0] == '[') { 09083 char tmpkey[256]; 09084 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 09085 tmpkey[strlen(tmpkey) - 1] = '\0'; 09086 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 09087 } else 09088 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 09089 if (!res) { 09090 reg->regstate = REG_STATE_AUTHSENT; 09091 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 09092 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 09093 } else 09094 return -1; 09095 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 09096 } else 09097 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 09098 return -1; 09099 }
| static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 7167 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_cli_iax2_show_registry(), and manager_iax2_show_registry().
07168 { 07169 switch(regstate) { 07170 case REG_STATE_UNREGISTERED: 07171 return "Unregistered"; 07172 case REG_STATE_REGSENT: 07173 return "Request Sent"; 07174 case REG_STATE_AUTHSENT: 07175 return "Auth. Sent"; 07176 case REG_STATE_REGISTERED: 07177 return "Registered"; 07178 case REG_STATE_REJECTED: 07179 return "Rejected"; 07180 case REG_STATE_TIMEOUT: 07181 return "Timeout"; 07182 case REG_STATE_NOAUTH: 07183 return "No Authentication"; 07184 default: 07185 return "Unknown"; 07186 } 07187 }
| static int reload | ( | void | ) | [static] |
Definition at line 13803 of file chan_iax2.c.
References reload_config().
13804 { 13805 return reload_config(); 13806 }
| static int reload_config | ( | void | ) | [static] |
Definition at line 13754 of file chan_iax2.c.
References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), config, debugaddr, iax2_do_register(), iax_provision_reload(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), reload_firmware(), set_config(), and set_peercnt_limit_all_cb().
Referenced by handle_cli_iax2_reload(), and reload().
13755 { 13756 static const char config[] = "iax.conf"; 13757 struct iax2_registry *reg; 13758 13759 if (set_config(config, 1) > 0) { 13760 prune_peers(); 13761 prune_users(); 13762 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13763 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13764 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 13765 trunk_timed = trunk_untimed = 0; 13766 trunk_nmaxmtu = trunk_maxmtu = 0; 13767 memset(&debugaddr, '\0', sizeof(debugaddr)); 13768 13769 AST_LIST_LOCK(®istrations); 13770 AST_LIST_TRAVERSE(®istrations, reg, entry) 13771 iax2_do_register(reg); 13772 AST_LIST_UNLOCK(®istrations); 13773 13774 /* Qualify hosts, too */ 13775 poke_all_peers(); 13776 } 13777 13778 reload_firmware(0); 13779 iax_provision_reload(1); 13780 ast_unload_realtime("iaxpeers"); 13781 13782 return 0; 13783 }
| static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 3305 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verb, destroy_firmware(), errno, LOG_WARNING, and try_firmware().
Referenced by __unload_module(), load_module(), and reload_config().
03306 { 03307 struct iax_firmware *cur = NULL; 03308 DIR *fwd; 03309 struct dirent *de; 03310 char dir[256], fn[256]; 03311 03312 AST_LIST_LOCK(&firmwares); 03313 03314 /* Mark all as dead */ 03315 AST_LIST_TRAVERSE(&firmwares, cur, list) 03316 cur->dead = 1; 03317 03318 /* Now that we have marked them dead... load new ones */ 03319 if (!unload) { 03320 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 03321 fwd = opendir(dir); 03322 if (fwd) { 03323 while((de = readdir(fwd))) { 03324 if (de->d_name[0] != '.') { 03325 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 03326 if (!try_firmware(fn)) { 03327 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 03328 } 03329 } 03330 } 03331 closedir(fwd); 03332 } else 03333 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 03334 } 03335 03336 /* Clean up leftovers */ 03337 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 03338 if (!cur->dead) 03339 continue; 03340 AST_LIST_REMOVE_CURRENT(list); 03341 destroy_firmware(cur); 03342 } 03343 AST_LIST_TRAVERSE_SAFE_END; 03344 03345 AST_LIST_UNLOCK(&firmwares); 03346 }
| static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2223 of file chan_iax2.c.
References ao2_unlink, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), resend_with_token(), and socket_process().
02224 { 02225 if (!pvt->peercallno) { 02226 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02227 return; 02228 } 02229 02230 ao2_unlink(iax_peercallno_pvts, pvt); 02231 }
| static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2204 of file chan_iax2.c.
References ao2_unlink, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by complete_transfer(), and iax2_destroy().
02205 { 02206 if (!pvt->transfercallno) { 02207 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02208 return; 02209 } 02210 02211 ao2_unlink(iax_transfercallno_pvts, pvt); 02212 }
| static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2740 of file chan_iax2.c.
References ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_log(), callno_entry::callno, LOG_ERROR, and callno_entry::validated.
Referenced by __find_callno(), make_trunk(), and sched_delay_remove().
02741 { 02742 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02743 02744 /* the callno_pool container is locked here primarily to ensure thread 02745 * safety of the total_nonval_callno_used check and decrement */ 02746 ao2_lock(callno_pool); 02747 02748 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02749 total_nonval_callno_used--; 02750 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02751 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02752 } 02753 02754 if (callno_entry->callno < TRUNK_CALL_START) { 02755 ao2_link(callno_pool, callno_entry); 02756 } else { 02757 ao2_link(callno_pool_trunk, callno_entry); 02758 } 02759 ao2_ref(callno_entry, -1); /* only container ref remains */ 02760 02761 ao2_unlock(callno_pool); 02762 return 0; 02763 }
| static void requirecalltoken_mark_auto | ( | const char * | name, | |
| int | subclass | |||
| ) | [static] |
Definition at line 4926 of file chan_iax2.c.
References ast_strlen_zero(), CALLTOKEN_AUTO, iax2_peer::calltoken_required, iax2_user::calltoken_required, CALLTOKEN_YES, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), and user_unref().
Referenced by handle_call_token().
04927 { 04928 struct iax2_user *user = NULL; 04929 struct iax2_peer *peer = NULL; 04930 04931 if (ast_strlen_zero(name)) { 04932 return; /* no username given */ 04933 } 04934 04935 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04936 user->calltoken_required = CALLTOKEN_YES; 04937 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04938 peer->calltoken_required = CALLTOKEN_YES; 04939 } 04940 04941 if (peer) { 04942 peer_unref(peer); 04943 } 04944 if (user) { 04945 user_unref(user); 04946 } 04947 }
| static void resend_with_token | ( | int | callno, | |
| struct iax_frame * | f, | |||
| const char * | newtoken | |||
| ) | [static] |
Definition at line 4844 of file chan_iax2.c.
References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, iax_frame::encmethods, ast_frame::frametype, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, send_command(), and ast_frame::subclass.
Referenced by socket_process().
04845 { 04846 struct chan_iax2_pvt *pvt = iaxs[callno]; 04847 int frametype = f->af.frametype; 04848 int subclass = f->af.subclass.integer; 04849 struct { 04850 struct ast_iax2_full_hdr fh; 04851 struct iax_ie_data ied; 04852 } data = { 04853 .ied.buf = { 0 }, 04854 .ied.pos = 0, 04855 }; 04856 /* total len - header len gives us the frame's IE len */ 04857 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04858 04859 if (!pvt) { 04860 return; /* this should not be possible if called from socket_process() */ 04861 } 04862 04863 /* 04864 * Check to make sure last frame sent is valid for call token resend 04865 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04866 * 2. Frame should _NOT_ already have a destination callno 04867 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04868 * 4. Pvt must have a calltoken_ie_len which represents the number of 04869 * bytes at the end of the frame used for the previous calltoken ie. 04870 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04871 * 6. Total length of f->data must be _LESS_ than size of our data struct 04872 * because f->data must be able to fit within data. 04873 */ 04874 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04875 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04876 (f->datalen > sizeof(data))) { 04877 04878 return; /* ignore resend, token was not valid for the dialog */ 04879 } 04880 04881 /* token is valid 04882 * 1. Copy frame data over 04883 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04884 * NOTE: Having the ie always be last is not protocol specified, 04885 * it is only an implementation choice. Since we only expect the ie to 04886 * be last for frames we have sent, this can no way be affected by 04887 * another end point. 04888 * 3. Remove frame from queue 04889 * 4. Free old frame 04890 * 5. Clear previous seqnos 04891 * 6. Resend with CALLTOKEN ie. 04892 */ 04893 04894 /* ---1.--- */ 04895 memcpy(&data, f->data, f->datalen); 04896 data.ied.pos = ie_data_pos; 04897 04898 /* ---2.--- */ 04899 /* move to the beginning of the calltoken ie so we can write over it */ 04900 data.ied.pos -= pvt->calltoken_ie_len; 04901 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04902 04903 /* make sure to update token length incase it ever has to be stripped off again */ 04904 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04905 04906 /* ---3.--- */ 04907 AST_LIST_REMOVE(&frame_queue[callno], f, list); 04908 04909 /* ---4.--- */ 04910 iax2_frame_free(f); 04911 04912 /* ---5.--- */ 04913 pvt->oseqno = 0; 04914 pvt->rseqno = 0; 04915 pvt->iseqno = 0; 04916 pvt->aseqno = 0; 04917 if (pvt->peercallno) { 04918 remove_by_peercallno(pvt); 04919 pvt->peercallno = 0; 04920 } 04921 04922 /* ---6.--- */ 04923 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04924 }
Definition at line 9580 of file chan_iax2.c.
References ast_string_field_set, iax_frame::callno, IAX_MAX_OSPBLOCK_NUM, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPBUFF_SIZE, iaxs, iax_ies::ospblocklength, and iax_ies::osptokenblock.
Referenced by socket_process().
09581 { 09582 int i; 09583 unsigned int length, offset = 0; 09584 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09585 09586 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09587 length = ies->ospblocklength[i]; 09588 if (length != 0) { 09589 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09590 /* OSP token block length wrong, clear buffer */ 09591 offset = 0; 09592 break; 09593 } else { 09594 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09595 offset += length; 09596 } 09597 } else { 09598 break; 09599 } 09600 } 09601 *(full_osptoken + offset) = '\0'; 09602 if (strlen(full_osptoken) != offset) { 09603 /* OSP token length wrong, clear buffer */ 09604 *full_osptoken = '\0'; 09605 } 09606 09607 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09608 }
Definition at line 9569 of file chan_iax2.c.
References iax_frame::callno, iaxs, iax_ies::rr_delay, iax_ies::rr_dropped, iax_ies::rr_jitter, iax_ies::rr_loss, iax_ies::rr_ooo, and iax_ies::rr_pkts.
Referenced by socket_process().
09570 { 09571 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09572 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09573 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09574 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09575 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09576 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09577 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09578 }
| static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
| struct callno_entry * | callno_entry | |||
| ) | [static] |
Definition at line 2812 of file chan_iax2.c.
References ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), and replace_callno().
Referenced by pvt_destructor().
02813 { 02814 int i; 02815 struct peercnt *peercnt; 02816 struct peercnt tmp = { 02817 .addr = sin->sin_addr.s_addr, 02818 }; 02819 02820 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02821 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02822 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02823 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02824 if (i == -1) { 02825 ao2_ref(peercnt, -1); 02826 } 02827 } 02828 02829 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02830 }
| static int schedule_delivery | ( | struct iax_frame * | fr, | |
| int | updatehistory, | |||
| int | fromtrunk, | |||
| unsigned int * | tsout | |||
| ) | [static] |
Definition at line 4243 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_channel_unlock, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), ast_sched_thread_del, ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, calc_rxstamp(), iax_frame::callno, ast_frame_subclass::codec, jb_frame::data, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len(), chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process(), and socket_process_meta().
04244 { 04245 int type, len; 04246 int ret; 04247 int needfree = 0; 04248 struct ast_channel *owner = NULL; 04249 struct ast_channel *bridge = NULL; 04250 04251 /* 04252 * Clear fr->af.data if there is no data in the buffer. Things 04253 * like AST_CONTROL_HOLD without a suggested music class must 04254 * have a NULL pointer. 04255 */ 04256 if (!fr->af.datalen) { 04257 memset(&fr->af.data, 0, sizeof(fr->af.data)); 04258 } 04259 04260 /* Attempt to recover wrapped timestamps */ 04261 unwrap_timestamp(fr); 04262 04263 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 04264 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 04265 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 04266 else { 04267 #if 0 04268 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 04269 #endif 04270 fr->af.delivery = ast_tv(0,0); 04271 } 04272 04273 type = JB_TYPE_CONTROL; 04274 len = 0; 04275 04276 if(fr->af.frametype == AST_FRAME_VOICE) { 04277 type = JB_TYPE_VOICE; 04278 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000); 04279 } else if(fr->af.frametype == AST_FRAME_CNG) { 04280 type = JB_TYPE_SILENCE; 04281 } 04282 04283 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04284 if (tsout) 04285 *tsout = fr->ts; 04286 __do_deliver(fr); 04287 return -1; 04288 } 04289 04290 iax2_lock_owner(fr->callno); 04291 if (!iaxs[fr->callno]) { 04292 /* The call dissappeared so discard this frame that we could not send. */ 04293 iax2_frame_free(fr); 04294 return -1; 04295 } 04296 if ((owner = iaxs[fr->callno]->owner)) 04297 bridge = ast_bridged_channel(owner); 04298 04299 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04300 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04301 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04302 jb_frame frame; 04303 04304 ast_channel_unlock(owner); 04305 04306 /* deliver any frames in the jb */ 04307 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04308 __do_deliver(frame.data); 04309 /* __do_deliver() can make the call disappear */ 04310 if (!iaxs[fr->callno]) 04311 return -1; 04312 } 04313 04314 jb_reset(iaxs[fr->callno]->jb); 04315 04316 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid); 04317 04318 /* deliver this frame now */ 04319 if (tsout) 04320 *tsout = fr->ts; 04321 __do_deliver(fr); 04322 return -1; 04323 } 04324 if (owner) { 04325 ast_channel_unlock(owner); 04326 } 04327 04328 /* insert into jitterbuffer */ 04329 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04330 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04331 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04332 if (ret == JB_DROP) { 04333 needfree++; 04334 } else if (ret == JB_SCHED) { 04335 update_jbsched(iaxs[fr->callno]); 04336 } 04337 if (tsout) 04338 *tsout = fr->ts; 04339 if (needfree) { 04340 /* Free our iax frame */ 04341 iax2_frame_free(fr); 04342 return -1; 04343 } 04344 return 0; 04345 }
| static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1889 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_destroy(), iaxs, iaxsl, LOG_DEBUG, option_debug, and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01890 { 01891 unsigned short callno = PTR_TO_CALLNO(vid); 01892 ast_mutex_lock(&iaxsl[callno]); 01893 if (iaxs[callno]) { 01894 if (option_debug) { 01895 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01896 } 01897 iax2_destroy(callno); 01898 } 01899 ast_mutex_unlock(&iaxsl[callno]); 01900 return 0; 01901 }
| static int send_apathetic_reply | ( | unsigned short | callno, | |
| unsigned short | dcallno, | |||
| struct sockaddr_in * | sin, | |||
| int | command, | |||
| int | ts, | |||
| unsigned char | seqno, | |||
| int | sockfd, | |||
| struct iax_ie_data * | ied | |||
| ) | [static] |
Definition at line 4806 of file chan_iax2.c.
References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), IAX_FLAG_RETRANS, iax_outputframe(), and iax_ie_data::pos.
Referenced by handle_call_token(), and socket_process().
04809 { 04810 struct { 04811 struct ast_iax2_full_hdr f; 04812 struct iax_ie_data ied; 04813 } data; 04814 size_t size = sizeof(struct ast_iax2_full_hdr); 04815 04816 if (ied) { 04817 size += ied->pos; 04818 memcpy(&data.ied, ied->buf, ied->pos); 04819 } 04820 04821 data.f.scallno = htons(0x8000 | callno); 04822 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS); 04823 data.f.ts = htonl(ts); 04824 data.f.iseqno = seqno; 04825 data.f.oseqno = 0; 04826 data.f.type = AST_FRAME_IAX; 04827 data.f.csub = compress_subclass(command); 04828 04829 iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr)); 04830 04831 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04832 }
| static int send_command | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 7606 of file chan_iax2.c.
References __send_command(), ast_debug, AST_FRAME_CONTROL, chan_iax2_pvt::callno, and iax2_is_control_frame_allowed().
Referenced by __attempt_transmit(), __send_lagrq(), __send_ping(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_key_rotate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), resend_with_token(), send_command_locked(), and socket_process().
07607 { 07608 if (type == AST_FRAME_CONTROL && !iax2_is_control_frame_allowed(command)) { 07609 /* Control frame should not go out on the wire. */ 07610 ast_debug(2, "Callno %d: Blocked sending control frame %d.\n", 07611 i->callno, command); 07612 return 0; 07613 } 07614 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07615 }
| 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 | |||
| ) | [static] |
Definition at line 7631 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, iax2_predestroy(), and iaxs.
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().
07632 { 07633 int call_num = i->callno; 07634 /* It is assumed that the callno has already been locked */ 07635 iax2_predestroy(i->callno); 07636 if (!iaxs[call_num]) 07637 return -1; 07638 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07639 }
| 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 | |||
| ) | [static] |
Definition at line 7641 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07642 { 07643 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07644 }
| static int send_command_locked | ( | unsigned short | callno, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 7617 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_unlock, iaxs, iaxsl, and send_command().
Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().
07618 { 07619 int res; 07620 ast_mutex_lock(&iaxsl[callno]); 07621 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07622 ast_mutex_unlock(&iaxsl[callno]); 07623 return res; 07624 }
| static int send_command_transfer | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 7646 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07647 { 07648 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07649 }
| static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1675 of file chan_iax2.c.
References __send_lagrq(), ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::lagid, and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01676 { 01677 int callno = (long) data; 01678 ast_mutex_lock(&iaxsl[callno]); 01679 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) { 01680 iaxs[callno]->lagid = -1; 01681 } 01682 ast_mutex_unlock(&iaxsl[callno]); 01683 01684 #ifdef SCHED_MULTITHREADED 01685 if (schedule_action(__send_lagrq, data)) 01686 #endif 01687 __send_lagrq(data); 01688 return 0; 01689 }
| static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3418 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax2_trunk_peer::addr, ast_debug, ast_inet_ntoa(), iax_frame::callno, iax_frame::data, iax_frame::datalen, errno, handle_error(), iax_outputframe(), iaxs, chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.
Referenced by __attempt_transmit(), iax2_send(), transmit_frame(), and vnak_retransmit().
03419 { 03420 int res; 03421 int callno = f->callno; 03422 03423 /* Don't send if there was an error, but return error instead */ 03424 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03425 return -1; 03426 03427 /* Called with iaxsl held */ 03428 if (iaxdebug) 03429 ast_debug(3, "Sending %u 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)); 03430 03431 if (f->transfer) { 03432 iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03433 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03434 } else { 03435 iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03436 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03437 } 03438 if (res < 0) { 03439 if (iaxdebug) 03440 ast_debug(1, "Received error: %s\n", strerror(errno)); 03441 handle_error(); 03442 } else 03443 res = 0; 03444 03445 return res; 03446 }
| static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1608 of file chan_iax2.c.
References __send_ping(), ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::pingid, and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01609 { 01610 int callno = (long) data; 01611 ast_mutex_lock(&iaxsl[callno]); 01612 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) { 01613 iaxs[callno]->pingid = -1; 01614 } 01615 ast_mutex_unlock(&iaxsl[callno]); 01616 01617 #ifdef SCHED_MULTITHREADED 01618 if (schedule_action(__send_ping, data)) 01619 #endif 01620 __send_ping(data); 01621 01622 return 0; 01623 }
| static void send_signaling | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
Definition at line 1913 of file chan_iax2.c.
References AST_LIST_REMOVE_HEAD, signaling_queue_entry::f, free_signaling_queue_entry(), and iax2_send().
Referenced by socket_process().
01914 { 01915 struct signaling_queue_entry *s = NULL; 01916 01917 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01918 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01919 free_signaling_queue_entry(s); 01920 } 01921 pvt->hold_signaling = 0; 01922 }
| static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [static] |
Definition at line 9233 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_debug, ast_inet_ntoa(), ast_test_flag64, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by iax2_trunk_queue(), and timing_read().
09234 { 09235 int res = 0; 09236 struct iax_frame *fr; 09237 struct ast_iax2_meta_hdr *meta; 09238 struct ast_iax2_meta_trunk_hdr *mth; 09239 int calls = 0; 09240 09241 /* Point to frame */ 09242 fr = (struct iax_frame *)tpeer->trunkdata; 09243 /* Point to meta data */ 09244 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 09245 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 09246 if (tpeer->trunkdatalen) { 09247 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 09248 meta->zeros = 0; 09249 meta->metacmd = IAX_META_TRUNK; 09250 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) 09251 meta->cmddata = IAX_META_TRUNK_MINI; 09252 else 09253 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 09254 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 09255 /* And the rest of the ast_iax2 header */ 09256 fr->direction = DIRECTION_OUTGRESS; 09257 fr->retrans = -1; 09258 fr->transfer = 0; 09259 /* Any appropriate call will do */ 09260 fr->data = fr->afdata; 09261 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 09262 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 09263 calls = tpeer->calls; 09264 #if 0 09265 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)); 09266 #endif 09267 /* Reset transmit trunk side data */ 09268 tpeer->trunkdatalen = 0; 09269 tpeer->calls = 0; 09270 } 09271 if (res < 0) 09272 return res; 09273 return calls; 09274 }
| static int set_config | ( | const char * | config_file, | |
| int | reload | |||
| ) | [static] |
Load configuration.
Definition at line 13258 of file chan_iax2.c.
References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, ast_clear_flag64, ast_config_destroy(), ast_config_load, ast_context_find_or_create(), ast_copy_string(), ast_false(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_netsock_bind(), ast_netsock_init(), ast_netsock_list_alloc(), ast_netsock_release(), ast_netsock_sockfd(), ast_netsock_unref(), ast_parse_allow_disallow(), ast_set2_flag64, ast_set_flag64, ast_set_flags_to64, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag64, ast_timer_set_rate(), ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTSAVE_SYSNAME, IAX_RTUPDATE, IAX_SENDCONNECTEDLINE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, peer_unref(), prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user_unref(), and ast_variable::value.
Referenced by load_module(), and reload_config().
13259 { 13260 struct ast_config *cfg, *ucfg; 13261 format_t capability = iax2_capability; 13262 struct ast_variable *v; 13263 char *cat; 13264 const char *utype; 13265 const char *tosval; 13266 int format; 13267 int portno = IAX_DEFAULT_PORTNO; 13268 int x; 13269 int mtuv; 13270 int subscribe_network_change = 1; 13271 struct iax2_user *user; 13272 struct iax2_peer *peer; 13273 struct ast_netsock *ns; 13274 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 13275 #if 0 13276 static unsigned short int last_port=0; 13277 #endif 13278 13279 cfg = ast_config_load(config_file, config_flags); 13280 13281 if (!cfg) { 13282 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 13283 return -1; 13284 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 13285 ucfg = ast_config_load("users.conf", config_flags); 13286 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 13287 return 0; 13288 /* Otherwise we need to reread both files */ 13289 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13290 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 13291 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13292 ast_config_destroy(ucfg); 13293 return 0; 13294 } 13295 if (!cfg) { 13296 /* should have been able to load the config here */ 13297 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file); 13298 return -1; 13299 } 13300 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 13301 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13302 return 0; 13303 } else { /* iax.conf changed, gotta reread users.conf, too */ 13304 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13305 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 13306 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 13307 ast_config_destroy(cfg); 13308 return 0; 13309 } 13310 } 13311 13312 if (reload) { 13313 set_config_destroy(); 13314 } 13315 13316 /* Reset global codec prefs */ 13317 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 13318 13319 /* Reset Global Flags */ 13320 memset(&globalflags, 0, sizeof(globalflags)); 13321 ast_set_flag64(&globalflags, IAX_RTUPDATE); 13322 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13323 13324 #ifdef SO_NO_CHECK 13325 nochecksums = 0; 13326 #endif 13327 /* Reset default parking lot */ 13328 default_parkinglot[0] = '\0'; 13329 13330 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13331 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13332 global_max_trunk_mtu = MAX_TRUNK_MTU; 13333 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 13334 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 13335 13336 maxauthreq = 3; 13337 13338 srvlookup = 0; 13339 13340 v = ast_variable_browse(cfg, "general"); 13341 13342 /* Seed initial tos value */ 13343 tosval = ast_variable_retrieve(cfg, "general", "tos"); 13344 if (tosval) { 13345 if (ast_str2tos(tosval, &qos.tos)) 13346 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 13347 } 13348 /* Seed initial cos value */ 13349 tosval = ast_variable_retrieve(cfg, "general", "cos"); 13350 if (tosval) { 13351 if (ast_str2cos(tosval, &qos.cos)) 13352 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 13353 } 13354 while(v) { 13355 if (!strcasecmp(v->name, "bindport")){ 13356 if (reload) 13357 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 13358 else 13359 portno = atoi(v->value); 13360 } else if (!strcasecmp(v->name, "pingtime")) 13361 ping_time = atoi(v->value); 13362 else if (!strcasecmp(v->name, "iaxthreadcount")) { 13363 if (reload) { 13364 if (atoi(v->value) != iaxthreadcount) 13365 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 13366 } else { 13367 iaxthreadcount = atoi(v->value); 13368 if (iaxthreadcount < 1) { 13369 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 13370 iaxthreadcount = 1; 13371 } else if (iaxthreadcount > 256) { 13372 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 13373 iaxthreadcount = 256; 13374 } 13375 } 13376 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 13377 if (reload) { 13378 AST_LIST_LOCK(&dynamic_list); 13379 iaxmaxthreadcount = atoi(v->value); 13380 AST_LIST_UNLOCK(&dynamic_list); 13381 } else { 13382 iaxmaxthreadcount = atoi(v->value); 13383 if (iaxmaxthreadcount < 0) { 13384 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 13385 iaxmaxthreadcount = 0; 13386 } else if (iaxmaxthreadcount > 256) { 13387 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 13388 iaxmaxthreadcount = 256; 13389 } 13390 } 13391 } else if (!strcasecmp(v->name, "nochecksums")) { 13392 #ifdef SO_NO_CHECK 13393 if (ast_true(v->value)) 13394 nochecksums = 1; 13395 else 13396 nochecksums = 0; 13397 #else 13398 if (ast_true(v->value)) 13399 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 13400 #endif 13401 } 13402 else if (!strcasecmp(v->name, "maxjitterbuffer")) 13403 maxjitterbuffer = atoi(v->value); 13404 else if (!strcasecmp(v->name, "resyncthreshold")) 13405 resyncthreshold = atoi(v->value); 13406 else if (!strcasecmp(v->name, "maxjitterinterps")) 13407 maxjitterinterps = atoi(v->value); 13408 else if (!strcasecmp(v->name, "jittertargetextra")) 13409 jittertargetextra = atoi(v->value); 13410 else if (!strcasecmp(v->name, "lagrqtime")) 13411 lagrq_time = atoi(v->value); 13412 else if (!strcasecmp(v->name, "maxregexpire")) 13413 max_reg_expire = atoi(v->value); 13414 else if (!strcasecmp(v->name, "minregexpire")) 13415 min_reg_expire = atoi(v->value); 13416 else if (!strcasecmp(v->name, "bindaddr")) { 13417 if (reload) { 13418 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 13419 } else { 13420 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 13421 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 13422 } else { 13423 if (strchr(v->value, ':')) 13424 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 13425 else 13426 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 13427 if (defaultsockfd < 0) 13428 defaultsockfd = ast_netsock_sockfd(ns); 13429 ast_netsock_unref(ns); 13430 } 13431 } 13432 } else if (!strcasecmp(v->name, "authdebug")) { 13433 authdebug = ast_true(v->value); 13434 } else if (!strcasecmp(v->name, "encryption")) { 13435 iax2_encryption |= get_encrypt_methods(v->value); 13436 if (!iax2_encryption) { 13437 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13438 } 13439 } else if (!strcasecmp(v->name, "forceencryption")) { 13440 if (ast_false(v->value)) { 13441 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13442 } else { 13443 iax2_encryption |= get_encrypt_methods(v->value); 13444 if (iax2_encryption) { 13445 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13446 } 13447 } 13448 } else if (!strcasecmp(v->name, "transfer")) { 13449 if (!strcasecmp(v->value, "mediaonly")) { 13450 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13451 } else if (ast_true(v->value)) { 13452 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13453 } else 13454 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13455 } else if (!strcasecmp(v->name, "codecpriority")) { 13456 if(!strcasecmp(v->value, "caller")) 13457 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST); 13458 else if(!strcasecmp(v->value, "disabled")) 13459 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13460 else if(!strcasecmp(v->value, "reqonly")) { 13461 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP); 13462 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13463 } 13464 } else if (!strcasecmp(v->name, "jitterbuffer")) 13465 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 13466 else if (!strcasecmp(v->name, "forcejitterbuffer")) 13467 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 13468 else if (!strcasecmp(v->name, "delayreject")) 13469 delayreject = ast_true(v->value); 13470 else if (!strcasecmp(v->name, "allowfwdownload")) 13471 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 13472 else if (!strcasecmp(v->name, "rtcachefriends")) 13473 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 13474 else if (!strcasecmp(v->name, "rtignoreregexpire")) 13475 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 13476 else if (!strcasecmp(v->name, "rtupdate")) 13477 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE); 13478 else if (!strcasecmp(v->name, "rtsavesysname")) 13479 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME); 13480 else if (!strcasecmp(v->name, "trunktimestamps")) 13481 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 13482 else if (!strcasecmp(v->name, "rtautoclear")) { 13483 int i = atoi(v->value); 13484 if(i > 0) 13485 global_rtautoclear = i; 13486 else 13487 i = 0; 13488 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 13489 } else if (!strcasecmp(v->name, "trunkfreq")) { 13490 trunkfreq = atoi(v->value); 13491 if (trunkfreq < 10) { 13492 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n"); 13493 trunkfreq = 10; 13494 } else if (trunkfreq > 1000) { 13495 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n"); 13496 trunkfreq = 1000; 13497 } 13498 if (timer) { 13499 ast_timer_set_rate(timer, 1000 / trunkfreq); 13500 } 13501 } else if (!strcasecmp(v->name, "trunkmtu")) { 13502 mtuv = atoi(v->value); 13503 if (mtuv == 0 ) 13504 global_max_trunk_mtu = 0; 13505 else if (mtuv >= 172 && mtuv < 4000) 13506 global_max_trunk_mtu = mtuv; 13507 else 13508 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 13509 mtuv, v->lineno); 13510 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 13511 trunkmaxsize = atoi(v->value); 13512 if (trunkmaxsize == 0) 13513 trunkmaxsize = MAX_TRUNKDATA; 13514 } else if (!strcasecmp(v->name, "autokill")) { 13515 if (sscanf(v->value, "%30d", &x) == 1) { 13516 if (x >= 0) 13517 autokill = x; 13518 else 13519 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 13520 } else if (ast_true(v->value)) { 13521 autokill = DEFAULT_MAXMS; 13522 } else { 13523 autokill = 0; 13524 } 13525 } else if (!strcasecmp(v->name, "bandwidth")) { 13526 if (!strcasecmp(v->value, "low")) { 13527 capability = IAX_CAPABILITY_LOWBANDWIDTH; 13528 } else if (!strcasecmp(v->value, "medium")) { 13529 capability = IAX_CAPABILITY_MEDBANDWIDTH; 13530 } else if (!strcasecmp(v->value, "high")) { 13531 capability = IAX_CAPABILITY_FULLBANDWIDTH; 13532 } else 13533 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 13534 } else if (!strcasecmp(v->name, "allow")) { 13535 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 13536 } else if (!strcasecmp(v->name, "disallow")) { 13537 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 13538 } else if (!strcasecmp(v->name, "register")) { 13539 iax2_register(v->value, v->lineno); 13540 } else if (!strcasecmp(v->name, "iaxcompat")) { 13541 iaxcompat = ast_true(v->value); 13542 } else if (!strcasecmp(v->name, "regcontext")) { 13543 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 13544 /* Create context if it doesn't exist already */ 13545 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 13546 } else if (!strcasecmp(v->name, "tos")) { 13547 if (ast_str2tos(v->value, &qos.tos)) 13548 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 13549 } else if (!strcasecmp(v->name, "cos")) { 13550 if (ast_str2cos(v->value, &qos.cos)) 13551 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 13552 } else if (!strcasecmp(v->name, "parkinglot")) { 13553 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 13554 } else if (!strcasecmp(v->name, "accountcode")) { 13555 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 13556 } else if (!strcasecmp(v->name, "mohinterpret")) { 13557 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 13558 } else if (!strcasecmp(v->name, "mohsuggest")) { 13559 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 13560 } else if (!strcasecmp(v->name, "amaflags")) { 13561 format = ast_cdr_amaflags2int(v->value); 13562 if (format < 0) { 13563 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13564 } else { 13565 amaflags = format; 13566 } 13567 } else if (!strcasecmp(v->name, "language")) { 13568 ast_copy_string(language, v->value, sizeof(language)); 13569 } else if (!strcasecmp(v->name, "maxauthreq")) { 13570 maxauthreq = atoi(v->value); 13571 if (maxauthreq < 0) 13572 maxauthreq = 0; 13573 } else if (!strcasecmp(v->name, "adsi")) { 13574 adsi = ast_true(v->value); 13575 } else if (!strcasecmp(v->name, "srvlookup")) { 13576 srvlookup = ast_true(v->value); 13577 } else if (!strcasecmp(v->name, "connectedline")) { 13578 if (ast_true(v->value)) { 13579 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13580 } else if (!strcasecmp(v->value, "send")) { 13581 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13582 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13583 } else if (!strcasecmp(v->value, "receive")) { 13584 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13585 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13586 } else { 13587 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13588 } 13589 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 13590 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 13591 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 13592 } 13593 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 13594 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 13595 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); 13596 } 13597 } else if (!strcasecmp(v->name, "calltokenoptional")) { 13598 if (add_calltoken_ignore(v->value)) { 13599 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 13600 } 13601 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 13602 if (ast_true(v->value)) { 13603 subscribe_network_change = 1; 13604 } else if (ast_false(v->value)) { 13605 subscribe_network_change = 0; 13606 } else { 13607 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 13608 } 13609 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 13610 if (ast_true(v->value)) { 13611 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13612 } else if (ast_false(v->value)) { 13613 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID); 13614 } else { 13615 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 13616 } 13617 }/*else if (strcasecmp(v->name,"type")) */ 13618 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13619 v = v->next; 13620 } 13621 13622 if (subscribe_network_change) { 13623 network_change_event_subscribe(); 13624 } else { 13625 network_change_event_unsubscribe(); 13626 } 13627 13628 if (defaultsockfd < 0) { 13629 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 13630 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 13631 } else { 13632 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 13633 defaultsockfd = ast_netsock_sockfd(ns); 13634 ast_netsock_unref(ns); 13635 } 13636 } 13637 if (reload) { 13638 ast_netsock_release(outsock); 13639 outsock = ast_netsock_list_alloc(); 13640 if (!outsock) { 13641 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13642 return -1; 13643 } 13644 ast_netsock_init(outsock); 13645 } 13646 13647 if (min_reg_expire > max_reg_expire) { 13648 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 13649 min_reg_expire, max_reg_expire, max_reg_expire); 13650 min_reg_expire = max_reg_expire; 13651 } 13652 iax2_capability = capability; 13653 13654 if (ucfg) { 13655 struct ast_variable *gen; 13656 int genhasiax; 13657 int genregisteriax; 13658 const char *hasiax, *registeriax; 13659 13660 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 13661 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 13662 gen = ast_variable_browse(ucfg, "general"); 13663 cat = ast_category_browse(ucfg, NULL); 13664 while (cat) { 13665 if (strcasecmp(cat, "general")) { 13666 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 13667 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 13668 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 13669 /* Start with general parameters, then specific parameters, user and peer */ 13670 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 13671 if (user) { 13672 ao2_link(users, user); 13673 user = user_unref(user); 13674 } 13675 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 13676 if (peer) { 13677 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13678 reg_source_db(peer); 13679 ao2_link(peers, peer); 13680 peer = peer_unref(peer); 13681 } 13682 } 13683 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 13684 char tmp[256]; 13685 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 13686 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 13687 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 13688 if (!host) 13689 host = ast_variable_retrieve(ucfg, "general", "host"); 13690 if (!username) 13691 username = ast_variable_retrieve(ucfg, "general", "username"); 13692 if (!secret) 13693 secret = ast_variable_retrieve(ucfg, "general", "secret"); 13694 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 13695 if (!ast_strlen_zero(secret)) 13696 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 13697 else 13698 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 13699 iax2_register(tmp, 0); 13700 } 13701 } 13702 } 13703 cat = ast_category_browse(ucfg, cat); 13704 } 13705 ast_config_destroy(ucfg); 13706 } 13707 13708 cat = ast_category_browse(cfg, NULL); 13709 while(cat) { 13710 if (strcasecmp(cat, "general")) { 13711 utype = ast_variable_retrieve(cfg, cat, "type"); 13712 if (!strcasecmp(cat, "callnumberlimits")) { 13713 build_callno_limits(ast_variable_browse(cfg, cat)); 13714 } else if (utype) { 13715 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 13716 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 13717 if (user) { 13718 ao2_link(users, user); 13719 user = user_unref(user); 13720 } 13721 } 13722 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 13723 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 13724 if (peer) { 13725 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13726 reg_source_db(peer); 13727 ao2_link(peers, peer); 13728 peer = peer_unref(peer); 13729 } 13730 } else if (strcasecmp(utype, "user")) { 13731 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 13732 } 13733 } else 13734 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 13735 } 13736 cat = ast_category_browse(cfg, cat); 13737 } 13738 ast_config_destroy(cfg); 13739 return 1; 13740 }
| static void set_config_destroy | ( | void | ) | [static] |
Definition at line 13241 of file chan_iax2.c.
References addr_range_delme_cb(), ao2_callback, ast_clear_flag64, delete_users(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, MAX_TRUNKDATA, and OBJ_NODATA.
Referenced by set_config().
13242 { 13243 strcpy(accountcode, ""); 13244 strcpy(language, ""); 13245 strcpy(mohinterpret, ""); 13246 strcpy(mohsuggest, ""); 13247 trunkmaxsize = MAX_TRUNKDATA; 13248 amaflags = 0; 13249 delayreject = 0; 13250 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | 13251 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13252 delete_users(); 13253 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 13254 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 13255 }
| static void set_hangup_source_and_cause | ( | int | callno, | |
| unsigned char | causecode | |||
| ) | [static] |
Definition at line 10024 of file chan_iax2.c.
References ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_mutex_lock, ast_mutex_unlock, ast_set_hangupsource(), ast_strdupa, ast_channel::hangupcause, iax2_lock_owner(), iaxs, iaxsl, name, and chan_iax2_pvt::owner.
Referenced by socket_process().
10025 { 10026 iax2_lock_owner(callno); 10027 if (iaxs[callno] && iaxs[callno]->owner) { 10028 struct ast_channel *owner; 10029 const char *name; 10030 10031 owner = iaxs[callno]->owner; 10032 if (causecode) { 10033 owner->hangupcause = causecode; 10034 } 10035 name = ast_strdupa(owner->name); 10036 ast_channel_ref(owner); 10037 ast_channel_unlock(owner); 10038 ast_mutex_unlock(&iaxsl[callno]); 10039 ast_set_hangupsource(owner, name, 0); 10040 ast_channel_unref(owner); 10041 ast_mutex_lock(&iaxsl[callno]); 10042 } 10043 }
| static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2348 of file chan_iax2.c.
References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), and addr_range::limit.
Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().
02349 { 02350 uint16_t limit = global_maxcallno; 02351 struct addr_range *addr_range; 02352 struct sockaddr_in sin = { 02353 .sin_addr.s_addr = peercnt->addr, 02354 }; 02355 02356 02357 if (peercnt->reg && peercnt->limit) { 02358 return; /* this peercnt has a custom limit set by a registration */ 02359 } 02360 02361 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02362 limit = addr_range->limit; 02363 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02364 ao2_ref(addr_range, -1); 02365 } 02366 02367 peercnt->limit = limit; 02368 }
| static int set_peercnt_limit_all_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2374 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02375 { 02376 struct peercnt *peercnt = obj; 02377 02378 set_peercnt_limit(peercnt); 02379 ast_debug(1, "Reset limits for peercnts table\n"); 02380 02381 return 0; 02382 }
| static void signal_condition | ( | ast_mutex_t * | lock, | |
| ast_cond_t * | cond | |||
| ) | [static] |
Definition at line 1052 of file chan_iax2.c.
References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.
Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().
01053 { 01054 ast_mutex_lock(lock); 01055 ast_cond_signal(cond); 01056 ast_mutex_unlock(lock); 01057 }
| static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 10045 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_aes_set_decrypt_key(), ast_alloca, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_clear_flag64, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_getformatname_multiple(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_event, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_sched_thread_del, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax_frame::cacheable, calc_timestamp(), iax_ies::called_number, ast_channel::caller, chan_iax2_pvt::calling_pres, iax2_peer::callno, chan_iax2_pvt::callno, iax_frame::callno, iax_ies::calltoken, iax_ies::calltokendata, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, cid_name, cid_num, ast_frame_subclass::codec, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), context, ast_iax2_full_hdr::csub, ast_datastore::data, ast_frame::data, ast_frame::datalen, DATASTORE_INHERIT_FOREVER, ast_iax2_full_hdr::dcallno, DEADLOCK_AVOIDANCE, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, ast_frame::frametype, iax_ies::fwdesc, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_is_control_frame_allowed(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, IAX_FORCE_ENCRYPT, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_IAX_UNKNOWN, IAX_IMMEDIATE, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxs, iaxsl, ast_party_caller::id, ast_party_connected_line::id, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::initid, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, iax_frame::iseqno, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_frame::len, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, iax_ies::musiconhold, ast_party_id::name, ast_variable::name, ast_channel::nativeformats, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, ast_variable::next, ast_party_id::number, ast_frame::offset, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, ast_party_name::presentation, ast_party_number::presentation, iax_ies::provver, iax_ies::provverpres, ast_frame::ptr, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, S_COR, S_OR, ast_frame::samples, save_osptoken(), save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, set_hangup_source_and_cause(), iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_party_name::str, ast_party_number::str, ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_NONE, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, ast_iax2_full_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, ast_party_name::valid, ast_party_number::valid, ast_variable::value, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames(), and iax2_process_thread().
10046 { 10047 struct sockaddr_in sin; 10048 int res; 10049 int updatehistory=1; 10050 int new = NEW_PREVENT; 10051 int dcallno = 0; 10052 char decrypted = 0; 10053 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 10054 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 10055 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 10056 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 10057 struct iax_frame *fr; 10058 struct iax_frame *cur; 10059 struct ast_frame f = { 0, }; 10060 struct ast_channel *c = NULL; 10061 struct iax2_dpcache *dp; 10062 struct iax2_peer *peer; 10063 struct iax_ies ies; 10064 struct iax_ie_data ied0, ied1; 10065 format_t format; 10066 int fd; 10067 int exists; 10068 int minivid = 0; 10069 char empty[32]=""; /* Safety measure */ 10070 struct iax_frame *duped_fr; 10071 char host_pref_buf[128]; 10072 char caller_pref_buf[128]; 10073 struct ast_codec_pref pref; 10074 char *using_prefs = "mine"; 10075 10076 /* allocate an iax_frame with 4096 bytes of data buffer */ 10077 fr = ast_alloca(sizeof(*fr) + 4096); 10078 memset(fr, 0, sizeof(*fr)); 10079 fr->afdatalen = 4096; /* From ast_alloca() above */ 10080 10081 /* Copy frequently used parameters to the stack */ 10082 res = thread->buf_len; 10083 fd = thread->iofd; 10084 memcpy(&sin, &thread->iosin, sizeof(sin)); 10085 10086 if (res < sizeof(*mh)) { 10087 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 10088 return 1; 10089 } 10090 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 10091 if (res < sizeof(*vh)) { 10092 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)); 10093 return 1; 10094 } 10095 10096 /* This is a video frame, get call number */ 10097 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 10098 minivid = 1; 10099 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 10100 return socket_process_meta(res, meta, &sin, fd, fr); 10101 10102 #ifdef DEBUG_SUPPORT 10103 if (res >= sizeof(*fh)) 10104 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 10105 #endif 10106 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10107 if (res < sizeof(*fh)) { 10108 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)); 10109 return 1; 10110 } 10111 10112 /* Get the destination call number */ 10113 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 10114 10115 10116 /* check to make sure this full frame isn't encrypted before we attempt 10117 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 10118 * callno is not found here, that just means one hasn't been allocated for 10119 * this connection yet. */ 10120 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 10121 ast_mutex_lock(&iaxsl[fr->callno]); 10122 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { 10123 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10124 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10125 ast_mutex_unlock(&iaxsl[fr->callno]); 10126 return 1; 10127 } 10128 decrypted = 1; 10129 } 10130 ast_mutex_unlock(&iaxsl[fr->callno]); 10131 } 10132 10133 /* Retrieve the type and subclass */ 10134 f.frametype = fh->type; 10135 if (f.frametype == AST_FRAME_VIDEO) { 10136 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 10137 } else if (f.frametype == AST_FRAME_VOICE) { 10138 f.subclass.codec = uncompress_subclass(fh->csub); 10139 } else { 10140 f.subclass.integer = uncompress_subclass(fh->csub); 10141 } 10142 10143 /* Deal with POKE/PONG without allocating a callno */ 10144 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) { 10145 /* Reply back with a PONG, but don't care about the result. */ 10146 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10147 return 1; 10148 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) { 10149 /* Ignore */ 10150 return 1; 10151 } 10152 10153 f.datalen = res - sizeof(*fh); 10154 if (f.datalen) { 10155 if (f.frametype == AST_FRAME_IAX) { 10156 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 10157 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 10158 ast_variables_destroy(ies.vars); 10159 return 1; 10160 } 10161 f.data.ptr = NULL; 10162 f.datalen = 0; 10163 } else { 10164 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 10165 memset(&ies, 0, sizeof(ies)); 10166 } 10167 } else { 10168 if (f.frametype == AST_FRAME_IAX) 10169 f.data.ptr = NULL; 10170 else 10171 f.data.ptr = empty; 10172 memset(&ies, 0, sizeof(ies)); 10173 } 10174 10175 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) { 10176 /* only set NEW_ALLOW if calltoken checks out */ 10177 if (handle_call_token(fh, &ies, &sin, fd)) { 10178 ast_variables_destroy(ies.vars); 10179 return 1; 10180 } 10181 10182 if (ies.calltoken && ies.calltokendata) { 10183 /* if we've gotten this far, and the calltoken ie data exists, 10184 * then calltoken validation _MUST_ have taken place. If calltoken 10185 * data is provided, it is always validated reguardless of any 10186 * calltokenoptional or requirecalltoken options */ 10187 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 10188 } else { 10189 new = NEW_ALLOW; 10190 } 10191 } 10192 } else { 10193 /* Don't know anything about it yet */ 10194 f.frametype = AST_FRAME_NULL; 10195 f.subclass.integer = 0; 10196 memset(&ies, 0, sizeof(ies)); 10197 } 10198 10199 if (!fr->callno) { 10200 int check_dcallno = 0; 10201 10202 /* 10203 * We enforce accurate destination call numbers for ACKs. This forces the other 10204 * end to know the destination call number before call setup can complete. 10205 * 10206 * Discussed in the following thread: 10207 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 10208 */ 10209 10210 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) { 10211 check_dcallno = 1; 10212 } 10213 10214 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 10215 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) { 10216 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10217 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) { 10218 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10219 } 10220 ast_variables_destroy(ies.vars); 10221 return 1; 10222 } 10223 } 10224 10225 if (fr->callno > 0) 10226 ast_mutex_lock(&iaxsl[fr->callno]); 10227 10228 if (!fr->callno || !iaxs[fr->callno]) { 10229 /* A call arrived for a nonexistent destination. Unless it's an "inval" 10230 frame, reply with an inval */ 10231 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10232 /* We can only raw hangup control frames */ 10233 if (((f.subclass.integer != IAX_COMMAND_INVAL) && 10234 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10235 (f.subclass.integer != IAX_COMMAND_TXACC) && 10236 (f.subclass.integer != IAX_COMMAND_FWDOWNL))|| 10237 (f.frametype != AST_FRAME_IAX)) 10238 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 10239 fd); 10240 } 10241 if (fr->callno > 0) 10242 ast_mutex_unlock(&iaxsl[fr->callno]); 10243 ast_variables_destroy(ies.vars); 10244 return 1; 10245 } 10246 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 10247 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10248 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10249 ast_variables_destroy(ies.vars); 10250 ast_mutex_unlock(&iaxsl[fr->callno]); 10251 return 1; 10252 } 10253 decrypted = 1; 10254 } 10255 10256 #ifdef DEBUG_SUPPORT 10257 if (decrypted) { 10258 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 10259 } 10260 #endif 10261 10262 10263 /* count this frame */ 10264 iaxs[fr->callno]->frames_received++; 10265 10266 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 10267 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */ 10268 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */ 10269 unsigned short new_peercallno; 10270 10271 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 10272 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 10273 if (iaxs[fr->callno]->peercallno) { 10274 remove_by_peercallno(iaxs[fr->callno]); 10275 } 10276 iaxs[fr->callno]->peercallno = new_peercallno; 10277 store_by_peercallno(iaxs[fr->callno]); 10278 } 10279 } 10280 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10281 if (iaxdebug) 10282 ast_debug(1, "Received packet %d, (%u, %d)\n", fh->oseqno, f.frametype, f.subclass.integer); 10283 /* Check if it's out of order (and not an ACK or INVAL) */ 10284 fr->oseqno = fh->oseqno; 10285 fr->iseqno = fh->iseqno; 10286 fr->ts = ntohl(fh->ts); 10287 #ifdef IAXTESTS 10288 if (test_resync) { 10289 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 10290 fr->ts += test_resync; 10291 } 10292 #endif /* IAXTESTS */ 10293 #if 0 10294 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 10295 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 10296 (f.subclass == IAX_COMMAND_NEW || 10297 f.subclass == IAX_COMMAND_AUTHREQ || 10298 f.subclass == IAX_COMMAND_ACCEPT || 10299 f.subclass == IAX_COMMAND_REJECT)) ) ) 10300 #endif 10301 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 10302 updatehistory = 0; 10303 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 10304 (iaxs[fr->callno]->iseqno || 10305 ((f.subclass.integer != IAX_COMMAND_TXCNT) && 10306 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10307 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10308 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10309 (f.subclass.integer != IAX_COMMAND_TXACC)) || 10310 (f.frametype != AST_FRAME_IAX))) { 10311 if ( 10312 ((f.subclass.integer != IAX_COMMAND_ACK) && 10313 (f.subclass.integer != IAX_COMMAND_INVAL) && 10314 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10315 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10316 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10317 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10318 (f.subclass.integer != IAX_COMMAND_TXACC) && 10319 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10320 (f.frametype != AST_FRAME_IAX)) { 10321 /* If it's not an ACK packet, it's out of order. */ 10322 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %u, subclass = %d)\n", 10323 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer); 10324 /* Check to see if we need to request retransmission, 10325 * and take sequence number wraparound into account */ 10326 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 10327 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 10328 if ((f.frametype != AST_FRAME_IAX) || 10329 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) { 10330 ast_debug(1, "Acking anyway\n"); 10331 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 10332 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 10333 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10334 } 10335 } else { 10336 /* Send a VNAK requesting retransmission */ 10337 iax2_vnak(fr->callno); 10338 } 10339 ast_variables_destroy(ies.vars); 10340 ast_mutex_unlock(&iaxsl[fr->callno]); 10341 return 1; 10342 } 10343 } else { 10344 /* Increment unless it's an ACK or VNAK */ 10345 if (((f.subclass.integer != IAX_COMMAND_ACK) && 10346 (f.subclass.integer != IAX_COMMAND_INVAL) && 10347 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10348 (f.subclass.integer != IAX_COMMAND_TXACC) && 10349 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10350 (f.frametype != AST_FRAME_IAX)) 10351 iaxs[fr->callno]->iseqno++; 10352 } 10353 /* Ensure text frames are NULL-terminated */ 10354 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 10355 if (res < thread->buf_size) 10356 thread->buf[res++] = '\0'; 10357 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 10358 thread->buf[res - 1] = '\0'; 10359 } 10360 10361 /* Handle implicit ACKing unless this is an INVAL, and only if this is 10362 from the real peer, not the transfer peer */ 10363 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10364 ((f.subclass.integer != IAX_COMMAND_INVAL) || 10365 (f.frametype != AST_FRAME_IAX))) { 10366 unsigned char x; 10367 int call_to_destroy; 10368 /* First we have to qualify that the ACKed value is within our window */ 10369 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 10370 x = fr->iseqno; 10371 else 10372 x = iaxs[fr->callno]->oseqno; 10373 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 10374 /* The acknowledgement is within our window. Time to acknowledge everything 10375 that it says to */ 10376 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 10377 /* Ack the packet with the given timestamp */ 10378 if (iaxdebug) 10379 ast_debug(1, "Cancelling transmission of packet %d\n", x); 10380 call_to_destroy = 0; 10381 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10382 /* If it's our call, and our timestamp, mark -1 retries */ 10383 if (x == cur->oseqno) { 10384 cur->retries = -1; 10385 /* Destroy call if this is the end */ 10386 if (cur->final) 10387 call_to_destroy = fr->callno; 10388 } 10389 } 10390 if (call_to_destroy) { 10391 if (iaxdebug) 10392 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 10393 ast_mutex_lock(&iaxsl[call_to_destroy]); 10394 iax2_destroy(call_to_destroy); 10395 ast_mutex_unlock(&iaxsl[call_to_destroy]); 10396 } 10397 } 10398 /* Note how much we've received acknowledgement for */ 10399 if (iaxs[fr->callno]) 10400 iaxs[fr->callno]->rseqno = fr->iseqno; 10401 else { 10402 /* Stop processing now */ 10403 ast_variables_destroy(ies.vars); 10404 ast_mutex_unlock(&iaxsl[fr->callno]); 10405 return 1; 10406 } 10407 } else { 10408 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 10409 } 10410 } 10411 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10412 ((f.frametype != AST_FRAME_IAX) || 10413 ((f.subclass.integer != IAX_COMMAND_TXACC) && 10414 (f.subclass.integer != IAX_COMMAND_TXCNT)))) { 10415 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 10416 ast_variables_destroy(ies.vars); 10417 ast_mutex_unlock(&iaxsl[fr->callno]); 10418 return 1; 10419 } 10420 10421 /* when we receive the first full frame for a new incoming channel, 10422 it is safe to start the PBX on the channel because we have now 10423 completed a 3-way handshake with the peer */ 10424 if ((f.frametype == AST_FRAME_VOICE) || 10425 (f.frametype == AST_FRAME_VIDEO) || 10426 (f.frametype == AST_FRAME_IAX)) { 10427 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 10428 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10429 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL, 10430 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) { 10431 ast_variables_destroy(ies.vars); 10432 ast_mutex_unlock(&iaxsl[fr->callno]); 10433 return 1; 10434 } 10435 } 10436 10437 if (ies.vars) { 10438 struct ast_datastore *variablestore = NULL; 10439 struct ast_variable *var, *prev = NULL; 10440 AST_LIST_HEAD(, ast_var_t) *varlist; 10441 10442 iax2_lock_owner(fr->callno); 10443 if (!iaxs[fr->callno]) { 10444 ast_variables_destroy(ies.vars); 10445 ast_mutex_unlock(&iaxsl[fr->callno]); 10446 return 1; 10447 } 10448 if ((c = iaxs[fr->callno]->owner)) { 10449 varlist = ast_calloc(1, sizeof(*varlist)); 10450 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10451 10452 if (variablestore && varlist) { 10453 variablestore->data = varlist; 10454 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10455 AST_LIST_HEAD_INIT(varlist); 10456 ast_debug(1, "I can haz IAX vars?\n"); 10457 for (var = ies.vars; var; var = var->next) { 10458 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10459 if (prev) { 10460 ast_free(prev); 10461 } 10462 prev = var; 10463 if (!newvar) { 10464 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10465 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10466 } else { 10467 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10468 } 10469 } 10470 if (prev) { 10471 ast_free(prev); 10472 } 10473 ies.vars = NULL; 10474 ast_channel_datastore_add(c, variablestore); 10475 } else { 10476 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10477 if (variablestore) { 10478 ast_datastore_free(variablestore); 10479 } 10480 if (varlist) { 10481 ast_free(varlist); 10482 } 10483 } 10484 ast_channel_unlock(c); 10485 } else { 10486 /* No channel yet, so transfer the variables directly over to the pvt, 10487 * for later inheritance. */ 10488 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 10489 for (var = ies.vars; var && var->next; var = var->next); 10490 if (var) { 10491 var->next = iaxs[fr->callno]->iaxvars; 10492 iaxs[fr->callno]->iaxvars = ies.vars; 10493 ies.vars = NULL; 10494 } 10495 } 10496 } 10497 10498 if (ies.vars) { 10499 ast_debug(1, "I have IAX variables, but they were not processed\n"); 10500 } 10501 } 10502 10503 /* once we receive our first IAX Full Frame that is not CallToken related, send all 10504 * queued signaling frames that were being held. */ 10505 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 10506 send_signaling(iaxs[fr->callno]); 10507 } 10508 10509 if (f.frametype == AST_FRAME_VOICE) { 10510 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) { 10511 iaxs[fr->callno]->voiceformat = f.subclass.codec; 10512 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec)); 10513 if (iaxs[fr->callno]->owner) { 10514 iax2_lock_owner(fr->callno); 10515 if (iaxs[fr->callno]) { 10516 if (iaxs[fr->callno]->owner) { 10517 format_t orignative; 10518 10519 orignative = iaxs[fr->callno]->owner->nativeformats; 10520 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec; 10521 if (iaxs[fr->callno]->owner->readformat) 10522 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10523 iaxs[fr->callno]->owner->nativeformats = orignative; 10524 ast_channel_unlock(iaxs[fr->callno]->owner); 10525 } 10526 } else { 10527 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 10528 /* Free remote variables (if any) */ 10529 if (ies.vars) { 10530 ast_variables_destroy(ies.vars); 10531 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 10532 ies.vars = NULL; 10533 } 10534 ast_mutex_unlock(&iaxsl[fr->callno]); 10535 return 1; 10536 } 10537 } 10538 } 10539 } 10540 if (f.frametype == AST_FRAME_VIDEO) { 10541 if (f.subclass.codec != iaxs[fr->callno]->videoformat) { 10542 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL)); 10543 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL; 10544 } 10545 } 10546 if (f.frametype == AST_FRAME_IAX) { 10547 ast_sched_thread_del(sched, iaxs[fr->callno]->initid); 10548 /* Handle the IAX pseudo frame itself */ 10549 if (iaxdebug) 10550 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer); 10551 10552 /* Update last ts unless the frame's timestamp originated with us. */ 10553 if (iaxs[fr->callno]->last < fr->ts && 10554 f.subclass.integer != IAX_COMMAND_ACK && 10555 f.subclass.integer != IAX_COMMAND_PONG && 10556 f.subclass.integer != IAX_COMMAND_LAGRP) { 10557 iaxs[fr->callno]->last = fr->ts; 10558 if (iaxdebug) 10559 ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts); 10560 } 10561 iaxs[fr->callno]->last_iax_message = f.subclass.integer; 10562 if (!iaxs[fr->callno]->first_iax_message) { 10563 iaxs[fr->callno]->first_iax_message = f.subclass.integer; 10564 } 10565 switch(f.subclass.integer) { 10566 case IAX_COMMAND_ACK: 10567 /* Do nothing */ 10568 break; 10569 case IAX_COMMAND_QUELCH: 10570 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10571 /* Generate Manager Hold event, if necessary*/ 10572 if (iaxs[fr->callno]->owner) { 10573 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10574 "Status: On\r\n" 10575 "Channel: %s\r\n" 10576 "Uniqueid: %s\r\n", 10577 iaxs[fr->callno]->owner->name, 10578 iaxs[fr->callno]->owner->uniqueid); 10579 } 10580 10581 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH); 10582 if (ies.musiconhold) { 10583 iax2_lock_owner(fr->callno); 10584 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 10585 break; 10586 } 10587 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10588 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 10589 10590 /* 10591 * We already hold the owner lock so we do not 10592 * need to check iaxs[fr->callno] after it returns. 10593 */ 10594 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 10595 S_OR(moh_suggest, NULL), 10596 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 10597 } 10598 ast_channel_unlock(iaxs[fr->callno]->owner); 10599 } 10600 } 10601 break; 10602 case IAX_COMMAND_UNQUELCH: 10603 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10604 iax2_lock_owner(fr->callno); 10605 if (!iaxs[fr->callno]) { 10606 break; 10607 } 10608 /* Generate Manager Unhold event, if necessary */ 10609 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { 10610 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10611 "Status: Off\r\n" 10612 "Channel: %s\r\n" 10613 "Uniqueid: %s\r\n", 10614 iaxs[fr->callno]->owner->name, 10615 iaxs[fr->callno]->owner->uniqueid); 10616 } 10617 10618 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH); 10619 if (!iaxs[fr->callno]->owner) { 10620 break; 10621 } 10622 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10623 /* 10624 * We already hold the owner lock so we do not 10625 * need to check iaxs[fr->callno] after it returns. 10626 */ 10627 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10628 } 10629 ast_channel_unlock(iaxs[fr->callno]->owner); 10630 } 10631 break; 10632 case IAX_COMMAND_TXACC: 10633 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10634 /* Ack the packet with the given timestamp */ 10635 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10636 /* Cancel any outstanding txcnt's */ 10637 if (cur->transfer) { 10638 cur->retries = -1; 10639 } 10640 } 10641 memset(&ied1, 0, sizeof(ied1)); 10642 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10643 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10644 iaxs[fr->callno]->transferring = TRANSFER_READY; 10645 } 10646 break; 10647 case IAX_COMMAND_NEW: 10648 /* Ignore if it's already up */ 10649 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10650 break; 10651 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10652 ast_mutex_unlock(&iaxsl[fr->callno]); 10653 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10654 ast_mutex_lock(&iaxsl[fr->callno]); 10655 if (!iaxs[fr->callno]) { 10656 break; 10657 } 10658 } 10659 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10660 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) { 10661 int new_callno; 10662 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10663 fr->callno = new_callno; 10664 } 10665 /* For security, always ack immediately */ 10666 if (delayreject) 10667 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10668 if (check_access(fr->callno, &sin, &ies)) { 10669 /* They're not allowed on */ 10670 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10671 if (authdebug) 10672 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); 10673 break; 10674 } 10675 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10676 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10677 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10678 break; 10679 } 10680 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10681 const char *context, *exten, *cid_num; 10682 10683 context = ast_strdupa(iaxs[fr->callno]->context); 10684 exten = ast_strdupa(iaxs[fr->callno]->exten); 10685 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10686 10687 /* This might re-enter the IAX code and need the lock */ 10688 ast_mutex_unlock(&iaxsl[fr->callno]); 10689 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10690 ast_mutex_lock(&iaxsl[fr->callno]); 10691 10692 if (!iaxs[fr->callno]) { 10693 break; 10694 } 10695 } else 10696 exists = 0; 10697 /* Get OSP token if it does exist */ 10698 save_osptoken(fr, &ies); 10699 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10700 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10701 memset(&ied0, 0, sizeof(ied0)); 10702 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10703 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10704 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10705 if (!iaxs[fr->callno]) { 10706 break; 10707 } 10708 if (authdebug) 10709 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); 10710 } else { 10711 /* Select an appropriate format */ 10712 10713 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10714 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10715 using_prefs = "reqonly"; 10716 } else { 10717 using_prefs = "disabled"; 10718 } 10719 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10720 memset(&pref, 0, sizeof(pref)); 10721 strcpy(caller_pref_buf, "disabled"); 10722 strcpy(host_pref_buf, "disabled"); 10723 } else { 10724 using_prefs = "mine"; 10725 /* If the information elements are in here... use them */ 10726 if (ies.codec_prefs) 10727 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10728 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10729 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10730 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10731 pref = iaxs[fr->callno]->rprefs; 10732 using_prefs = "caller"; 10733 } else { 10734 pref = iaxs[fr->callno]->prefs; 10735 } 10736 } else 10737 pref = iaxs[fr->callno]->prefs; 10738 10739 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10740 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10741 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10742 } 10743 if (!format) { 10744 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10745 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10746 if (!format) { 10747 memset(&ied0, 0, sizeof(ied0)); 10748 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10749 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10750 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10751 if (!iaxs[fr->callno]) { 10752 break; 10753 } 10754 if (authdebug) { 10755 char tmp[256], tmp2[256], tmp3[256]; 10756 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10757 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 10758 ast_inet_ntoa(sin.sin_addr), 10759 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10760 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10761 } else { 10762 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10763 ast_inet_ntoa(sin.sin_addr), 10764 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10765 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10766 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10767 } 10768 } 10769 } else { 10770 /* Pick one... */ 10771 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10772 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10773 format = 0; 10774 } else { 10775 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10776 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10777 memset(&pref, 0, sizeof(pref)); 10778 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10779 strcpy(caller_pref_buf,"disabled"); 10780 strcpy(host_pref_buf,"disabled"); 10781 } else { 10782 using_prefs = "mine"; 10783 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10784 /* Do the opposite of what we tried above. */ 10785 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10786 pref = iaxs[fr->callno]->prefs; 10787 } else { 10788 pref = iaxs[fr->callno]->rprefs; 10789 using_prefs = "caller"; 10790 } 10791 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10792 } else /* if no codec_prefs IE do it the old way */ 10793 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10794 } 10795 } 10796 10797 if (!format) { 10798 char tmp[256], tmp2[256], tmp3[256]; 10799 memset(&ied0, 0, sizeof(ied0)); 10800 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10801 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10802 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 10803 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10804 if (!iaxs[fr->callno]) { 10805 break; 10806 } 10807 if (authdebug) { 10808 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10809 ast_inet_ntoa(sin.sin_addr), 10810 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10811 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10812 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10813 } 10814 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10815 break; 10816 } 10817 } 10818 } 10819 if (format) { 10820 /* No authentication required, let them in */ 10821 memset(&ied1, 0, sizeof(ied1)); 10822 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10823 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 10824 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10825 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10826 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10827 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10828 "%srequested format = %s,\n" 10829 "%srequested prefs = %s,\n" 10830 "%sactual format = %s,\n" 10831 "%shost prefs = %s,\n" 10832 "%spriority = %s\n", 10833 ast_inet_ntoa(sin.sin_addr), 10834 VERBOSE_PREFIX_4, 10835 ast_getformatname(iaxs[fr->callno]->peerformat), 10836 VERBOSE_PREFIX_4, 10837 caller_pref_buf, 10838 VERBOSE_PREFIX_4, 10839 ast_getformatname(format), 10840 VERBOSE_PREFIX_4, 10841 host_pref_buf, 10842 VERBOSE_PREFIX_4, 10843 using_prefs); 10844 10845 iaxs[fr->callno]->chosenformat = format; 10846 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10847 } else { 10848 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10849 /* If this is a TBD call, we're ready but now what... */ 10850 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10851 } 10852 } 10853 } 10854 break; 10855 } 10856 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10857 merge_encryption(iaxs[fr->callno],ies.encmethods); 10858 else 10859 iaxs[fr->callno]->encmethods = 0; 10860 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10861 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10862 break; 10863 case IAX_COMMAND_DPREQ: 10864 /* Request status in the dialplan */ 10865 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10866 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10867 if (iaxcompat) { 10868 /* Spawn a thread for the lookup */ 10869 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10870 } else { 10871 /* Just look it up */ 10872 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10873 } 10874 } 10875 break; 10876 case IAX_COMMAND_HANGUP: 10877 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10878 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10879 /* Set hangup cause according to remote and hangupsource */ 10880 if (iaxs[fr->callno]->owner) { 10881 set_hangup_source_and_cause(fr->callno, ies.causecode); 10882 if (!iaxs[fr->callno]) { 10883 break; 10884 } 10885 } 10886 10887 /* Send ack immediately, before we destroy */ 10888 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10889 iax2_destroy(fr->callno); 10890 break; 10891 case IAX_COMMAND_REJECT: 10892 /* Set hangup cause according to remote and hangup source */ 10893 if (iaxs[fr->callno]->owner) { 10894 set_hangup_source_and_cause(fr->callno, ies.causecode); 10895 if (!iaxs[fr->callno]) { 10896 break; 10897 } 10898 } 10899 10900 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10901 if (iaxs[fr->callno]->owner && authdebug) 10902 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10903 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10904 ies.cause ? ies.cause : "<Unknown>"); 10905 ast_debug(1, "Immediately destroying %d, having received reject\n", 10906 fr->callno); 10907 } 10908 /* Send ack immediately, before we destroy */ 10909 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10910 fr->ts, NULL, 0, fr->iseqno); 10911 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) 10912 iaxs[fr->callno]->error = EPERM; 10913 iax2_destroy(fr->callno); 10914 break; 10915 case IAX_COMMAND_TRANSFER: 10916 { 10917 struct ast_channel *bridged_chan; 10918 struct ast_channel *owner; 10919 10920 iax2_lock_owner(fr->callno); 10921 if (!iaxs[fr->callno]) { 10922 /* Initiating call went away before we could transfer. */ 10923 break; 10924 } 10925 owner = iaxs[fr->callno]->owner; 10926 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 10927 if (bridged_chan && ies.called_number) { 10928 const char *context; 10929 10930 context = ast_strdupa(iaxs[fr->callno]->context); 10931 10932 ast_channel_ref(owner); 10933 ast_channel_ref(bridged_chan); 10934 ast_channel_unlock(owner); 10935 ast_mutex_unlock(&iaxsl[fr->callno]); 10936 10937 /* Set BLINDTRANSFER channel variables */ 10938 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name); 10939 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name); 10940 10941 /* DO NOT hold any locks while calling ast_parking_ext_valid() */ 10942 if (ast_parking_ext_valid(ies.called_number, owner, context)) { 10943 ast_debug(1, "Parking call '%s'\n", bridged_chan->name); 10944 if (iax_park(bridged_chan, owner, ies.called_number, context)) { 10945 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 10946 bridged_chan->name); 10947 } 10948 } else { 10949 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) { 10950 ast_log(LOG_WARNING, 10951 "Async goto of '%s' to '%s@%s' failed\n", 10952 bridged_chan->name, ies.called_number, context); 10953 } else { 10954 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", 10955 bridged_chan->name, ies.called_number, context); 10956 } 10957 } 10958 ast_channel_unref(owner); 10959 ast_channel_unref(bridged_chan); 10960 10961 ast_mutex_lock(&iaxsl[fr->callno]); 10962 } else { 10963 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10964 if (owner) { 10965 ast_channel_unlock(owner); 10966 } 10967 } 10968 10969 break; 10970 } 10971 case IAX_COMMAND_ACCEPT: 10972 /* Ignore if call is already up or needs authentication or is a TBD */ 10973 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10974 break; 10975 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10976 /* Send ack immediately, before we destroy */ 10977 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10978 iax2_destroy(fr->callno); 10979 break; 10980 } 10981 if (ies.format) { 10982 iaxs[fr->callno]->peerformat = ies.format; 10983 } else { 10984 if (iaxs[fr->callno]->owner) 10985 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10986 else 10987 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10988 } 10989 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)); 10990 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10991 memset(&ied0, 0, sizeof(ied0)); 10992 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10993 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10994 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10995 if (!iaxs[fr->callno]) { 10996 break; 10997 } 10998 if (authdebug) { 10999 char tmp1[256], tmp2[256]; 11000 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n", 11001 ast_inet_ntoa(sin.sin_addr), 11002 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11003 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11004 } 11005 } else { 11006 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11007 iax2_lock_owner(fr->callno); 11008 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 11009 /* Switch us to use a compatible format */ 11010 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 11011 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 11012 11013 /* Setup read/write formats properly. */ 11014 if (iaxs[fr->callno]->owner->writeformat) 11015 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 11016 if (iaxs[fr->callno]->owner->readformat) 11017 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 11018 ast_channel_unlock(iaxs[fr->callno]->owner); 11019 } 11020 } 11021 if (iaxs[fr->callno]) { 11022 AST_LIST_LOCK(&dpcache); 11023 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 11024 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 11025 iax2_dprequest(dp, fr->callno); 11026 AST_LIST_UNLOCK(&dpcache); 11027 } 11028 break; 11029 case IAX_COMMAND_POKE: 11030 /* Send back a pong packet with the original timestamp */ 11031 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 11032 break; 11033 case IAX_COMMAND_PING: 11034 { 11035 struct iax_ie_data pingied; 11036 construct_rr(iaxs[fr->callno], &pingied); 11037 /* Send back a pong packet with the original timestamp */ 11038 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 11039 } 11040 break; 11041 case IAX_COMMAND_PONG: 11042 /* Calculate ping time */ 11043 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 11044 /* save RR info */ 11045 save_rr(fr, &ies); 11046 11047 /* Good time to write jb stats for this call */ 11048 log_jitterstats(fr->callno); 11049 11050 if (iaxs[fr->callno]->peerpoke) { 11051 peer = iaxs[fr->callno]->peerpoke; 11052 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 11053 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 11054 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %u\n", peer->name, iaxs[fr->callno]->pingtime); 11055 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %u\r\n", peer->name, iaxs[fr->callno]->pingtime); 11056 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 11057 } 11058 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 11059 if (iaxs[fr->callno]->pingtime > peer->maxms) { 11060 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%u ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 11061 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %u\r\n", peer->name, iaxs[fr->callno]->pingtime); 11062 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 11063 } 11064 } 11065 peer->lastms = iaxs[fr->callno]->pingtime; 11066 if (peer->smoothing && (peer->lastms > -1)) 11067 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 11068 else if (peer->smoothing && peer->lastms < 0) 11069 peer->historicms = (0 + peer->historicms) / 2; 11070 else 11071 peer->historicms = iaxs[fr->callno]->pingtime; 11072 11073 /* Remove scheduled iax2_poke_noanswer */ 11074 if (peer->pokeexpire > -1) { 11075 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 11076 peer_unref(peer); 11077 peer->pokeexpire = -1; 11078 } 11079 } 11080 /* Schedule the next cycle */ 11081 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 11082 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11083 else 11084 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 11085 if (peer->pokeexpire == -1) 11086 peer_unref(peer); 11087 /* and finally send the ack */ 11088 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11089 /* And wrap up the qualify call */ 11090 iax2_destroy(fr->callno); 11091 peer->callno = 0; 11092 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 11093 } 11094 break; 11095 case IAX_COMMAND_LAGRQ: 11096 case IAX_COMMAND_LAGRP: 11097 f.src = "LAGRQ"; 11098 f.mallocd = 0; 11099 f.offset = 0; 11100 f.samples = 0; 11101 iax_frame_wrap(fr, &f); 11102 if (f.subclass.integer == IAX_COMMAND_LAGRQ) { 11103 /* Received a LAGRQ - echo back a LAGRP */ 11104 fr->af.subclass.integer = IAX_COMMAND_LAGRP; 11105 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 11106 } else { 11107 /* Received LAGRP in response to our LAGRQ */ 11108 unsigned int ts; 11109 /* This is a reply we've been given, actually measure the difference */ 11110 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 11111 iaxs[fr->callno]->lag = ts - fr->ts; 11112 if (iaxdebug) 11113 ast_debug(1, "Peer %s lag measured as %dms\n", 11114 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 11115 } 11116 break; 11117 case IAX_COMMAND_AUTHREQ: 11118 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11119 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>"); 11120 break; 11121 } 11122 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 11123 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 11124 .subclass.integer = AST_CONTROL_HANGUP, 11125 }; 11126 ast_log(LOG_WARNING, 11127 "I don't know how to authenticate %s to %s\n", 11128 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 11129 iax2_queue_frame(fr->callno, &hangup_fr); 11130 } 11131 break; 11132 case IAX_COMMAND_AUTHREP: 11133 /* For security, always ack immediately */ 11134 if (delayreject) 11135 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11136 /* Ignore once we've started */ 11137 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11138 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>"); 11139 break; 11140 } 11141 if (authenticate_verify(iaxs[fr->callno], &ies)) { 11142 if (authdebug) 11143 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); 11144 memset(&ied0, 0, sizeof(ied0)); 11145 auth_fail(fr->callno, IAX_COMMAND_REJECT); 11146 break; 11147 } 11148 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 11149 /* This might re-enter the IAX code and need the lock */ 11150 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 11151 } else 11152 exists = 0; 11153 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 11154 if (authdebug) 11155 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); 11156 memset(&ied0, 0, sizeof(ied0)); 11157 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11158 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11159 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11160 if (!iaxs[fr->callno]) { 11161 break; 11162 } 11163 } else { 11164 /* Select an appropriate format */ 11165 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11166 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11167 using_prefs = "reqonly"; 11168 } else { 11169 using_prefs = "disabled"; 11170 } 11171 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 11172 memset(&pref, 0, sizeof(pref)); 11173 strcpy(caller_pref_buf, "disabled"); 11174 strcpy(host_pref_buf, "disabled"); 11175 } else { 11176 using_prefs = "mine"; 11177 if (ies.codec_prefs) 11178 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 11179 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11180 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11181 pref = iaxs[fr->callno]->rprefs; 11182 using_prefs = "caller"; 11183 } else { 11184 pref = iaxs[fr->callno]->prefs; 11185 } 11186 } else /* if no codec_prefs IE do it the old way */ 11187 pref = iaxs[fr->callno]->prefs; 11188 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 11189 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 11190 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 11191 } 11192 if (!format) { 11193 char tmp1[256], tmp2[256], tmp3[256]; 11194 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11195 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n", 11196 ast_getformatname(iaxs[fr->callno]->peerformat), 11197 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability)); 11198 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 11199 } 11200 if (!format) { 11201 if (authdebug) { 11202 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11203 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr), 11204 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11205 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11206 } else { 11207 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11208 ast_inet_ntoa(sin.sin_addr), 11209 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11210 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11211 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11212 } 11213 } 11214 memset(&ied0, 0, sizeof(ied0)); 11215 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11216 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11217 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11218 if (!iaxs[fr->callno]) { 11219 break; 11220 } 11221 } else { 11222 /* Pick one... */ 11223 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11224 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 11225 format = 0; 11226 } else { 11227 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11228 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 11229 memset(&pref, 0, sizeof(pref)); 11230 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 11231 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11232 strcpy(caller_pref_buf,"disabled"); 11233 strcpy(host_pref_buf,"disabled"); 11234 } else { 11235 using_prefs = "mine"; 11236 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11237 /* Do the opposite of what we tried above. */ 11238 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11239 pref = iaxs[fr->callno]->prefs; 11240 } else { 11241 pref = iaxs[fr->callno]->rprefs; 11242 using_prefs = "caller"; 11243 } 11244 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 11245 } else /* if no codec_prefs IE do it the old way */ 11246 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11247 } 11248 } 11249 if (!format) { 11250 char tmp1[256], tmp2[256], tmp3[256]; 11251 ast_log(LOG_ERROR, "No best format in %s???\n", 11252 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 11253 if (authdebug) { 11254 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11255 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 11256 ast_inet_ntoa(sin.sin_addr), 11257 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11258 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11259 } else { 11260 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11261 ast_inet_ntoa(sin.sin_addr), 11262 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11263 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11264 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11265 } 11266 } 11267 memset(&ied0, 0, sizeof(ied0)); 11268 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11269 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11270 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11271 if (!iaxs[fr->callno]) { 11272 break; 11273 } 11274 } 11275 } 11276 } 11277 if (format) { 11278 /* Authentication received */ 11279 memset(&ied1, 0, sizeof(ied1)); 11280 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 11281 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 11282 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 11283 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 11284 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11285 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 11286 "%srequested format = %s,\n" 11287 "%srequested prefs = %s,\n" 11288 "%sactual format = %s,\n" 11289 "%shost prefs = %s,\n" 11290 "%spriority = %s\n", 11291 ast_inet_ntoa(sin.sin_addr), 11292 VERBOSE_PREFIX_4, 11293 ast_getformatname(iaxs[fr->callno]->peerformat), 11294 VERBOSE_PREFIX_4, 11295 caller_pref_buf, 11296 VERBOSE_PREFIX_4, 11297 ast_getformatname(format), 11298 VERBOSE_PREFIX_4, 11299 host_pref_buf, 11300 VERBOSE_PREFIX_4, 11301 using_prefs); 11302 11303 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11304 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1))) 11305 iax2_destroy(fr->callno); 11306 else if (ies.vars) { 11307 struct ast_datastore *variablestore; 11308 struct ast_variable *var, *prev = NULL; 11309 AST_LIST_HEAD(, ast_var_t) *varlist; 11310 varlist = ast_calloc(1, sizeof(*varlist)); 11311 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11312 if (variablestore && varlist) { 11313 variablestore->data = varlist; 11314 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11315 AST_LIST_HEAD_INIT(varlist); 11316 ast_debug(1, "I can haz IAX vars? w00t\n"); 11317 for (var = ies.vars; var; var = var->next) { 11318 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11319 if (prev) 11320 ast_free(prev); 11321 prev = var; 11322 if (!newvar) { 11323 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11324 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11325 } else { 11326 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11327 } 11328 } 11329 if (prev) 11330 ast_free(prev); 11331 ies.vars = NULL; 11332 ast_channel_datastore_add(c, variablestore); 11333 } else { 11334 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11335 if (variablestore) 11336 ast_datastore_free(variablestore); 11337 if (varlist) 11338 ast_free(varlist); 11339 } 11340 } 11341 } else { 11342 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11343 /* If this is a TBD call, we're ready but now what... */ 11344 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 11345 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) { 11346 goto immediatedial; 11347 } 11348 } 11349 } 11350 } 11351 break; 11352 case IAX_COMMAND_DIAL: 11353 immediatedial: 11354 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 11355 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11356 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 11357 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 11358 if (authdebug) 11359 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); 11360 memset(&ied0, 0, sizeof(ied0)); 11361 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11362 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11363 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11364 if (!iaxs[fr->callno]) { 11365 break; 11366 } 11367 } else { 11368 char tmp[256]; 11369 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11370 ast_verb(3, "Accepting DIAL from %s, formats = %s\n", 11371 ast_inet_ntoa(sin.sin_addr), 11372 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat)); 11373 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11374 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 11375 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1))) 11376 iax2_destroy(fr->callno); 11377 else if (ies.vars) { 11378 struct ast_datastore *variablestore; 11379 struct ast_variable *var, *prev = NULL; 11380 AST_LIST_HEAD(, ast_var_t) *varlist; 11381 varlist = ast_calloc(1, sizeof(*varlist)); 11382 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11383 ast_debug(1, "I can haz IAX vars? w00t\n"); 11384 if (variablestore && varlist) { 11385 variablestore->data = varlist; 11386 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11387 AST_LIST_HEAD_INIT(varlist); 11388 for (var = ies.vars; var; var = var->next) { 11389 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11390 if (prev) 11391 ast_free(prev); 11392 prev = var; 11393 if (!newvar) { 11394 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11395 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11396 } else { 11397 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11398 } 11399 } 11400 if (prev) 11401 ast_free(prev); 11402 ies.vars = NULL; 11403 ast_channel_datastore_add(c, variablestore); 11404 } else { 11405 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11406 if (variablestore) 11407 ast_datastore_free(variablestore); 11408 if (varlist) 11409 ast_free(varlist); 11410 } 11411 } 11412 } 11413 } 11414 break; 11415 case IAX_COMMAND_INVAL: 11416 iaxs[fr->callno]->error = ENOTCONN; 11417 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 11418 iax2_destroy(fr->callno); 11419 ast_debug(1, "Destroying call %d\n", fr->callno); 11420 break; 11421 case IAX_COMMAND_VNAK: 11422 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 11423 /* Force retransmission */ 11424 vnak_retransmit(fr->callno, fr->iseqno); 11425 break; 11426 case IAX_COMMAND_REGREQ: 11427 case IAX_COMMAND_REGREL: 11428 /* For security, always ack immediately */ 11429 if (delayreject) 11430 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11431 if (register_verify(fr->callno, &sin, &ies)) { 11432 if (!iaxs[fr->callno]) { 11433 break; 11434 } 11435 /* Send delayed failure */ 11436 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 11437 break; 11438 } 11439 if (!iaxs[fr->callno]) { 11440 break; 11441 } 11442 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 11443 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 11444 11445 if (f.subclass.integer == IAX_COMMAND_REGREL) { 11446 memset(&sin, 0, sizeof(sin)); 11447 sin.sin_family = AF_INET; 11448 } 11449 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) { 11450 ast_log(LOG_WARNING, "Registry error\n"); 11451 } 11452 if (!iaxs[fr->callno]) { 11453 break; 11454 } 11455 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 11456 ast_mutex_unlock(&iaxsl[fr->callno]); 11457 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 11458 ast_mutex_lock(&iaxsl[fr->callno]); 11459 } 11460 break; 11461 } 11462 registry_authrequest(fr->callno); 11463 break; 11464 case IAX_COMMAND_REGACK: 11465 if (iax2_ack_registry(&ies, &sin, fr->callno)) 11466 ast_log(LOG_WARNING, "Registration failure\n"); 11467 /* Send ack immediately, before we destroy */ 11468 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11469 iax2_destroy(fr->callno); 11470 break; 11471 case IAX_COMMAND_REGREJ: 11472 if (iaxs[fr->callno]->reg) { 11473 if (authdebug) { 11474 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)); 11475 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>"); 11476 } 11477 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 11478 } 11479 /* Send ack immediately, before we destroy */ 11480 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11481 iax2_destroy(fr->callno); 11482 break; 11483 case IAX_COMMAND_REGAUTH: 11484 /* Authentication request */ 11485 if (registry_rerequest(&ies, fr->callno, &sin)) { 11486 memset(&ied0, 0, sizeof(ied0)); 11487 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 11488 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 11489 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11490 } 11491 break; 11492 case IAX_COMMAND_TXREJ: 11493 while (iaxs[fr->callno] 11494 && iaxs[fr->callno]->bridgecallno 11495 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) { 11496 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 11497 } 11498 if (!iaxs[fr->callno]) { 11499 break; 11500 } 11501 11502 iaxs[fr->callno]->transferring = TRANSFER_NONE; 11503 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11504 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 11505 11506 if (!iaxs[fr->callno]->bridgecallno) { 11507 break; 11508 } 11509 11510 if (iaxs[iaxs[fr->callno]->bridgecallno] 11511 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 11512 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE; 11513 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 11514 } 11515 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11516 break; 11517 case IAX_COMMAND_TXREADY: 11518 while (iaxs[fr->callno] 11519 && iaxs[fr->callno]->bridgecallno 11520 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) { 11521 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 11522 } 11523 if (!iaxs[fr->callno]) { 11524 break; 11525 } 11526 11527 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 11528 iaxs[fr->callno]->transferring = TRANSFER_READY; 11529 } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) { 11530 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 11531 } else { 11532 if (iaxs[fr->callno]->bridgecallno) { 11533 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11534 } 11535 break; 11536 } 11537 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11538 11539 if (!iaxs[fr->callno]->bridgecallno) { 11540 break; 11541 } 11542 11543 if (!iaxs[iaxs[fr->callno]->bridgecallno] 11544 || (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY 11545 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) { 11546 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11547 break; 11548 } 11549 11550 /* Both sides are ready */ 11551 11552 /* XXX what isn't checked here is that both sides match transfer types. */ 11553 11554 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 11555 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11556 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11557 11558 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 11559 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 11560 11561 memset(&ied0, 0, sizeof(ied0)); 11562 memset(&ied1, 0, sizeof(ied1)); 11563 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11564 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11565 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 11566 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 11567 } else { 11568 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11569 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11570 11571 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 11572 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 11573 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 11574 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 11575 11576 /* Stop doing lag & ping requests */ 11577 stop_stuff(fr->callno); 11578 stop_stuff(iaxs[fr->callno]->bridgecallno); 11579 11580 memset(&ied0, 0, sizeof(ied0)); 11581 memset(&ied1, 0, sizeof(ied1)); 11582 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11583 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11584 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 11585 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 11586 } 11587 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11588 break; 11589 case IAX_COMMAND_TXREQ: 11590 try_transfer(iaxs[fr->callno], &ies); 11591 break; 11592 case IAX_COMMAND_TXCNT: 11593 if (iaxs[fr->callno]->transferring) 11594 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 11595 break; 11596 case IAX_COMMAND_TXREL: 11597 /* Send ack immediately, rather than waiting until we've changed addresses */ 11598 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11599 complete_transfer(fr->callno, &ies); 11600 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 11601 break; 11602 case IAX_COMMAND_TXMEDIA: 11603 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 11604 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 11605 /* Cancel any outstanding frames and start anew */ 11606 if (cur->transfer) { 11607 cur->retries = -1; 11608 } 11609 } 11610 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 11611 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 11612 } 11613 break; 11614 case IAX_COMMAND_RTKEY: 11615 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 11616 ast_log(LOG_WARNING, 11617 "we've been told to rotate our encryption key, " 11618 "but this isn't an encrypted call. bad things will happen.\n" 11619 ); 11620 break; 11621 } 11622 11623 IAX_DEBUGDIGEST("Receiving", ies.challenge); 11624 11625 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 11626 break; 11627 case IAX_COMMAND_DPREP: 11628 complete_dpreply(iaxs[fr->callno], &ies); 11629 break; 11630 case IAX_COMMAND_UNSUPPORT: 11631 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 11632 break; 11633 case IAX_COMMAND_FWDOWNL: 11634 /* Firmware download */ 11635 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 11636 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 11637 break; 11638 } 11639 memset(&ied0, 0, sizeof(ied0)); 11640 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 11641 if (res < 0) 11642 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11643 else if (res > 0) 11644 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11645 else 11646 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11647 break; 11648 case IAX_COMMAND_CALLTOKEN: 11649 { 11650 struct iax_frame *cur; 11651 /* find last sent frame */ 11652 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) { 11653 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 11654 } 11655 break; 11656 } 11657 default: 11658 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno); 11659 memset(&ied0, 0, sizeof(ied0)); 11660 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer); 11661 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11662 } 11663 /* Free remote variables (if any) */ 11664 if (ies.vars) { 11665 ast_variables_destroy(ies.vars); 11666 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11667 ies.vars = NULL; 11668 } 11669 11670 /* Don't actually pass these frames along */ 11671 if ((f.subclass.integer != IAX_COMMAND_ACK) && 11672 (f.subclass.integer != IAX_COMMAND_TXCNT) && 11673 (f.subclass.integer != IAX_COMMAND_TXACC) && 11674 (f.subclass.integer != IAX_COMMAND_INVAL) && 11675 (f.subclass.integer != IAX_COMMAND_VNAK)) { 11676 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) { 11677 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11678 } 11679 } 11680 ast_mutex_unlock(&iaxsl[fr->callno]); 11681 return 1; 11682 } 11683 /* Unless this is an ACK or INVAL frame, ack it */ 11684 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11685 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11686 } else if (minivid) { 11687 f.frametype = AST_FRAME_VIDEO; 11688 if (iaxs[fr->callno]->videoformat > 0) 11689 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0); 11690 else { 11691 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11692 iax2_vnak(fr->callno); 11693 ast_variables_destroy(ies.vars); 11694 ast_mutex_unlock(&iaxsl[fr->callno]); 11695 return 1; 11696 } 11697 f.datalen = res - sizeof(*vh); 11698 if (f.datalen) 11699 f.data.ptr = thread->buf + sizeof(*vh); 11700 else 11701 f.data.ptr = NULL; 11702 #ifdef IAXTESTS 11703 if (test_resync) { 11704 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11705 } else 11706 #endif /* IAXTESTS */ 11707 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11708 } else { 11709 /* A mini frame */ 11710 f.frametype = AST_FRAME_VOICE; 11711 if (iaxs[fr->callno]->voiceformat > 0) 11712 f.subclass.codec = iaxs[fr->callno]->voiceformat; 11713 else { 11714 ast_debug(1, "Received mini frame before first full voice frame\n"); 11715 iax2_vnak(fr->callno); 11716 ast_variables_destroy(ies.vars); 11717 ast_mutex_unlock(&iaxsl[fr->callno]); 11718 return 1; 11719 } 11720 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11721 if (f.datalen < 0) { 11722 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11723 ast_variables_destroy(ies.vars); 11724 ast_mutex_unlock(&iaxsl[fr->callno]); 11725 return 1; 11726 } 11727 if (f.datalen) 11728 f.data.ptr = thread->buf + sizeof(*mh); 11729 else 11730 f.data.ptr = NULL; 11731 #ifdef IAXTESTS 11732 if (test_resync) { 11733 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11734 } else 11735 #endif /* IAXTESTS */ 11736 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11737 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11738 } 11739 11740 /* Don't pass any packets until we're started */ 11741 if (!iaxs[fr->callno] 11742 || !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11743 ast_variables_destroy(ies.vars); 11744 ast_mutex_unlock(&iaxsl[fr->callno]); 11745 return 1; 11746 } 11747 11748 if (f.frametype == AST_FRAME_CONTROL) { 11749 if (!iax2_is_control_frame_allowed(f.subclass.integer)) { 11750 /* Control frame not allowed to come from the wire. */ 11751 ast_debug(2, "Callno %d: Blocked receiving control frame %d.\n", 11752 fr->callno, f.subclass.integer); 11753 ast_variables_destroy(ies.vars); 11754 ast_mutex_unlock(&iaxsl[fr->callno]); 11755 return 1; 11756 } 11757 if (f.subclass.integer == AST_CONTROL_CONNECTED_LINE 11758 || f.subclass.integer == AST_CONTROL_REDIRECTING) { 11759 if (iaxs[fr->callno] 11760 && !ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) { 11761 /* We are not configured to allow receiving these updates. */ 11762 ast_debug(2, "Callno %d: Config blocked receiving control frame %d.\n", 11763 fr->callno, f.subclass.integer); 11764 ast_variables_destroy(ies.vars); 11765 ast_mutex_unlock(&iaxsl[fr->callno]); 11766 return 1; 11767 } 11768 } 11769 11770 iax2_lock_owner(fr->callno); 11771 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 11772 if (f.subclass.integer == AST_CONTROL_BUSY) { 11773 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 11774 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) { 11775 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 11776 } 11777 ast_channel_unlock(iaxs[fr->callno]->owner); 11778 } 11779 } 11780 11781 if (f.frametype == AST_FRAME_CONTROL 11782 && f.subclass.integer == AST_CONTROL_CONNECTED_LINE 11783 && iaxs[fr->callno]) { 11784 struct ast_party_connected_line connected; 11785 11786 /* 11787 * Process a received connected line update. 11788 * 11789 * Initialize defaults. 11790 */ 11791 ast_party_connected_line_init(&connected); 11792 connected.id.number.presentation = iaxs[fr->callno]->calling_pres; 11793 connected.id.name.presentation = iaxs[fr->callno]->calling_pres; 11794 11795 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) { 11796 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str); 11797 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str); 11798 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id); 11799 11800 iax2_lock_owner(fr->callno); 11801 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 11802 ast_set_callerid(iaxs[fr->callno]->owner, 11803 S_COR(connected.id.number.valid, connected.id.number.str, ""), 11804 S_COR(connected.id.name.valid, connected.id.name.str, ""), 11805 NULL); 11806 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation; 11807 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation; 11808 ast_channel_unlock(iaxs[fr->callno]->owner); 11809 } 11810 } 11811 ast_party_connected_line_free(&connected); 11812 } 11813 11814 /* Common things */ 11815 f.src = "IAX2"; 11816 f.mallocd = 0; 11817 f.offset = 0; 11818 f.len = 0; 11819 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11820 f.samples = ast_codec_get_samples(&f); 11821 /* We need to byteswap incoming slinear samples from network byte order */ 11822 if (f.subclass.codec == AST_FORMAT_SLINEAR) 11823 ast_frame_byteswap_be(&f); 11824 } else 11825 f.samples = 0; 11826 iax_frame_wrap(fr, &f); 11827 11828 /* If this is our most recent packet, use it as our basis for timestamping */ 11829 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11830 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11831 fr->outoforder = 0; 11832 } else { 11833 if (iaxdebug && iaxs[fr->callno]) { 11834 ast_debug(1, "Received out of order packet... (type=%u, subclass %d, ts = %u, last = %u)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last); 11835 } 11836 fr->outoforder = -1; 11837 } 11838 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11839 if (iaxs[fr->callno]) { 11840 duped_fr = iaxfrdup2(fr); 11841 if (duped_fr) { 11842 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11843 } 11844 } 11845 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11846 iaxs[fr->callno]->last = fr->ts; 11847 #if 1 11848 if (iaxdebug) 11849 ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts); 11850 #endif 11851 } 11852 11853 /* Always run again */ 11854 ast_variables_destroy(ies.vars); 11855 ast_mutex_unlock(&iaxsl[fr->callno]); 11856 return 1; 11857 }
| static int socket_process_meta | ( | int | packet_len, | |
| struct ast_iax2_meta_hdr * | meta, | |||
| struct sockaddr_in * | sin, | |||
| int | sockfd, | |||
| struct iax_frame * | fr | |||
| ) | [static] |
Definition at line 9811 of file chan_iax2.c.
References ast_codec_get_samples(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_meta_hdr::cmddata, ast_frame_subclass::codec, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, find_callno_locked(), find_tpeer(), fix_peerts(), ast_frame::frametype, iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), iaxs, iaxsl, chan_iax2_pvt::last, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, len(), iax2_trunk_peer::lock, LOG_WARNING, ast_frame::mallocd, ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, ast_frame::offset, iax_frame::outoforder, ast_frame::ptr, iax2_trunk_peer::rxtrunktime, ast_frame::samples, schedule_delivery(), ast_frame::src, chan_iax2_pvt::state, ast_frame::subclass, iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
09813 { 09814 unsigned char metatype; 09815 struct ast_iax2_meta_trunk_mini *mtm; 09816 struct ast_iax2_meta_trunk_hdr *mth; 09817 struct ast_iax2_meta_trunk_entry *mte; 09818 struct iax2_trunk_peer *tpeer; 09819 unsigned int ts; 09820 void *ptr; 09821 struct timeval rxtrunktime; 09822 struct ast_frame f = { 0, }; 09823 09824 if (packet_len < sizeof(*meta)) { 09825 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09826 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09827 return 1; 09828 } 09829 09830 if (meta->metacmd != IAX_META_TRUNK) 09831 return 1; 09832 09833 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09834 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09835 (int) (sizeof(*meta) + sizeof(*mth))); 09836 return 1; 09837 } 09838 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09839 ts = ntohl(mth->ts); 09840 metatype = meta->cmddata; 09841 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09842 ptr = mth->data; 09843 tpeer = find_tpeer(sin, sockfd); 09844 if (!tpeer) { 09845 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09846 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09847 return 1; 09848 } 09849 tpeer->trunkact = ast_tvnow(); 09850 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09851 tpeer->rxtrunktime = tpeer->trunkact; 09852 rxtrunktime = tpeer->rxtrunktime; 09853 ast_mutex_unlock(&tpeer->lock); 09854 while (packet_len >= sizeof(*mte)) { 09855 /* Process channels */ 09856 unsigned short callno, trunked_ts, len; 09857 09858 if (metatype == IAX_META_TRUNK_MINI) { 09859 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09860 ptr += sizeof(*mtm); 09861 packet_len -= sizeof(*mtm); 09862 len = ntohs(mtm->len); 09863 callno = ntohs(mtm->mini.callno); 09864 trunked_ts = ntohs(mtm->mini.ts); 09865 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09866 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09867 ptr += sizeof(*mte); 09868 packet_len -= sizeof(*mte); 09869 len = ntohs(mte->len); 09870 callno = ntohs(mte->callno); 09871 trunked_ts = 0; 09872 } else { 09873 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09874 break; 09875 } 09876 /* Stop if we don't have enough data */ 09877 if (len > packet_len) 09878 break; 09879 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09880 if (!fr->callno) 09881 continue; 09882 09883 /* If it's a valid call, deliver the contents. If not, we 09884 drop it, since we don't have a scallno to use for an INVAL */ 09885 /* Process as a mini frame */ 09886 memset(&f, 0, sizeof(f)); 09887 f.frametype = AST_FRAME_VOICE; 09888 if (!iaxs[fr->callno]) { 09889 /* drop it */ 09890 } else if (iaxs[fr->callno]->voiceformat == 0) { 09891 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09892 iax2_vnak(fr->callno); 09893 } else { 09894 f.subclass.codec = iaxs[fr->callno]->voiceformat; 09895 f.datalen = len; 09896 if (f.datalen >= 0) { 09897 if (f.datalen) 09898 f.data.ptr = ptr; 09899 else 09900 f.data.ptr = NULL; 09901 if (trunked_ts) 09902 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09903 else 09904 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09905 /* Don't pass any packets until we're started */ 09906 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09907 struct iax_frame *duped_fr; 09908 09909 /* Common things */ 09910 f.src = "IAX2"; 09911 f.mallocd = 0; 09912 f.offset = 0; 09913 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09914 f.samples = ast_codec_get_samples(&f); 09915 else 09916 f.samples = 0; 09917 fr->outoforder = 0; 09918 iax_frame_wrap(fr, &f); 09919 duped_fr = iaxfrdup2(fr); 09920 if (duped_fr) 09921 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09922 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09923 iaxs[fr->callno]->last = fr->ts; 09924 } 09925 } else { 09926 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09927 } 09928 } 09929 ast_mutex_unlock(&iaxsl[fr->callno]); 09930 ptr += len; 09931 packet_len -= len; 09932 } 09933 09934 return 1; 09935 }
| static int socket_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 9731 of file chan_iax2.c.
References ast_copy_string(), ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), ast_iax2_full_hdr::csub, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), len(), LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), thread, and ast_iax2_full_hdr::type.
Referenced by peer_set_srcaddr(), and set_config().
09732 { 09733 struct iax2_thread *thread; 09734 socklen_t len; 09735 time_t t; 09736 static time_t last_errtime = 0; 09737 struct ast_iax2_full_hdr *fh; 09738 09739 if (!(thread = find_idle_thread())) { 09740 time(&t); 09741 if (t != last_errtime) { 09742 last_errtime = t; 09743 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09744 } 09745 usleep(1); 09746 return 1; 09747 } 09748 09749 len = sizeof(thread->iosin); 09750 thread->iofd = fd; 09751 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09752 thread->buf_size = sizeof(thread->readbuf); 09753 thread->buf = thread->readbuf; 09754 if (thread->buf_len < 0) { 09755 if (errno != ECONNREFUSED && errno != EAGAIN) 09756 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09757 handle_error(); 09758 thread->iostate = IAX_IOSTATE_IDLE; 09759 signal_condition(&thread->lock, &thread->cond); 09760 return 1; 09761 } 09762 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09763 thread->iostate = IAX_IOSTATE_IDLE; 09764 signal_condition(&thread->lock, &thread->cond); 09765 return 1; 09766 } 09767 09768 /* Determine if this frame is a full frame; if so, and any thread is currently 09769 processing a full frame for the same callno from this peer, then drop this 09770 frame (and the peer will retransmit it) */ 09771 fh = (struct ast_iax2_full_hdr *) thread->buf; 09772 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09773 struct iax2_thread *cur = NULL; 09774 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09775 09776 AST_LIST_LOCK(&active_list); 09777 AST_LIST_TRAVERSE(&active_list, cur, list) { 09778 if ((cur->ffinfo.callno == callno) && 09779 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09780 break; 09781 } 09782 if (cur) { 09783 /* we found another thread processing a full frame for this call, 09784 so queue it up for processing later. */ 09785 defer_full_frame(thread, cur); 09786 AST_LIST_UNLOCK(&active_list); 09787 thread->iostate = IAX_IOSTATE_IDLE; 09788 signal_condition(&thread->lock, &thread->cond); 09789 return 1; 09790 } else { 09791 /* this thread is going to process this frame, so mark it */ 09792 thread->ffinfo.callno = callno; 09793 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09794 thread->ffinfo.type = fh->type; 09795 thread->ffinfo.csub = fh->csub; 09796 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09797 } 09798 AST_LIST_UNLOCK(&active_list); 09799 } 09800 09801 /* Mark as ready and send on its way */ 09802 thread->iostate = IAX_IOSTATE_READY; 09803 #ifdef DEBUG_SCHED_MULTITHREAD 09804 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09805 #endif 09806 signal_condition(&thread->lock, &thread->cond); 09807 09808 return 1; 09809 }
| static void spawn_dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid | |||
| ) | [static] |
Definition at line 9398 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
09399 { 09400 pthread_t newthread; 09401 struct dpreq_data *dpr; 09402 09403 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 09404 return; 09405 09406 dpr->callno = callno; 09407 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 09408 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 09409 if (callerid) 09410 dpr->callerid = ast_strdup(callerid); 09411 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 09412 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 09413 } 09414 }
| static int start_network_thread | ( | void | ) | [static] |
Definition at line 12421 of file chan_iax2.c.
References ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, ast_verb, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, LOG_ERROR, LOG_WARNING, network_thread(), and thread.
Referenced by load_module().
12422 { 12423 struct iax2_thread *thread; 12424 int threadcount = 0; 12425 int x; 12426 for (x = 0; x < iaxthreadcount; x++) { 12427 thread = ast_calloc(1, sizeof(*thread)); 12428 if (thread) { 12429 thread->type = IAX_THREAD_TYPE_POOL; 12430 thread->threadnum = ++threadcount; 12431 ast_mutex_init(&thread->lock); 12432 ast_cond_init(&thread->cond, NULL); 12433 ast_mutex_init(&thread->init_lock); 12434 ast_cond_init(&thread->init_cond, NULL); 12435 12436 ast_mutex_lock(&thread->init_lock); 12437 12438 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 12439 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 12440 ast_mutex_destroy(&thread->lock); 12441 ast_cond_destroy(&thread->cond); 12442 ast_mutex_unlock(&thread->init_lock); 12443 ast_mutex_destroy(&thread->init_lock); 12444 ast_cond_destroy(&thread->init_cond); 12445 ast_free(thread); 12446 thread = NULL; 12447 continue; 12448 } 12449 /* Wait for the thread to be ready */ 12450 ast_cond_wait(&thread->init_cond, &thread->init_lock); 12451 12452 /* Done with init_lock */ 12453 ast_mutex_unlock(&thread->init_lock); 12454 12455 AST_LIST_LOCK(&idle_list); 12456 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 12457 AST_LIST_UNLOCK(&idle_list); 12458 } 12459 } 12460 if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) { 12461 ast_log(LOG_ERROR, "Failed to create new thread!\n"); 12462 return -1; 12463 } 12464 ast_verb(2, "%d helper threads started\n", threadcount); 12465 return 0; 12466 }
| static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 9101 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
09102 { 09103 iax2_destroy_helper(iaxs[callno]); 09104 }
| static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2213 of file chan_iax2.c.
References ao2_link, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
02214 { 02215 if (!pvt->peercallno) { 02216 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02217 return; 02218 } 02219 02220 ao2_link(iax_peercallno_pvts, pvt); 02221 }
| static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2194 of file chan_iax2.c.
References ao2_link, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
02195 { 02196 if (!pvt->transfercallno) { 02197 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02198 return; 02199 } 02200 02201 ao2_link(iax_transfercallno_pvts, pvt); 02202 }
| static int timing_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 9284 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, ast_free, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_timer_ack(), ast_tvnow(), ast_verbose, iax2_trunk_expired(), iax2_trunk_peer::lock, LOG_ERROR, send_trunk(), totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
09285 { 09286 int res, processed = 0, totalcalls = 0; 09287 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 09288 struct timeval now = ast_tvnow(); 09289 09290 if (iaxtrunkdebug) 09291 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 09292 09293 if (timer) { 09294 if (ast_timer_ack(timer, 1) < 0) { 09295 ast_log(LOG_ERROR, "Timer failed acknowledge\n"); 09296 return 0; 09297 } 09298 } 09299 09300 /* For each peer that supports trunking... */ 09301 AST_LIST_LOCK(&tpeers); 09302 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 09303 processed++; 09304 res = 0; 09305 ast_mutex_lock(&tpeer->lock); 09306 /* We can drop a single tpeer per pass. That makes all this logic 09307 substantially easier */ 09308 if (!drop && iax2_trunk_expired(tpeer, &now)) { 09309 /* Take it out of the list, but don't free it yet, because it 09310 could be in use */ 09311 AST_LIST_REMOVE_CURRENT(list); 09312 drop = tpeer; 09313 } else { 09314 res = send_trunk(tpeer, &now); 09315 trunk_timed++; 09316 if (iaxtrunkdebug) 09317 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %u bytes backloged and has hit a high water mark of %u bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc); 09318 } 09319 totalcalls += res; 09320 res = 0; 09321 ast_mutex_unlock(&tpeer->lock); 09322 } 09323 AST_LIST_TRAVERSE_SAFE_END; 09324 AST_LIST_UNLOCK(&tpeers); 09325 09326 if (drop) { 09327 ast_mutex_lock(&drop->lock); 09328 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 09329 because by the time they could get tpeerlock, we've already grabbed it */ 09330 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 09331 if (drop->trunkdata) { 09332 ast_free(drop->trunkdata); 09333 drop->trunkdata = NULL; 09334 } 09335 ast_mutex_unlock(&drop->lock); 09336 ast_mutex_destroy(&drop->lock); 09337 ast_free(drop); 09338 09339 } 09340 09341 if (iaxtrunkdebug) 09342 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 09343 iaxtrunkdebug = 0; 09344 09345 return 1; 09346 }
| static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 14694 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by load_objects().
14695 { 14696 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14697 14698 /* The frames_received field is used to hold whether we're matching 14699 * against a full frame or not ... */ 14700 14701 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 14702 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14703 }
| static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 14687 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
14688 { 14689 const struct chan_iax2_pvt *pvt = obj; 14690 14691 return pvt->transfercallno; 14692 }
| static int transmit_frame | ( | void * | data | ) | [static] |
Definition at line 4347 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, iax2_sched_add(), iax_frame_free(), iaxs, iaxsl, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), and iax_frame::sentyet.
Referenced by iax2_transmit().
04348 { 04349 struct iax_frame *fr = data; 04350 04351 ast_mutex_lock(&iaxsl[fr->callno]); 04352 04353 fr->sentyet = 1; 04354 04355 if (iaxs[fr->callno]) { 04356 send_packet(fr); 04357 } 04358 04359 if (fr->retries < 0) { 04360 ast_mutex_unlock(&iaxsl[fr->callno]); 04361 /* No retransmit requested */ 04362 iax_frame_free(fr); 04363 } else { 04364 /* We need reliable delivery. Schedule a retransmission */ 04365 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list); 04366 fr->retries++; 04367 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr); 04368 ast_mutex_unlock(&iaxsl[fr->callno]); 04369 } 04370 04371 return 0; 04372 }
| static int transmit_trunk | ( | struct iax_frame * | f, | |
| struct sockaddr_in * | sin, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 3405 of file chan_iax2.c.
References ast_debug, iax_frame::data, iax_frame::datalen, errno, and handle_error().
Referenced by send_trunk().
03406 { 03407 int res; 03408 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03409 sizeof(*sin)); 03410 if (res < 0) { 03411 ast_debug(1, "Received error: %s\n", strerror(errno)); 03412 handle_error(); 03413 } else 03414 res = 0; 03415 return res; 03416 }
| static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 3110 of file chan_iax2.c.
References ast_alloca, ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, errno, IAX_FIRMWARE_MAGIC, last, len(), LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), and ast_iax2_firmware_header::version.
Referenced by reload_firmware().
03111 { 03112 struct stat stbuf; 03113 struct iax_firmware *cur = NULL; 03114 int ifd, fd, res, len, chunk; 03115 struct ast_iax2_firmware_header *fwh, fwh2; 03116 struct MD5Context md5; 03117 unsigned char sum[16], buf[1024]; 03118 char *s2, *last; 03119 03120 s2 = ast_alloca(strlen(s) + 100); 03121 03122 last = strrchr(s, '/'); 03123 if (last) 03124 last++; 03125 else 03126 last = s; 03127 03128 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, ast_random()); 03129 03130 if ((res = stat(s, &stbuf) < 0)) { 03131 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 03132 return -1; 03133 } 03134 03135 /* Make sure it's not a directory */ 03136 if (S_ISDIR(stbuf.st_mode)) 03137 return -1; 03138 ifd = open(s, O_RDONLY); 03139 if (ifd < 0) { 03140 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 03141 return -1; 03142 } 03143 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 03144 if (fd < 0) { 03145 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 03146 close(ifd); 03147 return -1; 03148 } 03149 /* Unlink our newly created file */ 03150 unlink(s2); 03151 03152 /* Now copy the firmware into it */ 03153 len = stbuf.st_size; 03154 while(len) { 03155 chunk = len; 03156 if (chunk > sizeof(buf)) 03157 chunk = sizeof(buf); 03158 res = read(ifd, buf, chunk); 03159 if (res != chunk) { 03160 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03161 close(ifd); 03162 close(fd); 03163 return -1; 03164 } 03165 res = write(fd, buf, chunk); 03166 if (res != chunk) { 03167 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03168 close(ifd); 03169 close(fd); 03170 return -1; 03171 } 03172 len -= chunk; 03173 } 03174 close(ifd); 03175 /* Return to the beginning */ 03176 lseek(fd, 0, SEEK_SET); 03177 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 03178 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 03179 close(fd); 03180 return -1; 03181 } 03182 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 03183 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 03184 close(fd); 03185 return -1; 03186 } 03187 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 03188 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 03189 close(fd); 03190 return -1; 03191 } 03192 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 03193 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 03194 close(fd); 03195 return -1; 03196 } 03197 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 03198 if (fwh == MAP_FAILED) { 03199 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 03200 close(fd); 03201 return -1; 03202 } 03203 MD5Init(&md5); 03204 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 03205 MD5Final(sum, &md5); 03206 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 03207 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 03208 munmap((void*)fwh, stbuf.st_size); 03209 close(fd); 03210 return -1; 03211 } 03212 03213 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03214 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 03215 /* Found a candidate */ 03216 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 03217 /* The version we have on loaded is older, load this one instead */ 03218 break; 03219 /* This version is no newer than what we have. Don't worry about it. 03220 We'll consider it a proper load anyhow though */ 03221 munmap((void*)fwh, stbuf.st_size); 03222 close(fd); 03223 return 0; 03224 } 03225 } 03226 03227 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 03228 cur->fd = -1; 03229 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 03230 } 03231 03232 if (cur) { 03233 if (cur->fwh) 03234 munmap((void*)cur->fwh, cur->mmaplen); 03235 if (cur->fd > -1) 03236 close(cur->fd); 03237 cur->fwh = fwh; 03238 cur->fd = fd; 03239 cur->mmaplen = stbuf.st_size; 03240 cur->dead = 0; 03241 } 03242 03243 return 0; 03244 }
| static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8418 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, iax_ie_data::pos, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, TRANSFER_NONE, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
08419 { 08420 int newcall = 0; 08421 char newip[256]; 08422 struct iax_ie_data ied; 08423 struct sockaddr_in new = { 0, }; 08424 08425 memset(&ied, 0, sizeof(ied)); 08426 if (ies->apparent_addr) 08427 memmove(&new, ies->apparent_addr, sizeof(new)); 08428 if (ies->callno) 08429 newcall = ies->callno; 08430 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 08431 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08432 return -1; 08433 } 08434 pvt->transfercallno = newcall; 08435 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 08436 inet_aton(newip, &pvt->transfer.sin_addr); 08437 pvt->transfer.sin_family = AF_INET; 08438 pvt->transferid = ies->transferid; 08439 /* only store by transfercallno if this is a new transfer, 08440 * just in case we get a duplicate TXREQ */ 08441 if (pvt->transferring == TRANSFER_NONE) { 08442 store_by_transfercallno(pvt); 08443 } 08444 pvt->transferring = TRANSFER_BEGIN; 08445 08446 if (ies->transferid) 08447 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 08448 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 08449 return 0; 08450 }
| static format_t uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1711 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01712 { 01713 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01714 if (csub & IAX_FLAG_SC_LOG) { 01715 /* special case for 'compressed' -1 */ 01716 if (csub == 0xff) 01717 return -1; 01718 else 01719 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01720 } 01721 else 01722 return csub; 01723 }
| static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8712 of file chan_iax2.c.
References ao2_unlink, ast_sched_thread_del, iax2_peer::expire, peer_unref(), and iax2_peer::pokeexpire.
Referenced by __expire_registry(), build_peer(), and prune_peers().
08713 { 08714 if (peer->expire > -1) { 08715 if (!ast_sched_thread_del(sched, peer->expire)) { 08716 peer->expire = -1; 08717 peer_unref(peer); 08718 } 08719 } 08720 08721 if (peer->pokeexpire > -1) { 08722 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 08723 peer->pokeexpire = -1; 08724 peer_unref(peer); 08725 } 08726 } 08727 08728 ao2_unlink(peers, peer); 08729 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 14652 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
14653 { 14654 ast_custom_function_unregister(&iaxpeer_function); 14655 ast_custom_function_unregister(&iaxvar_function); 14656 return __unload_module(); 14657 }
| static void unlock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5555 of file chan_iax2.c.
References ast_mutex_unlock, and iaxsl.
Referenced by iax2_bridge().
05556 { 05557 ast_mutex_unlock(&iaxsl[callno1]); 05558 ast_mutex_unlock(&iaxsl[callno0]); 05559 }
| static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4100 of file chan_iax2.c.
References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, and iax_frame::ts.
Referenced by schedule_delivery().
04101 { 04102 /* Video mini frames only encode the lower 15 bits of the session 04103 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 04104 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 04105 const int lower_mask = (1 << ts_shift) - 1; 04106 const int upper_mask = ~lower_mask; 04107 const int last_upper = iaxs[fr->callno]->last & upper_mask; 04108 04109 if ( (fr->ts & upper_mask) == last_upper ) { 04110 const int x = fr->ts - iaxs[fr->callno]->last; 04111 const int threshold = (ts_shift == 15) ? 25000 : 50000; 04112 04113 if (x < -threshold) { 04114 /* Sudden big jump backwards in timestamp: 04115 What likely happened here is that miniframe timestamp has circled but we haven't 04116 gotten the update from the main packet. We'll just pretend that we did, and 04117 update the timestamp appropriately. */ 04118 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 04119 if (iaxdebug) 04120 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 04121 } else if (x > threshold) { 04122 /* Sudden apparent big jump forwards in timestamp: 04123 What's likely happened is this is an old miniframe belonging to the previous 04124 top 15 or 16-bit timestamp that has turned up out of order. 04125 Adjust the timestamp appropriately. */ 04126 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 04127 if (iaxdebug) 04128 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 04129 } 04130 } 04131 }
| static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4135 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_replace(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.
Referenced by __get_from_jb(), and schedule_delivery().
04136 { 04137 int when; 04138 04139 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 04140 04141 when = jb_next(pvt->jb) - when; 04142 04143 if (when <= 0) { 04144 /* XXX should really just empty until when > 0.. */ 04145 when = 1; 04146 } 04147 04148 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 04149 CALLNO_TO_PTR(pvt->callno)); 04150 }
| static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3541 of file chan_iax2.c.
References build_rand_pad(), iax_frame::callno, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, decode_frame(), iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, iax_frame::mydcx, and iax_frame::semirand.
Referenced by __attempt_transmit().
03542 { 03543 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03544 struct ast_iax2_full_hdr *fh = f->data; 03545 struct ast_frame af; 03546 03547 /* if frame is encrypted. decrypt before updating it. */ 03548 if (f->encmethods) { 03549 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03550 } 03551 /* Mark this as a retransmission */ 03552 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03553 /* Update iseqno */ 03554 f->iseqno = iaxs[f->callno]->iseqno; 03555 fh->iseqno = f->iseqno; 03556 03557 /* Now re-encrypt the frame */ 03558 if (f->encmethods) { 03559 /* since this is a retransmit frame, create a new random padding 03560 * before re-encrypting. */ 03561 build_rand_pad(f->semirand, sizeof(f->semirand)); 03562 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03563 } 03564 return 0; 03565 }
| static int update_registry | ( | struct sockaddr_in * | sin, | |
| int | callno, | |||
| char * | devtype, | |||
| int | fd, | |||
| unsigned short | refresh | |||
| ) | [static] |
Definition at line 8830 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, ast_sockaddr_cmp(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_verb, iax_ie_data::buf, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, iaxs, iaxsl, LOG_NOTICE, LOG_WARNING, mailbox, manager_event, iax2_peer::maxcallno, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), send_command_final(), iax2_peer::sockfd, and version.
Referenced by socket_process().
08831 { 08832 /* Called from IAX thread only, with proper iaxsl lock */ 08833 struct iax_ie_data ied = { 08834 .pos = 0, 08835 }; 08836 struct iax2_peer *p; 08837 int msgcount; 08838 char data[80]; 08839 int version; 08840 const char *peer_name; 08841 int res = -1; 08842 struct ast_sockaddr sockaddr; 08843 08844 ast_sockaddr_from_sin(&sockaddr, sin); 08845 08846 peer_name = ast_strdupa(iaxs[callno]->peer); 08847 08848 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08849 ast_mutex_unlock(&iaxsl[callno]); 08850 if (!(p = find_peer(peer_name, 1))) { 08851 ast_mutex_lock(&iaxsl[callno]); 08852 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08853 return -1; 08854 } 08855 ast_mutex_lock(&iaxsl[callno]); 08856 if (!iaxs[callno]) 08857 goto return_unref; 08858 08859 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08860 if (sin->sin_addr.s_addr) { 08861 time_t nowtime; 08862 time(&nowtime); 08863 realtime_update_peer(peer_name, &sockaddr, nowtime); 08864 } else { 08865 realtime_update_peer(peer_name, &sockaddr, 0); 08866 } 08867 } 08868 08869 /* treat an unspecified refresh interval as the minimum */ 08870 if (!refresh) { 08871 refresh = min_reg_expire; 08872 } 08873 if (refresh > max_reg_expire) { 08874 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08875 p->name, max_reg_expire, refresh); 08876 p->expiry = max_reg_expire; 08877 } else if (refresh < min_reg_expire) { 08878 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08879 p->name, min_reg_expire, refresh); 08880 p->expiry = min_reg_expire; 08881 } else { 08882 p->expiry = refresh; 08883 } 08884 08885 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) { 08886 if (iax2_regfunk) { 08887 iax2_regfunk(p->name, 1); 08888 } 08889 08890 /* modify entry in peercnts table as _not_ registered */ 08891 peercnt_modify((unsigned char) 0, 0, &p->addr); 08892 08893 /* Stash the IP address from which they registered */ 08894 ast_sockaddr_from_sin(&p->addr, sin); 08895 08896 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08897 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08898 ast_db_put("IAX/Registry", p->name, data); 08899 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08900 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08901 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08902 register_peer_exten(p, 1); 08903 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08904 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) { 08905 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08906 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08907 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08908 register_peer_exten(p, 0); 08909 ast_db_del("IAX/Registry", p->name); 08910 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08911 } 08912 /* Update the host */ 08913 /* Verify that the host is really there */ 08914 iax2_poke_peer(p, callno); 08915 } 08916 08917 /* modify entry in peercnts table as registered */ 08918 if (p->maxcallno) { 08919 peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr); 08920 } 08921 08922 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08923 if (!iaxs[callno]) { 08924 res = -1; 08925 goto return_unref; 08926 } 08927 08928 /* Store socket fd */ 08929 p->sockfd = fd; 08930 /* Setup the expiry */ 08931 if (p->expire > -1) { 08932 if (!ast_sched_thread_del(sched, p->expire)) { 08933 p->expire = -1; 08934 peer_unref(p); 08935 } 08936 } 08937 08938 if (p->expiry && sin->sin_addr.s_addr) { 08939 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08940 if (p->expire == -1) 08941 peer_unref(p); 08942 } 08943 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08944 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08945 if (sin->sin_addr.s_addr) { 08946 struct sockaddr_in peer_addr; 08947 08948 ast_sockaddr_to_sin(&p->addr, &peer_addr); 08949 08950 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08951 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr); 08952 if (!ast_strlen_zero(p->mailbox)) { 08953 struct ast_event *event; 08954 int new, old; 08955 char *mailbox, *context; 08956 08957 context = mailbox = ast_strdupa(p->mailbox); 08958 strsep(&context, "@"); 08959 if (ast_strlen_zero(context)) 08960 context = "default"; 08961 08962 event = ast_event_get_cached(AST_EVENT_MWI, 08963 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08964 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08965 AST_EVENT_IE_END); 08966 if (event) { 08967 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08968 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08969 ast_event_destroy(event); 08970 } else { /* Fall back on checking the mailbox directly */ 08971 ast_app_inboxcount(p->mailbox, &new, &old); 08972 } 08973 08974 if (new > 255) { 08975 new = 255; 08976 } 08977 if (old > 255) { 08978 old = 255; 08979 } 08980 msgcount = (old << 8) | new; 08981 08982 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08983 } 08984 if (ast_test_flag64(p, IAX_HASCALLERID)) { 08985 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08986 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08987 } 08988 } 08989 version = iax_check_version(devtype); 08990 if (version) 08991 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08992 08993 res = 0; 08994 08995 return_unref: 08996 peer_unref(p); 08997 08998 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08999 }
| static int user_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1758 of file chan_iax2.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
| static int user_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 13172 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
13173 { 13174 struct iax2_user *user = obj; 13175 13176 ast_set_flag64(user, IAX_DELME); 13177 13178 return 0; 13179 }
| static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12897 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by build_user().
12898 { 12899 struct iax2_user *user = obj; 12900 12901 ast_free_ha(user->ha); 12902 free_context(user->contexts); 12903 if(user->vars) { 12904 ast_variables_destroy(user->vars); 12905 user->vars = NULL; 12906 } 12907 ast_string_field_free_memory(user); 12908 }
| static int user_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1748 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_objects().
01749 { 01750 const struct iax2_user *user = obj; 01751 01752 return ast_str_hash(user->name); 01753 }
Definition at line 1805 of file chan_iax2.c.
References ao2_ref.
01806 { 01807 ao2_ref(user, +1); 01808 return user; 01809 }
Definition at line 1811 of file chan_iax2.c.
References ao2_ref.
Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), prune_users(), requirecalltoken_mark_auto(), set_config(), and users_data_provider_get().
01812 { 01813 ao2_ref(user, -1); 01814 return NULL; 01815 }
| static int users_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 14857 of file chan_iax2.c.
References iax2_user::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cdr_flags2str(), ast_copy_string(), ast_data_add_bool(), ast_data_add_codecs(), ast_data_add_int(), ast_data_add_node(), ast_data_add_password(), ast_data_add_str(), ast_data_add_structure, ast_data_remove_node(), ast_data_search_match(), ast_strlen_zero(), ast_test_flag64, iax2_user::authmethods, iax2_user::capability, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, and user_unref().
14859 { 14860 struct ast_data *data_user, *data_authmethods, *data_enum_node; 14861 struct iax2_user *user; 14862 struct ao2_iterator i; 14863 char auth[90]; 14864 char *pstr = ""; 14865 14866 i = ao2_iterator_init(users, 0); 14867 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 14868 data_user = ast_data_add_node(data_root, "user"); 14869 if (!data_user) { 14870 continue; 14871 } 14872 14873 ast_data_add_structure(iax2_user, data_user, user); 14874 14875 ast_data_add_codecs(data_user, "codecs", user->capability); 14876 14877 if (!ast_strlen_zero(user->secret)) { 14878 ast_copy_string(auth, user->secret, sizeof(auth)); 14879 } else if (!ast_strlen_zero(user->inkeys)) { 14880 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys); 14881 } else { 14882 ast_copy_string(auth, "no secret", sizeof(auth)); 14883 } 14884 ast_data_add_password(data_user, "secret", auth); 14885 14886 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT); 14887 14888 /* authmethods */ 14889 data_authmethods = ast_data_add_node(data_user, "authmethods"); 14890 if (!data_authmethods) { 14891 ast_data_remove_node(data_root, data_user); 14892 continue; 14893 } 14894 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA); 14895 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5); 14896 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT); 14897 14898 /* amaflags */ 14899 data_enum_node = ast_data_add_node(data_user, "amaflags"); 14900 if (!data_enum_node) { 14901 ast_data_remove_node(data_root, data_user); 14902 continue; 14903 } 14904 ast_data_add_int(data_enum_node, "value", user->amaflags); 14905 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags)); 14906 14907 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0); 14908 14909 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) { 14910 pstr = "REQ only"; 14911 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) { 14912 pstr = "disabled"; 14913 } else { 14914 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host"; 14915 } 14916 ast_data_add_str(data_user, "codec-preferences", pstr); 14917 14918 if (!ast_data_search_match(search, data_user)) { 14919 ast_data_remove_node(data_root, data_user); 14920 } 14921 } 14922 ao2_iterator_destroy(&i); 14923 14924 return 0; 14925 }
| static void vnak_retransmit | ( | int | callno, | |
| int | last | |||
| ) | [static] |
Definition at line 9202 of file chan_iax2.c.
References AST_LIST_TRAVERSE, f, iax_frame::oseqno, iax_frame::retries, and send_packet().
Referenced by socket_process().
09203 { 09204 struct iax_frame *f; 09205 09206 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) { 09207 /* Send a copy immediately */ 09208 if (((unsigned char) (f->oseqno - last) < 128) && 09209 (f->retries >= 0)) { 09210 send_packet(f); 09211 } 09212 } 09213 }
| static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5365 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
05366 { 05367 unsigned short callno = pvt->callno; 05368 05369 if (!pvt->peercallno) { 05370 /* We don't know the remote side's call number, yet. :( */ 05371 int count = 10; 05372 while (count-- && pvt && !pvt->peercallno) { 05373 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05374 pvt = iaxs[callno]; 05375 } 05376 if (!pvt || !pvt->peercallno) { 05377 return -1; 05378 } 05379 } 05380 05381 return 0; 05382 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 383 of file chan_iax2.c.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_async_goto(), ast_call_forward(), ast_cdr_setaccount(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_set_owners_and_peers(), begin_dial_channel(), build_peer(), check_peer_ok(), create_addr_from_peer(), dahdi_new(), dial_exec_full(), disa_exec(), do_forward(), findmeexec(), func_channel_write_real(), gtalk_new(), jingle_new(), local_call(), sip_new(), skinny_new(), tds_log(), and wait_for_answer().
int adsi = 0 [static] |
Definition at line 387 of file chan_iax2.c.
int amaflags = 0 [static] |
Definition at line 386 of file chan_iax2.c.
Referenced by ast_async_goto().
int authdebug = 1 [static] |
Definition at line 294 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 295 of file chan_iax2.c.
struct ao2_container* callno_pool [static] |
table of available call numbers
Definition at line 849 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 854 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 852 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
Definition at line 14397 of file chan_iax2.c.
Referenced by __unload_module(), and load_module().
| unsigned int cos |
Definition at line 305 of file chan_iax2.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1101 of file chan_iax2.c.
Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), and reload_config().
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Definition at line 272 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 317 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 388 of file chan_iax2.c.
int global_max_trunk_mtu [static] |
Maximum MTU, 0 if not used
Definition at line 267 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 439 of file chan_iax2.c.
struct ast_flags64 globalflags = { 0 } [static] |
Definition at line 391 of file chan_iax2.c.
format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 369 of file chan_iax2.c.
struct ast_data_entry iax2_data_providers[] [static] |
{
AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider),
AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider),
}
Definition at line 14937 of file chan_iax2.c.
Referenced by load_module().
int iax2_encryption = 0 [static] |
Definition at line 389 of file chan_iax2.c.
int(* iax2_regfunk)(const char *username, int onoff) = NULL [static] |
Referenced by __expire_registry(), reg_source_db(), and update_registry().
struct ast_switch iax2_switch [static] |
Definition at line 14283 of file chan_iax2.c.
Referenced by __unload_module(), and load_module().
struct ast_channel_tech iax2_tech [static] |
Definition at line 1216 of file chan_iax2.c.
Referenced by __unload_module(), acf_channel_read(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), and load_module().
struct ast_datastore_info iax2_variable_datastore_info [static] |
{
.type = "IAX2_VARIABLE",
.duplicate = iax2_dup_variable_datastore,
.destroy = iax2_free_variable_datastore,
}
Definition at line 1414 of file chan_iax2.c.
Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process().
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 1078 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().
struct ao2_container* iax_transfercallno_pvts [static] |
Another container of iax2_pvt structures.
* Active IAX2 pvt stucts used during transfering a call are stored here.
Definition at line 1094 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().
int iaxactivethreadcount = 0 [static] |
Definition at line 638 of file chan_iax2.c.
Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 296 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 371 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 299 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 301 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 636 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxdynamicthreadnum = 0 [static] |
Definition at line 637 of file chan_iax2.c.
Referenced by find_idle_thread().
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
Definition at line 635 of file chan_iax2.c.
Referenced by find_idle_thread(), and set_config().
struct ast_custom_function iaxpeer_function [static] |
{
.name = "IAXPEER",
.read = function_iaxpeer,
}
Definition at line 14203 of file chan_iax2.c.
Referenced by load_module(), and unload_module().
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
an array of iax2 pvt structures
The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.
Definition at line 1067 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __do_deliver(), __find_callno(), __get_from_jb(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_fail(), auth_reject(), authenticate_reply(), authenticate_request(), auto_hangup(), cache_get_callno_locked(), calc_timestamp(), check_access(), complete_transfer(), decrypt_frame(), delete_users(), dp_lookup(), find_cache(), fix_peerts(), function_iaxpeer(), handle_cli_iax2_show_channels(), iax2_ack_registry(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_do_register(), iax2_dprequest(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_lock_owner(), iax2_poke_peer(), iax2_predestroy(), iax2_prov_app(), iax2_provision(), iax2_queryoption(), iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), iax2_request(), iax2_setoption(), iax2_start_transfer(), iax2_vnak(), iax2_write(), load_module(), log_jitterstats(), make_trunk(), register_verify(), registry_authrequest(), registry_rerequest(), resend_with_token(), save_osptoken(), save_rr(), schedule_delivery(), scheduled_destroy(), send_command_final(), send_command_locked(), send_lagrq(), send_packet(), send_ping(), set_hangup_source_and_cause(), socket_process(), socket_process_meta(), stop_stuff(), transmit_frame(), unwrap_timestamp(), update_packet(), update_registry(), and wait_for_peercallno().
ast_mutex_t iaxsl[ARRAY_LEN(iaxs)] [static] |
chan_iax2_pvt structure locks
These locks are used when accessing a pvt structure in the iaxs array. The index used here is the same as used in the iaxs array. It is the local call number for the associated pvt struct.
Definition at line 1087 of file chan_iax2.c.
Referenced by __attempt_transmit(), __auth_reject(), __auto_congest(), __auto_hangup(), __find_callno(), __get_from_jb(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), __unload_module(), acf_channel_read(), ast_cli_netstats(), ast_iax2_new(), auth_reject(), authenticate_reply(), auto_hangup(), cache_get_callno_locked(), delete_users(), dp_lookup(), find_cache(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_stats(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_destroy(), iax2_destroy_helper(), iax2_do_register(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_key_rotate(), iax2_lock_owner(), iax2_poke_peer(), iax2_provision(), iax2_queryoption(), iax2_request(), iax2_setoption(), iax2_write(), load_module(), lock_both(), log_jitterstats(), make_trunk(), peer_destructor(), pvt_destructor(), register_verify(), registry_authrequest(), scheduled_destroy(), send_command_locked(), send_lagrq(), send_ping(), set_hangup_source_and_cause(), socket_process(), socket_process_meta(), transmit_frame(), unlock_both(), update_registry(), and wait_for_peercallno().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 634 of file chan_iax2.c.
Referenced by handle_cli_iax2_show_threads(), set_config(), and start_network_thread().
int iaxtrunkdebug = 0 [static] |
Definition at line 373 of file chan_iax2.c.
struct ast_custom_function iaxvar_function [static] |
{
.name = "IAXVAR",
.read = acf_iaxvar_read,
.write = acf_iaxvar_write,
}
Definition at line 10018 of file chan_iax2.c.
Referenced by load_module(), and unload_module().
struct io_context* io [static] |
Definition at line 364 of file chan_iax2.c.
int jittertargetextra = 40 [static] |
Definition at line 287 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 283 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 274 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 297 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 309 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 281 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 280 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 284 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 286 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 308 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 384 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 385 of file chan_iax2.c.
Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), set_peer_defaults(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 315 of file chan_iax2.c.
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 393 of file chan_iax2.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 278 of file chan_iax2.c.
struct ast_event_sub* network_change_event_subscription [static] |
subscription id for network change events
Definition at line 277 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 316 of file chan_iax2.c.
char* papp = "IAX2Provision" [static] |
Definition at line 12126 of file chan_iax2.c.
Referenced by __unload_module(), and load_module().
struct ast_data_handler peers_data_provider [static] |
{
.version = AST_DATA_HANDLER_VERSION,
.get = peers_data_provider_get
}
Definition at line 14927 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 282 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 258 of file chan_iax2.c.
Referenced by ast_best_codec(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), and set_config().
struct { ... } qos [static] |
Referenced by peer_set_srcaddr(), and set_config().
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 275 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 285 of file chan_iax2.c.
struct ast_sched_thread* sched [static] |
Definition at line 365 of file chan_iax2.c.
int srvlookup = 0 [static] |
Definition at line 311 of file chan_iax2.c.
Referenced by build_peer().
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 260 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 375 of file chan_iax2.c.
Definition at line 313 of file chan_iax2.c.
Referenced by find_timer(), kqueue_timer_hash(), kqueue_timer_open(), process_dahdi(), pthread_timer_ack(), pthread_timer_close(), pthread_timer_destructor(), pthread_timer_disable_continuous(), pthread_timer_enable_continuous(), pthread_timer_get_event(), pthread_timer_hash(), pthread_timer_open(), pthread_timer_set_rate(), run_timer(), softmix_bridge_create(), softmix_bridge_thread(), timer_destroy(), timerfd_timer_hash(), timerfd_timer_open(), and timing_test().
| unsigned int tos |
Definition at line 304 of file chan_iax2.c.
int trunk_maxmtu [static] |
Definition at line 268 of file chan_iax2.c.
int trunk_nmaxmtu [static] |
Trunk MTU statistics
Definition at line 268 of file chan_iax2.c.
int trunk_timed [static] |
Definition at line 268 of file chan_iax2.c.
int trunk_untimed [static] |
Definition at line 268 of file chan_iax2.c.
int trunkfreq = 20 [static] |
Definition at line 291 of file chan_iax2.c.
int trunkmaxsize = MAX_TRUNKDATA [static] |
Definition at line 292 of file chan_iax2.c.
struct ast_data_handler users_data_provider [static] |
{
.version = AST_DATA_HANDLER_VERSION,
.get = users_data_provider_get
}
Definition at line 14932 of file chan_iax2.c.
1.6.1