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 %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
| #define | ACN_FORMAT2 "%s %d %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_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 %4d %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 %d %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 14624 of file chan_iax2.c.
| #define DATA_EXPORT_IAX2_USER | ( | MEMBER | ) |
Definition at line 14701 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 1486 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 2048 of file chan_iax2.c.
Referenced by __find_callno(), and make_trunk().
| #define update_max_trunk | ( | ) | do { } while (0) |
Definition at line 2047 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 1974 of file chan_iax2.c.
01974 { 01975 /* do not allow a new call number, only search ones in use for match */ 01976 NEW_PREVENT = 0, 01977 /* search for match first, then allow a new one to be allocated */ 01978 NEW_ALLOW = 1, 01979 /* do not search for match, force a new call number */ 01980 NEW_FORCE = 2, 01981 /* do not search for match, force a new call number. Signifies call number 01982 * has been calltoken validated */ 01983 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01984 };
| 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 3485 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().
03486 { 03487 /* Attempt to transmit the frame to the remote peer... 03488 Called without iaxsl held. */ 03489 struct iax_frame *f = (struct iax_frame *)data; 03490 int freeme = 0; 03491 int callno = f->callno; 03492 03493 /* Make sure this call is still active */ 03494 if (callno) 03495 ast_mutex_lock(&iaxsl[callno]); 03496 if (callno && iaxs[callno]) { 03497 if (f->retries < 0) { 03498 /* Already ACK'd */ 03499 freeme = 1; 03500 } else if (f->retries >= max_retries) { 03501 /* Too many attempts. Record an error. */ 03502 if (f->transfer) { 03503 /* Transfer timeout */ 03504 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03505 } else if (f->final) { 03506 iax2_destroy(callno); 03507 } else { 03508 if (iaxs[callno]->owner) { 03509 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", 03510 ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr), 03511 iaxs[f->callno]->owner->name, 03512 f->af.frametype, 03513 f->af.subclass.integer, 03514 f->ts, 03515 f->oseqno); 03516 } 03517 iaxs[callno]->error = ETIMEDOUT; 03518 if (iaxs[callno]->owner) { 03519 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03520 /* Hangup the fd */ 03521 iax2_queue_frame(callno, &fr); /* XXX */ 03522 /* Remember, owner could disappear */ 03523 if (iaxs[callno] && iaxs[callno]->owner) 03524 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03525 } else { 03526 if (iaxs[callno]->reg) { 03527 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03528 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03529 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03530 } 03531 iax2_destroy(callno); 03532 } 03533 } 03534 freeme = 1; 03535 } else { 03536 /* Update it if it needs it */ 03537 update_packet(f); 03538 /* Attempt transmission */ 03539 send_packet(f); 03540 f->retries++; 03541 /* Try again later after 10 times as long */ 03542 f->retrytime *= 10; 03543 if (f->retrytime > MAX_RETRY_TIME) 03544 f->retrytime = MAX_RETRY_TIME; 03545 /* Transfer messages max out at one second */ 03546 if (f->transfer && (f->retrytime > 1000)) 03547 f->retrytime = 1000; 03548 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03549 } 03550 } else { 03551 /* Make sure it gets freed */ 03552 f->retries = -1; 03553 freeme = 1; 03554 } 03555 03556 if (freeme) { 03557 /* Don't attempt delivery, just remove it from the queue */ 03558 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03559 ast_mutex_unlock(&iaxsl[callno]); 03560 f->retrans = -1; /* this is safe because this is the scheduled function */ 03561 /* Free the IAX frame */ 03562 iax2_frame_free(f); 03563 } else if (callno) { 03564 ast_mutex_unlock(&iaxsl[callno]); 03565 } 03566 }
| static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 9012 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().
09013 { 09014 /* Called from IAX thread only, without iaxs lock */ 09015 int callno = (int)(long)(nothing); 09016 struct iax_ie_data ied; 09017 ast_mutex_lock(&iaxsl[callno]); 09018 if (iaxs[callno]) { 09019 memset(&ied, 0, sizeof(ied)); 09020 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 09021 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 09022 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 09023 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 09024 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 09025 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 09026 } 09027 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 09028 } 09029 ast_mutex_unlock(&iaxsl[callno]); 09030 }
| static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4675 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().
04676 { 04677 int callno = PTR_TO_CALLNO(nothing); 04678 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } }; 04679 ast_mutex_lock(&iaxsl[callno]); 04680 if (iaxs[callno]) { 04681 iaxs[callno]->initid = -1; 04682 iax2_queue_frame(callno, &f); 04683 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04684 } 04685 ast_mutex_unlock(&iaxsl[callno]); 04686 }
| static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 9061 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().
09062 { 09063 /* Called from IAX thread only, without iaxs lock */ 09064 int callno = (int)(long)(nothing); 09065 struct iax_ie_data ied; 09066 ast_mutex_lock(&iaxsl[callno]); 09067 if (iaxs[callno]) { 09068 memset(&ied, 0, sizeof(ied)); 09069 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 09070 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 09071 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 09072 } 09073 ast_mutex_unlock(&iaxsl[callno]); 09074 }
| static int __do_deliver | ( | void * | data | ) | [static] |
Definition at line 3273 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().
03274 { 03275 /* Just deliver the packet by using queueing. This is called by 03276 the IAX thread with the iaxsl lock held. */ 03277 struct iax_frame *fr = data; 03278 fr->retrans = -1; 03279 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03280 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE)) 03281 iax2_queue_frame(fr->callno, &fr->af); 03282 /* Free our iax frame */ 03283 iax2_frame_free(fr); 03284 /* And don't run again */ 03285 return 0; 03286 }
| static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8637 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().
08638 { 08639 struct iax2_peer *peer = (struct iax2_peer *) data; 08640 08641 if (!peer) 08642 return; 08643 if (peer->expire == -1) { 08644 /* Removed already (possibly through CLI), ignore */ 08645 return; 08646 } 08647 08648 peer->expire = -1; 08649 08650 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08651 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08652 realtime_update_peer(peer->name, &peer->addr, 0); 08653 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08654 /* modify entry in peercnts table as _not_ registered */ 08655 peercnt_modify((unsigned char) 0, 0, &peer->addr); 08656 /* Reset the address */ 08657 memset(&peer->addr, 0, sizeof(peer->addr)); 08658 /* Reset expiry value */ 08659 peer->expiry = min_reg_expire; 08660 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08661 ast_db_del("IAX/Registry", peer->name); 08662 register_peer_exten(peer, 0); 08663 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 08664 if (iax2_regfunk) 08665 iax2_regfunk(peer->name, 0); 08666 08667 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08668 unlink_peer(peer); 08669 08670 peer_unref(peer); 08671 }
| 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 2779 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().
02780 { 02781 int res = 0; 02782 int x; 02783 /* this call is calltoken validated as long as it is either NEW_FORCE 02784 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02785 int validated = (new > NEW_ALLOW) ? 1 : 0; 02786 char host[80]; 02787 02788 if (new <= NEW_ALLOW) { 02789 if (callno) { 02790 struct chan_iax2_pvt *pvt; 02791 struct chan_iax2_pvt tmp_pvt = { 02792 .callno = dcallno, 02793 .peercallno = callno, 02794 .transfercallno = callno, 02795 /* hack!! */ 02796 .frames_received = check_dcallno, 02797 }; 02798 02799 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02800 /* this works for finding normal call numbers not involving transfering */ 02801 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02802 if (return_locked) { 02803 ast_mutex_lock(&iaxsl[pvt->callno]); 02804 } 02805 res = pvt->callno; 02806 ao2_ref(pvt, -1); 02807 pvt = NULL; 02808 return res; 02809 } 02810 /* this searches for transfer call numbers that might not get caught otherwise */ 02811 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02812 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02813 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02814 if (return_locked) { 02815 ast_mutex_lock(&iaxsl[pvt->callno]); 02816 } 02817 res = pvt->callno; 02818 ao2_ref(pvt, -1); 02819 pvt = NULL; 02820 return res; 02821 } 02822 } 02823 /* This will occur on the first response to a message that we initiated, 02824 * such as a PING. */ 02825 if (dcallno) { 02826 ast_mutex_lock(&iaxsl[dcallno]); 02827 } 02828 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02829 iaxs[dcallno]->peercallno = callno; 02830 res = dcallno; 02831 store_by_peercallno(iaxs[dcallno]); 02832 if (!res || !return_locked) { 02833 ast_mutex_unlock(&iaxsl[dcallno]); 02834 } 02835 return res; 02836 } 02837 if (dcallno) { 02838 ast_mutex_unlock(&iaxsl[dcallno]); 02839 } 02840 #ifdef IAX_OLD_FIND 02841 /* If we get here, we SHOULD NOT find a call structure for this 02842 callno; if we do, it means that there is a call structure that 02843 has a peer callno but did NOT get entered into the hash table, 02844 which is bad. 02845 02846 If we find a call structure using this old, slow method, output a log 02847 message so we'll know about it. After a few months of leaving this in 02848 place, if we don't hear about people seeing these messages, we can 02849 remove this code for good. 02850 */ 02851 02852 for (x = 1; !res && x < maxnontrunkcall; x++) { 02853 ast_mutex_lock(&iaxsl[x]); 02854 if (iaxs[x]) { 02855 /* Look for an exact match */ 02856 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02857 res = x; 02858 } 02859 } 02860 if (!res || !return_locked) 02861 ast_mutex_unlock(&iaxsl[x]); 02862 } 02863 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02864 ast_mutex_lock(&iaxsl[x]); 02865 if (iaxs[x]) { 02866 /* Look for an exact match */ 02867 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02868 res = x; 02869 } 02870 } 02871 if (!res || !return_locked) 02872 ast_mutex_unlock(&iaxsl[x]); 02873 } 02874 #endif 02875 } 02876 if (!res && (new >= NEW_ALLOW)) { 02877 struct callno_entry *callno_entry; 02878 /* It may seem odd that we look through the peer list for a name for 02879 * this *incoming* call. Well, it is weird. However, users don't 02880 * have an IP address/port number that we can match against. So, 02881 * this is just checking for a peer that has that IP/port and 02882 * assuming that we have a user of the same name. This isn't always 02883 * correct, but it will be changed if needed after authentication. */ 02884 if (!iax2_getpeername(*sin, host, sizeof(host))) 02885 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02886 02887 if (peercnt_add(sin)) { 02888 /* This address has hit its callnumber limit. When the limit 02889 * is reached, the connection is not added to the peercnts table.*/ 02890 return 0; 02891 } 02892 02893 if (!(callno_entry = get_unused_callno(0, validated))) { 02894 /* since we ran out of space, remove the peercnt 02895 * entry we added earlier */ 02896 peercnt_remove_by_addr(sin); 02897 ast_log(LOG_WARNING, "No more space\n"); 02898 return 0; 02899 } 02900 x = callno_entry->callno; 02901 ast_mutex_lock(&iaxsl[x]); 02902 02903 iaxs[x] = new_iax(sin, host); 02904 update_max_nontrunk(); 02905 if (iaxs[x]) { 02906 if (iaxdebug) 02907 ast_debug(1, "Creating new call structure %d\n", x); 02908 iaxs[x]->callno_entry = callno_entry; 02909 iaxs[x]->sockfd = sockfd; 02910 iaxs[x]->addr.sin_port = sin->sin_port; 02911 iaxs[x]->addr.sin_family = sin->sin_family; 02912 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02913 iaxs[x]->peercallno = callno; 02914 iaxs[x]->callno = x; 02915 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02916 iaxs[x]->expiry = min_reg_expire; 02917 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02918 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02919 iaxs[x]->amaflags = amaflags; 02920 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 02921 ast_string_field_set(iaxs[x], accountcode, accountcode); 02922 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02923 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02924 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02925 02926 if (iaxs[x]->peercallno) { 02927 store_by_peercallno(iaxs[x]); 02928 } 02929 } else { 02930 ast_log(LOG_WARNING, "Out of resources\n"); 02931 ast_mutex_unlock(&iaxsl[x]); 02932 replace_callno(callno_entry); 02933 return 0; 02934 } 02935 if (!return_locked) 02936 ast_mutex_unlock(&iaxsl[x]); 02937 res = x; 02938 } 02939 return res; 02940 }
| static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4069 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().
04070 { 04071 int callno = PTR_TO_CALLNO(p); 04072 struct chan_iax2_pvt *pvt = NULL; 04073 struct iax_frame *fr; 04074 jb_frame frame; 04075 int ret; 04076 long ms; 04077 long next; 04078 struct timeval now = ast_tvnow(); 04079 04080 /* Make sure we have a valid private structure before going on */ 04081 ast_mutex_lock(&iaxsl[callno]); 04082 pvt = iaxs[callno]; 04083 if (!pvt) { 04084 /* No go! */ 04085 ast_mutex_unlock(&iaxsl[callno]); 04086 return; 04087 } 04088 04089 pvt->jbid = -1; 04090 04091 /* round up a millisecond since ast_sched_runq does; */ 04092 /* prevents us from spinning while waiting for our now */ 04093 /* to catch up with runq's now */ 04094 now.tv_usec += 1000; 04095 04096 ms = ast_tvdiff_ms(now, pvt->rxcore); 04097 04098 if(ms >= (next = jb_next(pvt->jb))) { 04099 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 04100 switch(ret) { 04101 case JB_OK: 04102 fr = frame.data; 04103 __do_deliver(fr); 04104 /* __do_deliver() can cause the call to disappear */ 04105 pvt = iaxs[callno]; 04106 break; 04107 case JB_INTERP: 04108 { 04109 struct ast_frame af = { 0, }; 04110 04111 /* create an interpolation frame */ 04112 af.frametype = AST_FRAME_VOICE; 04113 af.subclass.codec = pvt->voiceformat; 04114 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 04115 af.src = "IAX2 JB interpolation"; 04116 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 04117 af.offset = AST_FRIENDLY_OFFSET; 04118 04119 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 04120 * which we'd need to malloc, and then it would free it. That seems like a drag */ 04121 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 04122 iax2_queue_frame(callno, &af); 04123 /* iax2_queue_frame() could cause the call to disappear */ 04124 pvt = iaxs[callno]; 04125 } 04126 } 04127 break; 04128 case JB_DROP: 04129 iax2_frame_free(frame.data); 04130 break; 04131 case JB_NOFRAME: 04132 case JB_EMPTY: 04133 /* do nothing */ 04134 break; 04135 default: 04136 /* shouldn't happen */ 04137 break; 04138 } 04139 } 04140 if (pvt) 04141 update_jbsched(pvt); 04142 ast_mutex_unlock(&iaxsl[callno]); 04143 }
| static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8308 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08309 { 08310 struct iax2_registry *reg = (struct iax2_registry *)data; 08311 reg->expire = -1; 08312 iax2_do_register(reg); 08313 }
| static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12060 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().
12061 { 12062 struct iax2_peer *peer = (struct iax2_peer *)data; 12063 int callno; 12064 12065 if (peer->lastms > -1) { 12066 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 12067 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 12068 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 12069 } 12070 if ((callno = peer->callno) > 0) { 12071 ast_mutex_lock(&iaxsl[callno]); 12072 iax2_destroy(callno); 12073 ast_mutex_unlock(&iaxsl[callno]); 12074 } 12075 peer->callno = 0; 12076 peer->lastms = -1; 12077 /* Try again quickly */ 12078 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 12079 if (peer->pokeexpire == -1) 12080 peer_unref(peer); 12081 }
| static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9121 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
09122 { 09123 struct iax2_peer *peer = (struct iax2_peer *)data; 09124 iax2_poke_peer(peer, 0); 09125 peer_unref(peer); 09126 }
| static int __iax2_show_peers | ( | int | fd, | |
| int * | total, | |||
| struct mansession * | s, | |||
| const int | argc, | |||
| const char *const | argv[] | |||
| ) | [static] |
Definition at line 6672 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().
06673 { 06674 regex_t regexbuf; 06675 int havepattern = 0; 06676 int total_peers = 0; 06677 int online_peers = 0; 06678 int offline_peers = 0; 06679 int unmonitored_peers = 0; 06680 struct ao2_iterator i; 06681 06682 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" 06683 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" 06684 06685 struct iax2_peer *peer = NULL; 06686 char name[256]; 06687 struct ast_str *encmethods = ast_str_alloca(256); 06688 int registeredonly=0; 06689 char idtext[256] = ""; 06690 switch (argc) { 06691 case 6: 06692 if (!strcasecmp(argv[3], "registered")) 06693 registeredonly = 1; 06694 else 06695 return RESULT_SHOWUSAGE; 06696 if (!strcasecmp(argv[4], "like")) { 06697 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06698 return RESULT_SHOWUSAGE; 06699 havepattern = 1; 06700 } else 06701 return RESULT_SHOWUSAGE; 06702 break; 06703 case 5: 06704 if (!strcasecmp(argv[3], "like")) { 06705 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06706 return RESULT_SHOWUSAGE; 06707 havepattern = 1; 06708 } else 06709 return RESULT_SHOWUSAGE; 06710 break; 06711 case 4: 06712 if (!strcasecmp(argv[3], "registered")) 06713 registeredonly = 1; 06714 else 06715 return RESULT_SHOWUSAGE; 06716 break; 06717 case 3: 06718 break; 06719 default: 06720 return RESULT_SHOWUSAGE; 06721 } 06722 06723 06724 if (!s) 06725 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status"); 06726 06727 i = ao2_iterator_init(peers, 0); 06728 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 06729 char nm[20]; 06730 char status[20]; 06731 int retstatus; 06732 struct sockaddr_in peer_addr; 06733 06734 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 06735 06736 if (registeredonly && !peer_addr.sin_addr.s_addr) { 06737 continue; 06738 } 06739 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 06740 continue; 06741 } 06742 06743 if (!ast_strlen_zero(peer->username)) 06744 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06745 else 06746 ast_copy_string(name, peer->name, sizeof(name)); 06747 06748 encmethods_to_str(peer->encmethods, &encmethods); 06749 retstatus = peer_status(peer, status, sizeof(status)); 06750 if (retstatus > 0) 06751 online_peers++; 06752 else if (!retstatus) 06753 offline_peers++; 06754 else 06755 unmonitored_peers++; 06756 06757 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06758 06759 if (s) { 06760 astman_append(s, 06761 "Event: PeerEntry\r\n%s" 06762 "Channeltype: IAX2\r\n" 06763 "ObjectName: %s\r\n" 06764 "ChanObjectType: peer\r\n" 06765 "IPaddress: %s\r\n" 06766 "IPport: %d\r\n" 06767 "Dynamic: %s\r\n" 06768 "Trunk: %s\r\n" 06769 "Encryption: %s\r\n" 06770 "Status: %s\r\n\r\n", 06771 idtext, 06772 name, 06773 ast_sockaddr_stringify_addr(&peer->addr), 06774 ast_sockaddr_port(&peer->addr), 06775 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06776 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06777 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06778 status); 06779 } else { 06780 ast_cli(fd, FORMAT, name, 06781 ast_sockaddr_stringify_addr(&peer->addr), 06782 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06783 nm, 06784 ast_sockaddr_port(&peer->addr), 06785 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06786 peer->encmethods ? "(E)" : " ", 06787 status); 06788 } 06789 total_peers++; 06790 } 06791 ao2_iterator_destroy(&i); 06792 06793 if (!s) 06794 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n", 06795 total_peers, online_peers, offline_peers, unmonitored_peers); 06796 06797 if (havepattern) 06798 regfree(®exbuf); 06799 06800 if (total) 06801 *total = total_peers; 06802 06803 return RESULT_SUCCESS; 06804 #undef FORMAT 06805 #undef FORMAT2 06806 }
| static int __schedule_action | ( | void(*)(const void *data) | func, | |
| const void * | data, | |||
| const char * | funcname | |||
| ) | [static] |
Definition at line 1461 of file chan_iax2.c.
References ast_copy_string(), ast_debug, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, signal_condition(), and thread.
01462 { 01463 struct iax2_thread *thread; 01464 static time_t lasterror; 01465 time_t t; 01466 01467 thread = find_idle_thread(); 01468 if (thread != NULL) { 01469 thread->schedfunc = func; 01470 thread->scheddata = data; 01471 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01472 #ifdef DEBUG_SCHED_MULTITHREAD 01473 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01474 #endif 01475 signal_condition(&thread->lock, &thread->cond); 01476 return 0; 01477 } 01478 time(&t); 01479 if (t != lasterror) { 01480 lasterror = t; 01481 ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname); 01482 } 01483 01484 return -1; 01485 }
| 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 7499 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().
07501 { 07502 struct ast_frame f = { 0, }; 07503 int res = 0; 07504 07505 f.frametype = type; 07506 f.subclass.integer = command; 07507 f.datalen = datalen; 07508 f.src = __FUNCTION__; 07509 f.data.ptr = (void *) data; 07510 07511 if ((res = queue_signalling(i, &f)) <= 0) { 07512 return res; 07513 } 07514 07515 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07516 }
| static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1572 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().
01573 { 01574 int callno = (long) data; 01575 01576 ast_mutex_lock(&iaxsl[callno]); 01577 01578 if (iaxs[callno]) { 01579 if (iaxs[callno]->peercallno) { 01580 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01581 if (iaxs[callno]->lagid != DONT_RESCHEDULE) { 01582 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01583 } 01584 } 01585 } else { 01586 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01587 } 01588 01589 ast_mutex_unlock(&iaxsl[callno]); 01590 }
| static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1505 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().
01506 { 01507 int callno = (long) data; 01508 01509 ast_mutex_lock(&iaxsl[callno]); 01510 01511 if (iaxs[callno]) { 01512 if (iaxs[callno]->peercallno) { 01513 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01514 if (iaxs[callno]->pingid != DONT_RESCHEDULE) { 01515 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01516 } 01517 } 01518 } else { 01519 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01520 } 01521 01522 ast_mutex_unlock(&iaxsl[callno]); 01523 }
| static int __unload_module | ( | void | ) | [static] |
Definition at line 14428 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().
14429 { 14430 struct ast_context *con; 14431 int x; 14432 14433 network_change_event_unsubscribe(); 14434 14435 ast_manager_unregister("IAXpeers"); 14436 ast_manager_unregister("IAXpeerlist"); 14437 ast_manager_unregister("IAXnetstats"); 14438 ast_manager_unregister("IAXregistry"); 14439 ast_unregister_application(papp); 14440 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14441 ast_unregister_switch(&iax2_switch); 14442 ast_channel_unregister(&iax2_tech); 14443 14444 if (netthreadid != AST_PTHREADT_NULL) { 14445 pthread_cancel(netthreadid); 14446 pthread_kill(netthreadid, SIGURG); 14447 pthread_join(netthreadid, NULL); 14448 } 14449 14450 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14451 if (iaxs[x]) { 14452 iax2_destroy(x); 14453 } 14454 } 14455 14456 /* Call for all threads to halt */ 14457 cleanup_thread_list(&active_list); 14458 cleanup_thread_list(&dynamic_list); 14459 cleanup_thread_list(&idle_list); 14460 14461 ast_netsock_release(netsock); 14462 ast_netsock_release(outsock); 14463 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14464 if (iaxs[x]) { 14465 iax2_destroy(x); 14466 } 14467 } 14468 ast_manager_unregister( "IAXpeers" ); 14469 ast_manager_unregister( "IAXpeerlist" ); 14470 ast_manager_unregister( "IAXnetstats" ); 14471 ast_manager_unregister( "IAXregistry" ); 14472 ast_unregister_application(papp); 14473 #ifdef TEST_FRAMEWORK 14474 AST_TEST_UNREGISTER(test_iax2_peers_get); 14475 AST_TEST_UNREGISTER(test_iax2_users_get); 14476 #endif 14477 ast_data_unregister(NULL); 14478 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14479 ast_unregister_switch(&iax2_switch); 14480 ast_channel_unregister(&iax2_tech); 14481 delete_users(); 14482 iax_provision_unload(); 14483 reload_firmware(1); 14484 14485 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14486 ast_mutex_destroy(&iaxsl[x]); 14487 } 14488 14489 ao2_ref(peers, -1); 14490 ao2_ref(users, -1); 14491 ao2_ref(iax_peercallno_pvts, -1); 14492 ao2_ref(iax_transfercallno_pvts, -1); 14493 ao2_ref(peercnts, -1); 14494 ao2_ref(callno_limits, -1); 14495 ao2_ref(calltoken_ignores, -1); 14496 ao2_ref(callno_pool, -1); 14497 ao2_ref(callno_pool_trunk, -1); 14498 if (timer) { 14499 ast_timer_close(timer); 14500 timer = NULL; 14501 } 14502 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 14503 sched = ast_sched_thread_destroy(sched); 14504 14505 con = ast_context_find(regcontext); 14506 if (con) 14507 ast_context_destroy(con, "IAX2"); 14508 ast_unload_realtime("iaxpeers"); 14509 return 0; 14510 }
| static int acf_channel_read | ( | struct ast_channel * | chan, | |
| const char * | funcname, | |||
| char * | preparse, | |||
| char * | buf, | |||
| size_t | buflen | |||
| ) | [static] |
Definition at line 14068 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.
14069 { 14070 struct chan_iax2_pvt *pvt; 14071 unsigned int callno; 14072 int res = 0; 14073 14074 if (!chan || chan->tech != &iax2_tech) { 14075 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 14076 return -1; 14077 } 14078 14079 callno = PTR_TO_CALLNO(chan->tech_pvt); 14080 ast_mutex_lock(&iaxsl[callno]); 14081 if (!(pvt = iaxs[callno])) { 14082 ast_mutex_unlock(&iaxsl[callno]); 14083 return -1; 14084 } 14085 14086 if (!strcasecmp(args, "osptoken")) { 14087 ast_copy_string(buf, pvt->osptoken, buflen); 14088 } else if (!strcasecmp(args, "peerip")) { 14089 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 14090 } else if (!strcasecmp(args, "peername")) { 14091 ast_copy_string(buf, pvt->username, buflen); 14092 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) { 14093 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : ""); 14094 } else { 14095 res = -1; 14096 } 14097 14098 ast_mutex_unlock(&iaxsl[callno]); 14099 14100 return res; 14101 }
| static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 9843 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_datastore::data, iax2_variable_datastore_info, ast_var_t::name, ast_var_t::value, and var.
09844 { 09845 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09846 AST_LIST_HEAD(, ast_var_t) *varlist; 09847 struct ast_var_t *var; 09848 09849 if (!variablestore) { 09850 *buf = '\0'; 09851 return 0; 09852 } 09853 varlist = variablestore->data; 09854 09855 AST_LIST_LOCK(varlist); 09856 AST_LIST_TRAVERSE(varlist, var, entries) { 09857 if (strcmp(var->name, data) == 0) { 09858 ast_copy_string(buf, var->value, len); 09859 break; 09860 } 09861 } 09862 AST_LIST_UNLOCK(varlist); 09863 return 0; 09864 }
| static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 9866 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, ast_var_t::name, and var.
09867 { 09868 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09869 AST_LIST_HEAD(, ast_var_t) *varlist; 09870 struct ast_var_t *var; 09871 09872 if (!variablestore) { 09873 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09874 if (!variablestore) { 09875 ast_log(LOG_ERROR, "Memory allocation error\n"); 09876 return -1; 09877 } 09878 varlist = ast_calloc(1, sizeof(*varlist)); 09879 if (!varlist) { 09880 ast_datastore_free(variablestore); 09881 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09882 return -1; 09883 } 09884 09885 AST_LIST_HEAD_INIT(varlist); 09886 variablestore->data = varlist; 09887 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09888 ast_channel_datastore_add(chan, variablestore); 09889 } else 09890 varlist = variablestore->data; 09891 09892 AST_LIST_LOCK(varlist); 09893 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09894 if (strcmp(var->name, data) == 0) { 09895 AST_LIST_REMOVE_CURRENT(entries); 09896 ast_var_delete(var); 09897 break; 09898 } 09899 } 09900 AST_LIST_TRAVERSE_SAFE_END; 09901 var = ast_var_assign(data, value); 09902 if (var) 09903 AST_LIST_INSERT_TAIL(varlist, var, entries); 09904 else 09905 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09906 AST_LIST_UNLOCK(varlist); 09907 return 0; 09908 }
| static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2514 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().
02515 { 02516 struct addr_range tmp; 02517 struct addr_range *addr_range = NULL; 02518 struct ast_ha *ha = NULL; 02519 int error = 0; 02520 02521 if (ast_strlen_zero(addr)) { 02522 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02523 return -1; 02524 } 02525 02526 ha = ast_append_ha("permit", addr, NULL, &error); 02527 02528 /* check for valid config information */ 02529 if (error) { 02530 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02531 return -1; 02532 } 02533 02534 ast_copy_ha(ha, &tmp.ha); 02535 /* find or create the addr_range */ 02536 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02537 ao2_lock(addr_range); 02538 addr_range->delme = 0; 02539 ao2_unlock(addr_range); 02540 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02541 /* copy over config data into addr_range object */ 02542 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02543 ao2_link(calltoken_ignores, addr_range); 02544 } else { 02545 ast_free_ha(ha); 02546 return -1; 02547 } 02548 02549 ast_free_ha(ha); 02550 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02551 02552 return 0; 02553 }
| static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | ied | |||
| ) | [static] |
Definition at line 4751 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().
04752 { 04753 /* first make sure their are two empty bytes left in ied->buf */ 04754 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04755 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04756 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04757 pvt->calltoken_ie_len = 2; 04758 } 04759 }
| static int addr_range_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2165 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().
02166 { 02167 struct addr_range *lim1 = obj, *lim2 = arg; 02168 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) && 02169 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ? 02170 CMP_MATCH | CMP_STOP : 0; 02171 }
| static int addr_range_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2150 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
02151 { 02152 struct addr_range *lim = obj; 02153 lim->delme = 1; 02154 return 0; 02155 }
| static int addr_range_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2157 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, and addr_range::ha.
Referenced by load_objects().
02158 { 02159 const struct addr_range *lim = obj; 02160 struct sockaddr_in sin; 02161 ast_sockaddr_to_sin(&lim->ha.addr, &sin); 02162 return abs((int) sin.sin_addr.s_addr); 02163 }
| static int addr_range_match_address_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2185 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().
02186 { 02187 struct addr_range *addr_range = obj; 02188 struct sockaddr_in *sin = arg; 02189 struct sockaddr_in ha_netmask_sin; 02190 struct sockaddr_in ha_addr_sin; 02191 02192 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin); 02193 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin); 02194 02195 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) { 02196 return CMP_MATCH | CMP_STOP; 02197 } 02198 return 0; 02199 }
| static int apply_context | ( | struct iax2_context * | con, | |
| const char * | context | |||
| ) | [static] |
Definition at line 7557 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 7258 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().
07259 { 07260 int x; 07261 int numchans = 0; 07262 char first_message[10] = { 0, }; 07263 char last_message[10] = { 0, }; 07264 #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" 07265 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 07266 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07267 ast_mutex_lock(&iaxsl[x]); 07268 if (iaxs[x]) { 07269 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 07270 jb_info jbinfo; 07271 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07272 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07273 07274 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07275 jb_getinfo(iaxs[x]->jb, &jbinfo); 07276 localjitter = jbinfo.jitter; 07277 localdelay = jbinfo.current - jbinfo.min; 07278 locallost = jbinfo.frames_lost; 07279 locallosspct = jbinfo.losspct/1000; 07280 localdropped = jbinfo.frames_dropped; 07281 localooo = jbinfo.frames_ooo; 07282 } else { 07283 localjitter = -1; 07284 localdelay = 0; 07285 locallost = -1; 07286 locallosspct = -1; 07287 localdropped = 0; 07288 localooo = -1; 07289 } 07290 if (s) 07291 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07292 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07293 iaxs[x]->pingtime, 07294 localjitter, 07295 localdelay, 07296 locallost, 07297 locallosspct, 07298 localdropped, 07299 localooo, 07300 iaxs[x]->frames_received/1000, 07301 iaxs[x]->remote_rr.jitter, 07302 iaxs[x]->remote_rr.delay, 07303 iaxs[x]->remote_rr.losscnt, 07304 iaxs[x]->remote_rr.losspct, 07305 iaxs[x]->remote_rr.dropped, 07306 iaxs[x]->remote_rr.ooo, 07307 iaxs[x]->remote_rr.packets/1000, 07308 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07309 first_message, 07310 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07311 last_message); 07312 else 07313 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07314 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07315 iaxs[x]->pingtime, 07316 localjitter, 07317 localdelay, 07318 locallost, 07319 locallosspct, 07320 localdropped, 07321 localooo, 07322 iaxs[x]->frames_received/1000, 07323 iaxs[x]->remote_rr.jitter, 07324 iaxs[x]->remote_rr.delay, 07325 iaxs[x]->remote_rr.losscnt, 07326 iaxs[x]->remote_rr.losspct, 07327 iaxs[x]->remote_rr.dropped, 07328 iaxs[x]->remote_rr.ooo, 07329 iaxs[x]->remote_rr.packets/1000, 07330 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07331 first_message, 07332 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07333 last_message); 07334 numchans++; 07335 } 07336 ast_mutex_unlock(&iaxsl[x]); 07337 } 07338 07339 return numchans; 07340 }
| 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 5750 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().
05751 { 05752 struct ast_channel *tmp; 05753 struct chan_iax2_pvt *i; 05754 struct ast_variable *v = NULL; 05755 05756 if (!(i = iaxs[callno])) { 05757 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05758 return NULL; 05759 } 05760 05761 /* Don't hold call lock */ 05762 ast_mutex_unlock(&iaxsl[callno]); 05763 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); 05764 ast_mutex_lock(&iaxsl[callno]); 05765 if (i != iaxs[callno]) { 05766 if (tmp) { 05767 /* unlock and relock iaxsl[callno] to preserve locking order */ 05768 ast_mutex_unlock(&iaxsl[callno]); 05769 tmp = ast_channel_release(tmp); 05770 ast_mutex_lock(&iaxsl[callno]); 05771 } 05772 return NULL; 05773 } 05774 iax2_ami_channelupdate(i); 05775 if (!tmp) 05776 return NULL; 05777 tmp->tech = &iax2_tech; 05778 /* We can support any format by default, until we get restricted */ 05779 tmp->nativeformats = capability; 05780 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05781 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05782 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05783 05784 if (!ast_strlen_zero(i->parkinglot)) 05785 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05786 /* Don't use ast_set_callerid() here because it will 05787 * generate a NewCallerID event before the NewChannel event */ 05788 if (!ast_strlen_zero(i->ani)) { 05789 tmp->caller.ani.number.valid = 1; 05790 tmp->caller.ani.number.str = ast_strdup(i->ani); 05791 } else if (!ast_strlen_zero(i->cid_num)) { 05792 tmp->caller.ani.number.valid = 1; 05793 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 05794 } 05795 tmp->dialed.number.str = ast_strdup(i->dnid); 05796 if (!ast_strlen_zero(i->rdnis)) { 05797 tmp->redirecting.from.number.valid = 1; 05798 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 05799 } 05800 tmp->caller.id.name.presentation = i->calling_pres; 05801 tmp->caller.id.number.presentation = i->calling_pres; 05802 tmp->caller.id.number.plan = i->calling_ton; 05803 tmp->dialed.transit_network_select = i->calling_tns; 05804 if (!ast_strlen_zero(i->language)) 05805 ast_string_field_set(tmp, language, i->language); 05806 if (!ast_strlen_zero(i->accountcode)) 05807 ast_string_field_set(tmp, accountcode, i->accountcode); 05808 if (i->amaflags) 05809 tmp->amaflags = i->amaflags; 05810 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05811 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05812 if (i->adsi) 05813 tmp->adsicpe = i->peeradsicpe; 05814 else 05815 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05816 i->owner = tmp; 05817 i->capability = capability; 05818 05819 if (!cachable) { 05820 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE; 05821 } 05822 05823 /* Set inherited variables */ 05824 if (i->vars) { 05825 for (v = i->vars ; v ; v = v->next) 05826 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05827 } 05828 if (i->iaxvars) { 05829 struct ast_datastore *variablestore; 05830 struct ast_variable *var, *prev = NULL; 05831 AST_LIST_HEAD(, ast_var_t) *varlist; 05832 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05833 varlist = ast_calloc(1, sizeof(*varlist)); 05834 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05835 if (variablestore && varlist) { 05836 variablestore->data = varlist; 05837 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05838 AST_LIST_HEAD_INIT(varlist); 05839 for (var = i->iaxvars; var; var = var->next) { 05840 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05841 if (prev) 05842 ast_free(prev); 05843 prev = var; 05844 if (!newvar) { 05845 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05846 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05847 } else { 05848 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05849 } 05850 } 05851 if (prev) 05852 ast_free(prev); 05853 i->iaxvars = NULL; 05854 ast_channel_datastore_add(i->owner, variablestore); 05855 } else { 05856 if (variablestore) { 05857 ast_datastore_free(variablestore); 05858 } 05859 if (varlist) { 05860 ast_free(varlist); 05861 } 05862 } 05863 } 05864 05865 if (state != AST_STATE_DOWN) { 05866 if (ast_pbx_start(tmp)) { 05867 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05868 ast_hangup(tmp); 05869 i->owner = NULL; 05870 return NULL; 05871 } 05872 } 05873 05874 ast_module_ref(ast_module_info->self); 05875 return tmp; 05876 }
| 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 3568 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03569 { 03570 #ifdef SCHED_MULTITHREADED 03571 if (schedule_action(__attempt_transmit, data)) 03572 #endif 03573 __attempt_transmit(data); 03574 return 0; 03575 }
| static int auth_fail | ( | int | callno, | |
| int | failcode | |||
| ) | [static] |
Definition at line 9046 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().
09047 { 09048 /* Schedule sending the authentication failure in one second, to prevent 09049 guessing */ 09050 if (iaxs[callno]) { 09051 iaxs[callno]->authfail = failcode; 09052 if (delayreject) { 09053 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 09054 sched, 1000, auth_reject, (void *)(long)callno); 09055 } else 09056 auth_reject((void *)(long)callno); 09057 } 09058 return 0; 09059 }
| static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 9032 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().
09033 { 09034 int callno = (int)(long)(data); 09035 ast_mutex_lock(&iaxsl[callno]); 09036 if (iaxs[callno]) 09037 iaxs[callno]->authid = -1; 09038 ast_mutex_unlock(&iaxsl[callno]); 09039 #ifdef SCHED_MULTITHREADED 09040 if (schedule_action(__auth_reject, data)) 09041 #endif 09042 __auth_reject(data); 09043 return 0; 09044 }
| 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 8130 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().
08131 { 08132 int res = -1; 08133 int x; 08134 if (!ast_strlen_zero(keyn)) { 08135 if (!(authmethods & IAX_AUTH_RSA)) { 08136 if (ast_strlen_zero(secret)) 08137 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)); 08138 } else if (ast_strlen_zero(challenge)) { 08139 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 08140 } else { 08141 char sig[256]; 08142 struct ast_key *key; 08143 key = ast_key_get(keyn, AST_KEY_PRIVATE); 08144 if (!key) { 08145 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 08146 } else { 08147 if (ast_sign(key, (char*)challenge, sig)) { 08148 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 08149 res = -1; 08150 } else { 08151 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 08152 res = 0; 08153 } 08154 } 08155 } 08156 } 08157 /* Fall back */ 08158 if (res && !ast_strlen_zero(secret)) { 08159 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 08160 struct MD5Context md5; 08161 unsigned char digest[16]; 08162 char digres[128]; 08163 MD5Init(&md5); 08164 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 08165 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 08166 MD5Final(digest, &md5); 08167 /* If they support md5, authenticate with it. */ 08168 for (x=0;x<16;x++) 08169 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 08170 if (pvt) { 08171 build_encryption_keys(digest, pvt); 08172 } 08173 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 08174 res = 0; 08175 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 08176 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 08177 res = 0; 08178 } else 08179 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 08180 } 08181 return res; 08182 }
| 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 8188 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().
08189 { 08190 struct iax2_peer *peer = NULL; 08191 /* Start pessimistic */ 08192 int res = -1; 08193 int authmethods = 0; 08194 struct iax_ie_data ied; 08195 uint16_t callno = p->callno; 08196 08197 memset(&ied, 0, sizeof(ied)); 08198 08199 if (ies->username) 08200 ast_string_field_set(p, username, ies->username); 08201 if (ies->challenge) 08202 ast_string_field_set(p, challenge, ies->challenge); 08203 if (ies->authmethods) 08204 authmethods = ies->authmethods; 08205 if (authmethods & IAX_AUTH_MD5) 08206 merge_encryption(p, ies->encmethods); 08207 else 08208 p->encmethods = 0; 08209 08210 /* Check for override RSA authentication first */ 08211 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 08212 /* Normal password authentication */ 08213 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 08214 } else { 08215 struct ao2_iterator i = ao2_iterator_init(peers, 0); 08216 while ((peer = ao2_iterator_next(&i))) { 08217 struct sockaddr_in peer_addr; 08218 08219 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 08220 08221 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 08222 /* No peer specified at our end, or this is the peer */ 08223 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 08224 /* No username specified in peer rule, or this is the right username */ 08225 && (!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))) 08226 /* No specified host, or this is our host */ 08227 ) { 08228 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 08229 if (!res) { 08230 peer_unref(peer); 08231 break; 08232 } 08233 } 08234 peer_unref(peer); 08235 } 08236 ao2_iterator_destroy(&i); 08237 if (!peer) { 08238 /* We checked our list and didn't find one. It's unlikely, but possible, 08239 that we're trying to authenticate *to* a realtime peer */ 08240 const char *peer_name = ast_strdupa(p->peer); 08241 ast_mutex_unlock(&iaxsl[callno]); 08242 if ((peer = realtime_peer(peer_name, NULL))) { 08243 ast_mutex_lock(&iaxsl[callno]); 08244 if (!(p = iaxs[callno])) { 08245 peer_unref(peer); 08246 return -1; 08247 } 08248 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 08249 peer_unref(peer); 08250 } 08251 if (!peer) { 08252 ast_mutex_lock(&iaxsl[callno]); 08253 if (!(p = iaxs[callno])) 08254 return -1; 08255 } 08256 } 08257 } 08258 08259 if (ies->encmethods) { 08260 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 08261 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 08262 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n"); 08263 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 08264 } 08265 if (!res) { 08266 struct ast_datastore *variablestore; 08267 struct ast_variable *var, *prev = NULL; 08268 AST_LIST_HEAD(, ast_var_t) *varlist; 08269 varlist = ast_calloc(1, sizeof(*varlist)); 08270 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 08271 if (variablestore && varlist && p->owner) { 08272 variablestore->data = varlist; 08273 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 08274 AST_LIST_HEAD_INIT(varlist); 08275 for (var = ies->vars; var; var = var->next) { 08276 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 08277 if (prev) 08278 ast_free(prev); 08279 prev = var; 08280 if (!newvar) { 08281 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 08282 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08283 } else { 08284 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 08285 } 08286 } 08287 if (prev) 08288 ast_free(prev); 08289 ies->vars = NULL; 08290 ast_channel_datastore_add(p->owner, variablestore); 08291 } else { 08292 if (p->owner) 08293 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08294 if (variablestore) 08295 ast_datastore_free(variablestore); 08296 if (varlist) 08297 ast_free(varlist); 08298 } 08299 } 08300 08301 if (!res) 08302 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08303 return res; 08304 }
| static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7836 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().
07837 { 07838 struct iax_ie_data ied; 07839 int res = -1, authreq_restrict = 0; 07840 char challenge[10]; 07841 struct chan_iax2_pvt *p = iaxs[call_num]; 07842 07843 memset(&ied, 0, sizeof(ied)); 07844 07845 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07846 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07847 struct iax2_user *user, tmp_user = { 07848 .name = p->username, 07849 }; 07850 07851 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07852 if (user) { 07853 if (user->curauthreq == user->maxauthreq) 07854 authreq_restrict = 1; 07855 else 07856 user->curauthreq++; 07857 user = user_unref(user); 07858 } 07859 } 07860 07861 /* If the AUTHREQ limit test failed, send back an error */ 07862 if (authreq_restrict) { 07863 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07864 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07865 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07866 return 0; 07867 } 07868 07869 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07870 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07871 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07872 ast_string_field_set(p, challenge, challenge); 07873 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07874 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07875 } 07876 if (p->encmethods) 07877 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07878 07879 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07880 07881 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07882 07883 if (p->encmethods) 07884 ast_set_flag64(p, IAX_ENCRYPTED); 07885 07886 return res; 07887 }
| static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7889 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().
07890 { 07891 char requeststr[256]; 07892 char md5secret[256] = ""; 07893 char secret[256] = ""; 07894 char rsasecret[256] = ""; 07895 int res = -1; 07896 int x; 07897 struct iax2_user *user, tmp_user = { 07898 .name = p->username, 07899 }; 07900 07901 if (p->authrej) { 07902 return res; 07903 } 07904 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07905 if (user) { 07906 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07907 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07908 ast_clear_flag64(p, IAX_MAXAUTHREQ); 07909 } 07910 ast_string_field_set(p, host, user->name); 07911 user = user_unref(user); 07912 } 07913 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 07914 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n"); 07915 return res; 07916 } 07917 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07918 return res; 07919 if (ies->password) 07920 ast_copy_string(secret, ies->password, sizeof(secret)); 07921 if (ies->md5_result) 07922 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07923 if (ies->rsa_result) 07924 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07925 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07926 struct ast_key *key; 07927 char *keyn; 07928 char tmpkey[256]; 07929 char *stringp=NULL; 07930 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07931 stringp=tmpkey; 07932 keyn = strsep(&stringp, ":"); 07933 while(keyn) { 07934 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07935 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07936 res = 0; 07937 break; 07938 } else if (!key) 07939 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07940 keyn = strsep(&stringp, ":"); 07941 } 07942 } else if (p->authmethods & IAX_AUTH_MD5) { 07943 struct MD5Context md5; 07944 unsigned char digest[16]; 07945 char *tmppw, *stringp; 07946 07947 tmppw = ast_strdupa(p->secret); 07948 stringp = tmppw; 07949 while((tmppw = strsep(&stringp, ";"))) { 07950 MD5Init(&md5); 07951 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07952 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07953 MD5Final(digest, &md5); 07954 /* If they support md5, authenticate with it. */ 07955 for (x=0;x<16;x++) 07956 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07957 if (!strcasecmp(requeststr, md5secret)) { 07958 res = 0; 07959 break; 07960 } 07961 } 07962 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07963 if (!strcmp(secret, p->secret)) 07964 res = 0; 07965 } 07966 return res; 07967 }
| static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4688 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call().
04689 { 04690 #ifdef SCHED_MULTITHREADED 04691 if (schedule_action(__auto_congest, data)) 04692 #endif 04693 __auto_congest(data); 04694 return 0; 04695 }
| static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 9076 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().
09077 { 09078 int callno = (int)(long)(data); 09079 ast_mutex_lock(&iaxsl[callno]); 09080 if (iaxs[callno]) { 09081 iaxs[callno]->autoid = -1; 09082 } 09083 ast_mutex_unlock(&iaxsl[callno]); 09084 #ifdef SCHED_MULTITHREADED 09085 if (schedule_action(__auto_hangup, data)) 09086 #endif 09087 __auto_hangup(data); 09088 return 0; 09089 }
| static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2459 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().
02460 { 02461 struct addr_range *addr_range = NULL; 02462 struct addr_range tmp; 02463 struct ast_ha *ha; 02464 int limit; 02465 int error; 02466 int found; 02467 02468 for (; v; v = v->next) { 02469 limit = -1; 02470 error = 0; 02471 found = 0; 02472 ha = ast_append_ha("permit", v->name, NULL, &error); 02473 02474 /* check for valid config information */ 02475 if (error) { 02476 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02477 continue; 02478 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02479 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02480 ast_free_ha(ha); 02481 continue; 02482 } 02483 02484 ast_copy_ha(ha, &tmp.ha); 02485 /* find or create the addr_range */ 02486 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02487 ao2_lock(addr_range); 02488 found = 1; 02489 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02490 ast_free_ha(ha); 02491 return; /* out of memory */ 02492 } 02493 02494 /* copy over config data into addr_range object */ 02495 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02496 ast_free_ha(ha); /* cleanup the tmp ha */ 02497 addr_range->limit = limit; 02498 addr_range->delme = 0; 02499 02500 /* cleanup */ 02501 if (found) { 02502 ao2_unlock(addr_range); 02503 } else { 02504 ao2_link(callno_limits, addr_range); 02505 } 02506 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02507 } 02508 }
| static struct iax2_context* build_context | ( | const char * | context | ) | [static, read] |
Definition at line 12329 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), and iax2_context::context.
Referenced by build_user().
12330 { 12331 struct iax2_context *con; 12332 12333 if ((con = ast_calloc(1, sizeof(*con)))) 12334 ast_copy_string(con->context, context, sizeof(con->context)); 12335 12336 return con; 12337 }
| static void build_ecx_key | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 6217 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().
06218 { 06219 /* it is required to hold the corresponding decrypt key to our encrypt key 06220 * in the pvt struct because queued frames occasionally need to be decrypted and 06221 * re-encrypted when updated for a retransmission */ 06222 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 06223 ast_aes_set_encrypt_key(digest, &pvt->ecx); 06224 ast_aes_set_decrypt_key(digest, &pvt->mydcx); 06225 }
| static void build_encryption_keys | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 6211 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().
06212 { 06213 build_ecx_key(digest, pvt); 06214 ast_aes_set_decrypt_key(digest, &pvt->dcx); 06215 }
| 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 12478 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().
12479 { 12480 struct iax2_peer *peer = NULL; 12481 struct ast_ha *oldha = NULL; 12482 int maskfound = 0; 12483 int found = 0; 12484 int firstpass = 1; 12485 struct iax2_peer tmp_peer = { 12486 .name = name, 12487 }; 12488 12489 if (!temponly) { 12490 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 12491 if (peer && !ast_test_flag64(peer, IAX_DELME)) 12492 firstpass = 0; 12493 } 12494 12495 if (peer) { 12496 found++; 12497 if (firstpass) { 12498 oldha = peer->ha; 12499 peer->ha = NULL; 12500 } 12501 unlink_peer(peer); 12502 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 12503 peer->expire = -1; 12504 peer->pokeexpire = -1; 12505 peer->sockfd = defaultsockfd; 12506 peer->addr.ss.ss_family = AF_INET; 12507 peer->addr.len = sizeof(struct sockaddr_in); 12508 if (ast_string_field_init(peer, 32)) 12509 peer = peer_unref(peer); 12510 } 12511 12512 if (peer) { 12513 if (firstpass) { 12514 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12515 peer->encmethods = iax2_encryption; 12516 peer->adsi = adsi; 12517 ast_string_field_set(peer,secret,""); 12518 if (!found) { 12519 ast_string_field_set(peer, name, name); 12520 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12521 peer->expiry = min_reg_expire; 12522 } 12523 peer->prefs = prefs; 12524 peer->capability = iax2_capability; 12525 peer->smoothing = 0; 12526 peer->pokefreqok = DEFAULT_FREQ_OK; 12527 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 12528 peer->maxcallno = 0; 12529 peercnt_modify((unsigned char) 0, 0, &peer->addr); 12530 peer->calltoken_required = CALLTOKEN_DEFAULT; 12531 ast_string_field_set(peer,context,""); 12532 ast_string_field_set(peer,peercontext,""); 12533 ast_clear_flag64(peer, IAX_HASCALLERID); 12534 ast_string_field_set(peer, cid_name, ""); 12535 ast_string_field_set(peer, cid_num, ""); 12536 ast_string_field_set(peer, mohinterpret, mohinterpret); 12537 ast_string_field_set(peer, mohsuggest, mohsuggest); 12538 } 12539 12540 if (!v) { 12541 v = alt; 12542 alt = NULL; 12543 } 12544 while(v) { 12545 if (!strcasecmp(v->name, "secret")) { 12546 ast_string_field_set(peer, secret, v->value); 12547 } else if (!strcasecmp(v->name, "mailbox")) { 12548 ast_string_field_set(peer, mailbox, v->value); 12549 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12550 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12551 ast_string_field_set(peer, mailbox, name); 12552 } 12553 } else if (!strcasecmp(v->name, "mohinterpret")) { 12554 ast_string_field_set(peer, mohinterpret, v->value); 12555 } else if (!strcasecmp(v->name, "mohsuggest")) { 12556 ast_string_field_set(peer, mohsuggest, v->value); 12557 } else if (!strcasecmp(v->name, "dbsecret")) { 12558 ast_string_field_set(peer, dbsecret, v->value); 12559 } else if (!strcasecmp(v->name, "trunk")) { 12560 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12561 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12562 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12563 ast_clear_flag64(peer, IAX_TRUNK); 12564 } 12565 } else if (!strcasecmp(v->name, "auth")) { 12566 peer->authmethods = get_auth_methods(v->value); 12567 } else if (!strcasecmp(v->name, "encryption")) { 12568 peer->encmethods |= get_encrypt_methods(v->value); 12569 if (!peer->encmethods) { 12570 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12571 } 12572 } else if (!strcasecmp(v->name, "forceencryption")) { 12573 if (ast_false(v->value)) { 12574 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12575 } else { 12576 peer->encmethods |= get_encrypt_methods(v->value); 12577 if (peer->encmethods) { 12578 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12579 } 12580 } 12581 } else if (!strcasecmp(v->name, "transfer")) { 12582 if (!strcasecmp(v->value, "mediaonly")) { 12583 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12584 } else if (ast_true(v->value)) { 12585 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12586 } else 12587 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12588 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12589 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12590 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12591 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12592 } else if (!strcasecmp(v->name, "host")) { 12593 if (!strcasecmp(v->value, "dynamic")) { 12594 /* They'll register with us */ 12595 ast_set_flag64(peer, IAX_DYNAMIC); 12596 if (!found) { 12597 /* Initialize stuff iff we're not found, otherwise 12598 we keep going with what we had */ 12599 if (ast_sockaddr_port(&peer->addr)) { 12600 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr)); 12601 } 12602 ast_sockaddr_setnull(&peer->addr); 12603 } 12604 } else { 12605 /* Non-dynamic. Make sure we become that way if we're not */ 12606 ast_sched_thread_del(sched, peer->expire); 12607 ast_clear_flag64(peer, IAX_DYNAMIC); 12608 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12609 return peer_unref(peer); 12610 if (!ast_sockaddr_port(&peer->addr)) { 12611 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12612 } 12613 } 12614 if (!maskfound) 12615 inet_aton("255.255.255.255", &peer->mask); 12616 } else if (!strcasecmp(v->name, "defaultip")) { 12617 struct ast_sockaddr peer_defaddr_tmp; 12618 12619 peer_defaddr_tmp.ss.ss_family = AF_INET; 12620 if (ast_get_ip(&peer_defaddr_tmp, v->value)) { 12621 return peer_unref(peer); 12622 } 12623 ast_sockaddr_to_sin(&peer_defaddr_tmp, 12624 &peer->defaddr); 12625 } else if (!strcasecmp(v->name, "sourceaddress")) { 12626 peer_set_srcaddr(peer, v->value); 12627 } else if (!strcasecmp(v->name, "permit") || 12628 !strcasecmp(v->name, "deny")) { 12629 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12630 } else if (!strcasecmp(v->name, "mask")) { 12631 maskfound++; 12632 inet_aton(v->value, &peer->mask); 12633 } else if (!strcasecmp(v->name, "context")) { 12634 ast_string_field_set(peer, context, v->value); 12635 } else if (!strcasecmp(v->name, "regexten")) { 12636 ast_string_field_set(peer, regexten, v->value); 12637 } else if (!strcasecmp(v->name, "peercontext")) { 12638 ast_string_field_set(peer, peercontext, v->value); 12639 } else if (!strcasecmp(v->name, "port")) { 12640 if (ast_test_flag64(peer, IAX_DYNAMIC)) { 12641 peer->defaddr.sin_port = htons(atoi(v->value)); 12642 } else { 12643 ast_sockaddr_set_port(&peer->addr, atoi(v->value)); 12644 } 12645 } else if (!strcasecmp(v->name, "username")) { 12646 ast_string_field_set(peer, username, v->value); 12647 } else if (!strcasecmp(v->name, "allow")) { 12648 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12649 } else if (!strcasecmp(v->name, "disallow")) { 12650 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12651 } else if (!strcasecmp(v->name, "callerid")) { 12652 if (!ast_strlen_zero(v->value)) { 12653 char name2[80]; 12654 char num2[80]; 12655 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12656 ast_string_field_set(peer, cid_name, name2); 12657 ast_string_field_set(peer, cid_num, num2); 12658 } else { 12659 ast_string_field_set(peer, cid_name, ""); 12660 ast_string_field_set(peer, cid_num, ""); 12661 } 12662 ast_set_flag64(peer, IAX_HASCALLERID); 12663 } else if (!strcasecmp(v->name, "fullname")) { 12664 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12665 ast_set_flag64(peer, IAX_HASCALLERID); 12666 } else if (!strcasecmp(v->name, "cid_number")) { 12667 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12668 ast_set_flag64(peer, IAX_HASCALLERID); 12669 } else if (!strcasecmp(v->name, "sendani")) { 12670 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12671 } else if (!strcasecmp(v->name, "inkeys")) { 12672 ast_string_field_set(peer, inkeys, v->value); 12673 } else if (!strcasecmp(v->name, "outkey")) { 12674 ast_string_field_set(peer, outkey, v->value); 12675 } else if (!strcasecmp(v->name, "qualify")) { 12676 if (!strcasecmp(v->value, "no")) { 12677 peer->maxms = 0; 12678 } else if (!strcasecmp(v->value, "yes")) { 12679 peer->maxms = DEFAULT_MAXMS; 12680 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12681 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); 12682 peer->maxms = 0; 12683 } 12684 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12685 peer->smoothing = ast_true(v->value); 12686 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12687 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12688 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); 12689 } 12690 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12691 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12692 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); 12693 } 12694 } else if (!strcasecmp(v->name, "timezone")) { 12695 ast_string_field_set(peer, zonetag, v->value); 12696 } else if (!strcasecmp(v->name, "adsi")) { 12697 peer->adsi = ast_true(v->value); 12698 } else if (!strcasecmp(v->name, "connectedline")) { 12699 if (ast_true(v->value)) { 12700 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12701 } else if (!strcasecmp(v->value, "send")) { 12702 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12703 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12704 } else if (!strcasecmp(v->value, "receive")) { 12705 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12706 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12707 } else { 12708 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12709 } 12710 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12711 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12712 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12713 } else { 12714 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr); 12715 } 12716 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12717 /* default is required unless in optional ip list */ 12718 if (ast_false(v->value)) { 12719 peer->calltoken_required = CALLTOKEN_NO; 12720 } else if (!strcasecmp(v->value, "auto")) { 12721 peer->calltoken_required = CALLTOKEN_AUTO; 12722 } else if (ast_true(v->value)) { 12723 peer->calltoken_required = CALLTOKEN_YES; 12724 } else { 12725 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12726 } 12727 } /* else if (strcasecmp(v->name,"type")) */ 12728 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12729 v = v->next; 12730 if (!v) { 12731 v = alt; 12732 alt = NULL; 12733 } 12734 } 12735 if (!peer->authmethods) 12736 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12737 ast_clear_flag64(peer, IAX_DELME); 12738 } 12739 12740 if (oldha) 12741 ast_free_ha(oldha); 12742 12743 if (!ast_strlen_zero(peer->mailbox)) { 12744 char *mailbox, *context; 12745 context = mailbox = ast_strdupa(peer->mailbox); 12746 strsep(&context, "@"); 12747 if (ast_strlen_zero(context)) 12748 context = "default"; 12749 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12750 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12751 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12752 AST_EVENT_IE_END); 12753 } 12754 12755 return peer; 12756 }
| static void build_rand_pad | ( | unsigned char * | buf, | |
| ssize_t | len | |||
| ) | [static] |
Definition at line 6201 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
06202 { 06203 long tmp; 06204 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 06205 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 06206 buf += sizeof(tmp); 06207 len -= sizeof(tmp); 06208 } 06209 }
| 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 12772 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().
12773 { 12774 struct iax2_user *user = NULL; 12775 struct iax2_context *con, *conl = NULL; 12776 struct ast_ha *oldha = NULL; 12777 struct iax2_context *oldcon = NULL; 12778 int format; 12779 int firstpass=1; 12780 int oldcurauthreq = 0; 12781 char *varname = NULL, *varval = NULL; 12782 struct ast_variable *tmpvar = NULL; 12783 struct iax2_user tmp_user = { 12784 .name = name, 12785 }; 12786 12787 if (!temponly) { 12788 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12789 if (user && !ast_test_flag64(user, IAX_DELME)) 12790 firstpass = 0; 12791 } 12792 12793 if (user) { 12794 if (firstpass) { 12795 oldcurauthreq = user->curauthreq; 12796 oldha = user->ha; 12797 oldcon = user->contexts; 12798 user->ha = NULL; 12799 user->contexts = NULL; 12800 } 12801 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12802 ao2_unlink(users, user); 12803 } else { 12804 user = ao2_alloc(sizeof(*user), user_destructor); 12805 } 12806 12807 if (user) { 12808 if (firstpass) { 12809 ast_string_field_free_memory(user); 12810 memset(user, 0, sizeof(struct iax2_user)); 12811 if (ast_string_field_init(user, 32)) { 12812 user = user_unref(user); 12813 goto cleanup; 12814 } 12815 user->maxauthreq = maxauthreq; 12816 user->curauthreq = oldcurauthreq; 12817 user->prefs = prefs; 12818 user->capability = iax2_capability; 12819 user->encmethods = iax2_encryption; 12820 user->adsi = adsi; 12821 user->calltoken_required = CALLTOKEN_DEFAULT; 12822 ast_string_field_set(user, name, name); 12823 ast_string_field_set(user, language, language); 12824 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); 12825 ast_clear_flag64(user, IAX_HASCALLERID); 12826 ast_string_field_set(user, cid_name, ""); 12827 ast_string_field_set(user, cid_num, ""); 12828 ast_string_field_set(user, accountcode, accountcode); 12829 ast_string_field_set(user, mohinterpret, mohinterpret); 12830 ast_string_field_set(user, mohsuggest, mohsuggest); 12831 } 12832 if (!v) { 12833 v = alt; 12834 alt = NULL; 12835 } 12836 while(v) { 12837 if (!strcasecmp(v->name, "context")) { 12838 con = build_context(v->value); 12839 if (con) { 12840 if (conl) 12841 conl->next = con; 12842 else 12843 user->contexts = con; 12844 conl = con; 12845 } 12846 } else if (!strcasecmp(v->name, "permit") || 12847 !strcasecmp(v->name, "deny")) { 12848 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12849 } else if (!strcasecmp(v->name, "setvar")) { 12850 varname = ast_strdupa(v->value); 12851 if ((varval = strchr(varname, '='))) { 12852 *varval = '\0'; 12853 varval++; 12854 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12855 tmpvar->next = user->vars; 12856 user->vars = tmpvar; 12857 } 12858 } 12859 } else if (!strcasecmp(v->name, "allow")) { 12860 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12861 } else if (!strcasecmp(v->name, "disallow")) { 12862 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12863 } else if (!strcasecmp(v->name, "trunk")) { 12864 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 12865 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 12866 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12867 ast_clear_flag64(user, IAX_TRUNK); 12868 } 12869 } else if (!strcasecmp(v->name, "auth")) { 12870 user->authmethods = get_auth_methods(v->value); 12871 } else if (!strcasecmp(v->name, "encryption")) { 12872 user->encmethods |= get_encrypt_methods(v->value); 12873 if (!user->encmethods) { 12874 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12875 } 12876 } else if (!strcasecmp(v->name, "forceencryption")) { 12877 if (ast_false(v->value)) { 12878 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12879 } else { 12880 user->encmethods |= get_encrypt_methods(v->value); 12881 if (user->encmethods) { 12882 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 12883 } 12884 } 12885 } else if (!strcasecmp(v->name, "transfer")) { 12886 if (!strcasecmp(v->value, "mediaonly")) { 12887 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12888 } else if (ast_true(v->value)) { 12889 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12890 } else 12891 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12892 } else if (!strcasecmp(v->name, "codecpriority")) { 12893 if(!strcasecmp(v->value, "caller")) 12894 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 12895 else if(!strcasecmp(v->value, "disabled")) 12896 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12897 else if(!strcasecmp(v->value, "reqonly")) { 12898 ast_set_flag64(user, IAX_CODEC_NOCAP); 12899 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12900 } 12901 } else if (!strcasecmp(v->name, "immediate")) { 12902 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 12903 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12904 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 12905 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12906 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12907 } else if (!strcasecmp(v->name, "dbsecret")) { 12908 ast_string_field_set(user, dbsecret, v->value); 12909 } else if (!strcasecmp(v->name, "secret")) { 12910 if (!ast_strlen_zero(user->secret)) { 12911 char *old = ast_strdupa(user->secret); 12912 12913 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12914 } else 12915 ast_string_field_set(user, secret, v->value); 12916 } else if (!strcasecmp(v->name, "callerid")) { 12917 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12918 char name2[80]; 12919 char num2[80]; 12920 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12921 ast_string_field_set(user, cid_name, name2); 12922 ast_string_field_set(user, cid_num, num2); 12923 ast_set_flag64(user, IAX_HASCALLERID); 12924 } else { 12925 ast_clear_flag64(user, IAX_HASCALLERID); 12926 ast_string_field_set(user, cid_name, ""); 12927 ast_string_field_set(user, cid_num, ""); 12928 } 12929 } else if (!strcasecmp(v->name, "fullname")) { 12930 if (!ast_strlen_zero(v->value)) { 12931 ast_string_field_set(user, cid_name, v->value); 12932 ast_set_flag64(user, IAX_HASCALLERID); 12933 } else { 12934 ast_string_field_set(user, cid_name, ""); 12935 if (ast_strlen_zero(user->cid_num)) 12936 ast_clear_flag64(user, IAX_HASCALLERID); 12937 } 12938 } else if (!strcasecmp(v->name, "cid_number")) { 12939 if (!ast_strlen_zero(v->value)) { 12940 ast_string_field_set(user, cid_num, v->value); 12941 ast_set_flag64(user, IAX_HASCALLERID); 12942 } else { 12943 ast_string_field_set(user, cid_num, ""); 12944 if (ast_strlen_zero(user->cid_name)) 12945 ast_clear_flag64(user, IAX_HASCALLERID); 12946 } 12947 } else if (!strcasecmp(v->name, "accountcode")) { 12948 ast_string_field_set(user, accountcode, v->value); 12949 } else if (!strcasecmp(v->name, "mohinterpret")) { 12950 ast_string_field_set(user, mohinterpret, v->value); 12951 } else if (!strcasecmp(v->name, "mohsuggest")) { 12952 ast_string_field_set(user, mohsuggest, v->value); 12953 } else if (!strcasecmp(v->name, "parkinglot")) { 12954 ast_string_field_set(user, parkinglot, v->value); 12955 } else if (!strcasecmp(v->name, "language")) { 12956 ast_string_field_set(user, language, v->value); 12957 } else if (!strcasecmp(v->name, "amaflags")) { 12958 format = ast_cdr_amaflags2int(v->value); 12959 if (format < 0) { 12960 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12961 } else { 12962 user->amaflags = format; 12963 } 12964 } else if (!strcasecmp(v->name, "inkeys")) { 12965 ast_string_field_set(user, inkeys, v->value); 12966 } else if (!strcasecmp(v->name, "maxauthreq")) { 12967 user->maxauthreq = atoi(v->value); 12968 if (user->maxauthreq < 0) 12969 user->maxauthreq = 0; 12970 } else if (!strcasecmp(v->name, "adsi")) { 12971 user->adsi = ast_true(v->value); 12972 } else if (!strcasecmp(v->name, "connectedline")) { 12973 if (ast_true(v->value)) { 12974 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12975 } else if (!strcasecmp(v->value, "send")) { 12976 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 12977 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 12978 } else if (!strcasecmp(v->value, "receive")) { 12979 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 12980 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 12981 } else { 12982 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12983 } 12984 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12985 /* default is required unless in optional ip list */ 12986 if (ast_false(v->value)) { 12987 user->calltoken_required = CALLTOKEN_NO; 12988 } else if (!strcasecmp(v->value, "auto")) { 12989 user->calltoken_required = CALLTOKEN_AUTO; 12990 } else if (ast_true(v->value)) { 12991 user->calltoken_required = CALLTOKEN_YES; 12992 } else { 12993 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12994 } 12995 } /* else if (strcasecmp(v->name,"type")) */ 12996 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12997 v = v->next; 12998 if (!v) { 12999 v = alt; 13000 alt = NULL; 13001 } 13002 } 13003 if (!user->authmethods) { 13004 if (!ast_strlen_zero(user->secret)) { 13005 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 13006 if (!ast_strlen_zero(user->inkeys)) 13007 user->authmethods |= IAX_AUTH_RSA; 13008 } else if (!ast_strlen_zero(user->inkeys)) { 13009 user->authmethods = IAX_AUTH_RSA; 13010 } else { 13011 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 13012 } 13013 } 13014 ast_clear_flag64(user, IAX_DELME); 13015 } 13016 cleanup: 13017 if (oldha) 13018 ast_free_ha(oldha); 13019 if (oldcon) 13020 free_context(oldcon); 13021 return user; 13022 }
| static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13669 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().
13670 { 13671 struct sockaddr_in sin; 13672 int x; 13673 int callno; 13674 struct iax_ie_data ied; 13675 struct create_addr_info cai; 13676 struct parsed_dial_string pds; 13677 char *tmpstr; 13678 13679 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13680 /* Look for an *exact match* call. Once a call is negotiated, it can only 13681 look up entries for a single context */ 13682 if (!ast_mutex_trylock(&iaxsl[x])) { 13683 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13684 return x; 13685 ast_mutex_unlock(&iaxsl[x]); 13686 } 13687 } 13688 13689 /* No match found, we need to create a new one */ 13690 13691 memset(&cai, 0, sizeof(cai)); 13692 memset(&ied, 0, sizeof(ied)); 13693 memset(&pds, 0, sizeof(pds)); 13694 13695 tmpstr = ast_strdupa(data); 13696 parse_dial_string(tmpstr, &pds); 13697 13698 if (ast_strlen_zero(pds.peer)) { 13699 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13700 return -1; 13701 } 13702 13703 /* Populate our address from the given */ 13704 if (create_addr(pds.peer, NULL, &sin, &cai)) 13705 return -1; 13706 13707 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13708 pds.peer, pds.username, pds.password, pds.context); 13709 13710 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13711 if (callno < 1) { 13712 ast_log(LOG_WARNING, "Unable to create call\n"); 13713 return -1; 13714 } 13715 13716 ast_string_field_set(iaxs[callno], dproot, data); 13717 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13718 13719 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13720 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13721 /* the string format is slightly different from a standard dial string, 13722 because the context appears in the 'exten' position 13723 */ 13724 if (pds.exten) 13725 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13726 if (pds.username) 13727 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13728 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13729 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13730 /* Keep password handy */ 13731 if (pds.password) 13732 ast_string_field_set(iaxs[callno], secret, pds.password); 13733 if (pds.key) 13734 ast_string_field_set(iaxs[callno], outkey, pds.key); 13735 /* Start the call going */ 13736 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13737 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13738 13739 return callno; 13740 }
| static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | offset | |||
| ) | [static] |
Definition at line 6054 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().
06055 { 06056 /* Returns where in "receive time" we are. That is, how many ms 06057 since we received (or would have received) the frame with timestamp 0 */ 06058 int ms; 06059 #ifdef IAXTESTS 06060 int jit; 06061 #endif /* IAXTESTS */ 06062 /* Setup rxcore if necessary */ 06063 if (ast_tvzero(p->rxcore)) { 06064 p->rxcore = ast_tvnow(); 06065 if (iaxdebug) 06066 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 06067 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 06068 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 06069 #if 1 06070 if (iaxdebug) 06071 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 06072 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 06073 #endif 06074 } 06075 06076 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 06077 #ifdef IAXTESTS 06078 if (test_jit) { 06079 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 06080 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 06081 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 06082 jit = -jit; 06083 ms += jit; 06084 } 06085 } 06086 if (test_late) { 06087 ms += test_late; 06088 test_late = 0; 06089 } 06090 #endif /* IAXTESTS */ 06091 return ms; 06092 }
| static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | ts, | |||
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 5922 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().
05923 { 05924 int ms; 05925 int voice = 0; 05926 int genuine = 0; 05927 int adjust; 05928 int rate = ast_format_rate(f->subclass.codec) / 1000; 05929 struct timeval *delivery = NULL; 05930 05931 05932 /* What sort of frame do we have?: voice is self-explanatory 05933 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05934 non-genuine frames are CONTROL frames [ringing etc], DTMF 05935 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05936 the others need a timestamp slaved to the voice frames so that they go in sequence 05937 */ 05938 if (f->frametype == AST_FRAME_VOICE) { 05939 voice = 1; 05940 delivery = &f->delivery; 05941 } else if (f->frametype == AST_FRAME_IAX) { 05942 genuine = 1; 05943 } else if (f->frametype == AST_FRAME_CNG) { 05944 p->notsilenttx = 0; 05945 } 05946 05947 if (ast_tvzero(p->offset)) { 05948 p->offset = ast_tvnow(); 05949 /* Round to nearest 20ms for nice looking traces */ 05950 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05951 } 05952 /* If the timestamp is specified, just send it as is */ 05953 if (ts) 05954 return ts; 05955 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05956 if (delivery && !ast_tvzero(*delivery)) { 05957 ms = ast_tvdiff_ms(*delivery, p->offset); 05958 if (ms < 0) { 05959 ms = 0; 05960 } 05961 if (iaxdebug) 05962 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05963 } else { 05964 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05965 if (ms < 0) 05966 ms = 0; 05967 if (voice) { 05968 /* On a voice frame, use predicted values if appropriate */ 05969 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05970 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05971 /* AN EXPLANATION: 05972 When we send voice, we usually send "calculated" timestamps worked out 05973 on the basis of the number of samples sent. When we send other frames, 05974 we usually send timestamps worked out from the real clock. 05975 The problem is that they can tend to drift out of step because the 05976 source channel's clock and our clock may not be exactly at the same rate. 05977 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05978 for this call. Moving it adjusts timestamps for non-voice frames. 05979 We make the adjustment in the style of a moving average. Each time we 05980 adjust p->offset by 10% of the difference between our clock-derived 05981 timestamp and the predicted timestamp. That's why you see "10000" 05982 below even though IAX2 timestamps are in milliseconds. 05983 The use of a moving average avoids offset moving too radically. 05984 Generally, "adjust" roams back and forth around 0, with offset hardly 05985 changing at all. But if a consistent different starts to develop it 05986 will be eliminated over the course of 10 frames (200-300msecs) 05987 */ 05988 adjust = (ms - p->nextpred); 05989 if (adjust < 0) 05990 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05991 else if (adjust > 0) 05992 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05993 05994 if (!p->nextpred) { 05995 p->nextpred = ms; /*f->samples / rate;*/ 05996 if (p->nextpred <= p->lastsent) 05997 p->nextpred = p->lastsent + 3; 05998 } 05999 ms = p->nextpred; 06000 } else { 06001 /* in this case, just use the actual 06002 * time, since we're either way off 06003 * (shouldn't happen), or we're ending a 06004 * silent period -- and seed the next 06005 * predicted time. Also, round ms to the 06006 * next multiple of frame size (so our 06007 * silent periods are multiples of 06008 * frame size too) */ 06009 06010 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 06011 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 06012 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 06013 06014 if (f->samples >= rate) /* check to make sure we don't core dump */ 06015 { 06016 int diff = ms % (f->samples / rate); 06017 if (diff) 06018 ms += f->samples/rate - diff; 06019 } 06020 06021 p->nextpred = ms; 06022 p->notsilenttx = 1; 06023 } 06024 } else if ( f->frametype == AST_FRAME_VIDEO ) { 06025 /* 06026 * IAX2 draft 03 says that timestamps MUST be in order. 06027 * It does not say anything about several frames having the same timestamp 06028 * When transporting video, we can have a frame that spans multiple iax packets 06029 * (so called slices), so it would make sense to use the same timestamp for all of 06030 * them 06031 * We do want to make sure that frames don't go backwards though 06032 */ 06033 if ( (unsigned int)ms < p->lastsent ) 06034 ms = p->lastsent; 06035 } else { 06036 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 06037 it's a genuine frame */ 06038 if (genuine) { 06039 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 06040 if (ms <= p->lastsent) 06041 ms = p->lastsent + 3; 06042 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 06043 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 06044 ms = p->lastsent + 3; 06045 } 06046 } 06047 } 06048 p->lastsent = ms; 06049 if (voice) 06050 p->nextpred = p->nextpred + f->samples / rate; 06051 return ms; 06052 }
| static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
| int | sampms, | |||
| struct timeval * | now | |||
| ) | [static] |
Definition at line 5878 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().
05879 { 05880 unsigned long int mssincetx; /* unsigned to handle overflows */ 05881 long int ms, pred; 05882 05883 tpeer->trunkact = *now; 05884 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05885 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05886 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05887 tpeer->txtrunktime = *now; 05888 tpeer->lastsent = 999999; 05889 } 05890 /* Update last transmit time now */ 05891 tpeer->lasttxtime = *now; 05892 05893 /* Calculate ms offset */ 05894 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05895 /* Predict from last value */ 05896 pred = tpeer->lastsent + sampms; 05897 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05898 ms = pred; 05899 05900 /* We never send the same timestamp twice, so fudge a little if we must */ 05901 if (ms == tpeer->lastsent) 05902 ms = tpeer->lastsent + 1; 05903 tpeer->lastsent = ms; 05904 return ms; 05905 }
| static int callno_hash | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2682 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02683 { 02684 return abs(ast_random()); 02685 }
| static int calltoken_required | ( | struct sockaddr_in * | sin, | |
| const char * | name, | |||
| int | subclass | |||
| ) | [static] |
Definition at line 2206 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().
02207 { 02208 struct addr_range *addr_range; 02209 struct iax2_peer *peer = NULL; 02210 struct iax2_user *user = NULL; 02211 /* if no username is given, check for guest accounts */ 02212 const char *find = S_OR(name, "guest"); 02213 int res = 1; /* required by default */ 02214 int optional = 0; 02215 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 02216 /* There are only two cases in which calltoken validation is not required. 02217 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 02218 * the peer definition has not set the requirecalltoken option. 02219 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 02220 */ 02221 02222 /* ----- Case 1 ----- */ 02223 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 02224 ao2_ref(addr_range, -1); 02225 optional = 1; 02226 } 02227 02228 /* ----- Case 2 ----- */ 02229 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 02230 calltoken_required = user->calltoken_required; 02231 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 02232 calltoken_required = user->calltoken_required; 02233 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 02234 calltoken_required = peer->calltoken_required; 02235 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 02236 calltoken_required = peer->calltoken_required; 02237 } 02238 02239 if (peer) { 02240 peer_unref(peer); 02241 } 02242 if (user) { 02243 user_unref(user); 02244 } 02245 02246 ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required); 02247 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 02248 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 02249 res = 0; 02250 } 02251 02252 return res; 02253 }
| static int check_access | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7568 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().
07569 { 07570 /* Start pessimistic */ 07571 int res = -1; 07572 int version = 2; 07573 struct iax2_user *user = NULL, *best = NULL; 07574 int bestscore = 0; 07575 int gotcapability = 0; 07576 struct ast_variable *v = NULL, *tmpvar = NULL; 07577 struct ao2_iterator i; 07578 struct ast_sockaddr addr; 07579 07580 if (!iaxs[callno]) 07581 return res; 07582 if (ies->called_number) 07583 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07584 if (ies->calling_number) { 07585 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07586 ast_shrink_phone_number(ies->calling_number); 07587 } 07588 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07589 } 07590 if (ies->calling_name) 07591 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07592 if (ies->calling_ani) 07593 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07594 if (ies->dnid) 07595 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07596 if (ies->rdnis) 07597 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07598 if (ies->called_context) 07599 ast_string_field_set(iaxs[callno], context, ies->called_context); 07600 if (ies->language) 07601 ast_string_field_set(iaxs[callno], language, ies->language); 07602 if (ies->username) 07603 ast_string_field_set(iaxs[callno], username, ies->username); 07604 if (ies->calling_ton > -1) 07605 iaxs[callno]->calling_ton = ies->calling_ton; 07606 if (ies->calling_tns > -1) 07607 iaxs[callno]->calling_tns = ies->calling_tns; 07608 if (ies->calling_pres > -1) 07609 iaxs[callno]->calling_pres = ies->calling_pres; 07610 if (ies->format) 07611 iaxs[callno]->peerformat = ies->format; 07612 if (ies->adsicpe) 07613 iaxs[callno]->peeradsicpe = ies->adsicpe; 07614 if (ies->capability) { 07615 gotcapability = 1; 07616 iaxs[callno]->peercapability = ies->capability; 07617 } 07618 if (ies->version) 07619 version = ies->version; 07620 07621 /* Use provided preferences until told otherwise for actual preferences */ 07622 if (ies->codec_prefs) { 07623 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07624 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07625 } 07626 07627 if (!gotcapability) 07628 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07629 if (version > IAX_PROTO_VERSION) { 07630 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07631 ast_inet_ntoa(sin->sin_addr), version); 07632 return res; 07633 } 07634 /* Search the userlist for a compatible entry, and fill in the rest */ 07635 ast_sockaddr_from_sin(&addr, sin); 07636 i = ao2_iterator_init(users, 0); 07637 while ((user = ao2_iterator_next(&i))) { 07638 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07639 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07640 && ast_apply_ha(user->ha, &addr) == AST_SENSE_ALLOW /* Access is permitted from this IP */ 07641 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07642 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07643 if (!ast_strlen_zero(iaxs[callno]->username)) { 07644 /* Exact match, stop right now. */ 07645 if (best) 07646 user_unref(best); 07647 best = user; 07648 break; 07649 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07650 /* No required authentication */ 07651 if (user->ha) { 07652 /* There was host authentication and we passed, bonus! */ 07653 if (bestscore < 4) { 07654 bestscore = 4; 07655 if (best) 07656 user_unref(best); 07657 best = user; 07658 continue; 07659 } 07660 } else { 07661 /* No host access, but no secret, either, not bad */ 07662 if (bestscore < 3) { 07663 bestscore = 3; 07664 if (best) 07665 user_unref(best); 07666 best = user; 07667 continue; 07668 } 07669 } 07670 } else { 07671 if (user->ha) { 07672 /* Authentication, but host access too, eh, it's something.. */ 07673 if (bestscore < 2) { 07674 bestscore = 2; 07675 if (best) 07676 user_unref(best); 07677 best = user; 07678 continue; 07679 } 07680 } else { 07681 /* Authentication and no host access... This is our baseline */ 07682 if (bestscore < 1) { 07683 bestscore = 1; 07684 if (best) 07685 user_unref(best); 07686 best = user; 07687 continue; 07688 } 07689 } 07690 } 07691 } 07692 user_unref(user); 07693 } 07694 ao2_iterator_destroy(&i); 07695 user = best; 07696 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07697 user = realtime_user(iaxs[callno]->username, sin); 07698 if (user && (ast_apply_ha(user->ha, &addr) == AST_SENSE_DENY /* Access is denied from this IP */ 07699 || (!ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07700 !apply_context(user->contexts, iaxs[callno]->context)))) { /* Context is permitted */ 07701 user = user_unref(user); 07702 } 07703 } 07704 if (user) { 07705 /* We found our match (use the first) */ 07706 /* copy vars */ 07707 for (v = user->vars ; v ; v = v->next) { 07708 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07709 tmpvar->next = iaxs[callno]->vars; 07710 iaxs[callno]->vars = tmpvar; 07711 } 07712 } 07713 /* If a max AUTHREQ restriction is in place, activate it */ 07714 if (user->maxauthreq > 0) 07715 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07716 iaxs[callno]->prefs = user->prefs; 07717 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07718 iaxs[callno]->encmethods = user->encmethods; 07719 /* Store the requested username if not specified */ 07720 if (ast_strlen_zero(iaxs[callno]->username)) 07721 ast_string_field_set(iaxs[callno], username, user->name); 07722 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07723 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07724 iaxs[callno]->capability = user->capability; 07725 /* And use the default context */ 07726 if (ast_strlen_zero(iaxs[callno]->context)) { 07727 if (user->contexts) 07728 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07729 else 07730 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07731 } 07732 /* And any input keys */ 07733 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07734 /* And the permitted authentication methods */ 07735 iaxs[callno]->authmethods = user->authmethods; 07736 iaxs[callno]->adsi = user->adsi; 07737 /* If the user has callerid, override the remote caller id. */ 07738 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07739 iaxs[callno]->calling_tns = 0; 07740 iaxs[callno]->calling_ton = 0; 07741 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07742 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07743 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07744 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07745 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07746 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07747 } /* else user is allowed to set their own CID settings */ 07748 if (!ast_strlen_zero(user->accountcode)) 07749 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07750 if (!ast_strlen_zero(user->mohinterpret)) 07751 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07752 if (!ast_strlen_zero(user->mohsuggest)) 07753 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07754 if (!ast_strlen_zero(user->parkinglot)) 07755 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07756 if (user->amaflags) 07757 iaxs[callno]->amaflags = user->amaflags; 07758 if (!ast_strlen_zero(user->language)) 07759 ast_string_field_set(iaxs[callno], language, user->language); 07760 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07761 /* Keep this check last */ 07762 if (!ast_strlen_zero(user->dbsecret)) { 07763 char *family, *key=NULL; 07764 char buf[80]; 07765 family = ast_strdupa(user->dbsecret); 07766 key = strchr(family, '/'); 07767 if (key) { 07768 *key = '\0'; 07769 key++; 07770 } 07771 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07772 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07773 else 07774 ast_string_field_set(iaxs[callno], secret, buf); 07775 } else 07776 ast_string_field_set(iaxs[callno], secret, user->secret); 07777 res = 0; 07778 user = user_unref(user); 07779 } else { 07780 /* user was not found, but we should still fake an AUTHREQ. 07781 * Set authmethods to the last known authmethod used by the system 07782 * Set a fake secret, it's not looked at, just required to attempt authentication. 07783 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07784 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07785 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07786 iaxs[callno]->authrej = 1; 07787 if (!ast_strlen_zero(iaxs[callno]->username)) { 07788 /* only send the AUTHREQ if a username was specified. */ 07789 res = 0; 07790 } 07791 } 07792 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07793 return res; 07794 }
| static int check_provisioning | ( | struct sockaddr_in * | sin, | |
| int | sockfd, | |||
| char * | si, | |||
| unsigned int | ver | |||
| ) | [static] |
Definition at line 9446 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09447 { 09448 unsigned int ourver; 09449 char rsi[80]; 09450 snprintf(rsi, sizeof(rsi), "si-%s", si); 09451 if (iax_provision_version(&ourver, rsi, 1)) 09452 return 0; 09453 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09454 if (ourver != ver) 09455 iax2_provision(sin, sockfd, NULL, rsi, 1); 09456 return 0; 09457 }
| static int check_srcaddr | ( | struct sockaddr * | sa, | |
| socklen_t | salen | |||
| ) | [static] |
Check if address can be used as packet source.
Definition at line 12355 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
12356 { 12357 int sd; 12358 int res; 12359 12360 sd = socket(AF_INET, SOCK_DGRAM, 0); 12361 if (sd < 0) { 12362 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 12363 return -1; 12364 } 12365 12366 res = bind(sd, sa, salen); 12367 if (res < 0) { 12368 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 12369 close(sd); 12370 return 1; 12371 } 12372 12373 close(sd); 12374 return 0; 12375 }
| static void cleanup_thread_list | ( | void * | head | ) | [static] |
Definition at line 14408 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().
14409 { 14410 AST_LIST_HEAD(iax2_thread_list, iax2_thread); 14411 struct iax2_thread_list *list_head = head; 14412 struct iax2_thread *thread; 14413 14414 AST_LIST_LOCK(list_head); 14415 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) { 14416 pthread_t thread_id = thread->threadid; 14417 14418 thread->stop = 1; 14419 signal_condition(&thread->lock, &thread->cond); 14420 14421 AST_LIST_UNLOCK(list_head); 14422 pthread_join(thread_id, NULL); 14423 AST_LIST_LOCK(list_head); 14424 } 14425 AST_LIST_UNLOCK(list_head); 14426 }
| static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8358 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().
08359 { 08360 char exten[256] = ""; 08361 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08362 struct iax2_dpcache *dp = NULL; 08363 08364 if (ies->called_number) 08365 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08366 08367 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08368 status = CACHE_FLAG_EXISTS; 08369 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08370 status = CACHE_FLAG_CANEXIST; 08371 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08372 status = CACHE_FLAG_NONEXISTENT; 08373 08374 if (ies->refresh) 08375 expiry = ies->refresh; 08376 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08377 matchmore = CACHE_FLAG_MATCHMORE; 08378 08379 AST_LIST_LOCK(&dpcache); 08380 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08381 if (strcmp(dp->exten, exten)) 08382 continue; 08383 AST_LIST_REMOVE_CURRENT(peer_list); 08384 dp->callno = 0; 08385 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08386 if (dp->flags & CACHE_FLAG_PENDING) { 08387 dp->flags &= ~CACHE_FLAG_PENDING; 08388 dp->flags |= status; 08389 dp->flags |= matchmore; 08390 } 08391 /* Wake up waiters */ 08392 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08393 if (dp->waiters[x] > -1) { 08394 if (write(dp->waiters[x], "asdf", 4) < 0) { 08395 } 08396 } 08397 } 08398 } 08399 AST_LIST_TRAVERSE_SAFE_END; 08400 AST_LIST_UNLOCK(&dpcache); 08401 08402 return 0; 08403 }
| static char * complete_iax2_peers | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state, | |||
| uint64_t | flags | |||
| ) | [static] |
Definition at line 3835 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().
03836 { 03837 int which = 0; 03838 struct iax2_peer *peer; 03839 char *res = NULL; 03840 int wordlen = strlen(word); 03841 struct ao2_iterator i; 03842 03843 i = ao2_iterator_init(peers, 0); 03844 while ((peer = ao2_iterator_next(&i))) { 03845 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03846 && (!flags || ast_test_flag64(peer, flags))) { 03847 res = ast_strdup(peer->name); 03848 peer_unref(peer); 03849 break; 03850 } 03851 peer_unref(peer); 03852 } 03853 ao2_iterator_destroy(&i); 03854 03855 return res; 03856 }
| static char * complete_iax2_unregister | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 6921 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().
06922 { 06923 int which = 0; 06924 struct iax2_peer *p = NULL; 06925 char *res = NULL; 06926 int wordlen = strlen(word); 06927 06928 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06929 if (pos == 2) { 06930 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06931 while ((p = ao2_iterator_next(&i))) { 06932 if (!strncasecmp(p->name, word, wordlen) && 06933 ++which > state && p->expire > 0) { 06934 res = ast_strdup(p->name); 06935 peer_unref(p); 06936 break; 06937 } 06938 peer_unref(p); 06939 } 06940 ao2_iterator_destroy(&i); 06941 } 06942 06943 return res; 06944 }
| static int complete_transfer | ( | int | callno, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8405 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().
08406 { 08407 int peercallno = 0; 08408 struct chan_iax2_pvt *pvt = iaxs[callno]; 08409 struct iax_frame *cur; 08410 jb_frame frame; 08411 08412 if (ies->callno) 08413 peercallno = ies->callno; 08414 08415 if (peercallno < 1) { 08416 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08417 return -1; 08418 } 08419 remove_by_transfercallno(pvt); 08420 /* since a transfer has taken place, the address will change. 08421 * This must be accounted for in the peercnts table. Remove 08422 * the old address and add the new one */ 08423 peercnt_remove_by_addr(&pvt->addr); 08424 peercnt_add(&pvt->transfer); 08425 /* now copy over the new address */ 08426 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08427 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08428 /* Reset sequence numbers */ 08429 pvt->oseqno = 0; 08430 pvt->rseqno = 0; 08431 pvt->iseqno = 0; 08432 pvt->aseqno = 0; 08433 08434 if (pvt->peercallno) { 08435 remove_by_peercallno(pvt); 08436 } 08437 pvt->peercallno = peercallno; 08438 /*this is where the transfering call swiches hash tables */ 08439 store_by_peercallno(pvt); 08440 pvt->transferring = TRANSFER_NONE; 08441 pvt->svoiceformat = -1; 08442 pvt->voiceformat = 0; 08443 pvt->svideoformat = -1; 08444 pvt->videoformat = 0; 08445 pvt->transfercallno = 0; 08446 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08447 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08448 /* reset jitterbuffer */ 08449 while(jb_getall(pvt->jb,&frame) == JB_OK) 08450 iax2_frame_free(frame.data); 08451 jb_reset(pvt->jb); 08452 pvt->lag = 0; 08453 pvt->last = 0; 08454 pvt->lastsent = 0; 08455 pvt->nextpred = 0; 08456 pvt->pingtime = DEFAULT_RETRY_TIME; 08457 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08458 /* We must cancel any packets that would have been transmitted 08459 because now we're talking to someone new. It's okay, they 08460 were transmitted to someone that didn't care anyway. */ 08461 cur->retries = -1; 08462 } 08463 return 0; 08464 }
| static unsigned char compress_subclass | ( | format_t | subclass | ) | [static] |
Definition at line 1608 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().
01609 { 01610 int x; 01611 int power=-1; 01612 /* If it's 64 or smaller, just return it */ 01613 if (subclass < IAX_FLAG_SC_LOG) 01614 return subclass; 01615 /* Otherwise find its power */ 01616 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01617 if (subclass & (1LL << x)) { 01618 if (power > -1) { 01619 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass); 01620 return 0; 01621 } else 01622 power = x; 01623 } 01624 } 01625 return power | IAX_FLAG_SC_LOG; 01626 }
| static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | iep | |||
| ) | [static] |
Definition at line 9459 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().
09460 { 09461 jb_info stats; 09462 jb_getinfo(pvt->jb, &stats); 09463 09464 memset(iep, 0, sizeof(*iep)); 09465 09466 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09467 if(stats.frames_in == 0) stats.frames_in = 1; 09468 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09469 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09470 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09471 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09472 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09473 }
| static int create_addr | ( | const char * | peername, | |
| struct ast_channel * | c, | |||
| struct sockaddr_in * | sin, | |||
| struct create_addr_info * | cai | |||
| ) | [static] |
Definition at line 4574 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().
04575 { 04576 struct iax2_peer *peer; 04577 int res = -1; 04578 struct ast_codec_pref ourprefs; 04579 struct sockaddr_in peer_addr; 04580 04581 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04582 cai->sockfd = defaultsockfd; 04583 cai->maxtime = 0; 04584 sin->sin_family = AF_INET; 04585 04586 if (!(peer = find_peer(peername, 1))) { 04587 struct ast_sockaddr sin_tmp; 04588 04589 cai->found = 0; 04590 sin_tmp.ss.ss_family = AF_INET; 04591 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) { 04592 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04593 return -1; 04594 } 04595 ast_sockaddr_to_sin(&sin_tmp, sin); 04596 if (sin->sin_port == 0) { 04597 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04598 } 04599 /* use global iax prefs for unknown peer/user */ 04600 /* But move the calling channel's native codec to the top of the preference list */ 04601 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04602 if (c) 04603 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04604 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04605 return 0; 04606 } 04607 04608 cai->found = 1; 04609 04610 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 04611 04612 /* if the peer has no address (current or default), return failure */ 04613 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 04614 goto return_unref; 04615 } 04616 04617 /* if the peer is being monitored and is currently unreachable, return failure */ 04618 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04619 goto return_unref; 04620 04621 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04622 cai->maxtime = peer->maxms; 04623 cai->capability = peer->capability; 04624 cai->encmethods = peer->encmethods; 04625 cai->sockfd = peer->sockfd; 04626 cai->adsi = peer->adsi; 04627 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04628 /* Move the calling channel's native codec to the top of the preference list */ 04629 if (c) { 04630 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats); 04631 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04632 } 04633 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04634 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04635 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04636 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04637 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04638 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04639 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04640 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04641 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04642 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04643 if (ast_strlen_zero(peer->dbsecret)) { 04644 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04645 } else { 04646 char *family; 04647 char *key = NULL; 04648 04649 family = ast_strdupa(peer->dbsecret); 04650 key = strchr(family, '/'); 04651 if (key) 04652 *key++ = '\0'; 04653 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04654 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04655 goto return_unref; 04656 } 04657 } 04658 04659 if (peer_addr.sin_addr.s_addr) { 04660 sin->sin_addr = peer_addr.sin_addr; 04661 sin->sin_port = peer_addr.sin_port; 04662 } else { 04663 sin->sin_addr = peer->defaddr.sin_addr; 04664 sin->sin_port = peer->defaddr.sin_port; 04665 } 04666 04667 res = 0; 04668 04669 return_unref: 04670 peer_unref(peer); 04671 04672 return res; 04673 }
| static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2687 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().
02688 { 02689 uint16_t i; 02690 02691 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02692 return -1; 02693 } 02694 02695 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02696 return -1; 02697 } 02698 02699 /* start at 2, 0 and 1 are reserved */ 02700 for (i = 2; i < IAX_MAX_CALLS; i++) { 02701 struct callno_entry *callno_entry; 02702 02703 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02704 return -1; 02705 } 02706 02707 callno_entry->callno = i; 02708 02709 if (i < TRUNK_CALL_START) { 02710 ao2_link(callno_pool, callno_entry); 02711 } else { 02712 ao2_link(callno_pool_trunk, callno_entry); 02713 } 02714 02715 ao2_ref(callno_entry, -1); 02716 } 02717 02718 return 0; 02719 }
| 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 6275 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().
06276 { 06277 int padding; 06278 unsigned char *workspace; 06279 06280 workspace = ast_alloca(*datalen); 06281 memset(f, 0, sizeof(*f)); 06282 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06283 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06284 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06285 return -1; 06286 /* Decrypt */ 06287 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06288 06289 padding = 16 + (workspace[15] & 0x0f); 06290 if (iaxdebug) 06291 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 06292 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06293 return -1; 06294 06295 *datalen -= padding; 06296 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06297 f->frametype = fh->type; 06298 if (f->frametype == AST_FRAME_VIDEO) { 06299 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06300 } else if (f->frametype == AST_FRAME_VOICE) { 06301 f->subclass.codec = uncompress_subclass(fh->csub); 06302 } else { 06303 f->subclass.integer = uncompress_subclass(fh->csub); 06304 } 06305 } else { 06306 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06307 if (iaxdebug) 06308 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06309 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06310 return -1; 06311 /* Decrypt */ 06312 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06313 padding = 16 + (workspace[15] & 0x0f); 06314 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06315 return -1; 06316 *datalen -= padding; 06317 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06318 } 06319 return 0; 06320 }
| static int decrypt_frame | ( | int | callno, | |
| struct ast_iax2_full_hdr * | fh, | |||
| struct ast_frame * | f, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6361 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().
06362 { 06363 int res=-1; 06364 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06365 /* Search for possible keys, given secrets */ 06366 struct MD5Context md5; 06367 unsigned char digest[16]; 06368 char *tmppw, *stringp; 06369 06370 tmppw = ast_strdupa(iaxs[callno]->secret); 06371 stringp = tmppw; 06372 while ((tmppw = strsep(&stringp, ";"))) { 06373 MD5Init(&md5); 06374 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06375 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06376 MD5Final(digest, &md5); 06377 build_encryption_keys(digest, iaxs[callno]); 06378 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06379 if (!res) { 06380 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06381 break; 06382 } 06383 } 06384 } else 06385 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06386 return res; 06387 }
| 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 9606 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().
09607 { 09608 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09609 struct ast_iax2_full_hdr *fh, *cur_fh; 09610 09611 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09612 return; 09613 09614 pkt_buf->len = from_here->buf_len; 09615 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09616 09617 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09618 ast_mutex_lock(&to_here->lock); 09619 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09620 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09621 if (fh->oseqno < cur_fh->oseqno) { 09622 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09623 break; 09624 } 09625 } 09626 AST_LIST_TRAVERSE_SAFE_END 09627 09628 if (!cur_pkt_buf) 09629 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09630 09631 to_here->iostate = IAX_IOSTATE_READY; 09632 ast_cond_signal(&to_here->cond); 09633 09634 ast_mutex_unlock(&to_here->lock); 09635 }
| static void delete_users | ( | void | ) | [static] |
Definition at line 13042 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().
13043 { 13044 struct iax2_registry *reg; 13045 13046 ao2_callback(users, 0, user_delme_cb, NULL); 13047 13048 AST_LIST_LOCK(®istrations); 13049 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 13050 if (sched) { 13051 ast_sched_thread_del(sched, reg->expire); 13052 } 13053 if (reg->callno) { 13054 int callno = reg->callno; 13055 ast_mutex_lock(&iaxsl[callno]); 13056 if (iaxs[callno]) { 13057 iaxs[callno]->reg = NULL; 13058 iax2_destroy(callno); 13059 } 13060 ast_mutex_unlock(&iaxsl[callno]); 13061 } 13062 if (reg->dnsmgr) 13063 ast_dnsmgr_release(reg->dnsmgr); 13064 ast_free(reg); 13065 } 13066 AST_LIST_UNLOCK(®istrations); 13067 13068 ao2_callback(peers, 0, peer_delme_cb, NULL); 13069 }
| static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 3017 of file chan_iax2.c.
References ast_free.
Referenced by reload_firmware().
03018 { 03019 /* Close firmware */ 03020 if (cur->fwh) { 03021 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 03022 } 03023 close(cur->fd); 03024 ast_free(cur); 03025 }
| static void dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid, | |||
| int | skiplock | |||
| ) | [static] |
Definition at line 9261 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().
09262 { 09263 unsigned short dpstatus = 0; 09264 struct iax_ie_data ied1; 09265 int mm; 09266 09267 memset(&ied1, 0, sizeof(ied1)); 09268 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 09269 /* Must be started */ 09270 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 09271 dpstatus = IAX_DPSTATUS_EXISTS; 09272 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 09273 dpstatus = IAX_DPSTATUS_CANEXIST; 09274 } else { 09275 dpstatus = IAX_DPSTATUS_NONEXISTENT; 09276 } 09277 if (ast_ignore_pattern(context, callednum)) 09278 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 09279 if (mm) 09280 dpstatus |= IAX_DPSTATUS_MATCHMORE; 09281 if (!skiplock) 09282 ast_mutex_lock(&iaxsl[callno]); 09283 if (iaxs[callno]) { 09284 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 09285 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 09286 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 09287 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 09288 } 09289 if (!skiplock) 09290 ast_mutex_unlock(&iaxsl[callno]); 09291 }
| static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 9293 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 1542 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().
01543 { 01544 ast_str_set(buf, 0, "("); 01545 if (e & IAX_ENCRYPT_AES128) { 01546 ast_str_append(buf, 0, "aes128"); 01547 } 01548 if (e & IAX_ENCRYPT_KEYROTATE) { 01549 ast_str_append(buf, 0, ",keyrotate"); 01550 } 01551 if (ast_str_strlen(*buf) > 1) { 01552 ast_str_append(buf, 0, ")"); 01553 } else { 01554 ast_str_set(buf, 0, "No"); 01555 } 01556 }
| static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
| struct ast_iax2_full_hdr * | fh, | |||
| unsigned char * | poo, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6322 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().
06323 { 06324 int padding; 06325 unsigned char *workspace; 06326 workspace = ast_alloca(*datalen + 32); 06327 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06328 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06329 if (iaxdebug) 06330 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06331 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06332 padding = 16 + (padding & 0xf); 06333 memcpy(workspace, poo, padding); 06334 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06335 workspace[15] &= 0xf0; 06336 workspace[15] |= (padding & 0xf); 06337 if (iaxdebug) 06338 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 06339 *datalen += padding; 06340 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06341 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06342 memcpy(poo, workspace + *datalen - 32, 32); 06343 } else { 06344 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06345 if (iaxdebug) 06346 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06347 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06348 padding = 16 + (padding & 0xf); 06349 memcpy(workspace, poo, padding); 06350 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06351 workspace[15] &= 0xf0; 06352 workspace[15] |= (padding & 0x0f); 06353 *datalen += padding; 06354 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06355 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06356 memcpy(poo, workspace + *datalen - 32, 32); 06357 } 06358 return 0; 06359 }
| static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8673 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().
08674 { 08675 #ifdef SCHED_MULTITHREADED 08676 if (schedule_action(__expire_registry, data)) 08677 #endif 08678 __expire_registry(data); 08679 return 0; 08680 }
| 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 13742 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().
13743 { 13744 struct iax2_dpcache *dp = NULL; 13745 struct timeval now = ast_tvnow(); 13746 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13747 struct ast_channel *c = NULL; 13748 struct ast_frame *f = NULL; 13749 13750 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13751 if (ast_tvcmp(now, dp->expiry) > 0) { 13752 AST_LIST_REMOVE_CURRENT(cache_list); 13753 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13754 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13755 else 13756 ast_free(dp); 13757 continue; 13758 } 13759 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13760 break; 13761 } 13762 AST_LIST_TRAVERSE_SAFE_END; 13763 13764 if (!dp) { 13765 /* No matching entry. Create a new one. */ 13766 /* First, can we make a callno? */ 13767 if ((callno = cache_get_callno_locked(data)) < 0) { 13768 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13769 return NULL; 13770 } 13771 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13772 ast_mutex_unlock(&iaxsl[callno]); 13773 return NULL; 13774 } 13775 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13776 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13777 dp->expiry = ast_tvnow(); 13778 dp->orig = dp->expiry; 13779 /* Expires in 30 mins by default */ 13780 dp->expiry.tv_sec += iaxdefaultdpcache; 13781 dp->flags = CACHE_FLAG_PENDING; 13782 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13783 dp->waiters[x] = -1; 13784 /* Insert into the lists */ 13785 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13786 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13787 /* Send the request if we're already up */ 13788 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13789 iax2_dprequest(dp, callno); 13790 ast_mutex_unlock(&iaxsl[callno]); 13791 } 13792 13793 /* By here we must have a dp */ 13794 if (dp->flags & CACHE_FLAG_PENDING) { 13795 struct timeval start; 13796 int ms; 13797 /* Okay, here it starts to get nasty. We need a pipe now to wait 13798 for a reply to come back so long as it's pending */ 13799 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13800 /* Find an empty slot */ 13801 if (dp->waiters[x] < 0) 13802 break; 13803 } 13804 if (x >= ARRAY_LEN(dp->waiters)) { 13805 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13806 return NULL; 13807 } 13808 if (pipe(com)) { 13809 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13810 return NULL; 13811 } 13812 dp->waiters[x] = com[1]; 13813 /* Okay, now we wait */ 13814 timeout = iaxdefaulttimeout * 1000; 13815 /* Temporarily unlock */ 13816 AST_LIST_UNLOCK(&dpcache); 13817 /* Defer any dtmf */ 13818 if (chan) 13819 old = ast_channel_defer_dtmf(chan); 13820 doabort = 0; 13821 start = ast_tvnow(); 13822 while ((ms = ast_remaining_ms(start, timeout))) { 13823 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms); 13824 if (outfd > -1) 13825 break; 13826 if (!c) 13827 continue; 13828 if (!(f = ast_read(c))) { 13829 doabort = 1; 13830 break; 13831 } 13832 ast_frfree(f); 13833 } 13834 if (!ms) { 13835 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13836 } 13837 AST_LIST_LOCK(&dpcache); 13838 dp->waiters[x] = -1; 13839 close(com[1]); 13840 close(com[0]); 13841 if (doabort) { 13842 /* Don't interpret anything, just abort. Not sure what th epoint 13843 of undeferring dtmf on a hung up channel is but hey whatever */ 13844 if (!old && chan) 13845 ast_channel_undefer_dtmf(chan); 13846 return NULL; 13847 } 13848 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13849 /* Now to do non-independent analysis the results of our wait */ 13850 if (dp->flags & CACHE_FLAG_PENDING) { 13851 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13852 pending. Don't let it take as long to timeout. */ 13853 dp->flags &= ~CACHE_FLAG_PENDING; 13854 dp->flags |= CACHE_FLAG_TIMEOUT; 13855 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 13856 systems without leaving it unavailable once the server comes back online */ 13857 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 13858 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13859 if (dp->waiters[x] > -1) { 13860 if (write(dp->waiters[x], "asdf", 4) < 0) { 13861 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13862 } 13863 } 13864 } 13865 } 13866 } 13867 /* Our caller will obtain the rest */ 13868 if (!old && chan) 13869 ast_channel_undefer_dtmf(chan); 13870 } 13871 return dp; 13872 }
| 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 2942 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02942 { 02943 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02944 }
| 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 2946 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().
02946 { 02947 02948 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02949 }
| static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 1394 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().
01395 { 01396 struct iax2_thread *thread = NULL; 01397 01398 /* Pop the head of the idle list off */ 01399 AST_LIST_LOCK(&idle_list); 01400 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01401 AST_LIST_UNLOCK(&idle_list); 01402 01403 /* If we popped a thread off the idle list, just return it */ 01404 if (thread) { 01405 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01406 return thread; 01407 } 01408 01409 /* Pop the head of the dynamic list off */ 01410 AST_LIST_LOCK(&dynamic_list); 01411 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01412 AST_LIST_UNLOCK(&dynamic_list); 01413 01414 /* If we popped a thread off the dynamic list, just return it */ 01415 if (thread) { 01416 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01417 return thread; 01418 } 01419 01420 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01421 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01422 return NULL; 01423 01424 /* Set default values */ 01425 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01426 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01427 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01428 01429 /* Initialize lock and condition */ 01430 ast_mutex_init(&thread->lock); 01431 ast_cond_init(&thread->cond, NULL); 01432 ast_mutex_init(&thread->init_lock); 01433 ast_cond_init(&thread->init_cond, NULL); 01434 ast_mutex_lock(&thread->init_lock); 01435 01436 /* Create thread and send it on it's way */ 01437 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01438 ast_cond_destroy(&thread->cond); 01439 ast_mutex_destroy(&thread->lock); 01440 ast_mutex_unlock(&thread->init_lock); 01441 ast_cond_destroy(&thread->init_cond); 01442 ast_mutex_destroy(&thread->init_lock); 01443 ast_free(thread); 01444 return NULL; 01445 } 01446 01447 /* this thread is not processing a full frame (since it is idle), 01448 so ensure that the field for the full frame call number is empty */ 01449 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01450 01451 /* Wait for the thread to be ready before returning it to the caller */ 01452 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01453 01454 /* Done with init_lock */ 01455 ast_mutex_unlock(&thread->init_lock); 01456 01457 return thread; 01458 }
| static struct iax2_peer* find_peer | ( | const char * | name, | |
| int | realtime | |||
| ) | [static, read] |
Definition at line 1686 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().
01687 { 01688 struct iax2_peer *peer = NULL; 01689 struct iax2_peer tmp_peer = { 01690 .name = name, 01691 }; 01692 01693 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01694 01695 /* Now go for realtime if applicable */ 01696 if(!peer && realtime) 01697 peer = realtime_peer(name, NULL); 01698 01699 return peer; 01700 }
| static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
| int | fd | |||
| ) | [static, read] |
Definition at line 6094 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().
06095 { 06096 struct iax2_trunk_peer *tpeer = NULL; 06097 06098 /* Finds and locks trunk peer */ 06099 AST_LIST_LOCK(&tpeers); 06100 06101 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 06102 if (!inaddrcmp(&tpeer->addr, sin)) { 06103 ast_mutex_lock(&tpeer->lock); 06104 break; 06105 } 06106 } 06107 06108 if (!tpeer) { 06109 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 06110 ast_mutex_init(&tpeer->lock); 06111 tpeer->lastsent = 9999; 06112 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 06113 tpeer->trunkact = ast_tvnow(); 06114 ast_mutex_lock(&tpeer->lock); 06115 tpeer->sockfd = fd; 06116 #ifdef SO_NO_CHECK 06117 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 06118 #endif 06119 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06120 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 06121 } 06122 } 06123 06124 AST_LIST_UNLOCK(&tpeers); 06125 06126 return tpeer; 06127 }
| static struct iax2_user* find_user | ( | const char * | name | ) | [static, read] |
Definition at line 1714 of file chan_iax2.c.
References ao2_find, and OBJ_POINTER.
Referenced by calltoken_required(), handle_cli_iax2_prune_realtime(), and requirecalltoken_mark_auto().
01715 { 01716 struct iax2_user tmp_user = { 01717 .name = name, 01718 }; 01719 01720 return ao2_find(users, &tmp_user, OBJ_POINTER); 01721 }
| static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
| int | callno, | |||
| unsigned int | ts | |||
| ) | [static] |
Definition at line 5907 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05908 { 05909 long ms; /* NOT unsigned */ 05910 if (ast_tvzero(iaxs[callno]->rxcore)) { 05911 /* Initialize rxcore time if appropriate */ 05912 iaxs[callno]->rxcore = ast_tvnow(); 05913 /* Round to nearest 20ms so traces look pretty */ 05914 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05915 } 05916 /* Calculate difference between trunk and channel */ 05917 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05918 /* Return as the sum of trunk time and the difference between trunk and real time */ 05919 return ms + ts; 05920 }
| static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 12174 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
12175 { 12176 struct iax2_context *conl; 12177 while(con) { 12178 conl = con; 12179 con = con->next; 12180 ast_free(conl); 12181 } 12182 }
| static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1820 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 13995 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.
13996 { 13997 struct iax2_peer *peer; 13998 char *peername, *colname; 13999 14000 peername = ast_strdupa(data); 14001 14002 /* if our channel, return the IP address of the endpoint of current channel */ 14003 if (!strcmp(peername,"CURRENTCHANNEL")) { 14004 unsigned short callno; 14005 if (chan->tech != &iax2_tech) 14006 return -1; 14007 callno = PTR_TO_CALLNO(chan->tech_pvt); 14008 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 14009 return 0; 14010 } 14011 14012 if ((colname = strchr(peername, ','))) 14013 *colname++ = '\0'; 14014 else 14015 colname = "ip"; 14016 14017 if (!(peer = find_peer(peername, 1))) 14018 return -1; 14019 14020 if (!strcasecmp(colname, "ip")) { 14021 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 14022 } else if (!strcasecmp(colname, "status")) { 14023 peer_status(peer, buf, len); 14024 } else if (!strcasecmp(colname, "mailbox")) { 14025 ast_copy_string(buf, peer->mailbox, len); 14026 } else if (!strcasecmp(colname, "context")) { 14027 ast_copy_string(buf, peer->context, len); 14028 } else if (!strcasecmp(colname, "expire")) { 14029 snprintf(buf, len, "%d", peer->expire); 14030 } else if (!strcasecmp(colname, "dynamic")) { 14031 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 14032 } else if (!strcasecmp(colname, "callerid_name")) { 14033 ast_copy_string(buf, peer->cid_name, len); 14034 } else if (!strcasecmp(colname, "callerid_num")) { 14035 ast_copy_string(buf, peer->cid_num, len); 14036 } else if (!strcasecmp(colname, "codecs")) { 14037 ast_getformatname_multiple(buf, len -1, peer->capability); 14038 } else if (!strncasecmp(colname, "codec[", 6)) { 14039 char *codecnum, *ptr; 14040 int codec = 0; 14041 14042 /* skip over "codec" to the '[' */ 14043 codecnum = colname + 5; 14044 *codecnum = '\0'; 14045 codecnum++; 14046 if ((ptr = strchr(codecnum, ']'))) { 14047 *ptr = '\0'; 14048 } 14049 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 14050 ast_copy_string(buf, ast_getformatname(codec), len); 14051 } else { 14052 buf[0] = '\0'; 14053 } 14054 } else { 14055 buf[0] = '\0'; 14056 } 14057 14058 peer_unref(peer); 14059 14060 return 0; 14061 }
| static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 12339 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
12340 { 12341 int methods = 0; 12342 if (strstr(value, "rsa")) 12343 methods |= IAX_AUTH_RSA; 12344 if (strstr(value, "md5")) 12345 methods |= IAX_AUTH_MD5; 12346 if (strstr(value, "plaintext")) 12347 methods |= IAX_AUTH_PLAINTEXT; 12348 return methods; 12349 }
| static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1558 of file chan_iax2.c.
References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by build_peer(), build_user(), and set_config().
01559 { 01560 int e; 01561 if (!strcasecmp(s, "aes128")) 01562 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01563 else if (ast_true(s)) 01564 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01565 else 01566 e = 0; 01567 return e; 01568 }
| static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4145 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
04146 { 04147 #ifdef SCHED_MULTITHREADED 04148 if (schedule_action(__get_from_jb, data)) 04149 #endif 04150 __get_from_jb(data); 04151 return 0; 04152 }
| static struct callno_entry * get_unused_callno | ( | int | trunk, | |
| int | validated | |||
| ) | [static, read] |
Definition at line 2620 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().
02621 { 02622 struct callno_entry *callno_entry = NULL; 02623 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02624 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02625 /* Minor optimization for the extreme case. */ 02626 return NULL; 02627 } 02628 02629 /* the callno_pool container is locked here primarily to ensure thread 02630 * safety of the total_nonval_callno_used check and increment */ 02631 ao2_lock(callno_pool); 02632 02633 /* only a certain number of nonvalidated call numbers should be allocated. 02634 * If there ever is an attack, this separates the calltoken validating 02635 * users from the non calltoken validating users. */ 02636 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02637 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02638 ao2_unlock(callno_pool); 02639 return NULL; 02640 } 02641 02642 /* unlink the object from the container, taking over ownership 02643 * of the reference the container had to the object */ 02644 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02645 02646 if (callno_entry) { 02647 callno_entry->validated = validated; 02648 if (!validated) { 02649 total_nonval_callno_used++; 02650 } 02651 } 02652 02653 ao2_unlock(callno_pool); 02654 return callno_entry; 02655 }
| 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 4883 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().
04885 { 04886 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04887 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04888 struct ast_str *buf = ast_str_alloca(256); 04889 time_t t = time(NULL); 04890 char hash[41]; /* 40 char sha1 hash */ 04891 int subclass = uncompress_subclass(fh->csub); 04892 04893 /* ----- Case 1 ----- */ 04894 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04895 struct iax_ie_data ied = { 04896 .buf = { 0 }, 04897 .pos = 0, 04898 }; 04899 04900 /* create the hash with their address data and our timestamp */ 04901 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04902 ast_sha1_hash(hash, ast_str_buffer(buf)); 04903 04904 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04905 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04906 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04907 04908 return 1; 04909 04910 /* ----- Case 2 ----- */ 04911 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04912 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04913 char *rec_ts = NULL; /* received timestamp */ 04914 unsigned int rec_time; /* received time_t */ 04915 04916 /* split the timestamp from the hash data */ 04917 rec_hash = strchr((char *) ies->calltokendata, '?'); 04918 if (rec_hash) { 04919 *rec_hash++ = '\0'; 04920 rec_ts = (char *) ies->calltokendata; 04921 } 04922 04923 /* check that we have valid data before we do any comparisons */ 04924 if (!rec_hash || !rec_ts) { 04925 goto reject; 04926 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04927 goto reject; 04928 } 04929 04930 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04931 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04932 ast_sha1_hash(hash, ast_str_buffer(buf)); 04933 04934 /* compare hashes and then check timestamp delay */ 04935 if (strcmp(hash, rec_hash)) { 04936 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04937 goto reject; /* received hash does not match ours, reject */ 04938 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04939 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04940 goto reject; /* too much delay, reject */ 04941 } 04942 04943 /* at this point the call token is valid, returning 0 04944 * will allow socket_process to continue as usual */ 04945 requirecalltoken_mark_auto(ies->username, subclass); 04946 return 0; 04947 04948 /* ----- Case 3 ----- */ 04949 } else { /* calltokens are not supported for this client, how do we respond? */ 04950 if (calltoken_required(sin, ies->username, subclass)) { 04951 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")); 04952 goto reject; 04953 } 04954 return 0; /* calltoken is not required for this addr, so permit it. */ 04955 } 04956 04957 reject: 04958 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04959 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04960 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04961 } else { 04962 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04963 } 04964 04965 return 1; 04966 }
| static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 12021 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.
12022 { 12023 int force = 0; 12024 int res; 12025 12026 switch (cmd) { 12027 case CLI_INIT: 12028 e->command = "iax2 provision"; 12029 e->usage = 12030 "Usage: iax2 provision <host> <template> [forced]\n" 12031 " Provisions the given peer or IP address using a template\n" 12032 " matching either 'template' or '*' if the template is not\n" 12033 " found. If 'forced' is specified, even empty provisioning\n" 12034 " fields will be provisioned as empty fields.\n"; 12035 return NULL; 12036 case CLI_GENERATE: 12037 if (a->pos == 3) 12038 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 12039 return NULL; 12040 } 12041 12042 if (a->argc < 4) 12043 return CLI_SHOWUSAGE; 12044 if (a->argc > 4) { 12045 if (!strcasecmp(a->argv[4], "forced")) 12046 force = 1; 12047 else 12048 return CLI_SHOWUSAGE; 12049 } 12050 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 12051 if (res < 0) 12052 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 12053 else if (res < 1) 12054 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 12055 else 12056 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 12057 return CLI_SUCCESS; 12058 }
| static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3577 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.
03578 { 03579 struct iax2_peer *peer = NULL; 03580 struct iax2_user *user = NULL; 03581 static const char * const choices[] = { "all", NULL }; 03582 char *cmplt; 03583 03584 switch (cmd) { 03585 case CLI_INIT: 03586 e->command = "iax2 prune realtime"; 03587 e->usage = 03588 "Usage: iax2 prune realtime [<peername>|all]\n" 03589 " Prunes object(s) from the cache\n"; 03590 return NULL; 03591 case CLI_GENERATE: 03592 if (a->pos == 3) { 03593 cmplt = ast_cli_complete(a->word, choices, a->n); 03594 if (!cmplt) 03595 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03596 return cmplt; 03597 } 03598 return NULL; 03599 } 03600 if (a->argc != 4) 03601 return CLI_SHOWUSAGE; 03602 if (!strcmp(a->argv[3], "all")) { 03603 prune_users(); 03604 prune_peers(); 03605 ast_cli(a->fd, "Cache flushed successfully.\n"); 03606 return CLI_SUCCESS; 03607 } 03608 peer = find_peer(a->argv[3], 0); 03609 user = find_user(a->argv[3]); 03610 if (peer || user) { 03611 if (peer) { 03612 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 03613 ast_set_flag64(peer, IAX_RTAUTOCLEAR); 03614 expire_registry(peer_ref(peer)); 03615 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03616 } else { 03617 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03618 } 03619 peer_unref(peer); 03620 } 03621 if (user) { 03622 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 03623 ast_set_flag64(user, IAX_RTAUTOCLEAR); 03624 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03625 } else { 03626 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03627 } 03628 ao2_unlink(users,user); 03629 user_unref(user); 03630 } 03631 } else { 03632 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03633 } 03634 03635 return CLI_SUCCESS; 03636 }
| static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 13646 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
13647 { 13648 switch (cmd) { 13649 case CLI_INIT: 13650 e->command = "iax2 reload"; 13651 e->usage = 13652 "Usage: iax2 reload\n" 13653 " Reloads IAX configuration from iax.conf\n"; 13654 return NULL; 13655 case CLI_GENERATE: 13656 return NULL; 13657 } 13658 13659 reload_config(); 13660 13661 return CLI_SUCCESS; 13662 }
| static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7365 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.
07366 { 07367 switch (cmd) { 07368 case CLI_INIT: 07369 e->command = "iax2 set debug {on|off|peer}"; 07370 e->usage = 07371 "Usage: iax2 set debug {on|off|peer peername}\n" 07372 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07373 return NULL; 07374 case CLI_GENERATE: 07375 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07376 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07377 return NULL; 07378 } 07379 07380 if (a->argc < e->args || a->argc > e->args + 1) 07381 return CLI_SHOWUSAGE; 07382 07383 if (!strcasecmp(a->argv[3], "peer")) { 07384 struct iax2_peer *peer; 07385 struct sockaddr_in peer_addr; 07386 07387 07388 if (a->argc != e->args + 1) 07389 return CLI_SHOWUSAGE; 07390 07391 peer = find_peer(a->argv[4], 1); 07392 07393 if (!peer) { 07394 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07395 return CLI_FAILURE; 07396 } 07397 07398 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 07399 07400 debugaddr.sin_addr = peer_addr.sin_addr; 07401 debugaddr.sin_port = peer_addr.sin_port; 07402 07403 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07404 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07405 07406 ao2_ref(peer, -1); 07407 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07408 iaxdebug = 1; 07409 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07410 } else { 07411 iaxdebug = 0; 07412 memset(&debugaddr, 0, sizeof(debugaddr)); 07413 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07414 } 07415 return CLI_SUCCESS; 07416 }
| static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7444 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.
07445 { 07446 switch (cmd) { 07447 case CLI_INIT: 07448 e->command = "iax2 set debug jb {on|off}"; 07449 e->usage = 07450 "Usage: iax2 set debug jb {on|off}\n" 07451 " Enables/Disables jitterbuffer debugging information\n"; 07452 return NULL; 07453 case CLI_GENERATE: 07454 return NULL; 07455 } 07456 07457 if (a->argc != e->args) 07458 return CLI_SHOWUSAGE; 07459 07460 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07461 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07462 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07463 } else { 07464 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07465 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07466 } 07467 return CLI_SUCCESS; 07468 }
| static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7418 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.
07419 { 07420 switch (cmd) { 07421 case CLI_INIT: 07422 e->command = "iax2 set debug trunk {on|off}"; 07423 e->usage = 07424 "Usage: iax2 set debug trunk {on|off}\n" 07425 " Enables/Disables debugging of IAX trunking\n"; 07426 return NULL; 07427 case CLI_GENERATE: 07428 return NULL; 07429 } 07430 07431 if (a->argc != e->args) 07432 return CLI_SHOWUSAGE; 07433 07434 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07435 iaxtrunkdebug = 1; 07436 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07437 } else { 07438 iaxtrunkdebug = 0; 07439 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07440 } 07441 return CLI_SUCCESS; 07442 }
| 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 3904 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.
03905 { 03906 int mtuv; 03907 03908 switch (cmd) { 03909 case CLI_INIT: 03910 e->command = "iax2 set mtu"; 03911 e->usage = 03912 "Usage: iax2 set mtu <value>\n" 03913 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03914 " zero to disable. Disabling means that the operating system\n" 03915 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03916 " packet exceeds the UDP payload size. This is substantially\n" 03917 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03918 " greater for G.711 samples.\n"; 03919 return NULL; 03920 case CLI_GENERATE: 03921 return NULL; 03922 } 03923 03924 if (a->argc != 4) 03925 return CLI_SHOWUSAGE; 03926 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03927 mtuv = MAX_TRUNK_MTU; 03928 else 03929 mtuv = atoi(a->argv[3]); 03930 03931 if (mtuv == 0) { 03932 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03933 global_max_trunk_mtu = 0; 03934 return CLI_SUCCESS; 03935 } 03936 if (mtuv < 172 || mtuv > 4000) { 03937 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03938 return CLI_SHOWUSAGE; 03939 } 03940 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03941 global_max_trunk_mtu = mtuv; 03942 return CLI_SUCCESS; 03943 }
| static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3945 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.
03946 { 03947 struct iax2_dpcache *dp = NULL; 03948 char tmp[1024], *pc = NULL; 03949 int s, x, y; 03950 struct timeval now = ast_tvnow(); 03951 03952 switch (cmd) { 03953 case CLI_INIT: 03954 e->command = "iax2 show cache"; 03955 e->usage = 03956 "Usage: iax2 show cache\n" 03957 " Display currently cached IAX Dialplan results.\n"; 03958 return NULL; 03959 case CLI_GENERATE: 03960 return NULL; 03961 } 03962 03963 AST_LIST_LOCK(&dpcache); 03964 03965 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03966 03967 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 03968 s = dp->expiry.tv_sec - now.tv_sec; 03969 tmp[0] = '\0'; 03970 if (dp->flags & CACHE_FLAG_EXISTS) 03971 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03972 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03973 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03974 if (dp->flags & CACHE_FLAG_CANEXIST) 03975 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03976 if (dp->flags & CACHE_FLAG_PENDING) 03977 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03978 if (dp->flags & CACHE_FLAG_TIMEOUT) 03979 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03980 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03981 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03982 if (dp->flags & CACHE_FLAG_MATCHMORE) 03983 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03984 if (dp->flags & CACHE_FLAG_UNKNOWN) 03985 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03986 /* Trim trailing pipe */ 03987 if (!ast_strlen_zero(tmp)) { 03988 tmp[strlen(tmp) - 1] = '\0'; 03989 } else { 03990 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03991 } 03992 y = 0; 03993 pc = strchr(dp->peercontext, '@'); 03994 if (!pc) { 03995 pc = dp->peercontext; 03996 } else { 03997 pc++; 03998 } 03999 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 04000 if (dp->waiters[x] > -1) 04001 y++; 04002 } 04003 if (s > 0) { 04004 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 04005 } else { 04006 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 04007 } 04008 } 04009 04010 AST_LIST_UNLOCK(&dpcache); 04011 04012 return CLI_SUCCESS; 04013 }
| static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 2555 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.
02556 { 02557 struct ao2_iterator i; 02558 struct peercnt *peercnt; 02559 struct sockaddr_in sin; 02560 int found = 0; 02561 02562 switch (cmd) { 02563 case CLI_INIT: 02564 e->command = "iax2 show callnumber usage"; 02565 e->usage = 02566 "Usage: iax2 show callnumber usage [IP address]\n" 02567 " Shows current IP addresses which are consuming iax2 call numbers\n"; 02568 return NULL; 02569 case CLI_GENERATE: 02570 return NULL; 02571 case CLI_HANDLER: 02572 if (a->argc < 4 || a->argc > 5) 02573 return CLI_SHOWUSAGE; 02574 02575 if (a->argc == 4) { 02576 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02577 } 02578 02579 i = ao2_iterator_init(peercnts, 0); 02580 while ((peercnt = ao2_iterator_next(&i))) { 02581 sin.sin_addr.s_addr = peercnt->addr; 02582 if (a->argc == 5) { 02583 if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) { 02584 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02585 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02586 ao2_ref(peercnt, -1); 02587 found = 1; 02588 break; 02589 } 02590 } else { 02591 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02592 } 02593 ao2_ref(peercnt, -1); 02594 } 02595 ao2_iterator_destroy(&i); 02596 02597 if (a->argc == 4) { 02598 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n" 02599 "Non-CallToken Validated Callno Used: %d\n", 02600 global_maxcallno_nonval, 02601 total_nonval_callno_used); 02602 02603 ast_cli(a->fd, "Total Available Callno: %d\n" 02604 "Regular Callno Available: %d\n" 02605 "Trunk Callno Available: %d\n", 02606 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk), 02607 ao2_container_count(callno_pool), 02608 ao2_container_count(callno_pool_trunk)); 02609 } else if (a->argc == 5 && !found) { 02610 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] ); 02611 } 02612 02613 02614 return CLI_SUCCESS; 02615 default: 02616 return NULL; 02617 } 02618 }
| static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7192 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.
07193 { 07194 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 07195 #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" 07196 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 07197 int x; 07198 int numchans = 0; 07199 char first_message[10] = { 0, }; 07200 char last_message[10] = { 0, }; 07201 07202 switch (cmd) { 07203 case CLI_INIT: 07204 e->command = "iax2 show channels"; 07205 e->usage = 07206 "Usage: iax2 show channels\n" 07207 " Lists all currently active IAX channels.\n"; 07208 return NULL; 07209 case CLI_GENERATE: 07210 return NULL; 07211 } 07212 07213 if (a->argc != 3) 07214 return CLI_SHOWUSAGE; 07215 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 07216 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07217 ast_mutex_lock(&iaxsl[x]); 07218 if (iaxs[x]) { 07219 int lag, jitter, localdelay; 07220 jb_info jbinfo; 07221 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07222 jb_getinfo(iaxs[x]->jb, &jbinfo); 07223 jitter = jbinfo.jitter; 07224 localdelay = jbinfo.current - jbinfo.min; 07225 } else { 07226 jitter = -1; 07227 localdelay = 0; 07228 } 07229 07230 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07231 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07232 lag = iaxs[x]->remote_rr.delay; 07233 ast_cli(a->fd, FORMAT, 07234 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07235 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 07236 S_OR(iaxs[x]->username, "(None)"), 07237 iaxs[x]->callno, iaxs[x]->peercallno, 07238 iaxs[x]->oseqno, iaxs[x]->iseqno, 07239 lag, 07240 jitter, 07241 localdelay, 07242 ast_getformatname(iaxs[x]->voiceformat), 07243 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07244 first_message, 07245 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07246 last_message); 07247 numchans++; 07248 } 07249 ast_mutex_unlock(&iaxsl[x]); 07250 } 07251 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07252 return CLI_SUCCESS; 07253 #undef FORMAT 07254 #undef FORMAT2 07255 #undef FORMATB 07256 }
| static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6978 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.
06979 { 06980 struct iax_firmware *cur = NULL; 06981 06982 switch (cmd) { 06983 case CLI_INIT: 06984 e->command = "iax2 show firmware"; 06985 e->usage = 06986 "Usage: iax2 show firmware\n" 06987 " Lists all known IAX firmware images.\n"; 06988 return NULL; 06989 case CLI_GENERATE: 06990 return NULL; 06991 } 06992 06993 if (a->argc != 3 && a->argc != 4) 06994 return CLI_SHOWUSAGE; 06995 06996 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 06997 AST_LIST_LOCK(&firmwares); 06998 AST_LIST_TRAVERSE(&firmwares, cur, list) { 06999 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 07000 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 07001 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 07002 } 07003 } 07004 AST_LIST_UNLOCK(&firmwares); 07005 07006 return CLI_SUCCESS; 07007 }
| static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7342 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.
07343 { 07344 int numchans = 0; 07345 07346 switch (cmd) { 07347 case CLI_INIT: 07348 e->command = "iax2 show netstats"; 07349 e->usage = 07350 "Usage: iax2 show netstats\n" 07351 " Lists network status for all currently active IAX channels.\n"; 07352 return NULL; 07353 case CLI_GENERATE: 07354 return NULL; 07355 } 07356 if (a->argc != 3) 07357 return CLI_SHOWUSAGE; 07358 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 07359 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 07360 numchans = ast_cli_netstats(NULL, a->fd, 1); 07361 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07362 return CLI_SUCCESS; 07363 }
| 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 3752 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.
03753 { 03754 char status[30]; 03755 char cbuf[256]; 03756 struct iax2_peer *peer; 03757 char codec_buf[512]; 03758 struct ast_str *encmethods = ast_str_alloca(256); 03759 int x = 0, codec = 0, load_realtime = 0; 03760 03761 switch (cmd) { 03762 case CLI_INIT: 03763 e->command = "iax2 show peer"; 03764 e->usage = 03765 "Usage: iax2 show peer <name>\n" 03766 " Display details on specific IAX peer\n"; 03767 return NULL; 03768 case CLI_GENERATE: 03769 if (a->pos == 3) 03770 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03771 return NULL; 03772 } 03773 03774 if (a->argc < 4) 03775 return CLI_SHOWUSAGE; 03776 03777 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03778 03779 peer = find_peer(a->argv[3], load_realtime); 03780 if (peer) { 03781 struct sockaddr_in peer_addr; 03782 03783 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 03784 03785 encmethods_to_str(peer->encmethods, &encmethods); 03786 ast_cli(a->fd, "\n\n"); 03787 ast_cli(a->fd, " * Name : %s\n", peer->name); 03788 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03789 ast_cli(a->fd, " Context : %s\n", peer->context); 03790 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03791 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03792 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03793 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03794 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03795 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 03796 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03797 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03798 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03799 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03800 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)); 03801 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03802 ast_cli(a->fd, " Username : %s\n", peer->username); 03803 ast_cli(a->fd, " Codecs : "); 03804 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03805 ast_cli(a->fd, "%s\n", codec_buf); 03806 03807 ast_cli(a->fd, " Codec Order : ("); 03808 for(x = 0; x < 32 ; x++) { 03809 codec = ast_codec_pref_index(&peer->prefs,x); 03810 if(!codec) 03811 break; 03812 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03813 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03814 ast_cli(a->fd, "|"); 03815 } 03816 03817 if (!x) 03818 ast_cli(a->fd, "none"); 03819 ast_cli(a->fd, ")\n"); 03820 03821 ast_cli(a->fd, " Status : "); 03822 peer_status(peer, status, sizeof(status)); 03823 ast_cli(a->fd, "%s\n",status); 03824 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"); 03825 ast_cli(a->fd, "\n"); 03826 peer_unref(peer); 03827 } else { 03828 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03829 ast_cli(a->fd, "\n"); 03830 } 03831 03832 return CLI_SUCCESS; 03833 }
| static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6946 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.
06947 { 06948 switch (cmd) { 06949 case CLI_INIT: 06950 e->command = "iax2 show peers"; 06951 e->usage = 06952 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06953 " Lists all known IAX2 peers.\n" 06954 " Optional 'registered' argument lists only peers with known addresses.\n" 06955 " Optional regular expression pattern is used to filter the peer list.\n"; 06956 return NULL; 06957 case CLI_GENERATE: 06958 return NULL; 06959 } 06960 06961 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) { 06962 case RESULT_SHOWUSAGE: 06963 return CLI_SHOWUSAGE; 06964 case RESULT_FAILURE: 06965 return CLI_FAILURE; 06966 default: 06967 return CLI_SUCCESS; 06968 } 06969 }
| static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7101 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.
07102 { 07103 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 07104 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 07105 struct iax2_registry *reg = NULL; 07106 char host[80]; 07107 char perceived[80]; 07108 int counter = 0; 07109 07110 switch (cmd) { 07111 case CLI_INIT: 07112 e->command = "iax2 show registry"; 07113 e->usage = 07114 "Usage: iax2 show registry\n" 07115 " Lists all registration requests and status.\n"; 07116 return NULL; 07117 case CLI_GENERATE: 07118 return NULL; 07119 } 07120 if (a->argc != 3) 07121 return CLI_SHOWUSAGE; 07122 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 07123 AST_LIST_LOCK(®istrations); 07124 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07125 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07126 if (reg->us.sin_addr.s_addr) 07127 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07128 else 07129 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07130 ast_cli(a->fd, FORMAT, host, 07131 (reg->dnsmgr) ? "Y" : "N", 07132 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 07133 counter++; 07134 } 07135 AST_LIST_UNLOCK(®istrations); 07136 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 07137 return CLI_SUCCESS; 07138 #undef FORMAT 07139 #undef FORMAT2 07140 }
| static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3858 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.
03859 { 03860 struct iax_frame *cur; 03861 int cnt = 0, dead = 0, final = 0, i = 0; 03862 03863 switch (cmd) { 03864 case CLI_INIT: 03865 e->command = "iax2 show stats"; 03866 e->usage = 03867 "Usage: iax2 show stats\n" 03868 " Display statistics on IAX channel driver.\n"; 03869 return NULL; 03870 case CLI_GENERATE: 03871 return NULL; 03872 } 03873 03874 if (a->argc != 3) 03875 return CLI_SHOWUSAGE; 03876 03877 for (i = 0; i < ARRAY_LEN(frame_queue); i++) { 03878 ast_mutex_lock(&iaxsl[i]); 03879 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) { 03880 if (cur->retries < 0) 03881 dead++; 03882 if (cur->final) 03883 final++; 03884 cnt++; 03885 } 03886 ast_mutex_unlock(&iaxsl[i]); 03887 } 03888 03889 ast_cli(a->fd, " IAX Statistics\n"); 03890 ast_cli(a->fd, "---------------------\n"); 03891 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03892 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03893 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03894 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03895 03896 trunk_timed = trunk_untimed = 0; 03897 if (trunk_maxmtu > trunk_nmaxmtu) 03898 trunk_nmaxmtu = trunk_maxmtu; 03899 03900 return CLI_SUCCESS; 03901 }
| static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6808 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.
06809 { 06810 struct iax2_thread *thread = NULL; 06811 time_t t; 06812 int threadcount = 0, dynamiccount = 0; 06813 char type; 06814 06815 switch (cmd) { 06816 case CLI_INIT: 06817 e->command = "iax2 show threads"; 06818 e->usage = 06819 "Usage: iax2 show threads\n" 06820 " Lists status of IAX helper threads\n"; 06821 return NULL; 06822 case CLI_GENERATE: 06823 return NULL; 06824 } 06825 if (a->argc != 3) 06826 return CLI_SHOWUSAGE; 06827 06828 ast_cli(a->fd, "IAX2 Thread Information\n"); 06829 time(&t); 06830 ast_cli(a->fd, "Idle Threads:\n"); 06831 AST_LIST_LOCK(&idle_list); 06832 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06833 #ifdef DEBUG_SCHED_MULTITHREAD 06834 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06835 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06836 #else 06837 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06838 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06839 #endif 06840 threadcount++; 06841 } 06842 AST_LIST_UNLOCK(&idle_list); 06843 ast_cli(a->fd, "Active Threads:\n"); 06844 AST_LIST_LOCK(&active_list); 06845 AST_LIST_TRAVERSE(&active_list, thread, list) { 06846 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06847 type = 'D'; 06848 else 06849 type = 'P'; 06850 #ifdef DEBUG_SCHED_MULTITHREAD 06851 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06852 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06853 #else 06854 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06855 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06856 #endif 06857 threadcount++; 06858 } 06859 AST_LIST_UNLOCK(&active_list); 06860 ast_cli(a->fd, "Dynamic Threads:\n"); 06861 AST_LIST_LOCK(&dynamic_list); 06862 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06863 #ifdef DEBUG_SCHED_MULTITHREAD 06864 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06865 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06866 #else 06867 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06868 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06869 #endif 06870 dynamiccount++; 06871 } 06872 AST_LIST_UNLOCK(&dynamic_list); 06873 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06874 return CLI_SUCCESS; 06875 }
| static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6599 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().
06600 { 06601 regex_t regexbuf; 06602 int havepattern = 0; 06603 06604 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06605 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06606 06607 struct iax2_user *user = NULL; 06608 char auth[90]; 06609 char *pstr = ""; 06610 struct ao2_iterator i; 06611 06612 switch (cmd) { 06613 case CLI_INIT: 06614 e->command = "iax2 show users [like]"; 06615 e->usage = 06616 "Usage: iax2 show users [like <pattern>]\n" 06617 " Lists all known IAX2 users.\n" 06618 " Optional regular expression pattern is used to filter the user list.\n"; 06619 return NULL; 06620 case CLI_GENERATE: 06621 return NULL; 06622 } 06623 06624 switch (a->argc) { 06625 case 5: 06626 if (!strcasecmp(a->argv[3], "like")) { 06627 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06628 return CLI_SHOWUSAGE; 06629 havepattern = 1; 06630 } else 06631 return CLI_SHOWUSAGE; 06632 case 3: 06633 break; 06634 default: 06635 return CLI_SHOWUSAGE; 06636 } 06637 06638 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06639 i = ao2_iterator_init(users, 0); 06640 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 06641 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06642 continue; 06643 06644 if (!ast_strlen_zero(user->secret)) { 06645 ast_copy_string(auth,user->secret, sizeof(auth)); 06646 } else if (!ast_strlen_zero(user->inkeys)) { 06647 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06648 } else 06649 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06650 06651 if(ast_test_flag64(user, IAX_CODEC_NOCAP)) 06652 pstr = "REQ Only"; 06653 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS)) 06654 pstr = "Disabled"; 06655 else 06656 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06657 06658 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06659 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06660 user->ha ? "Yes" : "No", pstr); 06661 } 06662 ao2_iterator_destroy(&i); 06663 06664 if (havepattern) 06665 regfree(®exbuf); 06666 06667 return CLI_SUCCESS; 06668 #undef FORMAT 06669 #undef FORMAT2 06670 }
| static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3638 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.
03639 { 03640 switch (cmd) { 03641 case CLI_INIT: 03642 e->command = "iax2 test losspct"; 03643 e->usage = 03644 "Usage: iax2 test losspct <percentage>\n" 03645 " For testing, throws away <percentage> percent of incoming packets\n"; 03646 return NULL; 03647 case CLI_GENERATE: 03648 return NULL; 03649 } 03650 if (a->argc != 4) 03651 return CLI_SHOWUSAGE; 03652 03653 test_losspct = atoi(a->argv[3]); 03654 03655 return CLI_SUCCESS; 03656 }
| static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6877 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.
06878 { 06879 struct iax2_peer *p; 06880 06881 switch (cmd) { 06882 case CLI_INIT: 06883 e->command = "iax2 unregister"; 06884 e->usage = 06885 "Usage: iax2 unregister <peername>\n" 06886 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06887 return NULL; 06888 case CLI_GENERATE: 06889 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06890 } 06891 06892 if (a->argc != 3) 06893 return CLI_SHOWUSAGE; 06894 06895 p = find_peer(a->argv[2], 1); 06896 if (p) { 06897 if (p->expire > 0) { 06898 struct iax2_peer tmp_peer = { 06899 .name = a->argv[2], 06900 }; 06901 struct iax2_peer *peer; 06902 06903 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06904 if (peer) { 06905 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06906 peer_unref(peer); /* ref from ao2_find() */ 06907 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06908 } else { 06909 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06910 } 06911 } else { 06912 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06913 } 06914 peer_unref(p); 06915 } else { 06916 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06917 } 06918 return CLI_SUCCESS; 06919 }
| static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9576 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().
09577 { 09578 struct iax2_pkt_buf *pkt_buf; 09579 09580 ast_mutex_lock(&thread->lock); 09581 09582 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09583 ast_mutex_unlock(&thread->lock); 09584 09585 thread->buf = pkt_buf->buf; 09586 thread->buf_len = pkt_buf->len; 09587 thread->buf_size = pkt_buf->len + 1; 09588 09589 socket_process(thread); 09590 09591 thread->buf = NULL; 09592 ast_free(pkt_buf); 09593 09594 ast_mutex_lock(&thread->lock); 09595 } 09596 09597 ast_mutex_unlock(&thread->lock); 09598 }
| static int handle_error | ( | void | ) | [static] |
Definition at line 3288 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().
03289 { 03290 /* XXX Ideally we should figure out why an error occurred and then abort those 03291 rather than continuing to try. Unfortunately, the published interface does 03292 not seem to work XXX */ 03293 #if 0 03294 struct sockaddr_in *sin; 03295 int res; 03296 struct msghdr m; 03297 struct sock_extended_err e; 03298 m.msg_name = NULL; 03299 m.msg_namelen = 0; 03300 m.msg_iov = NULL; 03301 m.msg_control = &e; 03302 m.msg_controllen = sizeof(e); 03303 m.msg_flags = 0; 03304 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03305 if (res < 0) 03306 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03307 else { 03308 if (m.msg_controllen) { 03309 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03310 if (sin) 03311 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03312 else 03313 ast_log(LOG_WARNING, "No address detected??\n"); 03314 } else { 03315 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03316 } 03317 } 03318 #endif 03319 return 0; 03320 }
| static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
| struct sockaddr_in * | sin, | |||
| int | callno | |||
| ) | [static] |
Acknowledgment received for OUR registration.
Definition at line 8467 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().
08468 { 08469 struct iax2_registry *reg; 08470 /* Start pessimistic */ 08471 char peer[256] = ""; 08472 char msgstatus[60]; 08473 int refresh = 60; 08474 char ourip[256] = "<Unspecified>"; 08475 struct sockaddr_in oldus; 08476 struct sockaddr_in us; 08477 int oldmsgs; 08478 struct sockaddr_in reg_addr; 08479 08480 memset(&us, 0, sizeof(us)); 08481 if (ies->apparent_addr) { 08482 memmove(&us, ies->apparent_addr, sizeof(us)); 08483 } 08484 if (ies->username) { 08485 ast_copy_string(peer, ies->username, sizeof(peer)); 08486 } 08487 if (ies->refresh) { 08488 refresh = ies->refresh; 08489 } 08490 if (ies->calling_number) { 08491 /* We don't do anything with it really, but maybe we should */ 08492 } 08493 reg = iaxs[callno]->reg; 08494 if (!reg) { 08495 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08496 return -1; 08497 } 08498 memcpy(&oldus, ®->us, sizeof(oldus)); 08499 oldmsgs = reg->messages; 08500 ast_sockaddr_to_sin(®->addr, ®_addr); 08501 if (inaddrcmp(®_addr, sin)) { 08502 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08503 return -1; 08504 } 08505 memcpy(®->us, &us, sizeof(reg->us)); 08506 if (ies->msgcount >= 0) { 08507 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08508 } 08509 /* always refresh the registration at the interval requested by the server 08510 we are registering to 08511 */ 08512 reg->refresh = refresh; 08513 reg->expire = iax2_sched_replace(reg->expire, sched, 08514 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08515 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08516 if (reg->messages > 255) { 08517 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08518 } else if (reg->messages > 1) { 08519 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages); 08520 } else if (reg->messages > 0) { 08521 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus)); 08522 } else { 08523 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus)); 08524 } 08525 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08526 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08527 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08528 } 08529 reg->regstate = REG_STATE_REGISTERED; 08530 return 0; 08531 }
| static int attribute_pure iax2_allow_new | ( | int | frametype, | |
| int | subclass, | |||
| int | inbound | |||
| ) | [inline, static] |
Definition at line 2756 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().
02757 { 02758 if (frametype != AST_FRAME_IAX) { 02759 return 0; 02760 } 02761 switch (subclass) { 02762 case IAX_COMMAND_NEW: 02763 case IAX_COMMAND_REGREQ: 02764 case IAX_COMMAND_FWDOWNL: 02765 case IAX_COMMAND_REGREL: 02766 return 1; 02767 case IAX_COMMAND_POKE: 02768 if (!inbound) { 02769 return 1; 02770 } 02771 break; 02772 } 02773 return 0; 02774 }
| 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 1323 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().
01324 { 01325 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01326 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01327 pvt->owner ? pvt->owner->name : "", 01328 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01329 }
| static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5649 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.
05650 { 05651 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05652 ast_debug(1, "Answering IAX2 call\n"); 05653 ast_mutex_lock(&iaxsl[callno]); 05654 if (iaxs[callno]) 05655 iax2_ami_channelupdate(iaxs[callno]); 05656 ast_mutex_unlock(&iaxsl[callno]); 05657 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05658 }
| static int iax2_append_register | ( | const char * | hostname, | |
| const char * | username, | |||
| const char * | secret, | |||
| const char * | porta | |||
| ) | [static] |
Definition at line 8533 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().
08535 { 08536 struct iax2_registry *reg; 08537 08538 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08539 return -1; 08540 08541 reg->addr.ss.ss_family = AF_INET; 08542 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08543 ast_free(reg); 08544 return -1; 08545 } 08546 08547 ast_copy_string(reg->username, username, sizeof(reg->username)); 08548 08549 if (secret) 08550 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08551 08552 reg->expire = -1; 08553 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08554 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); 08555 08556 AST_LIST_LOCK(®istrations); 08557 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08558 AST_LIST_UNLOCK(®istrations); 08559 08560 return 0; 08561 }
| 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 5478 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().
05479 { 05480 struct ast_channel *cs[3]; 05481 struct ast_channel *who, *other; 05482 int to = -1; 05483 int res = -1; 05484 int transferstarted=0; 05485 struct ast_frame *f; 05486 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05487 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05488 struct timeval waittimer = {0, 0}; 05489 05490 /* We currently do not support native bridging if a timeoutms value has been provided */ 05491 if (timeoutms > 0) { 05492 return AST_BRIDGE_FAILED; 05493 } 05494 05495 timeoutms = -1; 05496 05497 lock_both(callno0, callno1); 05498 if (!iaxs[callno0] || !iaxs[callno1]) { 05499 unlock_both(callno0, callno1); 05500 return AST_BRIDGE_FAILED; 05501 } 05502 /* Put them in native bridge mode */ 05503 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05504 iaxs[callno0]->bridgecallno = callno1; 05505 iaxs[callno1]->bridgecallno = callno0; 05506 } 05507 unlock_both(callno0, callno1); 05508 05509 /* If not, try to bridge until we can execute a transfer, if we can */ 05510 cs[0] = c0; 05511 cs[1] = c1; 05512 for (/* ever */;;) { 05513 /* Check in case we got masqueraded into */ 05514 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05515 ast_verb(3, "Can't masquerade, we're different...\n"); 05516 /* Remove from native mode */ 05517 if (c0->tech == &iax2_tech) { 05518 ast_mutex_lock(&iaxsl[callno0]); 05519 iaxs[callno0]->bridgecallno = 0; 05520 ast_mutex_unlock(&iaxsl[callno0]); 05521 } 05522 if (c1->tech == &iax2_tech) { 05523 ast_mutex_lock(&iaxsl[callno1]); 05524 iaxs[callno1]->bridgecallno = 0; 05525 ast_mutex_unlock(&iaxsl[callno1]); 05526 } 05527 return AST_BRIDGE_FAILED_NOWARN; 05528 } 05529 if (c0->nativeformats != c1->nativeformats) { 05530 char buf0[256]; 05531 char buf1[256]; 05532 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats); 05533 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats); 05534 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1); 05535 /* Remove from native mode */ 05536 lock_both(callno0, callno1); 05537 if (iaxs[callno0]) 05538 iaxs[callno0]->bridgecallno = 0; 05539 if (iaxs[callno1]) 05540 iaxs[callno1]->bridgecallno = 0; 05541 unlock_both(callno0, callno1); 05542 return AST_BRIDGE_FAILED_NOWARN; 05543 } 05544 /* check if transfered and if we really want native bridging */ 05545 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) { 05546 /* Try the transfer */ 05547 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05548 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA))) 05549 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05550 transferstarted = 1; 05551 } 05552 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05553 /* Call has been transferred. We're no longer involved */ 05554 struct timeval now = ast_tvnow(); 05555 if (ast_tvzero(waittimer)) { 05556 waittimer = now; 05557 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05558 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05559 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05560 *fo = NULL; 05561 *rc = c0; 05562 res = AST_BRIDGE_COMPLETE; 05563 break; 05564 } 05565 } 05566 to = 1000; 05567 who = ast_waitfor_n(cs, 2, &to); 05568 /* XXX This will need to be updated to calculate 05569 * timeout correctly once timeoutms is allowed to be 05570 * > 0. Right now, this can go badly if the waitfor 05571 * times out in less than a millisecond 05572 */ 05573 if (timeoutms > -1) { 05574 timeoutms -= (1000 - to); 05575 if (timeoutms < 0) 05576 timeoutms = 0; 05577 } 05578 if (!who) { 05579 if (!timeoutms) { 05580 res = AST_BRIDGE_RETRY; 05581 break; 05582 } 05583 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05584 res = AST_BRIDGE_FAILED; 05585 break; 05586 } 05587 continue; 05588 } 05589 f = ast_read(who); 05590 if (!f) { 05591 *fo = NULL; 05592 *rc = who; 05593 res = AST_BRIDGE_COMPLETE; 05594 break; 05595 } 05596 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05597 if (f->frametype == AST_FRAME_CONTROL && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 05598 switch (f->subclass.integer) { 05599 case AST_CONTROL_VIDUPDATE: 05600 case AST_CONTROL_SRCUPDATE: 05601 case AST_CONTROL_SRCCHANGE: 05602 case AST_CONTROL_T38_PARAMETERS: 05603 ast_write(other, f); 05604 break; 05605 default: 05606 *fo = f; 05607 *rc = who; 05608 res = AST_BRIDGE_COMPLETE; 05609 break; 05610 } 05611 if (res == AST_BRIDGE_COMPLETE) { 05612 break; 05613 } 05614 } else if (f->frametype == AST_FRAME_VOICE 05615 || f->frametype == AST_FRAME_TEXT 05616 || f->frametype == AST_FRAME_VIDEO 05617 || f->frametype == AST_FRAME_IMAGE) { 05618 ast_write(other, f); 05619 } else if (f->frametype == AST_FRAME_DTMF) { 05620 /* monitored dtmf take out of the bridge. 05621 * check if we monitor the specific source. 05622 */ 05623 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05624 05625 if (flags & monitored_source) { 05626 *rc = who; 05627 *fo = f; 05628 res = AST_BRIDGE_COMPLETE; 05629 /* Remove from native mode */ 05630 break; 05631 } 05632 ast_write(other, f); 05633 } 05634 ast_frfree(f); 05635 /* Swap who gets priority */ 05636 cs[2] = cs[0]; 05637 cs[0] = cs[1]; 05638 cs[1] = cs[2]; 05639 } 05640 lock_both(callno0, callno1); 05641 if(iaxs[callno0]) 05642 iaxs[callno0]->bridgecallno = 0; 05643 if(iaxs[callno1]) 05644 iaxs[callno1]->bridgecallno = 0; 05645 unlock_both(callno0, callno1); 05646 return res; 05647 }
| static int iax2_call | ( | struct ast_channel * | c, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 5026 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.
05027 { 05028 struct sockaddr_in sin; 05029 char *l=NULL, *n=NULL, *tmpstr; 05030 struct iax_ie_data ied; 05031 char *defaultrdest = "s"; 05032 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05033 struct parsed_dial_string pds; 05034 struct create_addr_info cai; 05035 struct ast_var_t *var; 05036 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 05037 const char* osp_token_ptr; 05038 unsigned int osp_token_length; 05039 unsigned char osp_block_index; 05040 unsigned int osp_block_length; 05041 unsigned char osp_buffer[256]; 05042 05043 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 05044 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 05045 return -1; 05046 } 05047 05048 memset(&cai, 0, sizeof(cai)); 05049 cai.encmethods = iax2_encryption; 05050 05051 memset(&pds, 0, sizeof(pds)); 05052 tmpstr = ast_strdupa(dest); 05053 parse_dial_string(tmpstr, &pds); 05054 05055 if (ast_strlen_zero(pds.peer)) { 05056 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 05057 return -1; 05058 } 05059 if (!pds.exten) { 05060 pds.exten = defaultrdest; 05061 } 05062 if (create_addr(pds.peer, c, &sin, &cai)) { 05063 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 05064 return -1; 05065 } 05066 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) { 05067 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n"); 05068 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05069 return -1; 05070 } 05071 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 05072 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 05073 return -1; 05074 } 05075 if (!pds.username && !ast_strlen_zero(cai.username)) 05076 pds.username = cai.username; 05077 if (!pds.password && !ast_strlen_zero(cai.secret)) 05078 pds.password = cai.secret; 05079 if (!pds.key && !ast_strlen_zero(cai.outkey)) 05080 pds.key = cai.outkey; 05081 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 05082 pds.context = cai.peercontext; 05083 05084 /* Keep track of the context for outgoing calls too */ 05085 ast_copy_string(c->context, cai.context, sizeof(c->context)); 05086 05087 if (pds.port) 05088 sin.sin_port = htons(atoi(pds.port)); 05089 05090 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL; 05091 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL; 05092 05093 /* Now build request */ 05094 memset(&ied, 0, sizeof(ied)); 05095 05096 /* On new call, first IE MUST be IAX version of caller */ 05097 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 05098 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 05099 if (pds.options && strchr(pds.options, 'a')) { 05100 /* Request auto answer */ 05101 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 05102 } 05103 05104 /* WARNING: this breaks down at 190 bits! */ 05105 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 05106 05107 if (l) { 05108 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 05109 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05110 ast_party_id_presentation(&c->connected.id)); 05111 } else if (n) { 05112 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05113 ast_party_id_presentation(&c->connected.id)); 05114 } else { 05115 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 05116 } 05117 05118 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan); 05119 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select); 05120 05121 if (n) 05122 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 05123 if (ast_test_flag64(iaxs[callno], IAX_SENDANI) 05124 && c->connected.ani.number.valid 05125 && c->connected.ani.number.str) { 05126 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str); 05127 } 05128 05129 if (!ast_strlen_zero(c->language)) 05130 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 05131 if (!ast_strlen_zero(c->dialed.number.str)) { 05132 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str); 05133 } 05134 if (c->redirecting.from.number.valid 05135 && !ast_strlen_zero(c->redirecting.from.number.str)) { 05136 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str); 05137 } 05138 05139 if (pds.context) 05140 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 05141 05142 if (pds.username) 05143 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 05144 05145 if (cai.encmethods) 05146 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 05147 05148 ast_mutex_lock(&iaxsl[callno]); 05149 05150 if (!ast_strlen_zero(c->context)) 05151 ast_string_field_set(iaxs[callno], context, c->context); 05152 05153 if (pds.username) 05154 ast_string_field_set(iaxs[callno], username, pds.username); 05155 05156 iaxs[callno]->encmethods = cai.encmethods; 05157 05158 iaxs[callno]->adsi = cai.adsi; 05159 05160 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 05161 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 05162 05163 if (pds.key) 05164 ast_string_field_set(iaxs[callno], outkey, pds.key); 05165 if (pds.password) 05166 ast_string_field_set(iaxs[callno], secret, pds.password); 05167 05168 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats); 05169 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats); 05170 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability); 05171 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability); 05172 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 05173 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 05174 05175 if (iaxs[callno]->maxtime) { 05176 /* Initialize pingtime and auto-congest time */ 05177 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 05178 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 05179 } else if (autokill) { 05180 iaxs[callno]->pingtime = autokill / 2; 05181 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 05182 } 05183 05184 /* Check if there is an OSP token */ 05185 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 05186 if (!ast_strlen_zero(osp_token_ptr)) { 05187 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 05188 osp_block_index = 0; 05189 while (osp_token_length > 0) { 05190 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 05191 osp_buffer[0] = osp_block_index; 05192 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 05193 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 05194 osp_block_index++; 05195 osp_token_ptr += osp_block_length; 05196 osp_token_length -= osp_block_length; 05197 } 05198 } else 05199 ast_log(LOG_WARNING, "OSP token is too long\n"); 05200 } else if (iaxdebug) 05201 ast_debug(1, "OSP token is undefined\n"); 05202 05203 /* send the command using the appropriate socket for this peer */ 05204 iaxs[callno]->sockfd = cai.sockfd; 05205 05206 /* Add remote vars */ 05207 if (variablestore) { 05208 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 05209 ast_debug(1, "Found an IAX variable store on this channel\n"); 05210 AST_LIST_LOCK(variablelist); 05211 AST_LIST_TRAVERSE(variablelist, var, entries) { 05212 char tmp[256]; 05213 int i; 05214 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 05215 /* Automatically divide the value up into sized chunks */ 05216 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 05217 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 05218 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 05219 } 05220 } 05221 AST_LIST_UNLOCK(variablelist); 05222 } 05223 05224 /* Transmit the string in a "NEW" request */ 05225 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 05226 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 05227 05228 ast_mutex_unlock(&iaxsl[callno]); 05229 ast_setstate(c, AST_STATE_RINGING); 05230 05231 return 0; 05232 }
| 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 13898 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.
13899 { 13900 int res = 0; 13901 struct iax2_dpcache *dp = NULL; 13902 #if 0 13903 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13904 #endif 13905 if ((priority != 1) && (priority != 2)) 13906 return 0; 13907 13908 AST_LIST_LOCK(&dpcache); 13909 if ((dp = find_cache(chan, data, context, exten, priority))) { 13910 if (dp->flags & CACHE_FLAG_CANEXIST) 13911 res = 1; 13912 } else { 13913 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13914 } 13915 AST_LIST_UNLOCK(&dpcache); 13916 13917 return res; 13918 }
| static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4697 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().
04698 { 04699 struct timeval t = ast_tvnow(); 04700 struct ast_tm tm; 04701 unsigned int tmp; 04702 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04703 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04704 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04705 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04706 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04707 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04708 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04709 return tmp; 04710 }
| static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3392 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().
03393 { 03394 struct chan_iax2_pvt *pvt = NULL; 03395 struct ast_channel *owner = NULL; 03396 03397 retry: 03398 if ((pvt = iaxs[callno])) { 03399 #if 0 03400 /* iax2_destroy_helper gets called from this function later on. When 03401 * called twice, we get the (previously) familiar FRACK! errors in 03402 * devmode, from the scheduler. An alternative to this approach is to 03403 * reset the scheduler entries to -1 when they're deleted in 03404 * iax2_destroy_helper(). That approach was previously decided to be 03405 * "wrong" because "the memory is going to be deallocated anyway. Why 03406 * should we be resetting those values?" */ 03407 iax2_destroy_helper(pvt); 03408 #endif 03409 } 03410 03411 owner = pvt ? pvt->owner : NULL; 03412 03413 if (owner) { 03414 if (ast_channel_trylock(owner)) { 03415 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03416 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03417 goto retry; 03418 } 03419 } 03420 03421 if (!owner) { 03422 iaxs[callno] = NULL; 03423 } 03424 03425 if (pvt) { 03426 if (!owner) { 03427 pvt->owner = NULL; 03428 } else { 03429 /* If there's an owner, prod it to give up */ 03430 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03431 * because we already hold the owner channel lock. */ 03432 ast_queue_hangup(owner); 03433 } 03434 03435 if (pvt->peercallno) { 03436 remove_by_peercallno(pvt); 03437 } 03438 03439 if (pvt->transfercallno) { 03440 remove_by_transfercallno(pvt); 03441 } 03442 03443 if (!owner) { 03444 ao2_ref(pvt, -1); 03445 pvt = NULL; 03446 } 03447 } 03448 03449 if (owner) { 03450 ast_channel_unlock(owner); 03451 } 03452 03453 if (callno & TRUNK_CALL_START) { 03454 update_max_trunk(); 03455 } 03456 }
| static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1771 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().
01772 { 01773 /* Decrement AUTHREQ count if needed */ 01774 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) { 01775 struct iax2_user *user; 01776 struct iax2_user tmp_user = { 01777 .name = pvt->username, 01778 }; 01779 01780 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01781 if (user) { 01782 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01783 user_unref(user); 01784 } 01785 01786 ast_clear_flag64(pvt, IAX_MAXAUTHREQ); 01787 } 01788 /* No more pings or lagrq's */ 01789 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]); 01790 pvt->pingid = DONT_RESCHEDULE; 01791 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]); 01792 pvt->lagid = DONT_RESCHEDULE; 01793 ast_sched_thread_del(sched, pvt->autoid); 01794 ast_sched_thread_del(sched, pvt->authid); 01795 ast_sched_thread_del(sched, pvt->initid); 01796 ast_sched_thread_del(sched, pvt->jbid); 01797 ast_sched_thread_del(sched, pvt->keyrotateid); 01798 }
| static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 14104 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().
14105 { 14106 struct parsed_dial_string pds; 14107 char *tmp = ast_strdupa(data); 14108 struct iax2_peer *p; 14109 int res = AST_DEVICE_INVALID; 14110 14111 memset(&pds, 0, sizeof(pds)); 14112 parse_dial_string(tmp, &pds); 14113 14114 if (ast_strlen_zero(pds.peer)) { 14115 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 14116 return res; 14117 } 14118 14119 ast_debug(3, "Checking device state for device %s\n", pds.peer); 14120 14121 /* SLD: FIXME: second call to find_peer during registration */ 14122 if (!(p = find_peer(pds.peer, 1))) 14123 return res; 14124 14125 res = AST_DEVICE_UNAVAILABLE; 14126 ast_debug(3, "Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 14127 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 14128 14129 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) && 14130 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 14131 /* Peer is registered, or have default IP address 14132 and a valid registration */ 14133 if (p->historicms == 0 || p->historicms <= p->maxms) 14134 /* let the core figure out whether it is in use or not */ 14135 res = AST_DEVICE_UNKNOWN; 14136 } 14137 14138 peer_unref(p); 14139 14140 return res; 14141 }
| static int iax2_digit_begin | ( | struct ast_channel * | c, | |
| char | digit | |||
| ) | [static] |
Definition at line 4298 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04299 { 04300 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04301 }
| static int iax2_digit_end | ( | struct ast_channel * | c, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 4303 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04304 { 04305 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04306 }
| static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11879 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().
11880 { 11881 struct iax_ie_data ied; 11882 if (iaxdebug) 11883 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11884 11885 if (reg->dnsmgr && 11886 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) { 11887 /* Maybe the IP has changed, force DNS refresh */ 11888 ast_dnsmgr_refresh(reg->dnsmgr); 11889 } 11890 11891 /* 11892 * if IP has Changed, free allocated call to create a new one with new IP 11893 * call has the pointer to IP and must be updated to the new one 11894 */ 11895 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11896 int callno = reg->callno; 11897 ast_mutex_lock(&iaxsl[callno]); 11898 iax2_destroy(callno); 11899 ast_mutex_unlock(&iaxsl[callno]); 11900 reg->callno = 0; 11901 } 11902 if (!ast_sockaddr_ipv4(®->addr)) { 11903 if (iaxdebug) 11904 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11905 /* Setup the next registration attempt */ 11906 reg->expire = iax2_sched_replace(reg->expire, sched, 11907 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11908 return -1; 11909 } 11910 11911 if (!reg->callno) { 11912 struct sockaddr_in reg_addr; 11913 11914 ast_debug(3, "Allocate call number\n"); 11915 11916 ast_sockaddr_to_sin(®->addr, ®_addr); 11917 11918 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0); 11919 if (reg->callno < 1) { 11920 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11921 return -1; 11922 } else 11923 ast_debug(3, "Registration created on call %d\n", reg->callno); 11924 iaxs[reg->callno]->reg = reg; 11925 ast_mutex_unlock(&iaxsl[reg->callno]); 11926 } 11927 /* Setup the next registration a little early */ 11928 reg->expire = iax2_sched_replace(reg->expire, sched, 11929 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11930 /* Send the request */ 11931 memset(&ied, 0, sizeof(ied)); 11932 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11933 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11934 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11935 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11936 reg->regstate = REG_STATE_REGSENT; 11937 return 0; 11938 }
| static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8315 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
08316 { 08317 #ifdef SCHED_MULTITHREADED 08318 if (schedule_action(__iax2_do_register_s, data)) 08319 #endif 08320 __iax2_do_register_s(data); 08321 return 0; 08322 }
| static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
| int | callno | |||
| ) | [static] |
Definition at line 9091 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().
09092 { 09093 struct iax_ie_data ied; 09094 /* Auto-hangup with 30 seconds of inactivity */ 09095 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 09096 sched, 30000, auto_hangup, (void *)(long)callno); 09097 memset(&ied, 0, sizeof(ied)); 09098 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 09099 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 09100 dp->flags |= CACHE_FLAG_TRANSMITTED; 09101 }
| static void * iax2_dup_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1337 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.
01338 { 01339 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01340 struct ast_var_t *oldvar, *newvar; 01341 01342 newlist = ast_calloc(sizeof(*newlist), 1); 01343 if (!newlist) { 01344 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01345 return NULL; 01346 } 01347 01348 AST_LIST_HEAD_INIT(newlist); 01349 AST_LIST_LOCK(oldlist); 01350 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01351 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01352 if (newvar) 01353 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01354 else 01355 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01356 } 01357 AST_LIST_UNLOCK(oldlist); 01358 return newlist; 01359 }
| 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 13944 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().
13945 { 13946 char odata[256]; 13947 char req[256]; 13948 char *ncontext; 13949 struct iax2_dpcache *dp = NULL; 13950 struct ast_app *dial = NULL; 13951 #if 0 13952 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); 13953 #endif 13954 if (priority == 2) { 13955 /* Indicate status, can be overridden in dialplan */ 13956 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13957 if (dialstatus) { 13958 dial = pbx_findapp(dialstatus); 13959 if (dial) 13960 pbx_exec(chan, dial, ""); 13961 } 13962 return -1; 13963 } else if (priority != 1) 13964 return -1; 13965 13966 AST_LIST_LOCK(&dpcache); 13967 if ((dp = find_cache(chan, data, context, exten, priority))) { 13968 if (dp->flags & CACHE_FLAG_EXISTS) { 13969 ast_copy_string(odata, data, sizeof(odata)); 13970 ncontext = strchr(odata, '/'); 13971 if (ncontext) { 13972 *ncontext = '\0'; 13973 ncontext++; 13974 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13975 } else { 13976 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13977 } 13978 ast_verb(3, "Executing Dial('%s')\n", req); 13979 } else { 13980 AST_LIST_UNLOCK(&dpcache); 13981 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13982 return -1; 13983 } 13984 } 13985 AST_LIST_UNLOCK(&dpcache); 13986 13987 if ((dial = pbx_findapp("Dial"))) 13988 return pbx_exec(chan, dial, req); 13989 else 13990 ast_log(LOG_WARNING, "No dial application registered\n"); 13991 13992 return -1; 13993 }
| 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 13875 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.
13876 { 13877 int res = 0; 13878 struct iax2_dpcache *dp = NULL; 13879 #if 0 13880 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13881 #endif 13882 if ((priority != 1) && (priority != 2)) 13883 return 0; 13884 13885 AST_LIST_LOCK(&dpcache); 13886 if ((dp = find_cache(chan, data, context, exten, priority))) { 13887 if (dp->flags & CACHE_FLAG_EXISTS) 13888 res = 1; 13889 } else { 13890 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13891 } 13892 AST_LIST_UNLOCK(&dpcache); 13893 13894 return res; 13895 }
| static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 4325 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.
04326 { 04327 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04328 ast_mutex_lock(&iaxsl[callno]); 04329 if (iaxs[callno]) 04330 iaxs[callno]->owner = newchan; 04331 else 04332 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04333 ast_mutex_unlock(&iaxsl[callno]); 04334 return 0; 04335 }
| static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1800 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().
01801 { 01802 ast_sched_thread_del(sched, fr->retrans); 01803 iax_frame_free(fr); 01804 }
| static void iax2_free_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1361 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.
01362 { 01363 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01364 struct ast_var_t *oldvar; 01365 01366 AST_LIST_LOCK(oldlist); 01367 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01368 ast_free(oldvar); 01369 } 01370 AST_LIST_UNLOCK(oldlist); 01371 AST_LIST_HEAD_DESTROY(oldlist); 01372 ast_free(oldlist); 01373 }
| static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
| char * | host, | |||
| int | len | |||
| ) | [static] |
Definition at line 1734 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().
01735 { 01736 struct iax2_peer *peer = NULL; 01737 int res = 0; 01738 struct ao2_iterator i; 01739 01740 i = ao2_iterator_init(peers, 0); 01741 while ((peer = ao2_iterator_next(&i))) { 01742 struct sockaddr_in peer_addr; 01743 01744 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 01745 01746 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01747 (peer_addr.sin_port == sin.sin_port)) { 01748 ast_copy_string(host, peer->name, len); 01749 peer_unref(peer); 01750 res = 1; 01751 break; 01752 } 01753 peer_unref(peer); 01754 } 01755 ao2_iterator_destroy(&i); 01756 01757 if (!peer) { 01758 peer = realtime_peer(NULL, &sin); 01759 if (peer) { 01760 ast_copy_string(host, peer->name, len); 01761 peer_unref(peer); 01762 res = 1; 01763 } 01764 } 01765 01766 return res; 01767 }
| static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5724 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().
05725 { 05726 struct iax2_peer *peer; 05727 int res = 0; 05728 struct ao2_iterator i; 05729 05730 i = ao2_iterator_init(peers, 0); 05731 while ((peer = ao2_iterator_next(&i))) { 05732 struct sockaddr_in peer_addr; 05733 05734 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 05735 05736 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05737 (peer_addr.sin_port == sin.sin_port)) { 05738 res = ast_test_flag64(peer, IAX_TRUNK); 05739 peer_unref(peer); 05740 break; 05741 } 05742 peer_unref(peer); 05743 } 05744 ao2_iterator_destroy(&i); 05745 05746 return res; 05747 }
| static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5234 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.
05235 { 05236 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05237 struct iax_ie_data ied; 05238 int alreadygone; 05239 memset(&ied, 0, sizeof(ied)); 05240 ast_mutex_lock(&iaxsl[callno]); 05241 if (callno && iaxs[callno]) { 05242 ast_debug(1, "We're hanging up %s now...\n", c->name); 05243 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE); 05244 /* Send the hangup unless we have had a transmission error or are already gone */ 05245 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 05246 if (!iaxs[callno]->error && !alreadygone) { 05247 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 05248 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 05249 } 05250 if (!iaxs[callno]) { 05251 ast_mutex_unlock(&iaxsl[callno]); 05252 return 0; 05253 } 05254 } 05255 /* Explicitly predestroy it */ 05256 iax2_predestroy(callno); 05257 /* If we were already gone to begin with, destroy us now */ 05258 if (iaxs[callno] && alreadygone) { 05259 ast_debug(1, "Really destroying %s now...\n", c->name); 05260 iax2_destroy(callno); 05261 } else if (iaxs[callno]) { 05262 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 05263 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05264 iax2_destroy(callno); 05265 } 05266 } 05267 } else if (c->tech_pvt) { 05268 /* If this call no longer exists, but the channel still 05269 * references it we need to set the channel's tech_pvt to null 05270 * to avoid ast_channel_free() trying to free it. 05271 */ 05272 c->tech_pvt = NULL; 05273 } 05274 ast_mutex_unlock(&iaxsl[callno]); 05275 ast_verb(3, "Hungup '%s'\n", c->name); 05276 return 0; 05277 }
| static int iax2_indicate | ( | struct ast_channel * | c, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 5660 of file chan_iax2.c.
References AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, 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().
05661 { 05662 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05663 struct chan_iax2_pvt *pvt; 05664 int res = 0; 05665 05666 if (iaxdebug) 05667 ast_debug(1, "Indicating condition %d\n", condition); 05668 05669 ast_mutex_lock(&iaxsl[callno]); 05670 pvt = iaxs[callno]; 05671 05672 if (wait_for_peercallno(pvt)) { 05673 res = -1; 05674 goto done; 05675 } 05676 05677 switch (condition) { 05678 case AST_CONTROL_HOLD: 05679 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05680 ast_moh_start(c, data, pvt->mohinterpret); 05681 goto done; 05682 } 05683 break; 05684 case AST_CONTROL_UNHOLD: 05685 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05686 ast_moh_stop(c); 05687 goto done; 05688 } 05689 break; 05690 case AST_CONTROL_CONNECTED_LINE: 05691 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) 05692 goto done; 05693 break; 05694 } 05695 05696 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05697 05698 done: 05699 ast_mutex_unlock(&iaxsl[callno]); 05700 05701 return res; 05702 }
| static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5396 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().
05397 { 05398 int res = 0; 05399 struct chan_iax2_pvt *pvt = (void *) vpvt; 05400 struct MD5Context md5; 05401 char key[17] = ""; 05402 struct iax_ie_data ied = { 05403 .pos = 0, 05404 }; 05405 05406 ast_mutex_lock(&iaxsl[pvt->callno]); 05407 pvt->keyrotateid = 05408 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05409 05410 snprintf(key, sizeof(key), "%lX", ast_random()); 05411 05412 MD5Init(&md5); 05413 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05414 MD5Final((unsigned char *) key, &md5); 05415 05416 IAX_DEBUGDIGEST("Sending", key); 05417 05418 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05419 05420 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05421 05422 build_ecx_key((unsigned char *) key, pvt); 05423 05424 ast_mutex_unlock(&iaxsl[pvt->callno]); 05425 05426 return res; 05427 }
| 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 13921 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.
13922 { 13923 int res = 0; 13924 struct iax2_dpcache *dp = NULL; 13925 #if 0 13926 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13927 #endif 13928 if ((priority != 1) && (priority != 2)) 13929 return 0; 13930 13931 AST_LIST_LOCK(&dpcache); 13932 if ((dp = find_cache(chan, data, context, exten, priority))) { 13933 if (dp->flags & CACHE_FLAG_MATCHMORE) 13934 res = 1; 13935 } else { 13936 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13937 } 13938 AST_LIST_UNLOCK(&dpcache); 13939 13940 return res; 13941 }
| static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12083 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
12084 { 12085 struct iax2_peer *peer = (struct iax2_peer *)data; 12086 peer->pokeexpire = -1; 12087 #ifdef SCHED_MULTITHREADED 12088 if (schedule_action(__iax2_poke_noanswer, data)) 12089 #endif 12090 __iax2_poke_noanswer(data); 12091 peer_unref(peer); 12092 return 0; 12093 }
| static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
| int | heldcall | |||
| ) | [static] |
Definition at line 12104 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().
12105 { 12106 int callno; 12107 struct sockaddr_in peer_addr; 12108 12109 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) { 12110 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 12111 immediately after clearing things out */ 12112 peer->lastms = 0; 12113 peer->historicms = 0; 12114 peer->pokeexpire = -1; 12115 peer->callno = 0; 12116 return 0; 12117 } 12118 12119 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 12120 12121 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 12122 if ((callno = peer->callno) > 0) { 12123 ast_log(LOG_NOTICE, "Still have a callno...\n"); 12124 ast_mutex_lock(&iaxsl[callno]); 12125 iax2_destroy(callno); 12126 ast_mutex_unlock(&iaxsl[callno]); 12127 } 12128 if (heldcall) 12129 ast_mutex_unlock(&iaxsl[heldcall]); 12130 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0); 12131 if (heldcall) 12132 ast_mutex_lock(&iaxsl[heldcall]); 12133 if (peer->callno < 1) { 12134 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 12135 return -1; 12136 } 12137 12138 /* Speed up retransmission times for this qualify call */ 12139 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 12140 iaxs[peer->callno]->peerpoke = peer; 12141 12142 if (peer->pokeexpire > -1) { 12143 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 12144 peer->pokeexpire = -1; 12145 peer_unref(peer); 12146 } 12147 } 12148 12149 /* Queue up a new task to handle no reply */ 12150 /* If the host is already unreachable then use the unreachable interval instead */ 12151 if (peer->lastms < 0) 12152 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 12153 else 12154 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 12155 12156 if (peer->pokeexpire == -1) 12157 peer_unref(peer); 12158 12159 /* And send the poke */ 12160 ast_mutex_lock(&iaxsl[callno]); 12161 if (iaxs[callno]) { 12162 struct iax_ie_data ied = { 12163 .buf = { 0 }, 12164 .pos = 0, 12165 }; 12166 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 12167 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 12168 } 12169 ast_mutex_unlock(&iaxsl[callno]); 12170 12171 return 0; 12172 }
| static int iax2_poke_peer_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 12095 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
12096 { 12097 struct iax2_peer *peer = obj; 12098 12099 iax2_poke_peer(peer, 0); 12100 12101 return 0; 12102 }
| static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9128 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
09129 { 09130 struct iax2_peer *peer = (struct iax2_peer *)data; 09131 peer->pokeexpire = -1; 09132 #ifdef SCHED_MULTITHREADED 09133 if (schedule_action(__iax2_poke_peer_s, data)) 09134 #endif 09135 __iax2_poke_peer_s(data); 09136 return 0; 09137 }
| static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3369 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().
03370 { 03371 struct ast_channel *c = NULL; 03372 struct chan_iax2_pvt *pvt = iaxs[callno]; 03373 03374 if (!pvt) 03375 return -1; 03376 03377 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) { 03378 iax2_destroy_helper(pvt); 03379 ast_set_flag64(pvt, IAX_ALREADYGONE); 03380 } 03381 03382 if ((c = pvt->owner)) { 03383 c->tech_pvt = NULL; 03384 iax2_queue_hangup(callno); 03385 pvt->owner = NULL; 03386 ast_module_unref(ast_module_info->self); 03387 } 03388 03389 return 0; 03390 }
| static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 11733 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().
11734 { 11735 struct iax2_thread *thread = data; 11736 struct timeval wait; 11737 struct timespec ts; 11738 int put_into_idle = 0; 11739 int first_time = 1; 11740 int old_state; 11741 11742 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1); 11743 11744 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); 11745 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11746 11747 for (;;) { 11748 /* Wait for something to signal us to be awake */ 11749 ast_mutex_lock(&thread->lock); 11750 11751 if (thread->stop) { 11752 ast_mutex_unlock(&thread->lock); 11753 break; 11754 } 11755 11756 /* Flag that we're ready to accept signals */ 11757 if (first_time) { 11758 signal_condition(&thread->init_lock, &thread->init_cond); 11759 first_time = 0; 11760 } 11761 11762 /* Put into idle list if applicable */ 11763 if (put_into_idle) { 11764 insert_idle_thread(thread); 11765 } 11766 11767 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11768 struct iax2_thread *t = NULL; 11769 /* Wait to be signalled or time out */ 11770 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11771 ts.tv_sec = wait.tv_sec; 11772 ts.tv_nsec = wait.tv_usec * 1000; 11773 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11774 /* This thread was never put back into the available dynamic 11775 * thread list, so just go away. */ 11776 if (!put_into_idle || thread->stop) { 11777 ast_mutex_unlock(&thread->lock); 11778 break; 11779 } 11780 AST_LIST_LOCK(&dynamic_list); 11781 /* Account for the case where this thread is acquired *right* after a timeout */ 11782 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11783 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11784 AST_LIST_UNLOCK(&dynamic_list); 11785 if (t) { 11786 /* This dynamic thread timed out waiting for a task and was 11787 * not acquired immediately after the timeout, 11788 * so it's time to go away. */ 11789 ast_mutex_unlock(&thread->lock); 11790 break; 11791 } 11792 /* Someone grabbed our thread *right* after we timed out. 11793 * Wait for them to set us up with something to do and signal 11794 * us to continue. */ 11795 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11796 ts.tv_sec = wait.tv_sec; 11797 ts.tv_nsec = wait.tv_usec * 1000; 11798 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11799 ast_mutex_unlock(&thread->lock); 11800 break; 11801 } 11802 } 11803 } else { 11804 ast_cond_wait(&thread->cond, &thread->lock); 11805 } 11806 11807 /* Go back into our respective list */ 11808 put_into_idle = 1; 11809 11810 ast_mutex_unlock(&thread->lock); 11811 11812 if (thread->stop) { 11813 break; 11814 } 11815 11816 /* See what we need to do */ 11817 switch (thread->iostate) { 11818 case IAX_IOSTATE_IDLE: 11819 continue; 11820 case IAX_IOSTATE_READY: 11821 thread->actions++; 11822 thread->iostate = IAX_IOSTATE_PROCESSING; 11823 socket_process(thread); 11824 handle_deferred_full_frames(thread); 11825 break; 11826 case IAX_IOSTATE_SCHEDREADY: 11827 thread->actions++; 11828 thread->iostate = IAX_IOSTATE_PROCESSING; 11829 #ifdef SCHED_MULTITHREADED 11830 thread->schedfunc(thread->scheddata); 11831 #endif 11832 break; 11833 default: 11834 break; 11835 } 11836 11837 /* The network thread added us to the active_thread list when we were given 11838 * frames to process, Now that we are done, we must remove ourselves from 11839 * the active list, and return to the idle list */ 11840 AST_LIST_LOCK(&active_list); 11841 AST_LIST_REMOVE(&active_list, thread, list); 11842 AST_LIST_UNLOCK(&active_list); 11843 11844 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11845 handle_deferred_full_frames(thread); 11846 11847 time(&thread->checktime); 11848 thread->iostate = IAX_IOSTATE_IDLE; 11849 #ifdef DEBUG_SCHED_MULTITHREAD 11850 thread->curfunc[0]='\0'; 11851 #endif 11852 } 11853 11854 /*! 11855 * \note For some reason, idle threads are exiting without being 11856 * removed from an idle list, which is causing memory 11857 * corruption. Forcibly remove it from the list, if it's there. 11858 */ 11859 AST_LIST_LOCK(&idle_list); 11860 AST_LIST_REMOVE(&idle_list, thread, list); 11861 AST_LIST_UNLOCK(&idle_list); 11862 11863 AST_LIST_LOCK(&dynamic_list); 11864 AST_LIST_REMOVE(&dynamic_list, thread, list); 11865 AST_LIST_UNLOCK(&dynamic_list); 11866 11867 if (!thread->stop) { 11868 /* Nobody asked me to stop so nobody is waiting to join me. */ 11869 pthread_detach(pthread_self()); 11870 } 11871 11872 /* I am exiting here on my own volition, I need to clean up my own data structures 11873 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11874 */ 11875 pthread_cleanup_pop(1); 11876 return NULL; 11877 }
| static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11721 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().
11722 { 11723 struct iax2_thread *thread = data; 11724 ast_mutex_destroy(&thread->lock); 11725 ast_cond_destroy(&thread->cond); 11726 ast_mutex_destroy(&thread->init_lock); 11727 ast_cond_destroy(&thread->init_cond); 11728 ast_free(thread); 11729 /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */ 11730 ast_atomic_dec_and_test(&iaxactivethreadcount); 11731 }
| static int iax2_provision | ( | struct sockaddr_in * | end, | |
| int | sockfd, | |||
| const char * | dest, | |||
| const char * | template, | |||
| int | force | |||
| ) | [static] |
Definition at line 11940 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().
11941 { 11942 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11943 is found for template */ 11944 struct iax_ie_data provdata; 11945 struct iax_ie_data ied; 11946 unsigned int sig; 11947 struct sockaddr_in sin; 11948 int callno; 11949 struct create_addr_info cai; 11950 11951 memset(&cai, 0, sizeof(cai)); 11952 11953 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11954 11955 if (iax_provision_build(&provdata, &sig, template, force)) { 11956 ast_debug(1, "No provisioning found for template '%s'\n", template); 11957 return 0; 11958 } 11959 11960 if (end) { 11961 memcpy(&sin, end, sizeof(sin)); 11962 cai.sockfd = sockfd; 11963 } else if (create_addr(dest, NULL, &sin, &cai)) 11964 return -1; 11965 11966 /* Build the rest of the message */ 11967 memset(&ied, 0, sizeof(ied)); 11968 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11969 11970 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11971 if (!callno) 11972 return -1; 11973 11974 if (iaxs[callno]) { 11975 /* Schedule autodestruct in case they don't ever give us anything back */ 11976 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11977 sched, 15000, auto_hangup, (void *)(long)callno); 11978 ast_set_flag64(iaxs[callno], IAX_PROVISION); 11979 /* Got a call number now, so go ahead and send the provisioning information */ 11980 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11981 } 11982 ast_mutex_unlock(&iaxsl[callno]); 11983 11984 return 1; 11985 }
| static int iax2_queryoption | ( | struct ast_channel * | c, | |
| int | option, | |||
| void * | data, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 5373 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.
05374 { 05375 switch (option) { 05376 case AST_OPTION_SECURE_SIGNALING: 05377 case AST_OPTION_SECURE_MEDIA: 05378 { 05379 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05380 ast_mutex_lock(&iaxsl[callno]); 05381 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0; 05382 ast_mutex_unlock(&iaxsl[callno]); 05383 return 0; 05384 } 05385 default: 05386 return -1; 05387 } 05388 }
| 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 3007 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_control_data(), iax2_lock_owner(), and iaxs.
Referenced by socket_process().
03009 { 03010 iax2_lock_owner(callno); 03011 if (iaxs[callno] && iaxs[callno]->owner) { 03012 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 03013 ast_channel_unlock(iaxs[callno]->owner); 03014 } 03015 return 0; 03016 }
| 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 2961 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().
02962 { 02963 iax2_lock_owner(callno); 02964 if (iaxs[callno] && iaxs[callno]->owner) { 02965 ast_queue_frame(iaxs[callno]->owner, f); 02966 ast_channel_unlock(iaxs[callno]->owner); 02967 } 02968 return 0; 02969 }
| 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 2984 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_hangup(), iax2_lock_owner(), and iaxs.
Referenced by iax2_predestroy().
02985 { 02986 iax2_lock_owner(callno); 02987 if (iaxs[callno] && iaxs[callno]->owner) { 02988 ast_queue_hangup(iaxs[callno]->owner); 02989 ast_channel_unlock(iaxs[callno]->owner); 02990 } 02991 return 0; 02992 }
| static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 5390 of file chan_iax2.c.
References ast_debug, and ast_null_frame.
05391 { 05392 ast_debug(1, "I should never be called!\n"); 05393 return &ast_null_frame; 05394 }
| static int iax2_register | ( | const char * | value, | |
| int | lineno | |||
| ) | [static] |
Definition at line 8563 of file chan_iax2.c.
References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, and secret.
Referenced by set_config().
08564 { 08565 char copy[256]; 08566 char *username, *hostname, *secret; 08567 char *porta; 08568 char *stringp=NULL; 08569 08570 if (!value) 08571 return -1; 08572 08573 ast_copy_string(copy, value, sizeof(copy)); 08574 stringp = copy; 08575 username = strsep(&stringp, "@"); 08576 hostname = strsep(&stringp, "@"); 08577 08578 if (!hostname) { 08579 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08580 return -1; 08581 } 08582 08583 stringp = username; 08584 username = strsep(&stringp, ":"); 08585 secret = strsep(&stringp, ":"); 08586 stringp = hostname; 08587 hostname = strsep(&stringp, ":"); 08588 porta = strsep(&stringp, ":"); 08589 08590 if (porta && !atoi(porta)) { 08591 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08592 return -1; 08593 } 08594 08595 return iax2_append_register(hostname, username, secret, porta); 08596 }
| 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 12184 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.
12185 { 12186 int callno; 12187 int res; 12188 format_t fmt, native; 12189 struct sockaddr_in sin; 12190 struct ast_channel *c; 12191 struct parsed_dial_string pds; 12192 struct create_addr_info cai; 12193 char *tmpstr; 12194 12195 memset(&pds, 0, sizeof(pds)); 12196 tmpstr = ast_strdupa(data); 12197 parse_dial_string(tmpstr, &pds); 12198 12199 if (ast_strlen_zero(pds.peer)) { 12200 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12201 return NULL; 12202 } 12203 12204 memset(&cai, 0, sizeof(cai)); 12205 cai.capability = iax2_capability; 12206 12207 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12208 12209 /* Populate our address from the given */ 12210 if (create_addr(pds.peer, NULL, &sin, &cai)) { 12211 *cause = AST_CAUSE_UNREGISTERED; 12212 return NULL; 12213 } 12214 12215 if (pds.port) 12216 sin.sin_port = htons(atoi(pds.port)); 12217 12218 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12219 if (callno < 1) { 12220 ast_log(LOG_WARNING, "Unable to create call\n"); 12221 *cause = AST_CAUSE_CONGESTION; 12222 return NULL; 12223 } 12224 12225 /* If this is a trunk, update it now */ 12226 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12227 if (ast_test_flag64(&cai, IAX_TRUNK)) { 12228 int new_callno; 12229 if ((new_callno = make_trunk(callno, 1)) != -1) 12230 callno = new_callno; 12231 } 12232 iaxs[callno]->maxtime = cai.maxtime; 12233 if (cai.found) 12234 ast_string_field_set(iaxs[callno], host, pds.peer); 12235 12236 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found); 12237 12238 ast_mutex_unlock(&iaxsl[callno]); 12239 12240 if (c) { 12241 /* Choose a format we can live with */ 12242 if (c->nativeformats & format) 12243 c->nativeformats &= format; 12244 else { 12245 native = c->nativeformats; 12246 fmt = format; 12247 res = ast_translator_best_choice(&fmt, &native); 12248 if (res < 0) { 12249 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 12250 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 12251 ast_hangup(c); 12252 return NULL; 12253 } 12254 c->nativeformats = native; 12255 } 12256 c->readformat = ast_best_codec(c->nativeformats); 12257 c->writeformat = c->readformat; 12258 } 12259 12260 return c; 12261 }
| static int iax2_sched_add | ( | struct ast_sched_thread * | st, | |
| int | when, | |||
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 1497 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().
01499 { 01500 return ast_sched_thread_add(st, when, callback, data); 01501 }
| 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 1489 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().
01491 { 01492 ast_sched_thread_del(st, id); 01493 01494 return ast_sched_thread_add(st, when, callback, data); 01495 }
| 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 6389 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().
06390 { 06391 /* Queue a packet for delivery on a given private structure. Use "ts" for 06392 timestamp, or calculate if ts is 0. Send immediately without retransmission 06393 or delayed, with retransmission */ 06394 struct ast_iax2_full_hdr *fh; 06395 struct ast_iax2_mini_hdr *mh; 06396 struct ast_iax2_video_hdr *vh; 06397 struct { 06398 struct iax_frame fr2; 06399 unsigned char buffer[4096]; 06400 } frb; 06401 struct iax_frame *fr; 06402 int res; 06403 int sendmini=0; 06404 unsigned int lastsent; 06405 unsigned int fts; 06406 06407 frb.fr2.afdatalen = sizeof(frb.buffer); 06408 06409 if (!pvt) { 06410 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06411 return -1; 06412 } 06413 06414 lastsent = pvt->lastsent; 06415 06416 /* Calculate actual timestamp */ 06417 fts = calc_timestamp(pvt, ts, f); 06418 06419 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06420 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06421 * increment the "predicted timestamps" for voice, if we're predicting */ 06422 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06423 return 0; 06424 #if 0 06425 ast_log(LOG_NOTICE, 06426 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06427 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06428 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06429 pvt->keyrotateid != -1 ? "" : "no " 06430 ); 06431 #endif 06432 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06433 iax2_key_rotate(pvt); 06434 } 06435 06436 if ((ast_test_flag64(pvt, IAX_TRUNK) || 06437 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06438 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06439 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06440 (f->frametype == AST_FRAME_VOICE) 06441 /* is a voice frame */ && 06442 (f->subclass.codec == pvt->svoiceformat) 06443 /* is the same type */ ) { 06444 /* Force immediate rather than delayed transmission */ 06445 now = 1; 06446 /* Mark that mini-style frame is appropriate */ 06447 sendmini = 1; 06448 } 06449 if ( f->frametype == AST_FRAME_VIDEO ) { 06450 /* 06451 * If the lower 15 bits of the timestamp roll over, or if 06452 * the video format changed then send a full frame. 06453 * Otherwise send a mini video frame 06454 */ 06455 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06456 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat) 06457 ) { 06458 now = 1; 06459 sendmini = 1; 06460 } else { 06461 now = 0; 06462 sendmini = 0; 06463 } 06464 pvt->lastvsent = fts; 06465 } 06466 if (f->frametype == AST_FRAME_IAX) { 06467 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06468 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX; 06469 if (!pvt->first_iax_message) { 06470 pvt->first_iax_message = pvt->last_iax_message; 06471 } 06472 } 06473 /* Allocate an iax_frame */ 06474 if (now) { 06475 fr = &frb.fr2; 06476 } else 06477 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)); 06478 if (!fr) { 06479 ast_log(LOG_WARNING, "Out of memory\n"); 06480 return -1; 06481 } 06482 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06483 iax_frame_wrap(fr, f); 06484 06485 fr->ts = fts; 06486 fr->callno = pvt->callno; 06487 fr->transfer = transfer; 06488 fr->final = final; 06489 fr->encmethods = 0; 06490 if (!sendmini) { 06491 /* We need a full frame */ 06492 if (seqno > -1) 06493 fr->oseqno = seqno; 06494 else 06495 fr->oseqno = pvt->oseqno++; 06496 fr->iseqno = pvt->iseqno; 06497 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06498 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06499 fh->ts = htonl(fr->ts); 06500 fh->oseqno = fr->oseqno; 06501 if (transfer) { 06502 fh->iseqno = 0; 06503 } else 06504 fh->iseqno = fr->iseqno; 06505 /* Keep track of the last thing we've acknowledged */ 06506 if (!transfer) 06507 pvt->aseqno = fr->iseqno; 06508 fh->type = fr->af.frametype & 0xFF; 06509 06510 if (fr->af.frametype == AST_FRAME_VIDEO) { 06511 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6); 06512 } else if (fr->af.frametype == AST_FRAME_VOICE) { 06513 fh->csub = compress_subclass(fr->af.subclass.codec); 06514 } else { 06515 fh->csub = compress_subclass(fr->af.subclass.integer); 06516 } 06517 06518 if (transfer) { 06519 fr->dcallno = pvt->transfercallno; 06520 } else 06521 fr->dcallno = pvt->peercallno; 06522 fh->dcallno = htons(fr->dcallno); 06523 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06524 fr->data = fh; 06525 fr->retries = 0; 06526 /* Retry after 2x the ping time has passed */ 06527 fr->retrytime = pvt->pingtime * 2; 06528 if (fr->retrytime < MIN_RETRY_TIME) 06529 fr->retrytime = MIN_RETRY_TIME; 06530 if (fr->retrytime > MAX_RETRY_TIME) 06531 fr->retrytime = MAX_RETRY_TIME; 06532 /* Acks' don't get retried */ 06533 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK)) 06534 fr->retries = -1; 06535 else if (f->frametype == AST_FRAME_VOICE) 06536 pvt->svoiceformat = f->subclass.codec; 06537 else if (f->frametype == AST_FRAME_VIDEO) 06538 pvt->svideoformat = f->subclass.codec & ~0x1LL; 06539 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06540 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06541 if (fr->transfer) 06542 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06543 else 06544 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06545 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06546 fr->encmethods = pvt->encmethods; 06547 fr->ecx = pvt->ecx; 06548 fr->mydcx = pvt->mydcx; 06549 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06550 } else 06551 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06552 } 06553 06554 if (now) { 06555 res = send_packet(fr); 06556 } else 06557 res = iax2_transmit(fr); 06558 } else { 06559 if (ast_test_flag64(pvt, IAX_TRUNK)) { 06560 iax2_trunk_queue(pvt, fr); 06561 res = 0; 06562 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06563 /* Video frame have no sequence number */ 06564 fr->oseqno = -1; 06565 fr->iseqno = -1; 06566 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06567 vh->zeros = 0; 06568 vh->callno = htons(0x8000 | fr->callno); 06569 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0)); 06570 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06571 fr->data = vh; 06572 fr->retries = -1; 06573 res = send_packet(fr); 06574 } else { 06575 /* Mini-frames have no sequence number */ 06576 fr->oseqno = -1; 06577 fr->iseqno = -1; 06578 /* Mini frame will do */ 06579 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06580 mh->callno = htons(fr->callno); 06581 mh->ts = htons(fr->ts & 0xFFFF); 06582 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06583 fr->data = mh; 06584 fr->retries = -1; 06585 if (pvt->transferring == TRANSFER_MEDIAPASS) 06586 fr->transfer = 1; 06587 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06588 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06589 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06590 } else 06591 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06592 } 06593 res = send_packet(fr); 06594 } 06595 } 06596 return res; 06597 }
| static int iax2_sendhtml | ( | struct ast_channel * | c, | |
| int | subclass, | |||
| const char * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 4320 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04321 { 04322 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04323 }
| static int iax2_sendimage | ( | struct ast_channel * | c, | |
| struct ast_frame * | img | |||
| ) | [static] |
Definition at line 4315 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.
04316 { 04317 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1); 04318 }
| static int iax2_sendtext | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 4308 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04309 { 04310 04311 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04312 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04313 }
| static int iax2_setoption | ( | struct ast_channel * | c, | |
| int | option, | |||
| void * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 5301 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().
05302 { 05303 struct ast_option_header *h; 05304 int res; 05305 05306 switch (option) { 05307 case AST_OPTION_TXGAIN: 05308 case AST_OPTION_RXGAIN: 05309 /* these two cannot be sent, because they require a result */ 05310 errno = ENOSYS; 05311 return -1; 05312 case AST_OPTION_OPRMODE: 05313 errno = EINVAL; 05314 return -1; 05315 case AST_OPTION_SECURE_SIGNALING: 05316 case AST_OPTION_SECURE_MEDIA: 05317 { 05318 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05319 ast_mutex_lock(&iaxsl[callno]); 05320 if ((*(int *) data)) { 05321 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05322 } else { 05323 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05324 } 05325 ast_mutex_unlock(&iaxsl[callno]); 05326 return 0; 05327 } 05328 /* These options are sent to the other side across the network where 05329 * they will be passed to whatever channel is bridged there. Don't 05330 * do anything silly like pass an option that transmits pointers to 05331 * memory on this machine to a remote machine to use */ 05332 case AST_OPTION_TONE_VERIFY: 05333 case AST_OPTION_TDD: 05334 case AST_OPTION_RELAXDTMF: 05335 case AST_OPTION_AUDIO_MODE: 05336 case AST_OPTION_DIGIT_DETECT: 05337 case AST_OPTION_FAX_DETECT: 05338 { 05339 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05340 struct chan_iax2_pvt *pvt; 05341 05342 ast_mutex_lock(&iaxsl[callno]); 05343 pvt = iaxs[callno]; 05344 05345 if (wait_for_peercallno(pvt)) { 05346 ast_mutex_unlock(&iaxsl[callno]); 05347 return -1; 05348 } 05349 05350 ast_mutex_unlock(&iaxsl[callno]); 05351 05352 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05353 return -1; 05354 } 05355 05356 h->flag = AST_OPTION_FLAG_REQUEST; 05357 h->option = htons(option); 05358 memcpy(h->data, data, datalen); 05359 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05360 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05361 datalen + sizeof(*h), -1); 05362 ast_free(h); 05363 return res; 05364 } 05365 default: 05366 return -1; 05367 } 05368 05369 /* Just in case someone does a break instead of a return */ 05370 return -1; 05371 }
| static int iax2_start_transfer | ( | unsigned short | callno0, | |
| unsigned short | callno1, | |||
| int | mediaonly | |||
| ) | [static] |
Definition at line 5429 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().
05430 { 05431 int res; 05432 struct iax_ie_data ied0; 05433 struct iax_ie_data ied1; 05434 unsigned int transferid = (unsigned int)ast_random(); 05435 05436 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05437 ast_debug(1, "transfers are not supported for encrypted calls at this time\n"); 05438 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER); 05439 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER); 05440 return 0; 05441 } 05442 05443 memset(&ied0, 0, sizeof(ied0)); 05444 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05445 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05446 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05447 05448 memset(&ied1, 0, sizeof(ied1)); 05449 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05450 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05451 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05452 05453 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05454 if (res) 05455 return -1; 05456 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05457 if (res) 05458 return -1; 05459 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05460 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05461 return 0; 05462 }
| static int iax2_transfer | ( | struct ast_channel * | c, | |
| const char * | dest | |||
| ) | [static] |
Definition at line 5704 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.
05705 { 05706 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05707 struct iax_ie_data ied = { "", }; 05708 char tmp[256], *context; 05709 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 05710 ast_copy_string(tmp, dest, sizeof(tmp)); 05711 context = strchr(tmp, '@'); 05712 if (context) { 05713 *context = '\0'; 05714 context++; 05715 } 05716 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05717 if (context) 05718 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05719 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05720 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message)); 05721 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05722 }
| static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4291 of file chan_iax2.c.
References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().
Referenced by iax2_send().
04292 { 04293 fr->sentyet = 0; 04294 04295 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr); 04296 }
| static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [inline, static] |
Definition at line 9182 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
09183 { 09184 /* Drop when trunk is about 5 seconds idle */ 09185 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 09186 return 1; 09187 return 0; 09188 }
| static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_frame * | fr | |||
| ) | [static] |
Definition at line 6129 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().
06130 { 06131 struct ast_frame *f; 06132 struct iax2_trunk_peer *tpeer; 06133 void *tmp, *ptr; 06134 struct timeval now; 06135 struct ast_iax2_meta_trunk_entry *met; 06136 struct ast_iax2_meta_trunk_mini *mtm; 06137 06138 f = &fr->af; 06139 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 06140 if (tpeer) { 06141 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 06142 /* Need to reallocate space */ 06143 if (tpeer->trunkdataalloc < trunkmaxsize) { 06144 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 06145 ast_mutex_unlock(&tpeer->lock); 06146 return -1; 06147 } 06148 06149 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 06150 tpeer->trunkdata = tmp; 06151 ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 06152 } else { 06153 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)); 06154 ast_mutex_unlock(&tpeer->lock); 06155 return -1; 06156 } 06157 } 06158 06159 /* Append to meta frame */ 06160 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 06161 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) { 06162 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06163 mtm->len = htons(f->datalen); 06164 mtm->mini.callno = htons(pvt->callno); 06165 mtm->mini.ts = htons(0xffff & fr->ts); 06166 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06167 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 06168 } else { 06169 met = (struct ast_iax2_meta_trunk_entry *)ptr; 06170 /* Store call number and length in meta header */ 06171 met->callno = htons(pvt->callno); 06172 met->len = htons(f->datalen); 06173 /* Advance pointers/decrease length past trunk entry header */ 06174 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06175 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 06176 } 06177 /* Copy actual trunk data */ 06178 memcpy(ptr, f->data.ptr, f->datalen); 06179 tpeer->trunkdatalen += f->datalen; 06180 06181 tpeer->calls++; 06182 06183 /* track the largest mtu we actually have sent */ 06184 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 06185 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 06186 06187 /* if we have enough for a full MTU, ship it now without waiting */ 06188 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 06189 now = ast_tvnow(); 06190 send_trunk(tpeer, &now); 06191 trunk_untimed ++; 06192 } 06193 06194 ast_mutex_unlock(&tpeer->lock); 06195 } 06196 return 0; 06197 }
| static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 9103 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().
09104 { 09105 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 09106 }
| static int iax2_write | ( | struct ast_channel * | c, | |
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 7470 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.
07471 { 07472 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07473 int res = -1; 07474 ast_mutex_lock(&iaxsl[callno]); 07475 if (iaxs[callno]) { 07476 /* If there's an outstanding error, return failure now */ 07477 if (!iaxs[callno]->error) { 07478 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) 07479 res = 0; 07480 /* Don't waste bandwidth sending null frames */ 07481 else if (f->frametype == AST_FRAME_NULL) 07482 res = 0; 07483 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH)) 07484 res = 0; 07485 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07486 res = 0; 07487 else 07488 /* Simple, just queue for transmission */ 07489 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07490 } else { 07491 ast_debug(1, "Write error: %s\n", strerror(errno)); 07492 } 07493 } 07494 /* If it's already gone, just return */ 07495 ast_mutex_unlock(&iaxsl[callno]); 07496 return res; 07497 }
| static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 3163 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().
Referenced by update_registry().
03164 { 03165 int res = 0; 03166 struct iax_firmware *cur = NULL; 03167 03168 if (ast_strlen_zero(dev)) 03169 return 0; 03170 03171 AST_LIST_LOCK(&firmwares); 03172 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03173 if (!strcmp(dev, (char *)cur->fwh->devname)) { 03174 res = ntohs(cur->fwh->version); 03175 break; 03176 } 03177 } 03178 AST_LIST_UNLOCK(&firmwares); 03179 03180 return res; 03181 }
| 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 3183 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().
03184 { 03185 int res = -1; 03186 unsigned int bs = desc & 0xff; 03187 unsigned int start = (desc >> 8) & 0xffffff; 03188 unsigned int bytes; 03189 struct iax_firmware *cur; 03190 03191 if (ast_strlen_zero((char *)dev) || !bs) 03192 return -1; 03193 03194 start *= bs; 03195 03196 AST_LIST_LOCK(&firmwares); 03197 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03198 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 03199 continue; 03200 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 03201 if (start < ntohl(cur->fwh->datalen)) { 03202 bytes = ntohl(cur->fwh->datalen) - start; 03203 if (bytes > bs) 03204 bytes = bs; 03205 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 03206 } else { 03207 bytes = 0; 03208 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 03209 } 03210 if (bytes == bs) 03211 res = 0; 03212 else 03213 res = 1; 03214 break; 03215 } 03216 AST_LIST_UNLOCK(&firmwares); 03217 03218 return res; 03219 }
| 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 9356 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().
09357 { 09358 struct iax_dual *d; 09359 struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */ 09360 pthread_t th; 09361 09362 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 09363 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name); 09364 d = ast_calloc(1, sizeof(*d)); 09365 if (!chan1m || !chan2m || !d) { 09366 if (chan1m) { 09367 ast_hangup(chan1m); 09368 } 09369 if (chan2m) { 09370 ast_hangup(chan2m); 09371 } 09372 ast_free(d); 09373 return -1; 09374 } 09375 d->park_exten = ast_strdup(park_exten); 09376 d->park_context = ast_strdup(park_context); 09377 if (!d->park_exten || !d->park_context) { 09378 ast_hangup(chan1m); 09379 ast_hangup(chan2m); 09380 ast_free(d->park_exten); 09381 ast_free(d->park_context); 09382 ast_free(d); 09383 return -1; 09384 } 09385 09386 /* Make formats okay */ 09387 chan1m->readformat = chan1->readformat; 09388 chan1m->writeformat = chan1->writeformat; 09389 09390 /* Prepare for taking over the channel */ 09391 if (ast_channel_masquerade(chan1m, chan1)) { 09392 ast_hangup(chan1m); 09393 ast_hangup(chan2m); 09394 ast_free(d->park_exten); 09395 ast_free(d->park_context); 09396 ast_free(d); 09397 return -1; 09398 } 09399 09400 /* Setup the extensions and such */ 09401 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 09402 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 09403 chan1m->priority = chan1->priority; 09404 09405 ast_do_masquerade(chan1m); 09406 09407 /* We make a clone of the peer channel too, so we can play 09408 back the announcement */ 09409 09410 /* Make formats okay */ 09411 chan2m->readformat = chan2->readformat; 09412 chan2m->writeformat = chan2->writeformat; 09413 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot); 09414 09415 /* Prepare for taking over the channel */ 09416 if (ast_channel_masquerade(chan2m, chan2)) { 09417 ast_hangup(chan1m); 09418 ast_hangup(chan2m); 09419 ast_free(d->park_exten); 09420 ast_free(d->park_context); 09421 ast_free(d); 09422 return -1; 09423 } 09424 09425 /* Setup the extensions and such */ 09426 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 09427 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 09428 chan2m->priority = chan2->priority; 09429 09430 ast_do_masquerade(chan2m); 09431 09432 d->chan1 = chan1m; /* Transferee */ 09433 d->chan2 = chan2m; /* Transferer */ 09434 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) { 09435 /* Could not start thread */ 09436 ast_hangup(chan1m); 09437 ast_hangup(chan2m); 09438 ast_free(d->park_exten); 09439 ast_free(d->park_context); 09440 ast_free(d); 09441 return -1; 09442 } 09443 return 0; 09444 }
| static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 9329 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().
09330 { 09331 struct iax_dual *d; 09332 int res; 09333 int ext = 0; 09334 09335 d = stuff; 09336 09337 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n", 09338 d->chan2->name, d->chan1->name); 09339 09340 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext); 09341 if (res) { 09342 /* Parking failed. */ 09343 ast_hangup(d->chan1); 09344 } else { 09345 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 09346 } 09347 ast_hangup(d->chan2); 09348 09349 ast_free(d->park_exten); 09350 ast_free(d->park_context); 09351 ast_free(d); 09352 return NULL; 09353 }
Definition at line 1957 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().
01958 { 01959 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01960 if (new) { 01961 size_t afdatalen = new->afdatalen; 01962 memcpy(new, fr, sizeof(*new)); 01963 iax_frame_wrap(new, &fr->af); 01964 new->afdatalen = afdatalen; 01965 new->data = NULL; 01966 new->datalen = 0; 01967 new->direction = DIRECTION_INGRESS; 01968 new->retrans = -1; 01969 } 01970 return new; 01971 }
| static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1379 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().
01380 { 01381 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01382 AST_LIST_LOCK(&dynamic_list); 01383 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01384 AST_LIST_UNLOCK(&dynamic_list); 01385 } else { 01386 AST_LIST_LOCK(&idle_list); 01387 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01388 AST_LIST_UNLOCK(&idle_list); 01389 } 01390 01391 return; 01392 }
| 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 14803 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().
14804 { 14805 static const char config[] = "iax.conf"; 14806 int x = 0; 14807 struct iax2_registry *reg = NULL; 14808 14809 if (load_objects()) { 14810 return AST_MODULE_LOAD_FAILURE; 14811 } 14812 14813 memset(iaxs, 0, sizeof(iaxs)); 14814 14815 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14816 ast_mutex_init(&iaxsl[x]); 14817 } 14818 14819 if (!(sched = ast_sched_thread_create())) { 14820 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 14821 return AST_MODULE_LOAD_FAILURE; 14822 } 14823 14824 if (!(io = io_context_create())) { 14825 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 14826 sched = ast_sched_thread_destroy(sched); 14827 return AST_MODULE_LOAD_FAILURE; 14828 } 14829 14830 if (!(netsock = ast_netsock_list_alloc())) { 14831 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 14832 io_context_destroy(io); 14833 sched = ast_sched_thread_destroy(sched); 14834 return AST_MODULE_LOAD_FAILURE; 14835 } 14836 ast_netsock_init(netsock); 14837 14838 outsock = ast_netsock_list_alloc(); 14839 if (!outsock) { 14840 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 14841 io_context_destroy(io); 14842 sched = ast_sched_thread_destroy(sched); 14843 return AST_MODULE_LOAD_FAILURE; 14844 } 14845 ast_netsock_init(outsock); 14846 14847 randomcalltokendata = ast_random(); 14848 14849 iax_set_output(iax_debug_output); 14850 iax_set_error(iax_error_output); 14851 jb_setoutput(jb_error_output, jb_warning_output, NULL); 14852 14853 if ((timer = ast_timer_open())) { 14854 ast_timer_set_rate(timer, 1000 / trunkfreq); 14855 } 14856 14857 if (set_config(config, 0) == -1) { 14858 if (timer) { 14859 ast_timer_close(timer); 14860 timer = NULL; 14861 } 14862 return AST_MODULE_LOAD_DECLINE; 14863 } 14864 14865 #ifdef TEST_FRAMEWORK 14866 AST_TEST_REGISTER(test_iax2_peers_get); 14867 AST_TEST_REGISTER(test_iax2_users_get); 14868 #endif 14869 14870 /* Register AstData providers */ 14871 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers)); 14872 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14873 14874 ast_register_application_xml(papp, iax2_prov_app); 14875 14876 ast_custom_function_register(&iaxpeer_function); 14877 ast_custom_function_register(&iaxvar_function); 14878 14879 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers); 14880 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list); 14881 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats); 14882 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry); 14883 14884 if (ast_channel_register(&iax2_tech)) { 14885 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 14886 __unload_module(); 14887 return AST_MODULE_LOAD_FAILURE; 14888 } 14889 14890 if (ast_register_switch(&iax2_switch)) { 14891 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 14892 } 14893 14894 if (start_network_thread()) { 14895 ast_log(LOG_ERROR, "Unable to start network thread\n"); 14896 __unload_module(); 14897 return AST_MODULE_LOAD_FAILURE; 14898 } else { 14899 ast_verb(2, "IAX Ready and Listening\n"); 14900 } 14901 14902 AST_LIST_LOCK(®istrations); 14903 AST_LIST_TRAVERSE(®istrations, reg, entry) 14904 iax2_do_register(reg); 14905 AST_LIST_UNLOCK(®istrations); 14906 14907 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 14908 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 14909 14910 14911 reload_firmware(0); 14912 iax_provision_reload(0); 14913 14914 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 14915 14916 network_change_event_subscribe(); 14917 14918 return AST_MODULE_LOAD_SUCCESS; 14919 }
| static int load_objects | ( | void | ) | [static] |
Definition at line 14565 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().
14566 { 14567 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 14568 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 14569 14570 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 14571 goto container_fail; 14572 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 14573 goto container_fail; 14574 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 14575 goto container_fail; 14576 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 14577 goto container_fail; 14578 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 14579 goto container_fail; 14580 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14581 goto container_fail; 14582 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14583 goto container_fail; 14584 } else if (create_callno_pools()) { 14585 goto container_fail; 14586 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) { 14587 goto container_fail; 14588 } 14589 14590 return 0; 14591 14592 container_fail: 14593 if (peers) { 14594 ao2_ref(peers, -1); 14595 } 14596 if (users) { 14597 ao2_ref(users, -1); 14598 } 14599 if (iax_peercallno_pvts) { 14600 ao2_ref(iax_peercallno_pvts, -1); 14601 } 14602 if (iax_transfercallno_pvts) { 14603 ao2_ref(iax_transfercallno_pvts, -1); 14604 } 14605 if (peercnts) { 14606 ao2_ref(peercnts, -1); 14607 } 14608 if (callno_limits) { 14609 ao2_ref(callno_limits, -1); 14610 } 14611 if (calltoken_ignores) { 14612 ao2_ref(calltoken_ignores, -1); 14613 } 14614 if (callno_pool) { 14615 ao2_ref(callno_pool, -1); 14616 } 14617 if (callno_pool_trunk) { 14618 ao2_ref(callno_pool_trunk, -1); 14619 } 14620 return AST_MODULE_LOAD_FAILURE; 14621 }
| static void lock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5464 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
05465 { 05466 ast_mutex_lock(&iaxsl[callno0]); 05467 while (ast_mutex_trylock(&iaxsl[callno1])) { 05468 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05469 } 05470 }
| static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9516 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().
09517 { 09518 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09519 jb_info jbinfo; 09520 09521 ast_mutex_lock(&iaxsl[callno]); 09522 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 09523 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) { 09524 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09525 localjitter = jbinfo.jitter; 09526 localdelay = jbinfo.current - jbinfo.min; 09527 locallost = jbinfo.frames_lost; 09528 locallosspct = jbinfo.losspct/1000; 09529 localdropped = jbinfo.frames_dropped; 09530 localooo = jbinfo.frames_ooo; 09531 localpackets = jbinfo.frames_in; 09532 } 09533 ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n", 09534 iaxs[callno]->owner->name, 09535 iaxs[callno]->pingtime, 09536 localjitter, 09537 localdelay, 09538 locallost, 09539 locallosspct, 09540 localdropped, 09541 localooo, 09542 localpackets, 09543 iaxs[callno]->remote_rr.jitter, 09544 iaxs[callno]->remote_rr.delay, 09545 iaxs[callno]->remote_rr.losscnt, 09546 iaxs[callno]->remote_rr.losspct/1000, 09547 iaxs[callno]->remote_rr.dropped, 09548 iaxs[callno]->remote_rr.ooo, 09549 iaxs[callno]->remote_rr.packets); 09550 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n", 09551 iaxs[callno]->owner->name, 09552 iaxs[callno]->pingtime, 09553 localjitter, 09554 localdelay, 09555 locallost, 09556 locallosspct, 09557 localdropped, 09558 localooo, 09559 localpackets, 09560 iaxs[callno]->remote_rr.jitter, 09561 iaxs[callno]->remote_rr.delay, 09562 iaxs[callno]->remote_rr.losscnt, 09563 iaxs[callno]->remote_rr.losspct/1000, 09564 iaxs[callno]->remote_rr.dropped, 09565 iaxs[callno]->remote_rr.ooo, 09566 iaxs[callno]->remote_rr.packets); 09567 } 09568 ast_mutex_unlock(&iaxsl[callno]); 09569 }
| static int make_trunk | ( | unsigned short | callno, | |
| int | locked | |||
| ) | [static] |
Definition at line 2052 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().
02053 { 02054 int x; 02055 int res= 0; 02056 struct callno_entry *callno_entry; 02057 if (iaxs[callno]->oseqno) { 02058 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 02059 return -1; 02060 } 02061 if (callno >= TRUNK_CALL_START) { 02062 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 02063 return -1; 02064 } 02065 02066 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 02067 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 02068 return -1; 02069 } 02070 02071 x = callno_entry->callno; 02072 ast_mutex_lock(&iaxsl[x]); 02073 02074 /*! 02075 * \note We delete these before switching the slot, because if 02076 * they fire in the meantime, they will generate a warning. 02077 */ 02078 ast_sched_thread_del(sched, iaxs[callno]->pingid); 02079 ast_sched_thread_del(sched, iaxs[callno]->lagid); 02080 iaxs[callno]->lagid = iaxs[callno]->pingid = -1; 02081 iaxs[x] = iaxs[callno]; 02082 iaxs[x]->callno = x; 02083 02084 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 02085 * before assigning the new one */ 02086 if (iaxs[x]->callno_entry) { 02087 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 02088 } 02089 iaxs[x]->callno_entry = callno_entry; 02090 02091 iaxs[callno] = NULL; 02092 /* Update the two timers that should have been started */ 02093 iaxs[x]->pingid = iax2_sched_add(sched, 02094 ping_time * 1000, send_ping, (void *)(long)x); 02095 iaxs[x]->lagid = iax2_sched_add(sched, 02096 lagrq_time * 1000, send_lagrq, (void *)(long)x); 02097 02098 if (locked) 02099 ast_mutex_unlock(&iaxsl[callno]); 02100 res = x; 02101 if (!locked) 02102 ast_mutex_unlock(&iaxsl[x]); 02103 02104 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 02105 /* We move this call from a non-trunked to a trunked call */ 02106 update_max_trunk(); 02107 update_max_nontrunk(); 02108 return res; 02109 }
| static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 6971 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
06972 { 06973 ast_cli_netstats(s, -1, 0); 06974 astman_append(s, "\r\n"); 06975 return RESULT_SUCCESS; 06976 }
| 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 7034 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().
07035 { 07036 struct iax2_peer *peer = NULL; 07037 int peer_count = 0; 07038 char nm[20]; 07039 char status[20]; 07040 const char *id = astman_get_header(m,"ActionID"); 07041 char idtext[256] = ""; 07042 struct ast_str *encmethods = ast_str_alloca(256); 07043 struct ao2_iterator i; 07044 07045 if (!ast_strlen_zero(id)) 07046 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07047 07048 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 07049 07050 07051 i = ao2_iterator_init(peers, 0); 07052 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 07053 encmethods_to_str(peer->encmethods, &encmethods); 07054 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 07055 if (!ast_strlen_zero(peer->username)) { 07056 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 07057 } else { 07058 astman_append(s, "ObjectName: %s\r\n", peer->name); 07059 } 07060 astman_append(s, "ChanObjectType: peer\r\n"); 07061 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr)); 07062 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 07063 astman_append(s, "Mask: %s\r\n", nm); 07064 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr)); 07065 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 07066 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 07067 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 07068 peer_status(peer, status, sizeof(status)); 07069 astman_append(s, "Status: %s\r\n\r\n", status); 07070 peer_count++; 07071 } 07072 ao2_iterator_destroy(&i); 07073 07074 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 07075 return RESULT_SUCCESS; 07076 }
| static int manager_iax2_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
callback to display iax peers in manager
Definition at line 7010 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().
07011 { 07012 static const char * const a[] = { "iax2", "show", "peers" }; 07013 const char *id = astman_get_header(m,"ActionID"); 07014 char idtext[256] = ""; 07015 int total = 0; 07016 07017 if (!ast_strlen_zero(id)) 07018 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07019 07020 astman_send_listack(s, m, "Peer status list will follow", "start"); 07021 /* List the peers in separate manager events */ 07022 __iax2_show_peers(-1, &total, s, 3, a); 07023 /* Send final confirmation */ 07024 astman_append(s, 07025 "Event: PeerlistComplete\r\n" 07026 "EventList: Complete\r\n" 07027 "ListItems: %d\r\n" 07028 "%s" 07029 "\r\n", total, idtext); 07030 return 0; 07031 }
| static int manager_iax2_show_registry | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 7142 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().
07143 { 07144 const char *id = astman_get_header(m, "ActionID"); 07145 struct iax2_registry *reg = NULL; 07146 char idtext[256] = ""; 07147 char host[80] = ""; 07148 char perceived[80] = ""; 07149 int total = 0; 07150 07151 if (!ast_strlen_zero(id)) 07152 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07153 07154 astman_send_listack(s, m, "Registrations will follow", "start"); 07155 07156 AST_LIST_LOCK(®istrations); 07157 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07158 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07159 07160 if (reg->us.sin_addr.s_addr) { 07161 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07162 } else { 07163 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07164 } 07165 07166 astman_append(s, 07167 "Event: RegistryEntry\r\n" 07168 "%s" 07169 "Host: %s\r\n" 07170 "DNSmanager: %s\r\n" 07171 "Username: %s\r\n" 07172 "Perceived: %s\r\n" 07173 "Refresh: %d\r\n" 07174 "State: %s\r\n" 07175 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 07176 reg->refresh, regstate2str(reg->regstate)); 07177 07178 total++; 07179 } 07180 AST_LIST_UNLOCK(®istrations); 07181 07182 astman_append(s, 07183 "Event: RegistrationsComplete\r\n" 07184 "EventList: Complete\r\n" 07185 "ListItems: %d\r\n" 07186 "%s" 07187 "\r\n", total, idtext); 07188 07189 return 0; 07190 }
| 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 1986 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().
01987 { 01988 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01989 (cur->addr.sin_port == sin->sin_port)) { 01990 /* This is the main host */ 01991 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01992 (check_dcallno ? dcallno == cur->callno : 1) ) { 01993 /* That's us. Be sure we keep track of the peer call number */ 01994 return 1; 01995 } 01996 } 01997 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01998 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01999 /* We're transferring */ 02000 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 02001 return 1; 02002 } 02003 return 0; 02004 }
| static void memcpy_decrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_decrypt_key * | dcx | |||
| ) | [static] |
Definition at line 6227 of file chan_iax2.c.
References ast_aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
06228 { 06229 #if 0 06230 /* Debug with "fake encryption" */ 06231 int x; 06232 if (len % 16) 06233 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06234 for (x=0;x<len;x++) 06235 dst[x] = src[x] ^ 0xff; 06236 #else 06237 unsigned char lastblock[16] = { 0 }; 06238 int x; 06239 while(len > 0) { 06240 ast_aes_decrypt(src, dst, dcx); 06241 for (x=0;x<16;x++) 06242 dst[x] ^= lastblock[x]; 06243 memcpy(lastblock, src, sizeof(lastblock)); 06244 dst += 16; 06245 src += 16; 06246 len -= 16; 06247 } 06248 #endif 06249 }
| static void memcpy_encrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_encrypt_key * | ecx | |||
| ) | [static] |
Definition at line 6251 of file chan_iax2.c.
References ast_aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
06252 { 06253 #if 0 06254 /* Debug with "fake encryption" */ 06255 int x; 06256 if (len % 16) 06257 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06258 for (x=0;x<len;x++) 06259 dst[x] = src[x] ^ 0xff; 06260 #else 06261 unsigned char curblock[16] = { 0 }; 06262 int x; 06263 while(len > 0) { 06264 for (x=0;x<16;x++) 06265 curblock[x] ^= src[x]; 06266 ast_aes_encrypt(curblock, dst, ecx); 06267 memcpy(curblock, dst, sizeof(curblock)); 06268 dst += 16; 06269 src += 16; 06270 len -= 16; 06271 } 06272 #endif 06273 }
| static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | enc | |||
| ) | [static] |
Definition at line 7815 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().
07816 { 07817 /* Select exactly one common encryption if there are any */ 07818 p->encmethods &= enc; 07819 if (p->encmethods) { 07820 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07821 p->keyrotateid = -2; 07822 } 07823 if (p->encmethods & IAX_ENCRYPT_AES128) 07824 p->encmethods = IAX_ENCRYPT_AES128; 07825 else 07826 p->encmethods = 0; 07827 } 07828 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 1276 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 1311 of file chan_iax2.c.
References ast_debug, iax2_sched_add(), and network_change_event_sched_cb().
Referenced by network_change_event_subscribe().
01312 { 01313 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n"); 01314 if (network_change_event_sched_id == -1) { 01315 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 01316 } 01317 01318 }
| static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 1298 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().
01299 { 01300 struct iax2_registry *reg; 01301 network_change_event_sched_id = -1; 01302 AST_LIST_LOCK(®istrations); 01303 AST_LIST_TRAVERSE(®istrations, reg, entry) { 01304 iax2_do_register(reg); 01305 } 01306 AST_LIST_UNLOCK(®istrations); 01307 01308 return 0; 01309 }
| static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 1283 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().
01284 { 01285 if (!network_change_event_subscription) { 01286 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 01287 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END); 01288 } 01289 }
| static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 1291 of file chan_iax2.c.
References ast_event_unsubscribe().
Referenced by __unload_module(), and set_config().
01292 { 01293 if (network_change_event_subscription) { 01294 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 01295 } 01296 }
| static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 12263 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().
12264 { 12265 if (timer) { 12266 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 12267 } 12268 12269 for (;;) { 12270 pthread_testcancel(); 12271 /* Wake up once a second just in case SIGURG was sent while 12272 * we weren't in poll(), to make sure we don't hang when trying 12273 * to unload. */ 12274 if (ast_io_wait(io, 1000) <= 0) { 12275 break; 12276 } 12277 } 12278 12279 return NULL; 12280 }
| static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
| const char * | host | |||
| ) | [static, read] |
Definition at line 1915 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().
01916 { 01917 struct chan_iax2_pvt *tmp; 01918 jb_conf jbconf; 01919 01920 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01921 return NULL; 01922 } 01923 01924 if (ast_string_field_init(tmp, 32)) { 01925 ao2_ref(tmp, -1); 01926 tmp = NULL; 01927 return NULL; 01928 } 01929 01930 tmp->prefs = prefs; 01931 tmp->pingid = -1; 01932 tmp->lagid = -1; 01933 tmp->autoid = -1; 01934 tmp->authid = -1; 01935 tmp->initid = -1; 01936 tmp->keyrotateid = -1; 01937 01938 ast_string_field_set(tmp,exten, "s"); 01939 ast_string_field_set(tmp,host, host); 01940 01941 tmp->jb = jb_new(); 01942 tmp->jbid = -1; 01943 jbconf.max_jitterbuf = maxjitterbuffer; 01944 jbconf.resync_threshold = resyncthreshold; 01945 jbconf.max_contig_interp = maxjitterinterps; 01946 jbconf.target_extra = jittertargetextra; 01947 jb_setconf(tmp->jb,&jbconf); 01948 01949 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 01950 01951 tmp->hold_signaling = 1; 01952 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 01953 01954 return tmp; 01955 }
| 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 4986 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().
04987 { 04988 if (ast_strlen_zero(data)) 04989 return; 04990 04991 pds->peer = strsep(&data, "/"); 04992 pds->exten = strsep(&data, "/"); 04993 pds->options = data; 04994 04995 if (pds->exten) { 04996 data = pds->exten; 04997 pds->exten = strsep(&data, "@"); 04998 pds->context = data; 04999 } 05000 05001 if (strchr(pds->peer, '@')) { 05002 data = pds->peer; 05003 pds->username = strsep(&data, "@"); 05004 pds->peer = data; 05005 } 05006 05007 if (pds->username) { 05008 data = pds->username; 05009 pds->username = strsep(&data, ":"); 05010 pds->password = data; 05011 } 05012 05013 data = pds->peer; 05014 pds->peer = strsep(&data, ":"); 05015 pds->port = data; 05016 05017 /* check for a key name wrapped in [] in the secret position, if found, 05018 move it to the key field instead 05019 */ 05020 if (pds->password && (pds->password[0] == '[')) { 05021 pds->key = ast_strip_quoted(pds->password, "[", "]"); 05022 pds->password = NULL; 05023 } 05024 }
| static int peer_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1655 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 13024 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
13025 { 13026 struct iax2_peer *peer = obj; 13027 13028 ast_set_flag64(peer, IAX_DELME); 13029 13030 return 0; 13031 }
| static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 12453 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().
12454 { 12455 struct iax2_peer *peer = obj; 12456 int callno = peer->callno; 12457 12458 ast_free_ha(peer->ha); 12459 12460 if (callno > 0) { 12461 ast_mutex_lock(&iaxsl[callno]); 12462 iax2_destroy(callno); 12463 ast_mutex_unlock(&iaxsl[callno]); 12464 } 12465 12466 register_peer_exten(peer, 0); 12467 12468 if (peer->dnsmgr) 12469 ast_dnsmgr_release(peer->dnsmgr); 12470 12471 if (peer->mwi_event_sub) 12472 ast_event_unsubscribe(peer->mwi_event_sub); 12473 12474 ast_string_field_free_memory(peer); 12475 }
| static int peer_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1645 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_objects().
01646 { 01647 const struct iax2_peer *peer = obj; 01648 01649 return ast_str_hash(peer->name); 01650 }
Definition at line 1702 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().
01703 { 01704 ao2_ref(peer, +1); 01705 return peer; 01706 }
| static int peer_set_sock_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 14519 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
14520 { 14521 struct iax2_peer *peer = obj; 14522 14523 if (peer->sockfd < 0) 14524 peer->sockfd = defaultsockfd; 14525 14526 return 0; 14527 }
| 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 12380 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().
12381 { 12382 struct sockaddr_in sin; 12383 struct ast_sockaddr sin_tmp; 12384 int nonlocal = 1; 12385 int port = IAX_DEFAULT_PORTNO; 12386 int sockfd = defaultsockfd; 12387 char *tmp; 12388 char *addr; 12389 char *portstr; 12390 12391 tmp = ast_strdupa(srcaddr); 12392 addr = strsep(&tmp, ":"); 12393 portstr = tmp; 12394 12395 if (portstr) { 12396 port = atoi(portstr); 12397 if (port < 1) 12398 port = IAX_DEFAULT_PORTNO; 12399 } 12400 12401 sin_tmp.ss.ss_family = AF_INET; 12402 if (!ast_get_ip(&sin_tmp, addr)) { 12403 struct ast_netsock *sock; 12404 int res; 12405 12406 ast_sockaddr_to_sin(&sin_tmp, &sin); 12407 sin.sin_port = 0; 12408 sin.sin_family = AF_INET; 12409 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 12410 if (res == 0) { 12411 /* ip address valid. */ 12412 sin.sin_port = htons(port); 12413 if (!(sock = ast_netsock_find(netsock, &sin))) 12414 sock = ast_netsock_find(outsock, &sin); 12415 if (sock) { 12416 sockfd = ast_netsock_sockfd(sock); 12417 nonlocal = 0; 12418 } else { 12419 unsigned int orig_saddr = sin.sin_addr.s_addr; 12420 /* INADDR_ANY matches anyway! */ 12421 sin.sin_addr.s_addr = INADDR_ANY; 12422 if (ast_netsock_find(netsock, &sin)) { 12423 sin.sin_addr.s_addr = orig_saddr; 12424 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 12425 if (sock) { 12426 sockfd = ast_netsock_sockfd(sock); 12427 ast_netsock_unref(sock); 12428 nonlocal = 0; 12429 } else { 12430 nonlocal = 2; 12431 } 12432 } 12433 } 12434 } 12435 } 12436 12437 peer->sockfd = sockfd; 12438 12439 if (nonlocal == 1) { 12440 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 12441 srcaddr, peer->name); 12442 return -1; 12443 } else if (nonlocal == 2) { 12444 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 12445 srcaddr, peer->name); 12446 return -1; 12447 } else { 12448 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 12449 return 0; 12450 } 12451 }
| static int peer_status | ( | struct iax2_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
peer_status: Report Peer status in character string
Definition at line 3729 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().
03730 { 03731 int res = 0; 03732 if (peer->maxms) { 03733 if (peer->lastms < 0) { 03734 ast_copy_string(status, "UNREACHABLE", statuslen); 03735 } else if (peer->lastms > peer->maxms) { 03736 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03737 res = 1; 03738 } else if (peer->lastms) { 03739 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03740 res = 1; 03741 } else { 03742 ast_copy_string(status, "UNKNOWN", statuslen); 03743 } 03744 } else { 03745 ast_copy_string(status, "Unmonitored", statuslen); 03746 res = -1; 03747 } 03748 return res; 03749 }
Definition at line 1708 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().
01709 { 01710 ao2_ref(peer, -1); 01711 return NULL; 01712 }
| static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2349 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().
02350 { 02351 struct peercnt *peercnt; 02352 unsigned long addr = sin->sin_addr.s_addr; 02353 int res = 0; 02354 struct peercnt tmp = { 02355 .addr = addr, 02356 }; 02357 02358 /* Reasoning for peercnts container lock: Two identical ip addresses 02359 * could be added by different threads at the "same time". Without the container 02360 * lock, both threads could alloc space for the same object and attempt 02361 * to link to table. With the lock, one would create the object and link 02362 * to table while the other would find the already created peercnt object 02363 * rather than creating a new one. */ 02364 ao2_lock(peercnts); 02365 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02366 ao2_lock(peercnt); 02367 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02368 ao2_lock(peercnt); 02369 /* create and set defaults */ 02370 peercnt->addr = addr; 02371 set_peercnt_limit(peercnt); 02372 /* guarantees it does not go away after unlocking table 02373 * ao2_find automatically adds this */ 02374 ao2_link(peercnts, peercnt); 02375 } else { 02376 ao2_unlock(peercnts); 02377 return -1; 02378 } 02379 02380 /* check to see if the address has hit its callno limit. If not increment cur. */ 02381 if (peercnt->limit > peercnt->cur) { 02382 peercnt->cur++; 02383 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02384 } else { /* max num call numbers for this peer has been reached! */ 02385 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02386 res = -1; 02387 } 02388 02389 /* clean up locks and ref count */ 02390 ao2_unlock(peercnt); 02391 ao2_unlock(peercnts); 02392 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02393 02394 return res; 02395 }
| static int peercnt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2179 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 2173 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 2316 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().
02317 { 02318 /* this function turns off and on custom callno limits set by peer registration */ 02319 struct peercnt *peercnt; 02320 struct peercnt tmp = { 02321 .addr = 0, 02322 }; 02323 struct sockaddr_in sin; 02324 02325 ast_sockaddr_to_sin(sockaddr, &sin); 02326 02327 tmp.addr = sin.sin_addr.s_addr; 02328 02329 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02330 peercnt->reg = reg; 02331 if (limit) { 02332 peercnt->limit = limit; 02333 } else { 02334 set_peercnt_limit(peercnt); 02335 } 02336 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg); 02337 ao2_ref(peercnt, -1); /* decrement ref from find */ 02338 } 02339 }
| static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2401 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().
02402 { 02403 struct sockaddr_in sin = { 02404 .sin_addr.s_addr = peercnt->addr, 02405 }; 02406 02407 /* 02408 * Container locked here since peercnt may be unlinked from 02409 * list. If left unlocked, peercnt_add could try and grab this 02410 * entry from the table and modify it at the "same time" this 02411 * thread attemps to unlink it. 02412 */ 02413 ao2_lock(peercnts); 02414 peercnt->cur--; 02415 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02416 /* if this was the last connection from the peer remove it from table */ 02417 if (peercnt->cur == 0) { 02418 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02419 } 02420 ao2_unlock(peercnts); 02421 }
| static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2441 of file chan_iax2.c.
References ao2_find, ao2_ref, OBJ_POINTER, and peercnt_remove().
Referenced by __find_callno(), and complete_transfer().
02442 { 02443 struct peercnt *peercnt; 02444 struct peercnt tmp = { 02445 .addr = sin->sin_addr.s_addr, 02446 }; 02447 02448 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02449 peercnt_remove(peercnt); 02450 ao2_ref(peercnt, -1); /* decrement ref from find */ 02451 } 02452 return 0; 02453 }
| static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2427 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02428 { 02429 struct peercnt *peercnt = (struct peercnt *) obj; 02430 02431 peercnt_remove(peercnt); 02432 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02433 02434 return 0; 02435 }
| static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 14653 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.
14655 { 14656 struct ast_data *data_peer; 14657 struct iax2_peer *peer; 14658 struct ao2_iterator i; 14659 char status[20]; 14660 struct ast_str *encmethods = ast_str_alloca(256); 14661 14662 i = ao2_iterator_init(peers, 0); 14663 while ((peer = ao2_iterator_next(&i))) { 14664 data_peer = ast_data_add_node(data_root, "peer"); 14665 if (!data_peer) { 14666 peer_unref(peer); 14667 continue; 14668 } 14669 14670 ast_data_add_structure(iax2_peer, data_peer, peer); 14671 14672 ast_data_add_codecs(data_peer, "codecs", peer->capability); 14673 14674 peer_status(peer, status, sizeof(status)); 14675 ast_data_add_str(data_peer, "status", status); 14676 14677 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr)); 14678 14679 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask)); 14680 14681 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr)); 14682 14683 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK)); 14684 14685 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC)); 14686 14687 encmethods_to_str(peer->encmethods, &encmethods); 14688 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no"); 14689 14690 peer_unref(peer); 14691 14692 if (!ast_data_search_match(search, data_peer)) { 14693 ast_data_remove_node(data_root, data_peer); 14694 } 14695 } 14696 ao2_iterator_destroy(&i); 14697 14698 return 0; 14699 }
| static void poke_all_peers | ( | void | ) | [static] |
Definition at line 13603 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().
13604 { 13605 struct ao2_iterator i; 13606 struct iax2_peer *peer; 13607 13608 i = ao2_iterator_init(peers, 0); 13609 while ((peer = ao2_iterator_next(&i))) { 13610 iax2_poke_peer(peer, 0); 13611 peer_unref(peer); 13612 } 13613 ao2_iterator_destroy(&i); 13614 }
| static int prune_addr_range_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2305 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02306 { 02307 struct addr_range *addr_range = obj; 02308 02309 return addr_range->delme ? CMP_MATCH : 0; 02310 }
| static void prune_peers | ( | void | ) | [static] |
Definition at line 13087 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().
13088 { 13089 struct iax2_peer *peer; 13090 struct ao2_iterator i; 13091 13092 i = ao2_iterator_init(peers, 0); 13093 while ((peer = ao2_iterator_next(&i))) { 13094 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 13095 unlink_peer(peer); 13096 } 13097 peer_unref(peer); 13098 } 13099 ao2_iterator_destroy(&i); 13100 }
| static void prune_users | ( | void | ) | [static] |
Definition at line 13071 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().
13072 { 13073 struct iax2_user *user; 13074 struct ao2_iterator i; 13075 13076 i = ao2_iterator_init(users, 0); 13077 while ((user = ao2_iterator_next(&i))) { 13078 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 13079 ao2_unlink(users, user); 13080 } 13081 user_unref(user); 13082 } 13083 ao2_iterator_destroy(&i); 13084 }
| static int pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 14536 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by load_objects().
14537 { 14538 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14539 14540 /* The frames_received field is used to hold whether we're matching 14541 * against a full frame or not ... */ 14542 14543 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 14544 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14545 }
| static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1868 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().
01869 { 01870 struct chan_iax2_pvt *pvt = obj; 01871 struct iax_frame *cur = NULL; 01872 struct signaling_queue_entry *s = NULL; 01873 01874 ast_mutex_lock(&iaxsl[pvt->callno]); 01875 01876 iax2_destroy_helper(pvt); 01877 01878 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01879 pvt->callno_entry = NULL; 01880 01881 /* Already gone */ 01882 ast_set_flag64(pvt, IAX_ALREADYGONE); 01883 01884 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) { 01885 /* Cancel any pending transmissions */ 01886 cur->retries = -1; 01887 } 01888 01889 ast_mutex_unlock(&iaxsl[pvt->callno]); 01890 01891 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01892 free_signaling_queue_entry(s); 01893 } 01894 01895 if (pvt->reg) { 01896 pvt->reg->callno = 0; 01897 } 01898 01899 if (!pvt->owner) { 01900 jb_frame frame; 01901 if (pvt->vars) { 01902 ast_variables_destroy(pvt->vars); 01903 pvt->vars = NULL; 01904 } 01905 01906 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01907 iax2_frame_free(frame.data); 01908 } 01909 01910 jb_destroy(pvt->jb); 01911 ast_string_field_free_memory(pvt); 01912 } 01913 }
| static int pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 14529 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_objects().
14530 { 14531 const struct chan_iax2_pvt *pvt = obj; 14532 14533 return pvt->peercallno; 14534 }
| 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 1843 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().
01844 { 01845 struct signaling_queue_entry *qe; 01846 01847 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01848 return 1; /* do not queue this frame */ 01849 } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01850 return -1; /* out of memory */ 01851 } 01852 01853 /* copy ast_frame into our queue entry */ 01854 qe->f = *f; 01855 if (qe->f.datalen) { 01856 /* if there is data in this frame copy it over as well */ 01857 if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) { 01858 free_signaling_queue_entry(qe); 01859 return -1; 01860 } 01861 memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen); 01862 } 01863 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, qe, next); 01864 01865 return 0; 01866 }
| static int raw_hangup | ( | struct sockaddr_in * | sin, | |
| unsigned short | src, | |||
| unsigned short | dst, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 7796 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().
07797 { 07798 struct ast_iax2_full_hdr fh; 07799 fh.scallno = htons(src | IAX_FLAG_FULL); 07800 fh.dcallno = htons(dst); 07801 fh.ts = 0; 07802 fh.oseqno = 0; 07803 fh.iseqno = 0; 07804 fh.type = AST_FRAME_IAX; 07805 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07806 iax_outputframe(NULL, &fh, 0, sin, 0); 07807 #if 0 07808 if (option_debug) 07809 #endif 07810 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07811 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07812 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07813 }
| static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4341 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().
04342 { 04343 struct ast_variable *var = NULL; 04344 struct ast_variable *tmp; 04345 struct iax2_peer *peer=NULL; 04346 time_t regseconds = 0, nowtime; 04347 int dynamic=0; 04348 04349 if (peername) { 04350 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04351 if (!var && sin) 04352 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04353 } else if (sin) { 04354 char porta[25]; 04355 sprintf(porta, "%d", ntohs(sin->sin_port)); 04356 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04357 if (var) { 04358 /* We'll need the peer name in order to build the structure! */ 04359 for (tmp = var; tmp; tmp = tmp->next) { 04360 if (!strcasecmp(tmp->name, "name")) 04361 peername = tmp->value; 04362 } 04363 } 04364 } 04365 if (!var && peername) { /* Last ditch effort */ 04366 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04367 /*!\note 04368 * If this one loaded something, then we need to ensure that the host 04369 * field matched. The only reason why we can't have this as a criteria 04370 * is because we only have the IP address and the host field might be 04371 * set as a name (and the reverse PTR might not match). 04372 */ 04373 if (var && sin) { 04374 for (tmp = var; tmp; tmp = tmp->next) { 04375 if (!strcasecmp(tmp->name, "host")) { 04376 struct ast_hostent ahp; 04377 struct hostent *hp; 04378 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04379 /* No match */ 04380 ast_variables_destroy(var); 04381 var = NULL; 04382 } 04383 break; 04384 } 04385 } 04386 } 04387 } 04388 if (!var) 04389 return NULL; 04390 04391 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04392 04393 if (!peer) { 04394 ast_variables_destroy(var); 04395 return NULL; 04396 } 04397 04398 for (tmp = var; tmp; tmp = tmp->next) { 04399 /* Make sure it's not a user only... */ 04400 if (!strcasecmp(tmp->name, "type")) { 04401 if (strcasecmp(tmp->value, "friend") && 04402 strcasecmp(tmp->value, "peer")) { 04403 /* Whoops, we weren't supposed to exist! */ 04404 peer = peer_unref(peer); 04405 break; 04406 } 04407 } else if (!strcasecmp(tmp->name, "regseconds")) { 04408 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04409 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04410 if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) { 04411 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name); 04412 } 04413 } else if (!strcasecmp(tmp->name, "port")) { 04414 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value)); 04415 } else if (!strcasecmp(tmp->name, "host")) { 04416 if (!strcasecmp(tmp->value, "dynamic")) 04417 dynamic = 1; 04418 } 04419 } 04420 04421 ast_variables_destroy(var); 04422 04423 if (!peer) 04424 return NULL; 04425 04426 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04427 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04428 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) { 04429 if (peer->expire > -1) { 04430 if (!ast_sched_thread_del(sched, peer->expire)) { 04431 peer->expire = -1; 04432 peer_unref(peer); 04433 } 04434 } 04435 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04436 if (peer->expire == -1) 04437 peer_unref(peer); 04438 } 04439 ao2_link(peers, peer); 04440 if (ast_test_flag64(peer, IAX_DYNAMIC)) 04441 reg_source_db(peer); 04442 } else { 04443 ast_set_flag64(peer, IAX_TEMPONLY); 04444 } 04445 04446 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04447 time(&nowtime); 04448 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04449 memset(&peer->addr, 0, sizeof(peer->addr)); 04450 realtime_update_peer(peer->name, &peer->addr, 0); 04451 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04452 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04453 } 04454 else { 04455 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04456 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04457 } 04458 } 04459 04460 return peer; 04461 }
| static void realtime_update_peer | ( | const char * | peername, | |
| struct ast_sockaddr * | sockaddr, | |||
| time_t | regtime | |||
| ) | [static] |
Definition at line 4534 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().
04535 { 04536 char port[10]; 04537 char regseconds[20]; 04538 const char *sysname = ast_config_AST_SYSTEM_NAME; 04539 char *syslabel = NULL; 04540 04541 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04542 sysname = NULL; 04543 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME)) 04544 syslabel = "regserver"; 04545 04546 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04547 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr)); 04548 ast_update_realtime("iaxpeers", "name", peername, 04549 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 04550 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */ 04551 }
| static struct iax2_user * realtime_user | ( | const char * | username, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4463 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().
04464 { 04465 struct ast_variable *var; 04466 struct ast_variable *tmp; 04467 struct iax2_user *user=NULL; 04468 04469 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04470 if (!var) 04471 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04472 if (!var && sin) { 04473 char porta[6]; 04474 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04475 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04476 if (!var) 04477 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04478 } 04479 if (!var) { /* Last ditch effort */ 04480 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04481 /*!\note 04482 * If this one loaded something, then we need to ensure that the host 04483 * field matched. The only reason why we can't have this as a criteria 04484 * is because we only have the IP address and the host field might be 04485 * set as a name (and the reverse PTR might not match). 04486 */ 04487 if (var) { 04488 for (tmp = var; tmp; tmp = tmp->next) { 04489 if (!strcasecmp(tmp->name, "host")) { 04490 struct ast_hostent ahp; 04491 struct hostent *hp; 04492 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04493 /* No match */ 04494 ast_variables_destroy(var); 04495 var = NULL; 04496 } 04497 break; 04498 } 04499 } 04500 } 04501 } 04502 if (!var) 04503 return NULL; 04504 04505 tmp = var; 04506 while(tmp) { 04507 /* Make sure it's not a peer only... */ 04508 if (!strcasecmp(tmp->name, "type")) { 04509 if (strcasecmp(tmp->value, "friend") && 04510 strcasecmp(tmp->value, "user")) { 04511 return NULL; 04512 } 04513 } 04514 tmp = tmp->next; 04515 } 04516 04517 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)); 04518 04519 ast_variables_destroy(var); 04520 04521 if (!user) 04522 return NULL; 04523 04524 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04525 ast_set_flag64(user, IAX_RTCACHEFRIENDS); 04526 ao2_link(users, user); 04527 } else { 04528 ast_set_flag64(user, IAX_TEMPONLY); 04529 } 04530 04531 return user; 04532 }
| static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8682 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().
08683 { 08684 char data[80]; 08685 char *expiry; 08686 08687 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) { 08688 return; 08689 } 08690 08691 expiry = strrchr(data, ':'); 08692 if (!expiry) { 08693 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data); 08694 return; 08695 } 08696 *expiry++ = '\0'; 08697 08698 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) { 08699 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data); 08700 return; 08701 } 08702 08703 p->expiry = atoi(expiry); 08704 08705 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name, 08706 ast_sockaddr_stringify(&p->addr), p->expiry); 08707 08708 iax2_poke_peer(p, 0); 08709 if (p->expire > -1) { 08710 if (!ast_sched_thread_del(sched, p->expire)) { 08711 p->expire = -1; 08712 peer_unref(p); 08713 } 08714 } 08715 08716 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08717 08718 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08719 if (p->expire == -1) { 08720 peer_unref(p); 08721 } 08722 08723 if (iax2_regfunk) { 08724 iax2_regfunk(p->name, 1); 08725 } 08726 08727 register_peer_exten(p, 1); 08728 }
| static void register_peer_exten | ( | struct iax2_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Definition at line 8599 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().
08600 { 08601 char multi[256]; 08602 char *stringp, *ext; 08603 if (!ast_strlen_zero(regcontext)) { 08604 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08605 stringp = multi; 08606 while((ext = strsep(&stringp, "&"))) { 08607 if (onoff) { 08608 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08609 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08610 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08611 } else 08612 ast_context_remove_extension(regcontext, ext, 1, NULL); 08613 } 08614 } 08615 }
| static int register_verify | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Verify inbound registration.
Definition at line 7970 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().
07971 { 07972 char requeststr[256] = ""; 07973 char peer[256] = ""; 07974 char md5secret[256] = ""; 07975 char rsasecret[256] = ""; 07976 char secret[256] = ""; 07977 struct iax2_peer *p = NULL; 07978 struct ast_key *key; 07979 char *keyn; 07980 int x; 07981 int expire = 0; 07982 int res = -1; 07983 struct ast_sockaddr addr; 07984 07985 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07986 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 07987 if (ies->username) 07988 ast_copy_string(peer, ies->username, sizeof(peer)); 07989 if (ies->password) 07990 ast_copy_string(secret, ies->password, sizeof(secret)); 07991 if (ies->md5_result) 07992 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07993 if (ies->rsa_result) 07994 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07995 if (ies->refresh) 07996 expire = ies->refresh; 07997 07998 if (ast_strlen_zero(peer)) { 07999 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 08000 return -1; 08001 } 08002 08003 /* SLD: first call to lookup peer during registration */ 08004 ast_mutex_unlock(&iaxsl[callno]); 08005 p = find_peer(peer, 1); 08006 ast_mutex_lock(&iaxsl[callno]); 08007 if (!p || !iaxs[callno]) { 08008 if (iaxs[callno]) { 08009 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 08010 /* Anything, as long as it's non-blank */ 08011 ast_string_field_set(iaxs[callno], secret, "badsecret"); 08012 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 08013 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 08014 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 08015 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 08016 * to be plaintext, indicating it is an authmethod used by other peers on the system. 08017 * 08018 * If none of these cases exist, res will be returned as 0 without authentication indicating 08019 * an AUTHREQ needs to be sent out. */ 08020 08021 if (ast_strlen_zero(iaxs[callno]->challenge) && 08022 !(!ast_strlen_zero(secret) && plaintext)) { 08023 /* by setting res to 0, an REGAUTH will be sent */ 08024 res = 0; 08025 } 08026 } 08027 if (authdebug && !p) 08028 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08029 goto return_unref; 08030 } 08031 08032 if (!ast_test_flag64(p, IAX_DYNAMIC)) { 08033 if (authdebug) 08034 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08035 goto return_unref; 08036 } 08037 08038 ast_sockaddr_from_sin(&addr, sin); 08039 if (!ast_apply_ha(p->ha, &addr)) { 08040 if (authdebug) 08041 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08042 goto return_unref; 08043 } 08044 ast_string_field_set(iaxs[callno], secret, p->secret); 08045 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 08046 /* Check secret against what we have on file */ 08047 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08048 if (!ast_strlen_zero(p->inkeys)) { 08049 char tmpkeys[256]; 08050 char *stringp=NULL; 08051 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 08052 stringp=tmpkeys; 08053 keyn = strsep(&stringp, ":"); 08054 while(keyn) { 08055 key = ast_key_get(keyn, AST_KEY_PUBLIC); 08056 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 08057 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08058 break; 08059 } else if (!key) 08060 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 08061 keyn = strsep(&stringp, ":"); 08062 } 08063 if (!keyn) { 08064 if (authdebug) 08065 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 08066 goto return_unref; 08067 } 08068 } else { 08069 if (authdebug) 08070 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 08071 goto return_unref; 08072 } 08073 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08074 struct MD5Context md5; 08075 unsigned char digest[16]; 08076 char *tmppw, *stringp; 08077 08078 tmppw = ast_strdupa(p->secret); 08079 stringp = tmppw; 08080 while((tmppw = strsep(&stringp, ";"))) { 08081 MD5Init(&md5); 08082 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 08083 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08084 MD5Final(digest, &md5); 08085 for (x=0;x<16;x++) 08086 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 08087 if (!strcasecmp(requeststr, md5secret)) 08088 break; 08089 } 08090 if (tmppw) { 08091 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08092 } else { 08093 if (authdebug) 08094 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 08095 goto return_unref; 08096 } 08097 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 08098 /* They've provided a plain text password and we support that */ 08099 if (strcmp(secret, p->secret)) { 08100 if (authdebug) 08101 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08102 goto return_unref; 08103 } else 08104 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08105 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 08106 /* if challenge has been sent, but no challenge response if given, reject. */ 08107 goto return_unref; 08108 } 08109 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08110 08111 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 08112 res = 0; 08113 08114 return_unref: 08115 if (iaxs[callno]) { 08116 ast_string_field_set(iaxs[callno], peer, peer); 08117 08118 /* Choose lowest expiry number */ 08119 if (expire && (expire < iaxs[callno]->expiry)) { 08120 iaxs[callno]->expiry = expire; 08121 } 08122 } 08123 08124 if (p) { 08125 peer_unref(p); 08126 } 08127 return res; 08128 }
| static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8907 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().
08908 { 08909 struct iax_ie_data ied; 08910 struct iax2_peer *p; 08911 char challenge[10]; 08912 const char *peer_name; 08913 int sentauthmethod; 08914 08915 peer_name = ast_strdupa(iaxs[callno]->peer); 08916 08917 /* SLD: third call to find_peer in registration */ 08918 ast_mutex_unlock(&iaxsl[callno]); 08919 if ((p = find_peer(peer_name, 1))) { 08920 last_authmethod = p->authmethods; 08921 } 08922 08923 ast_mutex_lock(&iaxsl[callno]); 08924 if (!iaxs[callno]) 08925 goto return_unref; 08926 08927 memset(&ied, 0, sizeof(ied)); 08928 /* The selection of which delayed reject is sent may leak information, 08929 * if it sets a static response. For example, if a host is known to only 08930 * use MD5 authentication, then an RSA response would indicate that the 08931 * peer does not exist, and vice-versa. 08932 * Therefore, we use whatever the last peer used (which may vary over the 08933 * course of a server, which should leak minimal information). */ 08934 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08935 if (!p) { 08936 iaxs[callno]->authmethods = sentauthmethod; 08937 } 08938 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08939 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08940 /* Build the challenge */ 08941 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08942 ast_string_field_set(iaxs[callno], challenge, challenge); 08943 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08944 } 08945 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08946 08947 return_unref: 08948 if (p) { 08949 peer_unref(p); 08950 } 08951 08952 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08953 }
| static int registry_rerequest | ( | struct iax_ies * | ies, | |
| int | callno, | |||
| struct sockaddr_in * | sin | |||
| ) | [static] |
Definition at line 8955 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().
08956 { 08957 struct iax2_registry *reg; 08958 /* Start pessimistic */ 08959 struct iax_ie_data ied; 08960 char peer[256] = ""; 08961 char challenge[256] = ""; 08962 int res; 08963 int authmethods = 0; 08964 if (ies->authmethods) 08965 authmethods = ies->authmethods; 08966 if (ies->username) 08967 ast_copy_string(peer, ies->username, sizeof(peer)); 08968 if (ies->challenge) 08969 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 08970 memset(&ied, 0, sizeof(ied)); 08971 reg = iaxs[callno]->reg; 08972 if (reg) { 08973 struct sockaddr_in reg_addr; 08974 08975 ast_sockaddr_to_sin(®->addr, ®_addr); 08976 08977 if (inaddrcmp(®_addr, sin)) { 08978 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08979 return -1; 08980 } 08981 if (ast_strlen_zero(reg->secret)) { 08982 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 08983 reg->regstate = REG_STATE_NOAUTH; 08984 return -1; 08985 } 08986 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08987 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08988 if (reg->secret[0] == '[') { 08989 char tmpkey[256]; 08990 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 08991 tmpkey[strlen(tmpkey) - 1] = '\0'; 08992 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 08993 } else 08994 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 08995 if (!res) { 08996 reg->regstate = REG_STATE_AUTHSENT; 08997 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 08998 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08999 } else 09000 return -1; 09001 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 09002 } else 09003 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 09004 return -1; 09005 }
| static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 7079 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().
07080 { 07081 switch(regstate) { 07082 case REG_STATE_UNREGISTERED: 07083 return "Unregistered"; 07084 case REG_STATE_REGSENT: 07085 return "Request Sent"; 07086 case REG_STATE_AUTHSENT: 07087 return "Auth. Sent"; 07088 case REG_STATE_REGISTERED: 07089 return "Registered"; 07090 case REG_STATE_REJECTED: 07091 return "Rejected"; 07092 case REG_STATE_TIMEOUT: 07093 return "Timeout"; 07094 case REG_STATE_NOAUTH: 07095 return "No Authentication"; 07096 default: 07097 return "Unknown"; 07098 } 07099 }
| static int reload | ( | void | ) | [static] |
Definition at line 13664 of file chan_iax2.c.
References reload_config().
13665 { 13666 return reload_config(); 13667 }
| static int reload_config | ( | void | ) | [static] |
Definition at line 13615 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().
13616 { 13617 static const char config[] = "iax.conf"; 13618 struct iax2_registry *reg; 13619 13620 if (set_config(config, 1) > 0) { 13621 prune_peers(); 13622 prune_users(); 13623 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13624 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13625 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 13626 trunk_timed = trunk_untimed = 0; 13627 trunk_nmaxmtu = trunk_maxmtu = 0; 13628 memset(&debugaddr, '\0', sizeof(debugaddr)); 13629 13630 AST_LIST_LOCK(®istrations); 13631 AST_LIST_TRAVERSE(®istrations, reg, entry) 13632 iax2_do_register(reg); 13633 AST_LIST_UNLOCK(®istrations); 13634 13635 /* Qualify hosts, too */ 13636 poke_all_peers(); 13637 } 13638 13639 reload_firmware(0); 13640 iax_provision_reload(1); 13641 ast_unload_realtime("iaxpeers"); 13642 13643 return 0; 13644 }
| static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 3222 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().
03223 { 03224 struct iax_firmware *cur = NULL; 03225 DIR *fwd; 03226 struct dirent *de; 03227 char dir[256], fn[256]; 03228 03229 AST_LIST_LOCK(&firmwares); 03230 03231 /* Mark all as dead */ 03232 AST_LIST_TRAVERSE(&firmwares, cur, list) 03233 cur->dead = 1; 03234 03235 /* Now that we have marked them dead... load new ones */ 03236 if (!unload) { 03237 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 03238 fwd = opendir(dir); 03239 if (fwd) { 03240 while((de = readdir(fwd))) { 03241 if (de->d_name[0] != '.') { 03242 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 03243 if (!try_firmware(fn)) { 03244 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 03245 } 03246 } 03247 } 03248 closedir(fwd); 03249 } else 03250 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 03251 } 03252 03253 /* Clean up leftovers */ 03254 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 03255 if (!cur->dead) 03256 continue; 03257 AST_LIST_REMOVE_CURRENT(list); 03258 destroy_firmware(cur); 03259 } 03260 AST_LIST_TRAVERSE_SAFE_END; 03261 03262 AST_LIST_UNLOCK(&firmwares); 03263 }
| static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2140 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().
02141 { 02142 if (!pvt->peercallno) { 02143 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02144 return; 02145 } 02146 02147 ao2_unlink(iax_peercallno_pvts, pvt); 02148 }
| static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2121 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().
02122 { 02123 if (!pvt->transfercallno) { 02124 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02125 return; 02126 } 02127 02128 ao2_unlink(iax_transfercallno_pvts, pvt); 02129 }
| static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2657 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().
02658 { 02659 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02660 02661 /* the callno_pool container is locked here primarily to ensure thread 02662 * safety of the total_nonval_callno_used check and decrement */ 02663 ao2_lock(callno_pool); 02664 02665 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02666 total_nonval_callno_used--; 02667 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02668 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02669 } 02670 02671 if (callno_entry->callno < TRUNK_CALL_START) { 02672 ao2_link(callno_pool, callno_entry); 02673 } else { 02674 ao2_link(callno_pool_trunk, callno_entry); 02675 } 02676 ao2_ref(callno_entry, -1); /* only container ref remains */ 02677 02678 ao2_unlock(callno_pool); 02679 return 0; 02680 }
| static void requirecalltoken_mark_auto | ( | const char * | name, | |
| int | subclass | |||
| ) | [static] |
Definition at line 4843 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().
04844 { 04845 struct iax2_user *user = NULL; 04846 struct iax2_peer *peer = NULL; 04847 04848 if (ast_strlen_zero(name)) { 04849 return; /* no username given */ 04850 } 04851 04852 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04853 user->calltoken_required = CALLTOKEN_YES; 04854 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04855 peer->calltoken_required = CALLTOKEN_YES; 04856 } 04857 04858 if (peer) { 04859 peer_unref(peer); 04860 } 04861 if (user) { 04862 user_unref(user); 04863 } 04864 }
| static void resend_with_token | ( | int | callno, | |
| struct iax_frame * | f, | |||
| const char * | newtoken | |||
| ) | [static] |
Definition at line 4761 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().
04762 { 04763 struct chan_iax2_pvt *pvt = iaxs[callno]; 04764 int frametype = f->af.frametype; 04765 int subclass = f->af.subclass.integer; 04766 struct { 04767 struct ast_iax2_full_hdr fh; 04768 struct iax_ie_data ied; 04769 } data = { 04770 .ied.buf = { 0 }, 04771 .ied.pos = 0, 04772 }; 04773 /* total len - header len gives us the frame's IE len */ 04774 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04775 04776 if (!pvt) { 04777 return; /* this should not be possible if called from socket_process() */ 04778 } 04779 04780 /* 04781 * Check to make sure last frame sent is valid for call token resend 04782 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04783 * 2. Frame should _NOT_ already have a destination callno 04784 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04785 * 4. Pvt must have a calltoken_ie_len which represents the number of 04786 * bytes at the end of the frame used for the previous calltoken ie. 04787 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04788 * 6. Total length of f->data must be _LESS_ than size of our data struct 04789 * because f->data must be able to fit within data. 04790 */ 04791 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04792 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04793 (f->datalen > sizeof(data))) { 04794 04795 return; /* ignore resend, token was not valid for the dialog */ 04796 } 04797 04798 /* token is valid 04799 * 1. Copy frame data over 04800 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04801 * NOTE: Having the ie always be last is not protocol specified, 04802 * it is only an implementation choice. Since we only expect the ie to 04803 * be last for frames we have sent, this can no way be affected by 04804 * another end point. 04805 * 3. Remove frame from queue 04806 * 4. Free old frame 04807 * 5. Clear previous seqnos 04808 * 6. Resend with CALLTOKEN ie. 04809 */ 04810 04811 /* ---1.--- */ 04812 memcpy(&data, f->data, f->datalen); 04813 data.ied.pos = ie_data_pos; 04814 04815 /* ---2.--- */ 04816 /* move to the beginning of the calltoken ie so we can write over it */ 04817 data.ied.pos -= pvt->calltoken_ie_len; 04818 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04819 04820 /* make sure to update token length incase it ever has to be stripped off again */ 04821 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04822 04823 /* ---3.--- */ 04824 AST_LIST_REMOVE(&frame_queue[callno], f, list); 04825 04826 /* ---4.--- */ 04827 iax2_frame_free(f); 04828 04829 /* ---5.--- */ 04830 pvt->oseqno = 0; 04831 pvt->rseqno = 0; 04832 pvt->iseqno = 0; 04833 pvt->aseqno = 0; 04834 if (pvt->peercallno) { 04835 remove_by_peercallno(pvt); 04836 pvt->peercallno = 0; 04837 } 04838 04839 /* ---6.--- */ 04840 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04841 }
Definition at line 9486 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().
09487 { 09488 int i; 09489 unsigned int length, offset = 0; 09490 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09491 09492 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09493 length = ies->ospblocklength[i]; 09494 if (length != 0) { 09495 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09496 /* OSP token block length wrong, clear buffer */ 09497 offset = 0; 09498 break; 09499 } else { 09500 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09501 offset += length; 09502 } 09503 } else { 09504 break; 09505 } 09506 } 09507 *(full_osptoken + offset) = '\0'; 09508 if (strlen(full_osptoken) != offset) { 09509 /* OSP token length wrong, clear buffer */ 09510 *full_osptoken = '\0'; 09511 } 09512 09513 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09514 }
Definition at line 9475 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().
09476 { 09477 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09478 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09479 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09480 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09481 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09482 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09483 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09484 }
| static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
| struct callno_entry * | callno_entry | |||
| ) | [static] |
Definition at line 2729 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().
02730 { 02731 int i; 02732 struct peercnt *peercnt; 02733 struct peercnt tmp = { 02734 .addr = sin->sin_addr.s_addr, 02735 }; 02736 02737 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02738 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02739 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02740 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02741 if (i == -1) { 02742 ao2_ref(peercnt, -1); 02743 } 02744 } 02745 02746 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02747 }
| static int schedule_delivery | ( | struct iax_frame * | fr, | |
| int | updatehistory, | |||
| int | fromtrunk, | |||
| unsigned int * | tsout | |||
| ) | [static] |
Definition at line 4160 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().
04161 { 04162 int type, len; 04163 int ret; 04164 int needfree = 0; 04165 struct ast_channel *owner = NULL; 04166 struct ast_channel *bridge = NULL; 04167 04168 /* 04169 * Clear fr->af.data if there is no data in the buffer. Things 04170 * like AST_CONTROL_HOLD without a suggested music class must 04171 * have a NULL pointer. 04172 */ 04173 if (!fr->af.datalen) { 04174 memset(&fr->af.data, 0, sizeof(fr->af.data)); 04175 } 04176 04177 /* Attempt to recover wrapped timestamps */ 04178 unwrap_timestamp(fr); 04179 04180 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 04181 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 04182 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 04183 else { 04184 #if 0 04185 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 04186 #endif 04187 fr->af.delivery = ast_tv(0,0); 04188 } 04189 04190 type = JB_TYPE_CONTROL; 04191 len = 0; 04192 04193 if(fr->af.frametype == AST_FRAME_VOICE) { 04194 type = JB_TYPE_VOICE; 04195 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000); 04196 } else if(fr->af.frametype == AST_FRAME_CNG) { 04197 type = JB_TYPE_SILENCE; 04198 } 04199 04200 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04201 if (tsout) 04202 *tsout = fr->ts; 04203 __do_deliver(fr); 04204 return -1; 04205 } 04206 04207 iax2_lock_owner(fr->callno); 04208 if (!iaxs[fr->callno]) { 04209 /* The call dissappeared so discard this frame that we could not send. */ 04210 iax2_frame_free(fr); 04211 return -1; 04212 } 04213 if ((owner = iaxs[fr->callno]->owner)) 04214 bridge = ast_bridged_channel(owner); 04215 04216 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04217 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04218 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04219 jb_frame frame; 04220 04221 ast_channel_unlock(owner); 04222 04223 /* deliver any frames in the jb */ 04224 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04225 __do_deliver(frame.data); 04226 /* __do_deliver() can make the call disappear */ 04227 if (!iaxs[fr->callno]) 04228 return -1; 04229 } 04230 04231 jb_reset(iaxs[fr->callno]->jb); 04232 04233 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid); 04234 04235 /* deliver this frame now */ 04236 if (tsout) 04237 *tsout = fr->ts; 04238 __do_deliver(fr); 04239 return -1; 04240 } 04241 if (owner) { 04242 ast_channel_unlock(owner); 04243 } 04244 04245 /* insert into jitterbuffer */ 04246 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04247 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04248 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04249 if (ret == JB_DROP) { 04250 needfree++; 04251 } else if (ret == JB_SCHED) { 04252 update_jbsched(iaxs[fr->callno]); 04253 } 04254 if (tsout) 04255 *tsout = fr->ts; 04256 if (needfree) { 04257 /* Free our iax frame */ 04258 iax2_frame_free(fr); 04259 return -1; 04260 } 04261 return 0; 04262 }
| static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1806 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().
01807 { 01808 unsigned short callno = PTR_TO_CALLNO(vid); 01809 ast_mutex_lock(&iaxsl[callno]); 01810 if (iaxs[callno]) { 01811 if (option_debug) { 01812 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01813 } 01814 iax2_destroy(callno); 01815 } 01816 ast_mutex_unlock(&iaxsl[callno]); 01817 return 0; 01818 }
| 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 4723 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().
04726 { 04727 struct { 04728 struct ast_iax2_full_hdr f; 04729 struct iax_ie_data ied; 04730 } data; 04731 size_t size = sizeof(struct ast_iax2_full_hdr); 04732 04733 if (ied) { 04734 size += ied->pos; 04735 memcpy(&data.ied, ied->buf, ied->pos); 04736 } 04737 04738 data.f.scallno = htons(0x8000 | callno); 04739 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS); 04740 data.f.ts = htonl(ts); 04741 data.f.iseqno = seqno; 04742 data.f.oseqno = 0; 04743 data.f.type = AST_FRAME_IAX; 04744 data.f.csub = compress_subclass(command); 04745 04746 iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr)); 04747 04748 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04749 }
| 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 7518 of file chan_iax2.c.
References __send_command().
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().
07519 { 07520 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07521 }
| 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 7537 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().
07538 { 07539 int call_num = i->callno; 07540 /* It is assumed that the callno has already been locked */ 07541 iax2_predestroy(i->callno); 07542 if (!iaxs[call_num]) 07543 return -1; 07544 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07545 }
| 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 7547 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07548 { 07549 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07550 }
| 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 7523 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().
07524 { 07525 int res; 07526 ast_mutex_lock(&iaxsl[callno]); 07527 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07528 ast_mutex_unlock(&iaxsl[callno]); 07529 return res; 07530 }
| 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 7552 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07553 { 07554 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07555 }
| static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1592 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().
01593 { 01594 int callno = (long) data; 01595 ast_mutex_lock(&iaxsl[callno]); 01596 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) { 01597 iaxs[callno]->lagid = -1; 01598 } 01599 ast_mutex_unlock(&iaxsl[callno]); 01600 01601 #ifdef SCHED_MULTITHREADED 01602 if (schedule_action(__send_lagrq, data)) 01603 #endif 01604 __send_lagrq(data); 01605 return 0; 01606 }
| static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3335 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().
03336 { 03337 int res; 03338 int callno = f->callno; 03339 03340 /* Don't send if there was an error, but return error instead */ 03341 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03342 return -1; 03343 03344 /* Called with iaxsl held */ 03345 if (iaxdebug) 03346 ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port)); 03347 03348 if (f->transfer) { 03349 iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03350 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03351 } else { 03352 iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03353 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03354 } 03355 if (res < 0) { 03356 if (iaxdebug) 03357 ast_debug(1, "Received error: %s\n", strerror(errno)); 03358 handle_error(); 03359 } else 03360 res = 0; 03361 03362 return res; 03363 }
| static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1525 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().
01526 { 01527 int callno = (long) data; 01528 ast_mutex_lock(&iaxsl[callno]); 01529 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) { 01530 iaxs[callno]->pingid = -1; 01531 } 01532 ast_mutex_unlock(&iaxsl[callno]); 01533 01534 #ifdef SCHED_MULTITHREADED 01535 if (schedule_action(__send_ping, data)) 01536 #endif 01537 __send_ping(data); 01538 01539 return 0; 01540 }
| 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 1830 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().
01831 { 01832 struct signaling_queue_entry *s = NULL; 01833 01834 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01835 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01836 free_signaling_queue_entry(s); 01837 } 01838 pvt->hold_signaling = 0; 01839 }
| static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [static] |
Definition at line 9139 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().
09140 { 09141 int res = 0; 09142 struct iax_frame *fr; 09143 struct ast_iax2_meta_hdr *meta; 09144 struct ast_iax2_meta_trunk_hdr *mth; 09145 int calls = 0; 09146 09147 /* Point to frame */ 09148 fr = (struct iax_frame *)tpeer->trunkdata; 09149 /* Point to meta data */ 09150 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 09151 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 09152 if (tpeer->trunkdatalen) { 09153 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 09154 meta->zeros = 0; 09155 meta->metacmd = IAX_META_TRUNK; 09156 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) 09157 meta->cmddata = IAX_META_TRUNK_MINI; 09158 else 09159 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 09160 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 09161 /* And the rest of the ast_iax2 header */ 09162 fr->direction = DIRECTION_OUTGRESS; 09163 fr->retrans = -1; 09164 fr->transfer = 0; 09165 /* Any appropriate call will do */ 09166 fr->data = fr->afdata; 09167 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 09168 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 09169 calls = tpeer->calls; 09170 #if 0 09171 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)); 09172 #endif 09173 /* Reset transmit trunk side data */ 09174 tpeer->trunkdatalen = 0; 09175 tpeer->calls = 0; 09176 } 09177 if (res < 0) 09178 return res; 09179 return calls; 09180 }
| static int set_config | ( | const char * | config_file, | |
| int | reload | |||
| ) | [static] |
Load configuration.
Definition at line 13119 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().
13120 { 13121 struct ast_config *cfg, *ucfg; 13122 format_t capability = iax2_capability; 13123 struct ast_variable *v; 13124 char *cat; 13125 const char *utype; 13126 const char *tosval; 13127 int format; 13128 int portno = IAX_DEFAULT_PORTNO; 13129 int x; 13130 int mtuv; 13131 int subscribe_network_change = 1; 13132 struct iax2_user *user; 13133 struct iax2_peer *peer; 13134 struct ast_netsock *ns; 13135 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 13136 #if 0 13137 static unsigned short int last_port=0; 13138 #endif 13139 13140 cfg = ast_config_load(config_file, config_flags); 13141 13142 if (!cfg) { 13143 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 13144 return -1; 13145 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 13146 ucfg = ast_config_load("users.conf", config_flags); 13147 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 13148 return 0; 13149 /* Otherwise we need to reread both files */ 13150 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13151 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 13152 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13153 ast_config_destroy(ucfg); 13154 return 0; 13155 } 13156 if (!cfg) { 13157 /* should have been able to load the config here */ 13158 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file); 13159 return -1; 13160 } 13161 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 13162 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13163 return 0; 13164 } else { /* iax.conf changed, gotta reread users.conf, too */ 13165 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13166 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 13167 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 13168 ast_config_destroy(cfg); 13169 return 0; 13170 } 13171 } 13172 13173 if (reload) { 13174 set_config_destroy(); 13175 } 13176 13177 /* Reset global codec prefs */ 13178 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 13179 13180 /* Reset Global Flags */ 13181 memset(&globalflags, 0, sizeof(globalflags)); 13182 ast_set_flag64(&globalflags, IAX_RTUPDATE); 13183 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13184 13185 #ifdef SO_NO_CHECK 13186 nochecksums = 0; 13187 #endif 13188 /* Reset default parking lot */ 13189 default_parkinglot[0] = '\0'; 13190 13191 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13192 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13193 global_max_trunk_mtu = MAX_TRUNK_MTU; 13194 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 13195 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 13196 13197 maxauthreq = 3; 13198 13199 srvlookup = 0; 13200 13201 v = ast_variable_browse(cfg, "general"); 13202 13203 /* Seed initial tos value */ 13204 tosval = ast_variable_retrieve(cfg, "general", "tos"); 13205 if (tosval) { 13206 if (ast_str2tos(tosval, &qos.tos)) 13207 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 13208 } 13209 /* Seed initial cos value */ 13210 tosval = ast_variable_retrieve(cfg, "general", "cos"); 13211 if (tosval) { 13212 if (ast_str2cos(tosval, &qos.cos)) 13213 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 13214 } 13215 while(v) { 13216 if (!strcasecmp(v->name, "bindport")){ 13217 if (reload) 13218 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 13219 else 13220 portno = atoi(v->value); 13221 } else if (!strcasecmp(v->name, "pingtime")) 13222 ping_time = atoi(v->value); 13223 else if (!strcasecmp(v->name, "iaxthreadcount")) { 13224 if (reload) { 13225 if (atoi(v->value) != iaxthreadcount) 13226 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 13227 } else { 13228 iaxthreadcount = atoi(v->value); 13229 if (iaxthreadcount < 1) { 13230 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 13231 iaxthreadcount = 1; 13232 } else if (iaxthreadcount > 256) { 13233 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 13234 iaxthreadcount = 256; 13235 } 13236 } 13237 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 13238 if (reload) { 13239 AST_LIST_LOCK(&dynamic_list); 13240 iaxmaxthreadcount = atoi(v->value); 13241 AST_LIST_UNLOCK(&dynamic_list); 13242 } else { 13243 iaxmaxthreadcount = atoi(v->value); 13244 if (iaxmaxthreadcount < 0) { 13245 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 13246 iaxmaxthreadcount = 0; 13247 } else if (iaxmaxthreadcount > 256) { 13248 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 13249 iaxmaxthreadcount = 256; 13250 } 13251 } 13252 } else if (!strcasecmp(v->name, "nochecksums")) { 13253 #ifdef SO_NO_CHECK 13254 if (ast_true(v->value)) 13255 nochecksums = 1; 13256 else 13257 nochecksums = 0; 13258 #else 13259 if (ast_true(v->value)) 13260 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 13261 #endif 13262 } 13263 else if (!strcasecmp(v->name, "maxjitterbuffer")) 13264 maxjitterbuffer = atoi(v->value); 13265 else if (!strcasecmp(v->name, "resyncthreshold")) 13266 resyncthreshold = atoi(v->value); 13267 else if (!strcasecmp(v->name, "maxjitterinterps")) 13268 maxjitterinterps = atoi(v->value); 13269 else if (!strcasecmp(v->name, "jittertargetextra")) 13270 jittertargetextra = atoi(v->value); 13271 else if (!strcasecmp(v->name, "lagrqtime")) 13272 lagrq_time = atoi(v->value); 13273 else if (!strcasecmp(v->name, "maxregexpire")) 13274 max_reg_expire = atoi(v->value); 13275 else if (!strcasecmp(v->name, "minregexpire")) 13276 min_reg_expire = atoi(v->value); 13277 else if (!strcasecmp(v->name, "bindaddr")) { 13278 if (reload) { 13279 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 13280 } else { 13281 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 13282 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 13283 } else { 13284 if (strchr(v->value, ':')) 13285 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 13286 else 13287 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 13288 if (defaultsockfd < 0) 13289 defaultsockfd = ast_netsock_sockfd(ns); 13290 ast_netsock_unref(ns); 13291 } 13292 } 13293 } else if (!strcasecmp(v->name, "authdebug")) { 13294 authdebug = ast_true(v->value); 13295 } else if (!strcasecmp(v->name, "encryption")) { 13296 iax2_encryption |= get_encrypt_methods(v->value); 13297 if (!iax2_encryption) { 13298 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13299 } 13300 } else if (!strcasecmp(v->name, "forceencryption")) { 13301 if (ast_false(v->value)) { 13302 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13303 } else { 13304 iax2_encryption |= get_encrypt_methods(v->value); 13305 if (iax2_encryption) { 13306 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13307 } 13308 } 13309 } else if (!strcasecmp(v->name, "transfer")) { 13310 if (!strcasecmp(v->value, "mediaonly")) { 13311 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13312 } else if (ast_true(v->value)) { 13313 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13314 } else 13315 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13316 } else if (!strcasecmp(v->name, "codecpriority")) { 13317 if(!strcasecmp(v->value, "caller")) 13318 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST); 13319 else if(!strcasecmp(v->value, "disabled")) 13320 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13321 else if(!strcasecmp(v->value, "reqonly")) { 13322 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP); 13323 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13324 } 13325 } else if (!strcasecmp(v->name, "jitterbuffer")) 13326 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 13327 else if (!strcasecmp(v->name, "forcejitterbuffer")) 13328 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 13329 else if (!strcasecmp(v->name, "delayreject")) 13330 delayreject = ast_true(v->value); 13331 else if (!strcasecmp(v->name, "allowfwdownload")) 13332 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 13333 else if (!strcasecmp(v->name, "rtcachefriends")) 13334 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 13335 else if (!strcasecmp(v->name, "rtignoreregexpire")) 13336 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 13337 else if (!strcasecmp(v->name, "rtupdate")) 13338 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE); 13339 else if (!strcasecmp(v->name, "rtsavesysname")) 13340 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME); 13341 else if (!strcasecmp(v->name, "trunktimestamps")) 13342 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 13343 else if (!strcasecmp(v->name, "rtautoclear")) { 13344 int i = atoi(v->value); 13345 if(i > 0) 13346 global_rtautoclear = i; 13347 else 13348 i = 0; 13349 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 13350 } else if (!strcasecmp(v->name, "trunkfreq")) { 13351 trunkfreq = atoi(v->value); 13352 if (trunkfreq < 10) { 13353 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n"); 13354 trunkfreq = 10; 13355 } else if (trunkfreq > 1000) { 13356 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n"); 13357 trunkfreq = 1000; 13358 } 13359 if (timer) { 13360 ast_timer_set_rate(timer, 1000 / trunkfreq); 13361 } 13362 } else if (!strcasecmp(v->name, "trunkmtu")) { 13363 mtuv = atoi(v->value); 13364 if (mtuv == 0 ) 13365 global_max_trunk_mtu = 0; 13366 else if (mtuv >= 172 && mtuv < 4000) 13367 global_max_trunk_mtu = mtuv; 13368 else 13369 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 13370 mtuv, v->lineno); 13371 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 13372 trunkmaxsize = atoi(v->value); 13373 if (trunkmaxsize == 0) 13374 trunkmaxsize = MAX_TRUNKDATA; 13375 } else if (!strcasecmp(v->name, "autokill")) { 13376 if (sscanf(v->value, "%30d", &x) == 1) { 13377 if (x >= 0) 13378 autokill = x; 13379 else 13380 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 13381 } else if (ast_true(v->value)) { 13382 autokill = DEFAULT_MAXMS; 13383 } else { 13384 autokill = 0; 13385 } 13386 } else if (!strcasecmp(v->name, "bandwidth")) { 13387 if (!strcasecmp(v->value, "low")) { 13388 capability = IAX_CAPABILITY_LOWBANDWIDTH; 13389 } else if (!strcasecmp(v->value, "medium")) { 13390 capability = IAX_CAPABILITY_MEDBANDWIDTH; 13391 } else if (!strcasecmp(v->value, "high")) { 13392 capability = IAX_CAPABILITY_FULLBANDWIDTH; 13393 } else 13394 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 13395 } else if (!strcasecmp(v->name, "allow")) { 13396 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 13397 } else if (!strcasecmp(v->name, "disallow")) { 13398 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 13399 } else if (!strcasecmp(v->name, "register")) { 13400 iax2_register(v->value, v->lineno); 13401 } else if (!strcasecmp(v->name, "iaxcompat")) { 13402 iaxcompat = ast_true(v->value); 13403 } else if (!strcasecmp(v->name, "regcontext")) { 13404 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 13405 /* Create context if it doesn't exist already */ 13406 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 13407 } else if (!strcasecmp(v->name, "tos")) { 13408 if (ast_str2tos(v->value, &qos.tos)) 13409 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 13410 } else if (!strcasecmp(v->name, "cos")) { 13411 if (ast_str2cos(v->value, &qos.cos)) 13412 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 13413 } else if (!strcasecmp(v->name, "parkinglot")) { 13414 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 13415 } else if (!strcasecmp(v->name, "accountcode")) { 13416 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 13417 } else if (!strcasecmp(v->name, "mohinterpret")) { 13418 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 13419 } else if (!strcasecmp(v->name, "mohsuggest")) { 13420 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 13421 } else if (!strcasecmp(v->name, "amaflags")) { 13422 format = ast_cdr_amaflags2int(v->value); 13423 if (format < 0) { 13424 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13425 } else { 13426 amaflags = format; 13427 } 13428 } else if (!strcasecmp(v->name, "language")) { 13429 ast_copy_string(language, v->value, sizeof(language)); 13430 } else if (!strcasecmp(v->name, "maxauthreq")) { 13431 maxauthreq = atoi(v->value); 13432 if (maxauthreq < 0) 13433 maxauthreq = 0; 13434 } else if (!strcasecmp(v->name, "adsi")) { 13435 adsi = ast_true(v->value); 13436 } else if (!strcasecmp(v->name, "srvlookup")) { 13437 srvlookup = ast_true(v->value); 13438 } else if (!strcasecmp(v->name, "connectedline")) { 13439 if (ast_true(v->value)) { 13440 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13441 } else if (!strcasecmp(v->value, "send")) { 13442 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13443 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13444 } else if (!strcasecmp(v->value, "receive")) { 13445 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13446 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13447 } else { 13448 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13449 } 13450 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 13451 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 13452 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 13453 } 13454 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 13455 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 13456 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); 13457 } 13458 } else if (!strcasecmp(v->name, "calltokenoptional")) { 13459 if (add_calltoken_ignore(v->value)) { 13460 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 13461 } 13462 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 13463 if (ast_true(v->value)) { 13464 subscribe_network_change = 1; 13465 } else if (ast_false(v->value)) { 13466 subscribe_network_change = 0; 13467 } else { 13468 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 13469 } 13470 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 13471 if (ast_true(v->value)) { 13472 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13473 } else if (ast_false(v->value)) { 13474 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID); 13475 } else { 13476 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 13477 } 13478 }/*else if (strcasecmp(v->name,"type")) */ 13479 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13480 v = v->next; 13481 } 13482 13483 if (subscribe_network_change) { 13484 network_change_event_subscribe(); 13485 } else { 13486 network_change_event_unsubscribe(); 13487 } 13488 13489 if (defaultsockfd < 0) { 13490 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 13491 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 13492 } else { 13493 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 13494 defaultsockfd = ast_netsock_sockfd(ns); 13495 ast_netsock_unref(ns); 13496 } 13497 } 13498 if (reload) { 13499 ast_netsock_release(outsock); 13500 outsock = ast_netsock_list_alloc(); 13501 if (!outsock) { 13502 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13503 return -1; 13504 } 13505 ast_netsock_init(outsock); 13506 } 13507 13508 if (min_reg_expire > max_reg_expire) { 13509 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 13510 min_reg_expire, max_reg_expire, max_reg_expire); 13511 min_reg_expire = max_reg_expire; 13512 } 13513 iax2_capability = capability; 13514 13515 if (ucfg) { 13516 struct ast_variable *gen; 13517 int genhasiax; 13518 int genregisteriax; 13519 const char *hasiax, *registeriax; 13520 13521 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 13522 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 13523 gen = ast_variable_browse(ucfg, "general"); 13524 cat = ast_category_browse(ucfg, NULL); 13525 while (cat) { 13526 if (strcasecmp(cat, "general")) { 13527 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 13528 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 13529 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 13530 /* Start with general parameters, then specific parameters, user and peer */ 13531 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 13532 if (user) { 13533 ao2_link(users, user); 13534 user = user_unref(user); 13535 } 13536 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 13537 if (peer) { 13538 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13539 reg_source_db(peer); 13540 ao2_link(peers, peer); 13541 peer = peer_unref(peer); 13542 } 13543 } 13544 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 13545 char tmp[256]; 13546 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 13547 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 13548 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 13549 if (!host) 13550 host = ast_variable_retrieve(ucfg, "general", "host"); 13551 if (!username) 13552 username = ast_variable_retrieve(ucfg, "general", "username"); 13553 if (!secret) 13554 secret = ast_variable_retrieve(ucfg, "general", "secret"); 13555 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 13556 if (!ast_strlen_zero(secret)) 13557 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 13558 else 13559 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 13560 iax2_register(tmp, 0); 13561 } 13562 } 13563 } 13564 cat = ast_category_browse(ucfg, cat); 13565 } 13566 ast_config_destroy(ucfg); 13567 } 13568 13569 cat = ast_category_browse(cfg, NULL); 13570 while(cat) { 13571 if (strcasecmp(cat, "general")) { 13572 utype = ast_variable_retrieve(cfg, cat, "type"); 13573 if (!strcasecmp(cat, "callnumberlimits")) { 13574 build_callno_limits(ast_variable_browse(cfg, cat)); 13575 } else if (utype) { 13576 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 13577 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 13578 if (user) { 13579 ao2_link(users, user); 13580 user = user_unref(user); 13581 } 13582 } 13583 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 13584 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 13585 if (peer) { 13586 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13587 reg_source_db(peer); 13588 ao2_link(peers, peer); 13589 peer = peer_unref(peer); 13590 } 13591 } else if (strcasecmp(utype, "user")) { 13592 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 13593 } 13594 } else 13595 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 13596 } 13597 cat = ast_category_browse(cfg, cat); 13598 } 13599 ast_config_destroy(cfg); 13600 return 1; 13601 }
| static void set_config_destroy | ( | void | ) | [static] |
Definition at line 13102 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().
13103 { 13104 strcpy(accountcode, ""); 13105 strcpy(language, ""); 13106 strcpy(mohinterpret, ""); 13107 strcpy(mohsuggest, ""); 13108 trunkmaxsize = MAX_TRUNKDATA; 13109 amaflags = 0; 13110 delayreject = 0; 13111 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | 13112 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13113 delete_users(); 13114 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 13115 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 13116 }
| static void set_hangup_source_and_cause | ( | int | callno, | |
| unsigned char | causecode | |||
| ) | [static] |
Definition at line 9916 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().
09917 { 09918 iax2_lock_owner(callno); 09919 if (iaxs[callno] && iaxs[callno]->owner) { 09920 struct ast_channel *owner; 09921 const char *name; 09922 09923 owner = iaxs[callno]->owner; 09924 if (causecode) { 09925 owner->hangupcause = causecode; 09926 } 09927 name = ast_strdupa(owner->name); 09928 ast_channel_ref(owner); 09929 ast_channel_unlock(owner); 09930 ast_mutex_unlock(&iaxsl[callno]); 09931 ast_set_hangupsource(owner, name, 0); 09932 ast_channel_unref(owner); 09933 ast_mutex_lock(&iaxsl[callno]); 09934 } 09935 }
| static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2265 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().
02266 { 02267 uint16_t limit = global_maxcallno; 02268 struct addr_range *addr_range; 02269 struct sockaddr_in sin = { 02270 .sin_addr.s_addr = peercnt->addr, 02271 }; 02272 02273 02274 if (peercnt->reg && peercnt->limit) { 02275 return; /* this peercnt has a custom limit set by a registration */ 02276 } 02277 02278 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02279 limit = addr_range->limit; 02280 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02281 ao2_ref(addr_range, -1); 02282 } 02283 02284 peercnt->limit = limit; 02285 }
| static int set_peercnt_limit_all_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2291 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02292 { 02293 struct peercnt *peercnt = obj; 02294 02295 set_peercnt_limit(peercnt); 02296 ast_debug(1, "Reset limits for peercnts table\n"); 02297 02298 return 0; 02299 }
| 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 9937 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_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_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().
09938 { 09939 struct sockaddr_in sin; 09940 int res; 09941 int updatehistory=1; 09942 int new = NEW_PREVENT; 09943 int dcallno = 0; 09944 char decrypted = 0; 09945 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09946 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09947 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09948 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09949 struct iax_frame *fr; 09950 struct iax_frame *cur; 09951 struct ast_frame f = { 0, }; 09952 struct ast_channel *c = NULL; 09953 struct iax2_dpcache *dp; 09954 struct iax2_peer *peer; 09955 struct iax_ies ies; 09956 struct iax_ie_data ied0, ied1; 09957 format_t format; 09958 int fd; 09959 int exists; 09960 int minivid = 0; 09961 char empty[32]=""; /* Safety measure */ 09962 struct iax_frame *duped_fr; 09963 char host_pref_buf[128]; 09964 char caller_pref_buf[128]; 09965 struct ast_codec_pref pref; 09966 char *using_prefs = "mine"; 09967 09968 /* allocate an iax_frame with 4096 bytes of data buffer */ 09969 fr = ast_alloca(sizeof(*fr) + 4096); 09970 memset(fr, 0, sizeof(*fr)); 09971 fr->afdatalen = 4096; /* From ast_alloca() above */ 09972 09973 /* Copy frequently used parameters to the stack */ 09974 res = thread->buf_len; 09975 fd = thread->iofd; 09976 memcpy(&sin, &thread->iosin, sizeof(sin)); 09977 09978 if (res < sizeof(*mh)) { 09979 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09980 return 1; 09981 } 09982 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09983 if (res < sizeof(*vh)) { 09984 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)); 09985 return 1; 09986 } 09987 09988 /* This is a video frame, get call number */ 09989 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 09990 minivid = 1; 09991 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 09992 return socket_process_meta(res, meta, &sin, fd, fr); 09993 09994 #ifdef DEBUG_SUPPORT 09995 if (res >= sizeof(*fh)) 09996 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 09997 #endif 09998 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09999 if (res < sizeof(*fh)) { 10000 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)); 10001 return 1; 10002 } 10003 10004 /* Get the destination call number */ 10005 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 10006 10007 10008 /* check to make sure this full frame isn't encrypted before we attempt 10009 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 10010 * callno is not found here, that just means one hasn't been allocated for 10011 * this connection yet. */ 10012 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 10013 ast_mutex_lock(&iaxsl[fr->callno]); 10014 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { 10015 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10016 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10017 ast_mutex_unlock(&iaxsl[fr->callno]); 10018 return 1; 10019 } 10020 decrypted = 1; 10021 } 10022 ast_mutex_unlock(&iaxsl[fr->callno]); 10023 } 10024 10025 /* Retrieve the type and subclass */ 10026 f.frametype = fh->type; 10027 if (f.frametype == AST_FRAME_VIDEO) { 10028 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 10029 } else if (f.frametype == AST_FRAME_VOICE) { 10030 f.subclass.codec = uncompress_subclass(fh->csub); 10031 } else { 10032 f.subclass.integer = uncompress_subclass(fh->csub); 10033 } 10034 10035 /* Deal with POKE/PONG without allocating a callno */ 10036 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) { 10037 /* Reply back with a PONG, but don't care about the result. */ 10038 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10039 return 1; 10040 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) { 10041 /* Ignore */ 10042 return 1; 10043 } 10044 10045 f.datalen = res - sizeof(*fh); 10046 if (f.datalen) { 10047 if (f.frametype == AST_FRAME_IAX) { 10048 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 10049 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 10050 ast_variables_destroy(ies.vars); 10051 return 1; 10052 } 10053 f.data.ptr = NULL; 10054 f.datalen = 0; 10055 } else { 10056 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 10057 memset(&ies, 0, sizeof(ies)); 10058 } 10059 } else { 10060 if (f.frametype == AST_FRAME_IAX) 10061 f.data.ptr = NULL; 10062 else 10063 f.data.ptr = empty; 10064 memset(&ies, 0, sizeof(ies)); 10065 } 10066 10067 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) { 10068 /* only set NEW_ALLOW if calltoken checks out */ 10069 if (handle_call_token(fh, &ies, &sin, fd)) { 10070 ast_variables_destroy(ies.vars); 10071 return 1; 10072 } 10073 10074 if (ies.calltoken && ies.calltokendata) { 10075 /* if we've gotten this far, and the calltoken ie data exists, 10076 * then calltoken validation _MUST_ have taken place. If calltoken 10077 * data is provided, it is always validated reguardless of any 10078 * calltokenoptional or requirecalltoken options */ 10079 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 10080 } else { 10081 new = NEW_ALLOW; 10082 } 10083 } 10084 } else { 10085 /* Don't know anything about it yet */ 10086 f.frametype = AST_FRAME_NULL; 10087 f.subclass.integer = 0; 10088 memset(&ies, 0, sizeof(ies)); 10089 } 10090 10091 if (!fr->callno) { 10092 int check_dcallno = 0; 10093 10094 /* 10095 * We enforce accurate destination call numbers for ACKs. This forces the other 10096 * end to know the destination call number before call setup can complete. 10097 * 10098 * Discussed in the following thread: 10099 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 10100 */ 10101 10102 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) { 10103 check_dcallno = 1; 10104 } 10105 10106 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 10107 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) { 10108 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10109 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) { 10110 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10111 } 10112 ast_variables_destroy(ies.vars); 10113 return 1; 10114 } 10115 } 10116 10117 if (fr->callno > 0) 10118 ast_mutex_lock(&iaxsl[fr->callno]); 10119 10120 if (!fr->callno || !iaxs[fr->callno]) { 10121 /* A call arrived for a nonexistent destination. Unless it's an "inval" 10122 frame, reply with an inval */ 10123 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10124 /* We can only raw hangup control frames */ 10125 if (((f.subclass.integer != IAX_COMMAND_INVAL) && 10126 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10127 (f.subclass.integer != IAX_COMMAND_TXACC) && 10128 (f.subclass.integer != IAX_COMMAND_FWDOWNL))|| 10129 (f.frametype != AST_FRAME_IAX)) 10130 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 10131 fd); 10132 } 10133 if (fr->callno > 0) 10134 ast_mutex_unlock(&iaxsl[fr->callno]); 10135 ast_variables_destroy(ies.vars); 10136 return 1; 10137 } 10138 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 10139 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10140 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10141 ast_variables_destroy(ies.vars); 10142 ast_mutex_unlock(&iaxsl[fr->callno]); 10143 return 1; 10144 } 10145 decrypted = 1; 10146 } 10147 10148 #ifdef DEBUG_SUPPORT 10149 if (decrypted) { 10150 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 10151 } 10152 #endif 10153 10154 10155 /* count this frame */ 10156 iaxs[fr->callno]->frames_received++; 10157 10158 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 10159 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */ 10160 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */ 10161 unsigned short new_peercallno; 10162 10163 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 10164 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 10165 if (iaxs[fr->callno]->peercallno) { 10166 remove_by_peercallno(iaxs[fr->callno]); 10167 } 10168 iaxs[fr->callno]->peercallno = new_peercallno; 10169 store_by_peercallno(iaxs[fr->callno]); 10170 } 10171 } 10172 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10173 if (iaxdebug) 10174 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer); 10175 /* Check if it's out of order (and not an ACK or INVAL) */ 10176 fr->oseqno = fh->oseqno; 10177 fr->iseqno = fh->iseqno; 10178 fr->ts = ntohl(fh->ts); 10179 #ifdef IAXTESTS 10180 if (test_resync) { 10181 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 10182 fr->ts += test_resync; 10183 } 10184 #endif /* IAXTESTS */ 10185 #if 0 10186 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 10187 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 10188 (f.subclass == IAX_COMMAND_NEW || 10189 f.subclass == IAX_COMMAND_AUTHREQ || 10190 f.subclass == IAX_COMMAND_ACCEPT || 10191 f.subclass == IAX_COMMAND_REJECT)) ) ) 10192 #endif 10193 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 10194 updatehistory = 0; 10195 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 10196 (iaxs[fr->callno]->iseqno || 10197 ((f.subclass.integer != IAX_COMMAND_TXCNT) && 10198 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10199 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10200 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10201 (f.subclass.integer != IAX_COMMAND_TXACC)) || 10202 (f.frametype != AST_FRAME_IAX))) { 10203 if ( 10204 ((f.subclass.integer != IAX_COMMAND_ACK) && 10205 (f.subclass.integer != IAX_COMMAND_INVAL) && 10206 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10207 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10208 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10209 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10210 (f.subclass.integer != IAX_COMMAND_TXACC) && 10211 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10212 (f.frametype != AST_FRAME_IAX)) { 10213 /* If it's not an ACK packet, it's out of order. */ 10214 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 10215 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer); 10216 /* Check to see if we need to request retransmission, 10217 * and take sequence number wraparound into account */ 10218 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 10219 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 10220 if ((f.frametype != AST_FRAME_IAX) || 10221 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) { 10222 ast_debug(1, "Acking anyway\n"); 10223 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 10224 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 10225 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10226 } 10227 } else { 10228 /* Send a VNAK requesting retransmission */ 10229 iax2_vnak(fr->callno); 10230 } 10231 ast_variables_destroy(ies.vars); 10232 ast_mutex_unlock(&iaxsl[fr->callno]); 10233 return 1; 10234 } 10235 } else { 10236 /* Increment unless it's an ACK or VNAK */ 10237 if (((f.subclass.integer != IAX_COMMAND_ACK) && 10238 (f.subclass.integer != IAX_COMMAND_INVAL) && 10239 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10240 (f.subclass.integer != IAX_COMMAND_TXACC) && 10241 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10242 (f.frametype != AST_FRAME_IAX)) 10243 iaxs[fr->callno]->iseqno++; 10244 } 10245 /* Ensure text frames are NULL-terminated */ 10246 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 10247 if (res < thread->buf_size) 10248 thread->buf[res++] = '\0'; 10249 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 10250 thread->buf[res - 1] = '\0'; 10251 } 10252 10253 /* Handle implicit ACKing unless this is an INVAL, and only if this is 10254 from the real peer, not the transfer peer */ 10255 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10256 ((f.subclass.integer != IAX_COMMAND_INVAL) || 10257 (f.frametype != AST_FRAME_IAX))) { 10258 unsigned char x; 10259 int call_to_destroy; 10260 /* First we have to qualify that the ACKed value is within our window */ 10261 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 10262 x = fr->iseqno; 10263 else 10264 x = iaxs[fr->callno]->oseqno; 10265 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 10266 /* The acknowledgement is within our window. Time to acknowledge everything 10267 that it says to */ 10268 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 10269 /* Ack the packet with the given timestamp */ 10270 if (iaxdebug) 10271 ast_debug(1, "Cancelling transmission of packet %d\n", x); 10272 call_to_destroy = 0; 10273 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10274 /* If it's our call, and our timestamp, mark -1 retries */ 10275 if (x == cur->oseqno) { 10276 cur->retries = -1; 10277 /* Destroy call if this is the end */ 10278 if (cur->final) 10279 call_to_destroy = fr->callno; 10280 } 10281 } 10282 if (call_to_destroy) { 10283 if (iaxdebug) 10284 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 10285 ast_mutex_lock(&iaxsl[call_to_destroy]); 10286 iax2_destroy(call_to_destroy); 10287 ast_mutex_unlock(&iaxsl[call_to_destroy]); 10288 } 10289 } 10290 /* Note how much we've received acknowledgement for */ 10291 if (iaxs[fr->callno]) 10292 iaxs[fr->callno]->rseqno = fr->iseqno; 10293 else { 10294 /* Stop processing now */ 10295 ast_variables_destroy(ies.vars); 10296 ast_mutex_unlock(&iaxsl[fr->callno]); 10297 return 1; 10298 } 10299 } else { 10300 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 10301 } 10302 } 10303 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10304 ((f.frametype != AST_FRAME_IAX) || 10305 ((f.subclass.integer != IAX_COMMAND_TXACC) && 10306 (f.subclass.integer != IAX_COMMAND_TXCNT)))) { 10307 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 10308 ast_variables_destroy(ies.vars); 10309 ast_mutex_unlock(&iaxsl[fr->callno]); 10310 return 1; 10311 } 10312 10313 /* when we receive the first full frame for a new incoming channel, 10314 it is safe to start the PBX on the channel because we have now 10315 completed a 3-way handshake with the peer */ 10316 if ((f.frametype == AST_FRAME_VOICE) || 10317 (f.frametype == AST_FRAME_VIDEO) || 10318 (f.frametype == AST_FRAME_IAX)) { 10319 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 10320 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10321 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL, 10322 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) { 10323 ast_variables_destroy(ies.vars); 10324 ast_mutex_unlock(&iaxsl[fr->callno]); 10325 return 1; 10326 } 10327 } 10328 10329 if (ies.vars) { 10330 struct ast_datastore *variablestore = NULL; 10331 struct ast_variable *var, *prev = NULL; 10332 AST_LIST_HEAD(, ast_var_t) *varlist; 10333 10334 iax2_lock_owner(fr->callno); 10335 if (!iaxs[fr->callno]) { 10336 ast_variables_destroy(ies.vars); 10337 ast_mutex_unlock(&iaxsl[fr->callno]); 10338 return 1; 10339 } 10340 if ((c = iaxs[fr->callno]->owner)) { 10341 varlist = ast_calloc(1, sizeof(*varlist)); 10342 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10343 10344 if (variablestore && varlist) { 10345 variablestore->data = varlist; 10346 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10347 AST_LIST_HEAD_INIT(varlist); 10348 ast_debug(1, "I can haz IAX vars?\n"); 10349 for (var = ies.vars; var; var = var->next) { 10350 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10351 if (prev) { 10352 ast_free(prev); 10353 } 10354 prev = var; 10355 if (!newvar) { 10356 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10357 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10358 } else { 10359 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10360 } 10361 } 10362 if (prev) { 10363 ast_free(prev); 10364 } 10365 ies.vars = NULL; 10366 ast_channel_datastore_add(c, variablestore); 10367 } else { 10368 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10369 if (variablestore) { 10370 ast_datastore_free(variablestore); 10371 } 10372 if (varlist) { 10373 ast_free(varlist); 10374 } 10375 } 10376 ast_channel_unlock(c); 10377 } else { 10378 /* No channel yet, so transfer the variables directly over to the pvt, 10379 * for later inheritance. */ 10380 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 10381 for (var = ies.vars; var && var->next; var = var->next); 10382 if (var) { 10383 var->next = iaxs[fr->callno]->iaxvars; 10384 iaxs[fr->callno]->iaxvars = ies.vars; 10385 ies.vars = NULL; 10386 } 10387 } 10388 } 10389 10390 if (ies.vars) { 10391 ast_debug(1, "I have IAX variables, but they were not processed\n"); 10392 } 10393 } 10394 10395 /* once we receive our first IAX Full Frame that is not CallToken related, send all 10396 * queued signaling frames that were being held. */ 10397 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 10398 send_signaling(iaxs[fr->callno]); 10399 } 10400 10401 if (f.frametype == AST_FRAME_VOICE) { 10402 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) { 10403 iaxs[fr->callno]->voiceformat = f.subclass.codec; 10404 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec)); 10405 if (iaxs[fr->callno]->owner) { 10406 iax2_lock_owner(fr->callno); 10407 if (iaxs[fr->callno]) { 10408 if (iaxs[fr->callno]->owner) { 10409 format_t orignative; 10410 10411 orignative = iaxs[fr->callno]->owner->nativeformats; 10412 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec; 10413 if (iaxs[fr->callno]->owner->readformat) 10414 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10415 iaxs[fr->callno]->owner->nativeformats = orignative; 10416 ast_channel_unlock(iaxs[fr->callno]->owner); 10417 } 10418 } else { 10419 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 10420 /* Free remote variables (if any) */ 10421 if (ies.vars) { 10422 ast_variables_destroy(ies.vars); 10423 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 10424 ies.vars = NULL; 10425 } 10426 ast_mutex_unlock(&iaxsl[fr->callno]); 10427 return 1; 10428 } 10429 } 10430 } 10431 } 10432 if (f.frametype == AST_FRAME_VIDEO) { 10433 if (f.subclass.codec != iaxs[fr->callno]->videoformat) { 10434 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL)); 10435 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL; 10436 } 10437 } 10438 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 10439 if (f.subclass.integer == AST_CONTROL_BUSY) { 10440 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 10441 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) { 10442 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 10443 } 10444 } 10445 if (f.frametype == AST_FRAME_IAX) { 10446 ast_sched_thread_del(sched, iaxs[fr->callno]->initid); 10447 /* Handle the IAX pseudo frame itself */ 10448 if (iaxdebug) 10449 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer); 10450 10451 /* Update last ts unless the frame's timestamp originated with us. */ 10452 if (iaxs[fr->callno]->last < fr->ts && 10453 f.subclass.integer != IAX_COMMAND_ACK && 10454 f.subclass.integer != IAX_COMMAND_PONG && 10455 f.subclass.integer != IAX_COMMAND_LAGRP) { 10456 iaxs[fr->callno]->last = fr->ts; 10457 if (iaxdebug) 10458 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10459 } 10460 iaxs[fr->callno]->last_iax_message = f.subclass.integer; 10461 if (!iaxs[fr->callno]->first_iax_message) { 10462 iaxs[fr->callno]->first_iax_message = f.subclass.integer; 10463 } 10464 switch(f.subclass.integer) { 10465 case IAX_COMMAND_ACK: 10466 /* Do nothing */ 10467 break; 10468 case IAX_COMMAND_QUELCH: 10469 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10470 /* Generate Manager Hold event, if necessary*/ 10471 if (iaxs[fr->callno]->owner) { 10472 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10473 "Status: On\r\n" 10474 "Channel: %s\r\n" 10475 "Uniqueid: %s\r\n", 10476 iaxs[fr->callno]->owner->name, 10477 iaxs[fr->callno]->owner->uniqueid); 10478 } 10479 10480 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH); 10481 if (ies.musiconhold) { 10482 iax2_lock_owner(fr->callno); 10483 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 10484 break; 10485 } 10486 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10487 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 10488 10489 /* 10490 * We already hold the owner lock so we do not 10491 * need to check iaxs[fr->callno] after it returns. 10492 */ 10493 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 10494 S_OR(moh_suggest, NULL), 10495 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 10496 } 10497 ast_channel_unlock(iaxs[fr->callno]->owner); 10498 } 10499 } 10500 break; 10501 case IAX_COMMAND_UNQUELCH: 10502 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10503 iax2_lock_owner(fr->callno); 10504 if (!iaxs[fr->callno]) { 10505 break; 10506 } 10507 /* Generate Manager Unhold event, if necessary */ 10508 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { 10509 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10510 "Status: Off\r\n" 10511 "Channel: %s\r\n" 10512 "Uniqueid: %s\r\n", 10513 iaxs[fr->callno]->owner->name, 10514 iaxs[fr->callno]->owner->uniqueid); 10515 } 10516 10517 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH); 10518 if (!iaxs[fr->callno]->owner) { 10519 break; 10520 } 10521 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10522 /* 10523 * We already hold the owner lock so we do not 10524 * need to check iaxs[fr->callno] after it returns. 10525 */ 10526 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10527 } 10528 ast_channel_unlock(iaxs[fr->callno]->owner); 10529 } 10530 break; 10531 case IAX_COMMAND_TXACC: 10532 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10533 /* Ack the packet with the given timestamp */ 10534 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10535 /* Cancel any outstanding txcnt's */ 10536 if (cur->transfer) { 10537 cur->retries = -1; 10538 } 10539 } 10540 memset(&ied1, 0, sizeof(ied1)); 10541 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10542 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10543 iaxs[fr->callno]->transferring = TRANSFER_READY; 10544 } 10545 break; 10546 case IAX_COMMAND_NEW: 10547 /* Ignore if it's already up */ 10548 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10549 break; 10550 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10551 ast_mutex_unlock(&iaxsl[fr->callno]); 10552 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10553 ast_mutex_lock(&iaxsl[fr->callno]); 10554 if (!iaxs[fr->callno]) { 10555 break; 10556 } 10557 } 10558 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10559 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) { 10560 int new_callno; 10561 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10562 fr->callno = new_callno; 10563 } 10564 /* For security, always ack immediately */ 10565 if (delayreject) 10566 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10567 if (check_access(fr->callno, &sin, &ies)) { 10568 /* They're not allowed on */ 10569 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10570 if (authdebug) 10571 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); 10572 break; 10573 } 10574 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10575 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10576 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10577 break; 10578 } 10579 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10580 const char *context, *exten, *cid_num; 10581 10582 context = ast_strdupa(iaxs[fr->callno]->context); 10583 exten = ast_strdupa(iaxs[fr->callno]->exten); 10584 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10585 10586 /* This might re-enter the IAX code and need the lock */ 10587 ast_mutex_unlock(&iaxsl[fr->callno]); 10588 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10589 ast_mutex_lock(&iaxsl[fr->callno]); 10590 10591 if (!iaxs[fr->callno]) { 10592 break; 10593 } 10594 } else 10595 exists = 0; 10596 /* Get OSP token if it does exist */ 10597 save_osptoken(fr, &ies); 10598 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10599 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10600 memset(&ied0, 0, sizeof(ied0)); 10601 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10602 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10603 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10604 if (!iaxs[fr->callno]) { 10605 break; 10606 } 10607 if (authdebug) 10608 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); 10609 } else { 10610 /* Select an appropriate format */ 10611 10612 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10613 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10614 using_prefs = "reqonly"; 10615 } else { 10616 using_prefs = "disabled"; 10617 } 10618 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10619 memset(&pref, 0, sizeof(pref)); 10620 strcpy(caller_pref_buf, "disabled"); 10621 strcpy(host_pref_buf, "disabled"); 10622 } else { 10623 using_prefs = "mine"; 10624 /* If the information elements are in here... use them */ 10625 if (ies.codec_prefs) 10626 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10627 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10628 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10629 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10630 pref = iaxs[fr->callno]->rprefs; 10631 using_prefs = "caller"; 10632 } else { 10633 pref = iaxs[fr->callno]->prefs; 10634 } 10635 } else 10636 pref = iaxs[fr->callno]->prefs; 10637 10638 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10639 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10640 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10641 } 10642 if (!format) { 10643 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10644 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10645 if (!format) { 10646 memset(&ied0, 0, sizeof(ied0)); 10647 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10648 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10649 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10650 if (!iaxs[fr->callno]) { 10651 break; 10652 } 10653 if (authdebug) { 10654 char tmp[256], tmp2[256], tmp3[256]; 10655 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10656 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 10657 ast_inet_ntoa(sin.sin_addr), 10658 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10659 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10660 } else { 10661 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10662 ast_inet_ntoa(sin.sin_addr), 10663 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10664 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10665 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10666 } 10667 } 10668 } else { 10669 /* Pick one... */ 10670 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10671 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10672 format = 0; 10673 } else { 10674 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10675 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10676 memset(&pref, 0, sizeof(pref)); 10677 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10678 strcpy(caller_pref_buf,"disabled"); 10679 strcpy(host_pref_buf,"disabled"); 10680 } else { 10681 using_prefs = "mine"; 10682 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10683 /* Do the opposite of what we tried above. */ 10684 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10685 pref = iaxs[fr->callno]->prefs; 10686 } else { 10687 pref = iaxs[fr->callno]->rprefs; 10688 using_prefs = "caller"; 10689 } 10690 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10691 } else /* if no codec_prefs IE do it the old way */ 10692 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10693 } 10694 } 10695 10696 if (!format) { 10697 char tmp[256], tmp2[256], tmp3[256]; 10698 memset(&ied0, 0, sizeof(ied0)); 10699 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10700 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10701 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 10702 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10703 if (!iaxs[fr->callno]) { 10704 break; 10705 } 10706 if (authdebug) { 10707 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10708 ast_inet_ntoa(sin.sin_addr), 10709 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10710 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10711 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10712 } 10713 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10714 break; 10715 } 10716 } 10717 } 10718 if (format) { 10719 /* No authentication required, let them in */ 10720 memset(&ied1, 0, sizeof(ied1)); 10721 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10722 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 10723 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10724 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10725 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10726 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10727 "%srequested format = %s,\n" 10728 "%srequested prefs = %s,\n" 10729 "%sactual format = %s,\n" 10730 "%shost prefs = %s,\n" 10731 "%spriority = %s\n", 10732 ast_inet_ntoa(sin.sin_addr), 10733 VERBOSE_PREFIX_4, 10734 ast_getformatname(iaxs[fr->callno]->peerformat), 10735 VERBOSE_PREFIX_4, 10736 caller_pref_buf, 10737 VERBOSE_PREFIX_4, 10738 ast_getformatname(format), 10739 VERBOSE_PREFIX_4, 10740 host_pref_buf, 10741 VERBOSE_PREFIX_4, 10742 using_prefs); 10743 10744 iaxs[fr->callno]->chosenformat = format; 10745 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10746 } else { 10747 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10748 /* If this is a TBD call, we're ready but now what... */ 10749 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10750 } 10751 } 10752 } 10753 break; 10754 } 10755 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10756 merge_encryption(iaxs[fr->callno],ies.encmethods); 10757 else 10758 iaxs[fr->callno]->encmethods = 0; 10759 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10760 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10761 break; 10762 case IAX_COMMAND_DPREQ: 10763 /* Request status in the dialplan */ 10764 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10765 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10766 if (iaxcompat) { 10767 /* Spawn a thread for the lookup */ 10768 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10769 } else { 10770 /* Just look it up */ 10771 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10772 } 10773 } 10774 break; 10775 case IAX_COMMAND_HANGUP: 10776 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10777 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10778 /* Set hangup cause according to remote and hangupsource */ 10779 if (iaxs[fr->callno]->owner) { 10780 set_hangup_source_and_cause(fr->callno, ies.causecode); 10781 if (!iaxs[fr->callno]) { 10782 break; 10783 } 10784 } 10785 10786 /* Send ack immediately, before we destroy */ 10787 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10788 iax2_destroy(fr->callno); 10789 break; 10790 case IAX_COMMAND_REJECT: 10791 /* Set hangup cause according to remote and hangup source */ 10792 if (iaxs[fr->callno]->owner) { 10793 set_hangup_source_and_cause(fr->callno, ies.causecode); 10794 if (!iaxs[fr->callno]) { 10795 break; 10796 } 10797 } 10798 10799 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10800 if (iaxs[fr->callno]->owner && authdebug) 10801 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10802 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10803 ies.cause ? ies.cause : "<Unknown>"); 10804 ast_debug(1, "Immediately destroying %d, having received reject\n", 10805 fr->callno); 10806 } 10807 /* Send ack immediately, before we destroy */ 10808 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10809 fr->ts, NULL, 0, fr->iseqno); 10810 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) 10811 iaxs[fr->callno]->error = EPERM; 10812 iax2_destroy(fr->callno); 10813 break; 10814 case IAX_COMMAND_TRANSFER: 10815 { 10816 struct ast_channel *bridged_chan; 10817 struct ast_channel *owner; 10818 10819 iax2_lock_owner(fr->callno); 10820 if (!iaxs[fr->callno]) { 10821 /* Initiating call went away before we could transfer. */ 10822 break; 10823 } 10824 owner = iaxs[fr->callno]->owner; 10825 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 10826 if (bridged_chan && ies.called_number) { 10827 const char *context; 10828 10829 context = ast_strdupa(iaxs[fr->callno]->context); 10830 10831 ast_channel_ref(owner); 10832 ast_channel_ref(bridged_chan); 10833 ast_channel_unlock(owner); 10834 ast_mutex_unlock(&iaxsl[fr->callno]); 10835 10836 /* Set BLINDTRANSFER channel variables */ 10837 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name); 10838 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name); 10839 10840 /* DO NOT hold any locks while calling ast_parking_ext_valid() */ 10841 if (ast_parking_ext_valid(ies.called_number, owner, context)) { 10842 ast_debug(1, "Parking call '%s'\n", bridged_chan->name); 10843 if (iax_park(bridged_chan, owner, ies.called_number, context)) { 10844 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 10845 bridged_chan->name); 10846 } 10847 } else { 10848 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) { 10849 ast_log(LOG_WARNING, 10850 "Async goto of '%s' to '%s@%s' failed\n", 10851 bridged_chan->name, ies.called_number, context); 10852 } else { 10853 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", 10854 bridged_chan->name, ies.called_number, context); 10855 } 10856 } 10857 ast_channel_unref(owner); 10858 ast_channel_unref(bridged_chan); 10859 10860 ast_mutex_lock(&iaxsl[fr->callno]); 10861 } else { 10862 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10863 if (owner) { 10864 ast_channel_unlock(owner); 10865 } 10866 } 10867 10868 break; 10869 } 10870 case IAX_COMMAND_ACCEPT: 10871 /* Ignore if call is already up or needs authentication or is a TBD */ 10872 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10873 break; 10874 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10875 /* Send ack immediately, before we destroy */ 10876 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10877 iax2_destroy(fr->callno); 10878 break; 10879 } 10880 if (ies.format) { 10881 iaxs[fr->callno]->peerformat = ies.format; 10882 } else { 10883 if (iaxs[fr->callno]->owner) 10884 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10885 else 10886 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10887 } 10888 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)); 10889 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10890 memset(&ied0, 0, sizeof(ied0)); 10891 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10892 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10893 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10894 if (!iaxs[fr->callno]) { 10895 break; 10896 } 10897 if (authdebug) { 10898 char tmp1[256], tmp2[256]; 10899 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n", 10900 ast_inet_ntoa(sin.sin_addr), 10901 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10902 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10903 } 10904 } else { 10905 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10906 iax2_lock_owner(fr->callno); 10907 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10908 /* Switch us to use a compatible format */ 10909 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 10910 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 10911 10912 /* Setup read/write formats properly. */ 10913 if (iaxs[fr->callno]->owner->writeformat) 10914 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 10915 if (iaxs[fr->callno]->owner->readformat) 10916 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10917 ast_channel_unlock(iaxs[fr->callno]->owner); 10918 } 10919 } 10920 if (iaxs[fr->callno]) { 10921 AST_LIST_LOCK(&dpcache); 10922 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10923 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10924 iax2_dprequest(dp, fr->callno); 10925 AST_LIST_UNLOCK(&dpcache); 10926 } 10927 break; 10928 case IAX_COMMAND_POKE: 10929 /* Send back a pong packet with the original timestamp */ 10930 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10931 break; 10932 case IAX_COMMAND_PING: 10933 { 10934 struct iax_ie_data pingied; 10935 construct_rr(iaxs[fr->callno], &pingied); 10936 /* Send back a pong packet with the original timestamp */ 10937 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10938 } 10939 break; 10940 case IAX_COMMAND_PONG: 10941 /* Calculate ping time */ 10942 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10943 /* save RR info */ 10944 save_rr(fr, &ies); 10945 10946 /* Good time to write jb stats for this call */ 10947 log_jitterstats(fr->callno); 10948 10949 if (iaxs[fr->callno]->peerpoke) { 10950 peer = iaxs[fr->callno]->peerpoke; 10951 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10952 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10953 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10954 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 10955 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 10956 } 10957 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10958 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10959 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10960 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 10961 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 10962 } 10963 } 10964 peer->lastms = iaxs[fr->callno]->pingtime; 10965 if (peer->smoothing && (peer->lastms > -1)) 10966 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10967 else if (peer->smoothing && peer->lastms < 0) 10968 peer->historicms = (0 + peer->historicms) / 2; 10969 else 10970 peer->historicms = iaxs[fr->callno]->pingtime; 10971 10972 /* Remove scheduled iax2_poke_noanswer */ 10973 if (peer->pokeexpire > -1) { 10974 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 10975 peer_unref(peer); 10976 peer->pokeexpire = -1; 10977 } 10978 } 10979 /* Schedule the next cycle */ 10980 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 10981 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10982 else 10983 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 10984 if (peer->pokeexpire == -1) 10985 peer_unref(peer); 10986 /* and finally send the ack */ 10987 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10988 /* And wrap up the qualify call */ 10989 iax2_destroy(fr->callno); 10990 peer->callno = 0; 10991 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 10992 } 10993 break; 10994 case IAX_COMMAND_LAGRQ: 10995 case IAX_COMMAND_LAGRP: 10996 f.src = "LAGRQ"; 10997 f.mallocd = 0; 10998 f.offset = 0; 10999 f.samples = 0; 11000 iax_frame_wrap(fr, &f); 11001 if (f.subclass.integer == IAX_COMMAND_LAGRQ) { 11002 /* Received a LAGRQ - echo back a LAGRP */ 11003 fr->af.subclass.integer = IAX_COMMAND_LAGRP; 11004 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 11005 } else { 11006 /* Received LAGRP in response to our LAGRQ */ 11007 unsigned int ts; 11008 /* This is a reply we've been given, actually measure the difference */ 11009 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 11010 iaxs[fr->callno]->lag = ts - fr->ts; 11011 if (iaxdebug) 11012 ast_debug(1, "Peer %s lag measured as %dms\n", 11013 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 11014 } 11015 break; 11016 case IAX_COMMAND_AUTHREQ: 11017 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11018 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>"); 11019 break; 11020 } 11021 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 11022 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 11023 .subclass.integer = AST_CONTROL_HANGUP, 11024 }; 11025 ast_log(LOG_WARNING, 11026 "I don't know how to authenticate %s to %s\n", 11027 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 11028 iax2_queue_frame(fr->callno, &hangup_fr); 11029 } 11030 break; 11031 case IAX_COMMAND_AUTHREP: 11032 /* For security, always ack immediately */ 11033 if (delayreject) 11034 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11035 /* Ignore once we've started */ 11036 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11037 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>"); 11038 break; 11039 } 11040 if (authenticate_verify(iaxs[fr->callno], &ies)) { 11041 if (authdebug) 11042 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); 11043 memset(&ied0, 0, sizeof(ied0)); 11044 auth_fail(fr->callno, IAX_COMMAND_REJECT); 11045 break; 11046 } 11047 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 11048 /* This might re-enter the IAX code and need the lock */ 11049 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 11050 } else 11051 exists = 0; 11052 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 11053 if (authdebug) 11054 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); 11055 memset(&ied0, 0, sizeof(ied0)); 11056 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11057 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11058 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11059 if (!iaxs[fr->callno]) { 11060 break; 11061 } 11062 } else { 11063 /* Select an appropriate format */ 11064 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11065 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11066 using_prefs = "reqonly"; 11067 } else { 11068 using_prefs = "disabled"; 11069 } 11070 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 11071 memset(&pref, 0, sizeof(pref)); 11072 strcpy(caller_pref_buf, "disabled"); 11073 strcpy(host_pref_buf, "disabled"); 11074 } else { 11075 using_prefs = "mine"; 11076 if (ies.codec_prefs) 11077 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 11078 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11079 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11080 pref = iaxs[fr->callno]->rprefs; 11081 using_prefs = "caller"; 11082 } else { 11083 pref = iaxs[fr->callno]->prefs; 11084 } 11085 } else /* if no codec_prefs IE do it the old way */ 11086 pref = iaxs[fr->callno]->prefs; 11087 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 11088 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 11089 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 11090 } 11091 if (!format) { 11092 char tmp1[256], tmp2[256], tmp3[256]; 11093 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11094 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n", 11095 ast_getformatname(iaxs[fr->callno]->peerformat), 11096 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability)); 11097 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 11098 } 11099 if (!format) { 11100 if (authdebug) { 11101 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11102 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr), 11103 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11104 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11105 } else { 11106 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11107 ast_inet_ntoa(sin.sin_addr), 11108 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11109 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11110 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11111 } 11112 } 11113 memset(&ied0, 0, sizeof(ied0)); 11114 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11115 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11116 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11117 if (!iaxs[fr->callno]) { 11118 break; 11119 } 11120 } else { 11121 /* Pick one... */ 11122 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11123 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 11124 format = 0; 11125 } else { 11126 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11127 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 11128 memset(&pref, 0, sizeof(pref)); 11129 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 11130 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11131 strcpy(caller_pref_buf,"disabled"); 11132 strcpy(host_pref_buf,"disabled"); 11133 } else { 11134 using_prefs = "mine"; 11135 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11136 /* Do the opposite of what we tried above. */ 11137 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11138 pref = iaxs[fr->callno]->prefs; 11139 } else { 11140 pref = iaxs[fr->callno]->rprefs; 11141 using_prefs = "caller"; 11142 } 11143 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 11144 } else /* if no codec_prefs IE do it the old way */ 11145 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11146 } 11147 } 11148 if (!format) { 11149 char tmp1[256], tmp2[256], tmp3[256]; 11150 ast_log(LOG_ERROR, "No best format in %s???\n", 11151 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 11152 if (authdebug) { 11153 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11154 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 11155 ast_inet_ntoa(sin.sin_addr), 11156 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11157 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11158 } else { 11159 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11160 ast_inet_ntoa(sin.sin_addr), 11161 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11162 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11163 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11164 } 11165 } 11166 memset(&ied0, 0, sizeof(ied0)); 11167 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11168 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11169 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11170 if (!iaxs[fr->callno]) { 11171 break; 11172 } 11173 } 11174 } 11175 } 11176 if (format) { 11177 /* Authentication received */ 11178 memset(&ied1, 0, sizeof(ied1)); 11179 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 11180 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 11181 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 11182 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 11183 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11184 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 11185 "%srequested format = %s,\n" 11186 "%srequested prefs = %s,\n" 11187 "%sactual format = %s,\n" 11188 "%shost prefs = %s,\n" 11189 "%spriority = %s\n", 11190 ast_inet_ntoa(sin.sin_addr), 11191 VERBOSE_PREFIX_4, 11192 ast_getformatname(iaxs[fr->callno]->peerformat), 11193 VERBOSE_PREFIX_4, 11194 caller_pref_buf, 11195 VERBOSE_PREFIX_4, 11196 ast_getformatname(format), 11197 VERBOSE_PREFIX_4, 11198 host_pref_buf, 11199 VERBOSE_PREFIX_4, 11200 using_prefs); 11201 11202 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11203 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1))) 11204 iax2_destroy(fr->callno); 11205 else if (ies.vars) { 11206 struct ast_datastore *variablestore; 11207 struct ast_variable *var, *prev = NULL; 11208 AST_LIST_HEAD(, ast_var_t) *varlist; 11209 varlist = ast_calloc(1, sizeof(*varlist)); 11210 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11211 if (variablestore && varlist) { 11212 variablestore->data = varlist; 11213 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11214 AST_LIST_HEAD_INIT(varlist); 11215 ast_debug(1, "I can haz IAX vars? w00t\n"); 11216 for (var = ies.vars; var; var = var->next) { 11217 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11218 if (prev) 11219 ast_free(prev); 11220 prev = var; 11221 if (!newvar) { 11222 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11223 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11224 } else { 11225 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11226 } 11227 } 11228 if (prev) 11229 ast_free(prev); 11230 ies.vars = NULL; 11231 ast_channel_datastore_add(c, variablestore); 11232 } else { 11233 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11234 if (variablestore) 11235 ast_datastore_free(variablestore); 11236 if (varlist) 11237 ast_free(varlist); 11238 } 11239 } 11240 } else { 11241 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11242 /* If this is a TBD call, we're ready but now what... */ 11243 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 11244 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) { 11245 goto immediatedial; 11246 } 11247 } 11248 } 11249 } 11250 break; 11251 case IAX_COMMAND_DIAL: 11252 immediatedial: 11253 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 11254 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11255 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 11256 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 11257 if (authdebug) 11258 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); 11259 memset(&ied0, 0, sizeof(ied0)); 11260 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11261 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11262 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11263 if (!iaxs[fr->callno]) { 11264 break; 11265 } 11266 } else { 11267 char tmp[256]; 11268 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11269 ast_verb(3, "Accepting DIAL from %s, formats = %s\n", 11270 ast_inet_ntoa(sin.sin_addr), 11271 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat)); 11272 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11273 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 11274 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1))) 11275 iax2_destroy(fr->callno); 11276 else if (ies.vars) { 11277 struct ast_datastore *variablestore; 11278 struct ast_variable *var, *prev = NULL; 11279 AST_LIST_HEAD(, ast_var_t) *varlist; 11280 varlist = ast_calloc(1, sizeof(*varlist)); 11281 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11282 ast_debug(1, "I can haz IAX vars? w00t\n"); 11283 if (variablestore && varlist) { 11284 variablestore->data = varlist; 11285 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11286 AST_LIST_HEAD_INIT(varlist); 11287 for (var = ies.vars; var; var = var->next) { 11288 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11289 if (prev) 11290 ast_free(prev); 11291 prev = var; 11292 if (!newvar) { 11293 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11294 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11295 } else { 11296 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11297 } 11298 } 11299 if (prev) 11300 ast_free(prev); 11301 ies.vars = NULL; 11302 ast_channel_datastore_add(c, variablestore); 11303 } else { 11304 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11305 if (variablestore) 11306 ast_datastore_free(variablestore); 11307 if (varlist) 11308 ast_free(varlist); 11309 } 11310 } 11311 } 11312 } 11313 break; 11314 case IAX_COMMAND_INVAL: 11315 iaxs[fr->callno]->error = ENOTCONN; 11316 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 11317 iax2_destroy(fr->callno); 11318 ast_debug(1, "Destroying call %d\n", fr->callno); 11319 break; 11320 case IAX_COMMAND_VNAK: 11321 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 11322 /* Force retransmission */ 11323 vnak_retransmit(fr->callno, fr->iseqno); 11324 break; 11325 case IAX_COMMAND_REGREQ: 11326 case IAX_COMMAND_REGREL: 11327 /* For security, always ack immediately */ 11328 if (delayreject) 11329 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11330 if (register_verify(fr->callno, &sin, &ies)) { 11331 if (!iaxs[fr->callno]) { 11332 break; 11333 } 11334 /* Send delayed failure */ 11335 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 11336 break; 11337 } 11338 if (!iaxs[fr->callno]) { 11339 break; 11340 } 11341 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 11342 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 11343 11344 if (f.subclass.integer == IAX_COMMAND_REGREL) { 11345 memset(&sin, 0, sizeof(sin)); 11346 sin.sin_family = AF_INET; 11347 } 11348 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) { 11349 ast_log(LOG_WARNING, "Registry error\n"); 11350 } 11351 if (!iaxs[fr->callno]) { 11352 break; 11353 } 11354 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 11355 ast_mutex_unlock(&iaxsl[fr->callno]); 11356 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 11357 ast_mutex_lock(&iaxsl[fr->callno]); 11358 } 11359 break; 11360 } 11361 registry_authrequest(fr->callno); 11362 break; 11363 case IAX_COMMAND_REGACK: 11364 if (iax2_ack_registry(&ies, &sin, fr->callno)) 11365 ast_log(LOG_WARNING, "Registration failure\n"); 11366 /* Send ack immediately, before we destroy */ 11367 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11368 iax2_destroy(fr->callno); 11369 break; 11370 case IAX_COMMAND_REGREJ: 11371 if (iaxs[fr->callno]->reg) { 11372 if (authdebug) { 11373 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)); 11374 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>"); 11375 } 11376 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 11377 } 11378 /* Send ack immediately, before we destroy */ 11379 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11380 iax2_destroy(fr->callno); 11381 break; 11382 case IAX_COMMAND_REGAUTH: 11383 /* Authentication request */ 11384 if (registry_rerequest(&ies, fr->callno, &sin)) { 11385 memset(&ied0, 0, sizeof(ied0)); 11386 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 11387 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 11388 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11389 } 11390 break; 11391 case IAX_COMMAND_TXREJ: 11392 while (iaxs[fr->callno] 11393 && iaxs[fr->callno]->bridgecallno 11394 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) { 11395 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 11396 } 11397 if (!iaxs[fr->callno]) { 11398 break; 11399 } 11400 11401 iaxs[fr->callno]->transferring = TRANSFER_NONE; 11402 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11403 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 11404 11405 if (!iaxs[fr->callno]->bridgecallno) { 11406 break; 11407 } 11408 11409 if (iaxs[iaxs[fr->callno]->bridgecallno] 11410 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 11411 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE; 11412 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 11413 } 11414 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11415 break; 11416 case IAX_COMMAND_TXREADY: 11417 while (iaxs[fr->callno] 11418 && iaxs[fr->callno]->bridgecallno 11419 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) { 11420 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 11421 } 11422 if (!iaxs[fr->callno]) { 11423 break; 11424 } 11425 11426 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 11427 iaxs[fr->callno]->transferring = TRANSFER_READY; 11428 } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) { 11429 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 11430 } else { 11431 if (iaxs[fr->callno]->bridgecallno) { 11432 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11433 } 11434 break; 11435 } 11436 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11437 11438 if (!iaxs[fr->callno]->bridgecallno) { 11439 break; 11440 } 11441 11442 if (!iaxs[iaxs[fr->callno]->bridgecallno] 11443 || (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY 11444 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) { 11445 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11446 break; 11447 } 11448 11449 /* Both sides are ready */ 11450 11451 /* XXX what isn't checked here is that both sides match transfer types. */ 11452 11453 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 11454 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11455 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11456 11457 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 11458 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 11459 11460 memset(&ied0, 0, sizeof(ied0)); 11461 memset(&ied1, 0, sizeof(ied1)); 11462 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11463 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11464 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 11465 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 11466 } else { 11467 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11468 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11469 11470 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 11471 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 11472 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 11473 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 11474 11475 /* Stop doing lag & ping requests */ 11476 stop_stuff(fr->callno); 11477 stop_stuff(iaxs[fr->callno]->bridgecallno); 11478 11479 memset(&ied0, 0, sizeof(ied0)); 11480 memset(&ied1, 0, sizeof(ied1)); 11481 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11482 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11483 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 11484 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 11485 } 11486 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11487 break; 11488 case IAX_COMMAND_TXREQ: 11489 try_transfer(iaxs[fr->callno], &ies); 11490 break; 11491 case IAX_COMMAND_TXCNT: 11492 if (iaxs[fr->callno]->transferring) 11493 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 11494 break; 11495 case IAX_COMMAND_TXREL: 11496 /* Send ack immediately, rather than waiting until we've changed addresses */ 11497 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11498 complete_transfer(fr->callno, &ies); 11499 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 11500 break; 11501 case IAX_COMMAND_TXMEDIA: 11502 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 11503 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 11504 /* Cancel any outstanding frames and start anew */ 11505 if (cur->transfer) { 11506 cur->retries = -1; 11507 } 11508 } 11509 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 11510 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 11511 } 11512 break; 11513 case IAX_COMMAND_RTKEY: 11514 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 11515 ast_log(LOG_WARNING, 11516 "we've been told to rotate our encryption key, " 11517 "but this isn't an encrypted call. bad things will happen.\n" 11518 ); 11519 break; 11520 } 11521 11522 IAX_DEBUGDIGEST("Receiving", ies.challenge); 11523 11524 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 11525 break; 11526 case IAX_COMMAND_DPREP: 11527 complete_dpreply(iaxs[fr->callno], &ies); 11528 break; 11529 case IAX_COMMAND_UNSUPPORT: 11530 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 11531 break; 11532 case IAX_COMMAND_FWDOWNL: 11533 /* Firmware download */ 11534 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 11535 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 11536 break; 11537 } 11538 memset(&ied0, 0, sizeof(ied0)); 11539 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 11540 if (res < 0) 11541 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11542 else if (res > 0) 11543 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11544 else 11545 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11546 break; 11547 case IAX_COMMAND_CALLTOKEN: 11548 { 11549 struct iax_frame *cur; 11550 /* find last sent frame */ 11551 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) { 11552 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 11553 } 11554 break; 11555 } 11556 default: 11557 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno); 11558 memset(&ied0, 0, sizeof(ied0)); 11559 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer); 11560 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11561 } 11562 /* Free remote variables (if any) */ 11563 if (ies.vars) { 11564 ast_variables_destroy(ies.vars); 11565 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11566 ies.vars = NULL; 11567 } 11568 11569 /* Don't actually pass these frames along */ 11570 if ((f.subclass.integer != IAX_COMMAND_ACK) && 11571 (f.subclass.integer != IAX_COMMAND_TXCNT) && 11572 (f.subclass.integer != IAX_COMMAND_TXACC) && 11573 (f.subclass.integer != IAX_COMMAND_INVAL) && 11574 (f.subclass.integer != IAX_COMMAND_VNAK)) { 11575 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) { 11576 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11577 } 11578 } 11579 ast_mutex_unlock(&iaxsl[fr->callno]); 11580 return 1; 11581 } 11582 /* Unless this is an ACK or INVAL frame, ack it */ 11583 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11584 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11585 } else if (minivid) { 11586 f.frametype = AST_FRAME_VIDEO; 11587 if (iaxs[fr->callno]->videoformat > 0) 11588 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0); 11589 else { 11590 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11591 iax2_vnak(fr->callno); 11592 ast_variables_destroy(ies.vars); 11593 ast_mutex_unlock(&iaxsl[fr->callno]); 11594 return 1; 11595 } 11596 f.datalen = res - sizeof(*vh); 11597 if (f.datalen) 11598 f.data.ptr = thread->buf + sizeof(*vh); 11599 else 11600 f.data.ptr = NULL; 11601 #ifdef IAXTESTS 11602 if (test_resync) { 11603 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11604 } else 11605 #endif /* IAXTESTS */ 11606 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11607 } else { 11608 /* A mini frame */ 11609 f.frametype = AST_FRAME_VOICE; 11610 if (iaxs[fr->callno]->voiceformat > 0) 11611 f.subclass.codec = iaxs[fr->callno]->voiceformat; 11612 else { 11613 ast_debug(1, "Received mini frame before first full voice frame\n"); 11614 iax2_vnak(fr->callno); 11615 ast_variables_destroy(ies.vars); 11616 ast_mutex_unlock(&iaxsl[fr->callno]); 11617 return 1; 11618 } 11619 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11620 if (f.datalen < 0) { 11621 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11622 ast_variables_destroy(ies.vars); 11623 ast_mutex_unlock(&iaxsl[fr->callno]); 11624 return 1; 11625 } 11626 if (f.datalen) 11627 f.data.ptr = thread->buf + sizeof(*mh); 11628 else 11629 f.data.ptr = NULL; 11630 #ifdef IAXTESTS 11631 if (test_resync) { 11632 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11633 } else 11634 #endif /* IAXTESTS */ 11635 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11636 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11637 } 11638 /* Don't pass any packets until we're started */ 11639 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11640 ast_variables_destroy(ies.vars); 11641 ast_mutex_unlock(&iaxsl[fr->callno]); 11642 return 1; 11643 } 11644 /* Don't allow connected line updates unless we are configured to */ 11645 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) { 11646 struct ast_party_connected_line connected; 11647 11648 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) { 11649 ast_variables_destroy(ies.vars); 11650 ast_mutex_unlock(&iaxsl[fr->callno]); 11651 return 1; 11652 } 11653 11654 /* Initialize defaults */ 11655 ast_party_connected_line_init(&connected); 11656 connected.id.number.presentation = iaxs[fr->callno]->calling_pres; 11657 connected.id.name.presentation = iaxs[fr->callno]->calling_pres; 11658 11659 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) { 11660 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str); 11661 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str); 11662 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id); 11663 11664 iax2_lock_owner(fr->callno); 11665 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 11666 ast_set_callerid(iaxs[fr->callno]->owner, 11667 S_COR(connected.id.number.valid, connected.id.number.str, ""), 11668 S_COR(connected.id.name.valid, connected.id.name.str, ""), 11669 NULL); 11670 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation; 11671 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation; 11672 ast_channel_unlock(iaxs[fr->callno]->owner); 11673 } 11674 } 11675 ast_party_connected_line_free(&connected); 11676 } 11677 /* Common things */ 11678 f.src = "IAX2"; 11679 f.mallocd = 0; 11680 f.offset = 0; 11681 f.len = 0; 11682 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11683 f.samples = ast_codec_get_samples(&f); 11684 /* We need to byteswap incoming slinear samples from network byte order */ 11685 if (f.subclass.codec == AST_FORMAT_SLINEAR) 11686 ast_frame_byteswap_be(&f); 11687 } else 11688 f.samples = 0; 11689 iax_frame_wrap(fr, &f); 11690 11691 /* If this is our most recent packet, use it as our basis for timestamping */ 11692 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11693 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11694 fr->outoforder = 0; 11695 } else { 11696 if (iaxdebug && iaxs[fr->callno]) { 11697 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last); 11698 } 11699 fr->outoforder = -1; 11700 } 11701 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11702 duped_fr = iaxfrdup2(fr); 11703 if (duped_fr) { 11704 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11705 } 11706 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11707 iaxs[fr->callno]->last = fr->ts; 11708 #if 1 11709 if (iaxdebug) 11710 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 11711 #endif 11712 } 11713 11714 /* Always run again */ 11715 ast_variables_destroy(ies.vars); 11716 ast_mutex_unlock(&iaxsl[fr->callno]); 11717 return 1; 11718 }
| 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 9717 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().
09719 { 09720 unsigned char metatype; 09721 struct ast_iax2_meta_trunk_mini *mtm; 09722 struct ast_iax2_meta_trunk_hdr *mth; 09723 struct ast_iax2_meta_trunk_entry *mte; 09724 struct iax2_trunk_peer *tpeer; 09725 unsigned int ts; 09726 void *ptr; 09727 struct timeval rxtrunktime; 09728 struct ast_frame f = { 0, }; 09729 09730 if (packet_len < sizeof(*meta)) { 09731 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09732 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09733 return 1; 09734 } 09735 09736 if (meta->metacmd != IAX_META_TRUNK) 09737 return 1; 09738 09739 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09740 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09741 (int) (sizeof(*meta) + sizeof(*mth))); 09742 return 1; 09743 } 09744 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09745 ts = ntohl(mth->ts); 09746 metatype = meta->cmddata; 09747 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09748 ptr = mth->data; 09749 tpeer = find_tpeer(sin, sockfd); 09750 if (!tpeer) { 09751 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09752 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09753 return 1; 09754 } 09755 tpeer->trunkact = ast_tvnow(); 09756 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09757 tpeer->rxtrunktime = tpeer->trunkact; 09758 rxtrunktime = tpeer->rxtrunktime; 09759 ast_mutex_unlock(&tpeer->lock); 09760 while (packet_len >= sizeof(*mte)) { 09761 /* Process channels */ 09762 unsigned short callno, trunked_ts, len; 09763 09764 if (metatype == IAX_META_TRUNK_MINI) { 09765 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09766 ptr += sizeof(*mtm); 09767 packet_len -= sizeof(*mtm); 09768 len = ntohs(mtm->len); 09769 callno = ntohs(mtm->mini.callno); 09770 trunked_ts = ntohs(mtm->mini.ts); 09771 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09772 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09773 ptr += sizeof(*mte); 09774 packet_len -= sizeof(*mte); 09775 len = ntohs(mte->len); 09776 callno = ntohs(mte->callno); 09777 trunked_ts = 0; 09778 } else { 09779 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09780 break; 09781 } 09782 /* Stop if we don't have enough data */ 09783 if (len > packet_len) 09784 break; 09785 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09786 if (!fr->callno) 09787 continue; 09788 09789 /* If it's a valid call, deliver the contents. If not, we 09790 drop it, since we don't have a scallno to use for an INVAL */ 09791 /* Process as a mini frame */ 09792 memset(&f, 0, sizeof(f)); 09793 f.frametype = AST_FRAME_VOICE; 09794 if (!iaxs[fr->callno]) { 09795 /* drop it */ 09796 } else if (iaxs[fr->callno]->voiceformat == 0) { 09797 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09798 iax2_vnak(fr->callno); 09799 } else { 09800 f.subclass.codec = iaxs[fr->callno]->voiceformat; 09801 f.datalen = len; 09802 if (f.datalen >= 0) { 09803 if (f.datalen) 09804 f.data.ptr = ptr; 09805 else 09806 f.data.ptr = NULL; 09807 if (trunked_ts) 09808 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09809 else 09810 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09811 /* Don't pass any packets until we're started */ 09812 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09813 struct iax_frame *duped_fr; 09814 09815 /* Common things */ 09816 f.src = "IAX2"; 09817 f.mallocd = 0; 09818 f.offset = 0; 09819 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09820 f.samples = ast_codec_get_samples(&f); 09821 else 09822 f.samples = 0; 09823 fr->outoforder = 0; 09824 iax_frame_wrap(fr, &f); 09825 duped_fr = iaxfrdup2(fr); 09826 if (duped_fr) 09827 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09828 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09829 iaxs[fr->callno]->last = fr->ts; 09830 } 09831 } else { 09832 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09833 } 09834 } 09835 ast_mutex_unlock(&iaxsl[fr->callno]); 09836 ptr += len; 09837 packet_len -= len; 09838 } 09839 09840 return 1; 09841 }
| static int socket_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 9637 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().
09638 { 09639 struct iax2_thread *thread; 09640 socklen_t len; 09641 time_t t; 09642 static time_t last_errtime = 0; 09643 struct ast_iax2_full_hdr *fh; 09644 09645 if (!(thread = find_idle_thread())) { 09646 time(&t); 09647 if (t != last_errtime) { 09648 last_errtime = t; 09649 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09650 } 09651 usleep(1); 09652 return 1; 09653 } 09654 09655 len = sizeof(thread->iosin); 09656 thread->iofd = fd; 09657 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09658 thread->buf_size = sizeof(thread->readbuf); 09659 thread->buf = thread->readbuf; 09660 if (thread->buf_len < 0) { 09661 if (errno != ECONNREFUSED && errno != EAGAIN) 09662 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09663 handle_error(); 09664 thread->iostate = IAX_IOSTATE_IDLE; 09665 signal_condition(&thread->lock, &thread->cond); 09666 return 1; 09667 } 09668 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09669 thread->iostate = IAX_IOSTATE_IDLE; 09670 signal_condition(&thread->lock, &thread->cond); 09671 return 1; 09672 } 09673 09674 /* Determine if this frame is a full frame; if so, and any thread is currently 09675 processing a full frame for the same callno from this peer, then drop this 09676 frame (and the peer will retransmit it) */ 09677 fh = (struct ast_iax2_full_hdr *) thread->buf; 09678 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09679 struct iax2_thread *cur = NULL; 09680 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09681 09682 AST_LIST_LOCK(&active_list); 09683 AST_LIST_TRAVERSE(&active_list, cur, list) { 09684 if ((cur->ffinfo.callno == callno) && 09685 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09686 break; 09687 } 09688 if (cur) { 09689 /* we found another thread processing a full frame for this call, 09690 so queue it up for processing later. */ 09691 defer_full_frame(thread, cur); 09692 AST_LIST_UNLOCK(&active_list); 09693 thread->iostate = IAX_IOSTATE_IDLE; 09694 signal_condition(&thread->lock, &thread->cond); 09695 return 1; 09696 } else { 09697 /* this thread is going to process this frame, so mark it */ 09698 thread->ffinfo.callno = callno; 09699 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09700 thread->ffinfo.type = fh->type; 09701 thread->ffinfo.csub = fh->csub; 09702 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09703 } 09704 AST_LIST_UNLOCK(&active_list); 09705 } 09706 09707 /* Mark as ready and send on its way */ 09708 thread->iostate = IAX_IOSTATE_READY; 09709 #ifdef DEBUG_SCHED_MULTITHREAD 09710 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09711 #endif 09712 signal_condition(&thread->lock, &thread->cond); 09713 09714 return 1; 09715 }
| static void spawn_dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid | |||
| ) | [static] |
Definition at line 9304 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().
09305 { 09306 pthread_t newthread; 09307 struct dpreq_data *dpr; 09308 09309 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 09310 return; 09311 09312 dpr->callno = callno; 09313 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 09314 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 09315 if (callerid) 09316 dpr->callerid = ast_strdup(callerid); 09317 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 09318 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 09319 } 09320 }
| static int start_network_thread | ( | void | ) | [static] |
Definition at line 12282 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().
12283 { 12284 struct iax2_thread *thread; 12285 int threadcount = 0; 12286 int x; 12287 for (x = 0; x < iaxthreadcount; x++) { 12288 thread = ast_calloc(1, sizeof(*thread)); 12289 if (thread) { 12290 thread->type = IAX_THREAD_TYPE_POOL; 12291 thread->threadnum = ++threadcount; 12292 ast_mutex_init(&thread->lock); 12293 ast_cond_init(&thread->cond, NULL); 12294 ast_mutex_init(&thread->init_lock); 12295 ast_cond_init(&thread->init_cond, NULL); 12296 12297 ast_mutex_lock(&thread->init_lock); 12298 12299 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 12300 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 12301 ast_mutex_destroy(&thread->lock); 12302 ast_cond_destroy(&thread->cond); 12303 ast_mutex_unlock(&thread->init_lock); 12304 ast_mutex_destroy(&thread->init_lock); 12305 ast_cond_destroy(&thread->init_cond); 12306 ast_free(thread); 12307 thread = NULL; 12308 continue; 12309 } 12310 /* Wait for the thread to be ready */ 12311 ast_cond_wait(&thread->init_cond, &thread->init_lock); 12312 12313 /* Done with init_lock */ 12314 ast_mutex_unlock(&thread->init_lock); 12315 12316 AST_LIST_LOCK(&idle_list); 12317 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 12318 AST_LIST_UNLOCK(&idle_list); 12319 } 12320 } 12321 if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) { 12322 ast_log(LOG_ERROR, "Failed to create new thread!\n"); 12323 return -1; 12324 } 12325 ast_verb(2, "%d helper threads started\n", threadcount); 12326 return 0; 12327 }
| static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 9007 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
09008 { 09009 iax2_destroy_helper(iaxs[callno]); 09010 }
| static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2130 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().
02131 { 02132 if (!pvt->peercallno) { 02133 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02134 return; 02135 } 02136 02137 ao2_link(iax_peercallno_pvts, pvt); 02138 }
| static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2111 of file chan_iax2.c.
References ao2_link, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
02112 { 02113 if (!pvt->transfercallno) { 02114 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02115 return; 02116 } 02117 02118 ao2_link(iax_transfercallno_pvts, pvt); 02119 }
| static int timing_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 9190 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().
09191 { 09192 int res, processed = 0, totalcalls = 0; 09193 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 09194 struct timeval now = ast_tvnow(); 09195 09196 if (iaxtrunkdebug) 09197 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 09198 09199 if (timer) { 09200 if (ast_timer_ack(timer, 1) < 0) { 09201 ast_log(LOG_ERROR, "Timer failed acknowledge\n"); 09202 return 0; 09203 } 09204 } 09205 09206 /* For each peer that supports trunking... */ 09207 AST_LIST_LOCK(&tpeers); 09208 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 09209 processed++; 09210 res = 0; 09211 ast_mutex_lock(&tpeer->lock); 09212 /* We can drop a single tpeer per pass. That makes all this logic 09213 substantially easier */ 09214 if (!drop && iax2_trunk_expired(tpeer, &now)) { 09215 /* Take it out of the list, but don't free it yet, because it 09216 could be in use */ 09217 AST_LIST_REMOVE_CURRENT(list); 09218 drop = tpeer; 09219 } else { 09220 res = send_trunk(tpeer, &now); 09221 trunk_timed++; 09222 if (iaxtrunkdebug) 09223 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc); 09224 } 09225 totalcalls += res; 09226 res = 0; 09227 ast_mutex_unlock(&tpeer->lock); 09228 } 09229 AST_LIST_TRAVERSE_SAFE_END; 09230 AST_LIST_UNLOCK(&tpeers); 09231 09232 if (drop) { 09233 ast_mutex_lock(&drop->lock); 09234 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 09235 because by the time they could get tpeerlock, we've already grabbed it */ 09236 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 09237 if (drop->trunkdata) { 09238 ast_free(drop->trunkdata); 09239 drop->trunkdata = NULL; 09240 } 09241 ast_mutex_unlock(&drop->lock); 09242 ast_mutex_destroy(&drop->lock); 09243 ast_free(drop); 09244 09245 } 09246 09247 if (iaxtrunkdebug) 09248 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 09249 iaxtrunkdebug = 0; 09250 09251 return 1; 09252 }
| static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 14554 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by load_objects().
14555 { 14556 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14557 14558 /* The frames_received field is used to hold whether we're matching 14559 * against a full frame or not ... */ 14560 14561 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 14562 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14563 }
| static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 14547 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
14548 { 14549 const struct chan_iax2_pvt *pvt = obj; 14550 14551 return pvt->transfercallno; 14552 }
| static int transmit_frame | ( | void * | data | ) | [static] |
Definition at line 4264 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().
04265 { 04266 struct iax_frame *fr = data; 04267 04268 ast_mutex_lock(&iaxsl[fr->callno]); 04269 04270 fr->sentyet = 1; 04271 04272 if (iaxs[fr->callno]) { 04273 send_packet(fr); 04274 } 04275 04276 if (fr->retries < 0) { 04277 ast_mutex_unlock(&iaxsl[fr->callno]); 04278 /* No retransmit requested */ 04279 iax_frame_free(fr); 04280 } else { 04281 /* We need reliable delivery. Schedule a retransmission */ 04282 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list); 04283 fr->retries++; 04284 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr); 04285 ast_mutex_unlock(&iaxsl[fr->callno]); 04286 } 04287 04288 return 0; 04289 }
| static int transmit_trunk | ( | struct iax_frame * | f, | |
| struct sockaddr_in * | sin, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 3322 of file chan_iax2.c.
References ast_debug, iax_frame::data, iax_frame::datalen, errno, and handle_error().
Referenced by send_trunk().
03323 { 03324 int res; 03325 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03326 sizeof(*sin)); 03327 if (res < 0) { 03328 ast_debug(1, "Received error: %s\n", strerror(errno)); 03329 handle_error(); 03330 } else 03331 res = 0; 03332 return res; 03333 }
| static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 3027 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().
03028 { 03029 struct stat stbuf; 03030 struct iax_firmware *cur = NULL; 03031 int ifd, fd, res, len, chunk; 03032 struct ast_iax2_firmware_header *fwh, fwh2; 03033 struct MD5Context md5; 03034 unsigned char sum[16], buf[1024]; 03035 char *s2, *last; 03036 03037 s2 = ast_alloca(strlen(s) + 100); 03038 03039 last = strrchr(s, '/'); 03040 if (last) 03041 last++; 03042 else 03043 last = s; 03044 03045 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 03046 03047 if ((res = stat(s, &stbuf) < 0)) { 03048 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 03049 return -1; 03050 } 03051 03052 /* Make sure it's not a directory */ 03053 if (S_ISDIR(stbuf.st_mode)) 03054 return -1; 03055 ifd = open(s, O_RDONLY); 03056 if (ifd < 0) { 03057 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 03058 return -1; 03059 } 03060 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 03061 if (fd < 0) { 03062 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 03063 close(ifd); 03064 return -1; 03065 } 03066 /* Unlink our newly created file */ 03067 unlink(s2); 03068 03069 /* Now copy the firmware into it */ 03070 len = stbuf.st_size; 03071 while(len) { 03072 chunk = len; 03073 if (chunk > sizeof(buf)) 03074 chunk = sizeof(buf); 03075 res = read(ifd, buf, chunk); 03076 if (res != chunk) { 03077 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03078 close(ifd); 03079 close(fd); 03080 return -1; 03081 } 03082 res = write(fd, buf, chunk); 03083 if (res != chunk) { 03084 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03085 close(ifd); 03086 close(fd); 03087 return -1; 03088 } 03089 len -= chunk; 03090 } 03091 close(ifd); 03092 /* Return to the beginning */ 03093 lseek(fd, 0, SEEK_SET); 03094 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 03095 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 03096 close(fd); 03097 return -1; 03098 } 03099 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 03100 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 03101 close(fd); 03102 return -1; 03103 } 03104 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 03105 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 03106 close(fd); 03107 return -1; 03108 } 03109 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 03110 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 03111 close(fd); 03112 return -1; 03113 } 03114 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 03115 if (fwh == MAP_FAILED) { 03116 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 03117 close(fd); 03118 return -1; 03119 } 03120 MD5Init(&md5); 03121 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 03122 MD5Final(sum, &md5); 03123 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 03124 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 03125 munmap((void*)fwh, stbuf.st_size); 03126 close(fd); 03127 return -1; 03128 } 03129 03130 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03131 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 03132 /* Found a candidate */ 03133 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 03134 /* The version we have on loaded is older, load this one instead */ 03135 break; 03136 /* This version is no newer than what we have. Don't worry about it. 03137 We'll consider it a proper load anyhow though */ 03138 munmap((void*)fwh, stbuf.st_size); 03139 close(fd); 03140 return 0; 03141 } 03142 } 03143 03144 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 03145 cur->fd = -1; 03146 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 03147 } 03148 03149 if (cur) { 03150 if (cur->fwh) 03151 munmap((void*)cur->fwh, cur->mmaplen); 03152 if (cur->fd > -1) 03153 close(cur->fd); 03154 cur->fwh = fwh; 03155 cur->fd = fd; 03156 cur->mmaplen = stbuf.st_size; 03157 cur->dead = 0; 03158 } 03159 03160 return 0; 03161 }
| static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8324 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().
08325 { 08326 int newcall = 0; 08327 char newip[256]; 08328 struct iax_ie_data ied; 08329 struct sockaddr_in new = { 0, }; 08330 08331 memset(&ied, 0, sizeof(ied)); 08332 if (ies->apparent_addr) 08333 memmove(&new, ies->apparent_addr, sizeof(new)); 08334 if (ies->callno) 08335 newcall = ies->callno; 08336 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 08337 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08338 return -1; 08339 } 08340 pvt->transfercallno = newcall; 08341 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 08342 inet_aton(newip, &pvt->transfer.sin_addr); 08343 pvt->transfer.sin_family = AF_INET; 08344 pvt->transferid = ies->transferid; 08345 /* only store by transfercallno if this is a new transfer, 08346 * just in case we get a duplicate TXREQ */ 08347 if (pvt->transferring == TRANSFER_NONE) { 08348 store_by_transfercallno(pvt); 08349 } 08350 pvt->transferring = TRANSFER_BEGIN; 08351 08352 if (ies->transferid) 08353 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 08354 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 08355 return 0; 08356 }
| static format_t uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1628 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01629 { 01630 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01631 if (csub & IAX_FLAG_SC_LOG) { 01632 /* special case for 'compressed' -1 */ 01633 if (csub == 0xff) 01634 return -1; 01635 else 01636 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01637 } 01638 else 01639 return csub; 01640 }
| static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8618 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().
08619 { 08620 if (peer->expire > -1) { 08621 if (!ast_sched_thread_del(sched, peer->expire)) { 08622 peer->expire = -1; 08623 peer_unref(peer); 08624 } 08625 } 08626 08627 if (peer->pokeexpire > -1) { 08628 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 08629 peer->pokeexpire = -1; 08630 peer_unref(peer); 08631 } 08632 } 08633 08634 ao2_unlink(peers, peer); 08635 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 14512 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
14513 { 14514 ast_custom_function_unregister(&iaxpeer_function); 14515 ast_custom_function_unregister(&iaxvar_function); 14516 return __unload_module(); 14517 }
| static void unlock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5472 of file chan_iax2.c.
References ast_mutex_unlock, and iaxsl.
Referenced by iax2_bridge().
05473 { 05474 ast_mutex_unlock(&iaxsl[callno1]); 05475 ast_mutex_unlock(&iaxsl[callno0]); 05476 }
| static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4017 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().
04018 { 04019 /* Video mini frames only encode the lower 15 bits of the session 04020 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 04021 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 04022 const int lower_mask = (1 << ts_shift) - 1; 04023 const int upper_mask = ~lower_mask; 04024 const int last_upper = iaxs[fr->callno]->last & upper_mask; 04025 04026 if ( (fr->ts & upper_mask) == last_upper ) { 04027 const int x = fr->ts - iaxs[fr->callno]->last; 04028 const int threshold = (ts_shift == 15) ? 25000 : 50000; 04029 04030 if (x < -threshold) { 04031 /* Sudden big jump backwards in timestamp: 04032 What likely happened here is that miniframe timestamp has circled but we haven't 04033 gotten the update from the main packet. We'll just pretend that we did, and 04034 update the timestamp appropriately. */ 04035 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 04036 if (iaxdebug) 04037 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 04038 } else if (x > threshold) { 04039 /* Sudden apparent big jump forwards in timestamp: 04040 What's likely happened is this is an old miniframe belonging to the previous 04041 top 15 or 16-bit timestamp that has turned up out of order. 04042 Adjust the timestamp appropriately. */ 04043 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 04044 if (iaxdebug) 04045 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 04046 } 04047 } 04048 }
| static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4052 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().
04053 { 04054 int when; 04055 04056 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 04057 04058 when = jb_next(pvt->jb) - when; 04059 04060 if (when <= 0) { 04061 /* XXX should really just empty until when > 0.. */ 04062 when = 1; 04063 } 04064 04065 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 04066 CALLNO_TO_PTR(pvt->callno)); 04067 }
| static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3458 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().
03459 { 03460 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03461 struct ast_iax2_full_hdr *fh = f->data; 03462 struct ast_frame af; 03463 03464 /* if frame is encrypted. decrypt before updating it. */ 03465 if (f->encmethods) { 03466 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03467 } 03468 /* Mark this as a retransmission */ 03469 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03470 /* Update iseqno */ 03471 f->iseqno = iaxs[f->callno]->iseqno; 03472 fh->iseqno = f->iseqno; 03473 03474 /* Now re-encrypt the frame */ 03475 if (f->encmethods) { 03476 /* since this is a retransmit frame, create a new random padding 03477 * before re-encrypting. */ 03478 build_rand_pad(f->semirand, sizeof(f->semirand)); 03479 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03480 } 03481 return 0; 03482 }
| static int update_registry | ( | struct sockaddr_in * | sin, | |
| int | callno, | |||
| char * | devtype, | |||
| int | fd, | |||
| unsigned short | refresh | |||
| ) | [static] |
Definition at line 8736 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().
08737 { 08738 /* Called from IAX thread only, with proper iaxsl lock */ 08739 struct iax_ie_data ied = { 08740 .pos = 0, 08741 }; 08742 struct iax2_peer *p; 08743 int msgcount; 08744 char data[80]; 08745 int version; 08746 const char *peer_name; 08747 int res = -1; 08748 struct ast_sockaddr sockaddr; 08749 08750 ast_sockaddr_from_sin(&sockaddr, sin); 08751 08752 peer_name = ast_strdupa(iaxs[callno]->peer); 08753 08754 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08755 ast_mutex_unlock(&iaxsl[callno]); 08756 if (!(p = find_peer(peer_name, 1))) { 08757 ast_mutex_lock(&iaxsl[callno]); 08758 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08759 return -1; 08760 } 08761 ast_mutex_lock(&iaxsl[callno]); 08762 if (!iaxs[callno]) 08763 goto return_unref; 08764 08765 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08766 if (sin->sin_addr.s_addr) { 08767 time_t nowtime; 08768 time(&nowtime); 08769 realtime_update_peer(peer_name, &sockaddr, nowtime); 08770 } else { 08771 realtime_update_peer(peer_name, &sockaddr, 0); 08772 } 08773 } 08774 08775 /* treat an unspecified refresh interval as the minimum */ 08776 if (!refresh) { 08777 refresh = min_reg_expire; 08778 } 08779 if (refresh > max_reg_expire) { 08780 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08781 p->name, max_reg_expire, refresh); 08782 p->expiry = max_reg_expire; 08783 } else if (refresh < min_reg_expire) { 08784 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08785 p->name, min_reg_expire, refresh); 08786 p->expiry = min_reg_expire; 08787 } else { 08788 p->expiry = refresh; 08789 } 08790 08791 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) { 08792 if (iax2_regfunk) { 08793 iax2_regfunk(p->name, 1); 08794 } 08795 08796 /* modify entry in peercnts table as _not_ registered */ 08797 peercnt_modify((unsigned char) 0, 0, &p->addr); 08798 08799 /* Stash the IP address from which they registered */ 08800 ast_sockaddr_from_sin(&p->addr, sin); 08801 08802 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08803 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08804 ast_db_put("IAX/Registry", p->name, data); 08805 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08806 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08807 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08808 register_peer_exten(p, 1); 08809 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08810 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) { 08811 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08812 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08813 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08814 register_peer_exten(p, 0); 08815 ast_db_del("IAX/Registry", p->name); 08816 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08817 } 08818 /* Update the host */ 08819 /* Verify that the host is really there */ 08820 iax2_poke_peer(p, callno); 08821 } 08822 08823 /* modify entry in peercnts table as registered */ 08824 if (p->maxcallno) { 08825 peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr); 08826 } 08827 08828 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08829 if (!iaxs[callno]) { 08830 res = -1; 08831 goto return_unref; 08832 } 08833 08834 /* Store socket fd */ 08835 p->sockfd = fd; 08836 /* Setup the expiry */ 08837 if (p->expire > -1) { 08838 if (!ast_sched_thread_del(sched, p->expire)) { 08839 p->expire = -1; 08840 peer_unref(p); 08841 } 08842 } 08843 08844 if (p->expiry && sin->sin_addr.s_addr) { 08845 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08846 if (p->expire == -1) 08847 peer_unref(p); 08848 } 08849 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08850 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08851 if (sin->sin_addr.s_addr) { 08852 struct sockaddr_in peer_addr; 08853 08854 ast_sockaddr_to_sin(&p->addr, &peer_addr); 08855 08856 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08857 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr); 08858 if (!ast_strlen_zero(p->mailbox)) { 08859 struct ast_event *event; 08860 int new, old; 08861 char *mailbox, *context; 08862 08863 context = mailbox = ast_strdupa(p->mailbox); 08864 strsep(&context, "@"); 08865 if (ast_strlen_zero(context)) 08866 context = "default"; 08867 08868 event = ast_event_get_cached(AST_EVENT_MWI, 08869 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08870 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08871 AST_EVENT_IE_END); 08872 if (event) { 08873 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08874 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08875 ast_event_destroy(event); 08876 } else { /* Fall back on checking the mailbox directly */ 08877 ast_app_inboxcount(p->mailbox, &new, &old); 08878 } 08879 08880 if (new > 255) { 08881 new = 255; 08882 } 08883 if (old > 255) { 08884 old = 255; 08885 } 08886 msgcount = (old << 8) | new; 08887 08888 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08889 } 08890 if (ast_test_flag64(p, IAX_HASCALLERID)) { 08891 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08892 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08893 } 08894 } 08895 version = iax_check_version(devtype); 08896 if (version) 08897 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08898 08899 res = 0; 08900 08901 return_unref: 08902 peer_unref(p); 08903 08904 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08905 }
| static int user_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1675 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 13033 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
13034 { 13035 struct iax2_user *user = obj; 13036 13037 ast_set_flag64(user, IAX_DELME); 13038 13039 return 0; 13040 }
| static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12758 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().
12759 { 12760 struct iax2_user *user = obj; 12761 12762 ast_free_ha(user->ha); 12763 free_context(user->contexts); 12764 if(user->vars) { 12765 ast_variables_destroy(user->vars); 12766 user->vars = NULL; 12767 } 12768 ast_string_field_free_memory(user); 12769 }
| static int user_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1665 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_objects().
01666 { 01667 const struct iax2_user *user = obj; 01668 01669 return ast_str_hash(user->name); 01670 }
Definition at line 1722 of file chan_iax2.c.
References ao2_ref.
01723 { 01724 ao2_ref(user, +1); 01725 return user; 01726 }
Definition at line 1728 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().
01729 { 01730 ao2_ref(user, -1); 01731 return NULL; 01732 }
| static int users_data_provider_get | ( | const struct ast_data_search * | search, | |
| struct ast_data * | data_root | |||
| ) | [static] |
Definition at line 14717 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().
14719 { 14720 struct ast_data *data_user, *data_authmethods, *data_enum_node; 14721 struct iax2_user *user; 14722 struct ao2_iterator i; 14723 char auth[90]; 14724 char *pstr = ""; 14725 14726 i = ao2_iterator_init(users, 0); 14727 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 14728 data_user = ast_data_add_node(data_root, "user"); 14729 if (!data_user) { 14730 continue; 14731 } 14732 14733 ast_data_add_structure(iax2_user, data_user, user); 14734 14735 ast_data_add_codecs(data_user, "codecs", user->capability); 14736 14737 if (!ast_strlen_zero(user->secret)) { 14738 ast_copy_string(auth, user->secret, sizeof(auth)); 14739 } else if (!ast_strlen_zero(user->inkeys)) { 14740 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys); 14741 } else { 14742 ast_copy_string(auth, "no secret", sizeof(auth)); 14743 } 14744 ast_data_add_password(data_user, "secret", auth); 14745 14746 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT); 14747 14748 /* authmethods */ 14749 data_authmethods = ast_data_add_node(data_user, "authmethods"); 14750 if (!data_authmethods) { 14751 ast_data_remove_node(data_root, data_user); 14752 continue; 14753 } 14754 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA); 14755 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5); 14756 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT); 14757 14758 /* amaflags */ 14759 data_enum_node = ast_data_add_node(data_user, "amaflags"); 14760 if (!data_enum_node) { 14761 ast_data_remove_node(data_root, data_user); 14762 continue; 14763 } 14764 ast_data_add_int(data_enum_node, "value", user->amaflags); 14765 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags)); 14766 14767 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0); 14768 14769 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) { 14770 pstr = "REQ only"; 14771 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) { 14772 pstr = "disabled"; 14773 } else { 14774 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host"; 14775 } 14776 ast_data_add_str(data_user, "codec-preferences", pstr); 14777 14778 if (!ast_data_search_match(search, data_user)) { 14779 ast_data_remove_node(data_root, data_user); 14780 } 14781 } 14782 ao2_iterator_destroy(&i); 14783 14784 return 0; 14785 }
| static void vnak_retransmit | ( | int | callno, | |
| int | last | |||
| ) | [static] |
Definition at line 9108 of file chan_iax2.c.
References AST_LIST_TRAVERSE, f, iax_frame::oseqno, iax_frame::retries, and send_packet().
Referenced by socket_process().
09109 { 09110 struct iax_frame *f; 09111 09112 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) { 09113 /* Send a copy immediately */ 09114 if (((unsigned char) (f->oseqno - last) < 128) && 09115 (f->retries >= 0)) { 09116 send_packet(f); 09117 } 09118 } 09119 }
| static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5282 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().
05283 { 05284 unsigned short callno = pvt->callno; 05285 05286 if (!pvt->peercallno) { 05287 /* We don't know the remote side's call number, yet. :( */ 05288 int count = 10; 05289 while (count-- && pvt && !pvt->peercallno) { 05290 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05291 pvt = iaxs[callno]; 05292 } 05293 if (!pvt || !pvt->peercallno) { 05294 return -1; 05295 } 05296 } 05297 05298 return 0; 05299 }
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 14257 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 14797 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 14143 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 1331 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 14063 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 9910 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 11987 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 14787 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 14792 of file chan_iax2.c.
1.6.1