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 14552 of file chan_iax2.c.
#define DATA_EXPORT_IAX2_USER | ( | MEMBER | ) |
Definition at line 14629 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 /* Make sure this call is still active */ 03493 if (callno) 03494 ast_mutex_lock(&iaxsl[callno]); 03495 if (callno && iaxs[callno]) { 03496 if ((f->retries < 0) /* Already ACK'd */ || 03497 (f->retries >= max_retries) /* Too many attempts */) { 03498 /* Record an error if we've transmitted too many times */ 03499 if (f->retries >= max_retries) { 03500 if (f->transfer) { 03501 /* Transfer timeout */ 03502 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03503 } else if (f->final) { 03504 iax2_destroy(callno); 03505 } else { 03506 if (iaxs[callno]->owner) 03507 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass.integer, f->ts, f->oseqno); 03508 iaxs[callno]->error = ETIMEDOUT; 03509 if (iaxs[callno]->owner) { 03510 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03511 /* Hangup the fd */ 03512 iax2_queue_frame(callno, &fr); /* XXX */ 03513 /* Remember, owner could disappear */ 03514 if (iaxs[callno] && iaxs[callno]->owner) 03515 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03516 } else { 03517 if (iaxs[callno]->reg) { 03518 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03519 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03520 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03521 } 03522 iax2_destroy(callno); 03523 } 03524 } 03525 03526 } 03527 freeme = 1; 03528 } else { 03529 /* Update it if it needs it */ 03530 update_packet(f); 03531 /* Attempt transmission */ 03532 send_packet(f); 03533 f->retries++; 03534 /* Try again later after 10 times as long */ 03535 f->retrytime *= 10; 03536 if (f->retrytime > MAX_RETRY_TIME) 03537 f->retrytime = MAX_RETRY_TIME; 03538 /* Transfer messages max out at one second */ 03539 if (f->transfer && (f->retrytime > 1000)) 03540 f->retrytime = 1000; 03541 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03542 } 03543 } else { 03544 /* Make sure it gets freed */ 03545 f->retries = -1; 03546 freeme = 1; 03547 } 03548 03549 if (freeme) { 03550 /* Don't attempt delivery, just remove it from the queue */ 03551 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03552 ast_mutex_unlock(&iaxsl[callno]); 03553 f->retrans = -1; /* this is safe because this is the scheduled function */ 03554 /* Free the IAX frame */ 03555 iax2_frame_free(f); 03556 } else if (callno) { 03557 ast_mutex_unlock(&iaxsl[callno]); 03558 } 03559 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 8993 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().
08994 { 08995 /* Called from IAX thread only, without iaxs lock */ 08996 int callno = (int)(long)(nothing); 08997 struct iax_ie_data ied; 08998 ast_mutex_lock(&iaxsl[callno]); 08999 if (iaxs[callno]) { 09000 memset(&ied, 0, sizeof(ied)); 09001 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 09002 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 09003 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 09004 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 09005 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 09006 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 09007 } 09008 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 09009 } 09010 ast_mutex_unlock(&iaxsl[callno]); 09011 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4668 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().
04669 { 04670 int callno = PTR_TO_CALLNO(nothing); 04671 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } }; 04672 ast_mutex_lock(&iaxsl[callno]); 04673 if (iaxs[callno]) { 04674 iaxs[callno]->initid = -1; 04675 iax2_queue_frame(callno, &f); 04676 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04677 } 04678 ast_mutex_unlock(&iaxsl[callno]); 04679 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 9042 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().
09043 { 09044 /* Called from IAX thread only, without iaxs lock */ 09045 int callno = (int)(long)(nothing); 09046 struct iax_ie_data ied; 09047 ast_mutex_lock(&iaxsl[callno]); 09048 if (iaxs[callno]) { 09049 memset(&ied, 0, sizeof(ied)); 09050 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 09051 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 09052 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 09053 } 09054 ast_mutex_unlock(&iaxsl[callno]); 09055 }
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 8619 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().
08620 { 08621 struct iax2_peer *peer = (struct iax2_peer *) data; 08622 08623 if (!peer) 08624 return; 08625 if (peer->expire == -1) { 08626 /* Removed already (possibly through CLI), ignore */ 08627 return; 08628 } 08629 08630 peer->expire = -1; 08631 08632 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08633 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08634 realtime_update_peer(peer->name, &peer->addr, 0); 08635 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08636 /* modify entry in peercnts table as _not_ registered */ 08637 peercnt_modify(0, 0, &peer->addr); 08638 /* Reset the address */ 08639 memset(&peer->addr, 0, sizeof(peer->addr)); 08640 /* Reset expiry value */ 08641 peer->expiry = min_reg_expire; 08642 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08643 ast_db_del("IAX/Registry", peer->name); 08644 register_peer_exten(peer, 0); 08645 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 08646 if (iax2_regfunk) 08647 iax2_regfunk(peer->name, 0); 08648 08649 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08650 unlink_peer(peer); 08651 08652 peer_unref(peer); 08653 }
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 4062 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().
04063 { 04064 int callno = PTR_TO_CALLNO(p); 04065 struct chan_iax2_pvt *pvt = NULL; 04066 struct iax_frame *fr; 04067 jb_frame frame; 04068 int ret; 04069 long ms; 04070 long next; 04071 struct timeval now = ast_tvnow(); 04072 04073 /* Make sure we have a valid private structure before going on */ 04074 ast_mutex_lock(&iaxsl[callno]); 04075 pvt = iaxs[callno]; 04076 if (!pvt) { 04077 /* No go! */ 04078 ast_mutex_unlock(&iaxsl[callno]); 04079 return; 04080 } 04081 04082 pvt->jbid = -1; 04083 04084 /* round up a millisecond since ast_sched_runq does; */ 04085 /* prevents us from spinning while waiting for our now */ 04086 /* to catch up with runq's now */ 04087 now.tv_usec += 1000; 04088 04089 ms = ast_tvdiff_ms(now, pvt->rxcore); 04090 04091 if(ms >= (next = jb_next(pvt->jb))) { 04092 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 04093 switch(ret) { 04094 case JB_OK: 04095 fr = frame.data; 04096 __do_deliver(fr); 04097 /* __do_deliver() can cause the call to disappear */ 04098 pvt = iaxs[callno]; 04099 break; 04100 case JB_INTERP: 04101 { 04102 struct ast_frame af = { 0, }; 04103 04104 /* create an interpolation frame */ 04105 af.frametype = AST_FRAME_VOICE; 04106 af.subclass.codec = pvt->voiceformat; 04107 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 04108 af.src = "IAX2 JB interpolation"; 04109 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 04110 af.offset = AST_FRIENDLY_OFFSET; 04111 04112 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 04113 * which we'd need to malloc, and then it would free it. That seems like a drag */ 04114 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 04115 iax2_queue_frame(callno, &af); 04116 /* iax2_queue_frame() could cause the call to disappear */ 04117 pvt = iaxs[callno]; 04118 } 04119 } 04120 break; 04121 case JB_DROP: 04122 iax2_frame_free(frame.data); 04123 break; 04124 case JB_NOFRAME: 04125 case JB_EMPTY: 04126 /* do nothing */ 04127 break; 04128 default: 04129 /* shouldn't happen */ 04130 break; 04131 } 04132 } 04133 if (pvt) 04134 update_jbsched(pvt); 04135 ast_mutex_unlock(&iaxsl[callno]); 04136 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8290 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08291 { 08292 struct iax2_registry *reg = (struct iax2_registry *)data; 08293 reg->expire = -1; 08294 iax2_do_register(reg); 08295 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11998 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().
11999 { 12000 struct iax2_peer *peer = (struct iax2_peer *)data; 12001 int callno; 12002 12003 if (peer->lastms > -1) { 12004 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 12005 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 12006 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 12007 } 12008 if ((callno = peer->callno) > 0) { 12009 ast_mutex_lock(&iaxsl[callno]); 12010 iax2_destroy(callno); 12011 ast_mutex_unlock(&iaxsl[callno]); 12012 } 12013 peer->callno = 0; 12014 peer->lastms = -1; 12015 /* Try again quickly */ 12016 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 12017 if (peer->pokeexpire == -1) 12018 peer_unref(peer); 12019 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9102 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
09103 { 09104 struct iax2_peer *peer = (struct iax2_peer *)data; 09105 iax2_poke_peer(peer, 0); 09106 peer_unref(peer); 09107 }
static int __iax2_show_peers | ( | int | fd, | |
int * | total, | |||
struct mansession * | s, | |||
const int | argc, | |||
const char *const | argv[] | |||
) | [static] |
Definition at line 6654 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().
06655 { 06656 regex_t regexbuf; 06657 int havepattern = 0; 06658 int total_peers = 0; 06659 int online_peers = 0; 06660 int offline_peers = 0; 06661 int unmonitored_peers = 0; 06662 struct ao2_iterator i; 06663 06664 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" 06665 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" 06666 06667 struct iax2_peer *peer = NULL; 06668 char name[256]; 06669 struct ast_str *encmethods = ast_str_alloca(256); 06670 int registeredonly=0; 06671 char idtext[256] = ""; 06672 switch (argc) { 06673 case 6: 06674 if (!strcasecmp(argv[3], "registered")) 06675 registeredonly = 1; 06676 else 06677 return RESULT_SHOWUSAGE; 06678 if (!strcasecmp(argv[4], "like")) { 06679 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06680 return RESULT_SHOWUSAGE; 06681 havepattern = 1; 06682 } else 06683 return RESULT_SHOWUSAGE; 06684 break; 06685 case 5: 06686 if (!strcasecmp(argv[3], "like")) { 06687 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06688 return RESULT_SHOWUSAGE; 06689 havepattern = 1; 06690 } else 06691 return RESULT_SHOWUSAGE; 06692 break; 06693 case 4: 06694 if (!strcasecmp(argv[3], "registered")) 06695 registeredonly = 1; 06696 else 06697 return RESULT_SHOWUSAGE; 06698 break; 06699 case 3: 06700 break; 06701 default: 06702 return RESULT_SHOWUSAGE; 06703 } 06704 06705 06706 if (!s) 06707 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status"); 06708 06709 i = ao2_iterator_init(peers, 0); 06710 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 06711 char nm[20]; 06712 char status[20]; 06713 int retstatus; 06714 struct sockaddr_in peer_addr; 06715 06716 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 06717 06718 if (registeredonly && !peer_addr.sin_addr.s_addr) { 06719 continue; 06720 } 06721 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 06722 continue; 06723 } 06724 06725 if (!ast_strlen_zero(peer->username)) 06726 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06727 else 06728 ast_copy_string(name, peer->name, sizeof(name)); 06729 06730 encmethods_to_str(peer->encmethods, &encmethods); 06731 retstatus = peer_status(peer, status, sizeof(status)); 06732 if (retstatus > 0) 06733 online_peers++; 06734 else if (!retstatus) 06735 offline_peers++; 06736 else 06737 unmonitored_peers++; 06738 06739 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06740 06741 if (s) { 06742 astman_append(s, 06743 "Event: PeerEntry\r\n%s" 06744 "Channeltype: IAX2\r\n" 06745 "ObjectName: %s\r\n" 06746 "ChanObjectType: peer\r\n" 06747 "IPaddress: %s\r\n" 06748 "IPport: %d\r\n" 06749 "Dynamic: %s\r\n" 06750 "Trunk: %s\r\n" 06751 "Encryption: %s\r\n" 06752 "Status: %s\r\n\r\n", 06753 idtext, 06754 name, 06755 ast_sockaddr_stringify_addr(&peer->addr), 06756 ast_sockaddr_port(&peer->addr), 06757 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06758 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06759 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06760 status); 06761 } else { 06762 ast_cli(fd, FORMAT, name, 06763 ast_sockaddr_stringify_addr(&peer->addr), 06764 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06765 nm, 06766 ast_sockaddr_port(&peer->addr), 06767 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06768 peer->encmethods ? "(E)" : " ", 06769 status); 06770 } 06771 total_peers++; 06772 } 06773 ao2_iterator_destroy(&i); 06774 06775 if (!s) 06776 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n", 06777 total_peers, online_peers, offline_peers, unmonitored_peers); 06778 06779 if (havepattern) 06780 regfree(®exbuf); 06781 06782 if (total) 06783 *total = total_peers; 06784 06785 return RESULT_SUCCESS; 06786 #undef FORMAT 06787 #undef FORMAT2 06788 }
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 = NULL; 01464 static time_t lasterror; 01465 static time_t t; 01466 01467 thread = find_idle_thread(); 01468 01469 if (thread != NULL) { 01470 thread->schedfunc = func; 01471 thread->scheddata = data; 01472 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01473 #ifdef DEBUG_SCHED_MULTITHREAD 01474 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01475 #endif 01476 signal_condition(&thread->lock, &thread->cond); 01477 return 0; 01478 } 01479 time(&t); 01480 if (t != lasterror) 01481 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01482 lasterror = t; 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 7481 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().
07483 { 07484 struct ast_frame f = { 0, }; 07485 int res = 0; 07486 07487 f.frametype = type; 07488 f.subclass.integer = command; 07489 f.datalen = datalen; 07490 f.src = __FUNCTION__; 07491 f.data.ptr = (void *) data; 07492 07493 if ((res = queue_signalling(i, &f)) <= 0) { 07494 return res; 07495 } 07496 07497 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07498 }
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 14356 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().
14357 { 14358 struct ast_context *con; 14359 int x; 14360 14361 network_change_event_unsubscribe(); 14362 14363 ast_manager_unregister("IAXpeers"); 14364 ast_manager_unregister("IAXpeerlist"); 14365 ast_manager_unregister("IAXnetstats"); 14366 ast_manager_unregister("IAXregistry"); 14367 ast_unregister_application(papp); 14368 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14369 ast_unregister_switch(&iax2_switch); 14370 ast_channel_unregister(&iax2_tech); 14371 14372 if (netthreadid != AST_PTHREADT_NULL) { 14373 pthread_cancel(netthreadid); 14374 pthread_kill(netthreadid, SIGURG); 14375 pthread_join(netthreadid, NULL); 14376 } 14377 14378 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14379 if (iaxs[x]) { 14380 iax2_destroy(x); 14381 } 14382 } 14383 14384 /* Call for all threads to halt */ 14385 cleanup_thread_list(&idle_list); 14386 cleanup_thread_list(&active_list); 14387 cleanup_thread_list(&dynamic_list); 14388 14389 ast_netsock_release(netsock); 14390 ast_netsock_release(outsock); 14391 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14392 if (iaxs[x]) { 14393 iax2_destroy(x); 14394 } 14395 } 14396 ast_manager_unregister( "IAXpeers" ); 14397 ast_manager_unregister( "IAXpeerlist" ); 14398 ast_manager_unregister( "IAXnetstats" ); 14399 ast_manager_unregister( "IAXregistry" ); 14400 ast_unregister_application(papp); 14401 #ifdef TEST_FRAMEWORK 14402 AST_TEST_UNREGISTER(test_iax2_peers_get); 14403 AST_TEST_UNREGISTER(test_iax2_users_get); 14404 #endif 14405 ast_data_unregister(NULL); 14406 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14407 ast_unregister_switch(&iax2_switch); 14408 ast_channel_unregister(&iax2_tech); 14409 delete_users(); 14410 iax_provision_unload(); 14411 reload_firmware(1); 14412 14413 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14414 ast_mutex_destroy(&iaxsl[x]); 14415 } 14416 14417 ao2_ref(peers, -1); 14418 ao2_ref(users, -1); 14419 ao2_ref(iax_peercallno_pvts, -1); 14420 ao2_ref(iax_transfercallno_pvts, -1); 14421 ao2_ref(peercnts, -1); 14422 ao2_ref(callno_limits, -1); 14423 ao2_ref(calltoken_ignores, -1); 14424 ao2_ref(callno_pool, -1); 14425 ao2_ref(callno_pool_trunk, -1); 14426 if (timer) { 14427 ast_timer_close(timer); 14428 timer = NULL; 14429 } 14430 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 14431 sched = ast_sched_thread_destroy(sched); 14432 14433 con = ast_context_find(regcontext); 14434 if (con) 14435 ast_context_destroy(con, "IAX2"); 14436 ast_unload_realtime("iaxpeers"); 14437 return 0; 14438 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
const char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 13996 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.
13997 { 13998 struct chan_iax2_pvt *pvt; 13999 unsigned int callno; 14000 int res = 0; 14001 14002 if (!chan || chan->tech != &iax2_tech) { 14003 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 14004 return -1; 14005 } 14006 14007 callno = PTR_TO_CALLNO(chan->tech_pvt); 14008 ast_mutex_lock(&iaxsl[callno]); 14009 if (!(pvt = iaxs[callno])) { 14010 ast_mutex_unlock(&iaxsl[callno]); 14011 return -1; 14012 } 14013 14014 if (!strcasecmp(args, "osptoken")) { 14015 ast_copy_string(buf, pvt->osptoken, buflen); 14016 } else if (!strcasecmp(args, "peerip")) { 14017 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 14018 } else if (!strcasecmp(args, "peername")) { 14019 ast_copy_string(buf, pvt->username, buflen); 14020 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) { 14021 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : ""); 14022 } else { 14023 res = -1; 14024 } 14025 14026 ast_mutex_unlock(&iaxsl[callno]); 14027 14028 return res; 14029 }
static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 9820 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.
09821 { 09822 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09823 AST_LIST_HEAD(, ast_var_t) *varlist; 09824 struct ast_var_t *var; 09825 09826 if (!variablestore) { 09827 *buf = '\0'; 09828 return 0; 09829 } 09830 varlist = variablestore->data; 09831 09832 AST_LIST_LOCK(varlist); 09833 AST_LIST_TRAVERSE(varlist, var, entries) { 09834 if (strcmp(var->name, data) == 0) { 09835 ast_copy_string(buf, var->value, len); 09836 break; 09837 } 09838 } 09839 AST_LIST_UNLOCK(varlist); 09840 return 0; 09841 }
static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 9843 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.
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 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09851 if (!variablestore) { 09852 ast_log(LOG_ERROR, "Memory allocation error\n"); 09853 return -1; 09854 } 09855 varlist = ast_calloc(1, sizeof(*varlist)); 09856 if (!varlist) { 09857 ast_datastore_free(variablestore); 09858 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09859 return -1; 09860 } 09861 09862 AST_LIST_HEAD_INIT(varlist); 09863 variablestore->data = varlist; 09864 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09865 ast_channel_datastore_add(chan, variablestore); 09866 } else 09867 varlist = variablestore->data; 09868 09869 AST_LIST_LOCK(varlist); 09870 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09871 if (strcmp(var->name, data) == 0) { 09872 AST_LIST_REMOVE_CURRENT(entries); 09873 ast_var_delete(var); 09874 break; 09875 } 09876 } 09877 AST_LIST_TRAVERSE_SAFE_END; 09878 var = ast_var_assign(data, value); 09879 if (var) 09880 AST_LIST_INSERT_TAIL(varlist, var, entries); 09881 else 09882 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09883 AST_LIST_UNLOCK(varlist); 09884 return 0; 09885 }
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 4744 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().
04745 { 04746 /* first make sure their are two empty bytes left in ied->buf */ 04747 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04748 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04749 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04750 pvt->calltoken_ie_len = 2; 04751 } 04752 }
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 7539 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 7240 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().
07241 { 07242 int x; 07243 int numchans = 0; 07244 char first_message[10] = { 0, }; 07245 char last_message[10] = { 0, }; 07246 #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" 07247 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 07248 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07249 ast_mutex_lock(&iaxsl[x]); 07250 if (iaxs[x]) { 07251 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 07252 jb_info jbinfo; 07253 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07254 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07255 07256 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07257 jb_getinfo(iaxs[x]->jb, &jbinfo); 07258 localjitter = jbinfo.jitter; 07259 localdelay = jbinfo.current - jbinfo.min; 07260 locallost = jbinfo.frames_lost; 07261 locallosspct = jbinfo.losspct/1000; 07262 localdropped = jbinfo.frames_dropped; 07263 localooo = jbinfo.frames_ooo; 07264 } else { 07265 localjitter = -1; 07266 localdelay = 0; 07267 locallost = -1; 07268 locallosspct = -1; 07269 localdropped = 0; 07270 localooo = -1; 07271 } 07272 if (s) 07273 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07274 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07275 iaxs[x]->pingtime, 07276 localjitter, 07277 localdelay, 07278 locallost, 07279 locallosspct, 07280 localdropped, 07281 localooo, 07282 iaxs[x]->frames_received/1000, 07283 iaxs[x]->remote_rr.jitter, 07284 iaxs[x]->remote_rr.delay, 07285 iaxs[x]->remote_rr.losscnt, 07286 iaxs[x]->remote_rr.losspct, 07287 iaxs[x]->remote_rr.dropped, 07288 iaxs[x]->remote_rr.ooo, 07289 iaxs[x]->remote_rr.packets/1000, 07290 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07291 first_message, 07292 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07293 last_message); 07294 else 07295 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07296 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07297 iaxs[x]->pingtime, 07298 localjitter, 07299 localdelay, 07300 locallost, 07301 locallosspct, 07302 localdropped, 07303 localooo, 07304 iaxs[x]->frames_received/1000, 07305 iaxs[x]->remote_rr.jitter, 07306 iaxs[x]->remote_rr.delay, 07307 iaxs[x]->remote_rr.losscnt, 07308 iaxs[x]->remote_rr.losspct, 07309 iaxs[x]->remote_rr.dropped, 07310 iaxs[x]->remote_rr.ooo, 07311 iaxs[x]->remote_rr.packets/1000, 07312 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07313 first_message, 07314 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07315 last_message); 07316 numchans++; 07317 } 07318 ast_mutex_unlock(&iaxsl[x]); 07319 } 07320 07321 return numchans; 07322 }
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 5732 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().
05733 { 05734 struct ast_channel *tmp; 05735 struct chan_iax2_pvt *i; 05736 struct ast_variable *v = NULL; 05737 05738 if (!(i = iaxs[callno])) { 05739 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05740 return NULL; 05741 } 05742 05743 /* Don't hold call lock */ 05744 ast_mutex_unlock(&iaxsl[callno]); 05745 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); 05746 ast_mutex_lock(&iaxsl[callno]); 05747 if (i != iaxs[callno]) { 05748 if (tmp) { 05749 /* unlock and relock iaxsl[callno] to preserve locking order */ 05750 ast_mutex_unlock(&iaxsl[callno]); 05751 tmp = ast_channel_release(tmp); 05752 ast_mutex_lock(&iaxsl[callno]); 05753 } 05754 return NULL; 05755 } 05756 iax2_ami_channelupdate(i); 05757 if (!tmp) 05758 return NULL; 05759 tmp->tech = &iax2_tech; 05760 /* We can support any format by default, until we get restricted */ 05761 tmp->nativeformats = capability; 05762 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05763 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05764 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05765 05766 if (!ast_strlen_zero(i->parkinglot)) 05767 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05768 /* Don't use ast_set_callerid() here because it will 05769 * generate a NewCallerID event before the NewChannel event */ 05770 if (!ast_strlen_zero(i->ani)) { 05771 tmp->caller.ani.number.valid = 1; 05772 tmp->caller.ani.number.str = ast_strdup(i->ani); 05773 } else if (!ast_strlen_zero(i->cid_num)) { 05774 tmp->caller.ani.number.valid = 1; 05775 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 05776 } 05777 tmp->dialed.number.str = ast_strdup(i->dnid); 05778 if (!ast_strlen_zero(i->rdnis)) { 05779 tmp->redirecting.from.number.valid = 1; 05780 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 05781 } 05782 tmp->caller.id.name.presentation = i->calling_pres; 05783 tmp->caller.id.number.presentation = i->calling_pres; 05784 tmp->caller.id.number.plan = i->calling_ton; 05785 tmp->dialed.transit_network_select = i->calling_tns; 05786 if (!ast_strlen_zero(i->language)) 05787 ast_string_field_set(tmp, language, i->language); 05788 if (!ast_strlen_zero(i->accountcode)) 05789 ast_string_field_set(tmp, accountcode, i->accountcode); 05790 if (i->amaflags) 05791 tmp->amaflags = i->amaflags; 05792 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05793 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05794 if (i->adsi) 05795 tmp->adsicpe = i->peeradsicpe; 05796 else 05797 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05798 i->owner = tmp; 05799 i->capability = capability; 05800 05801 if (!cachable) { 05802 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE; 05803 } 05804 05805 /* Set inherited variables */ 05806 if (i->vars) { 05807 for (v = i->vars ; v ; v = v->next) 05808 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05809 } 05810 if (i->iaxvars) { 05811 struct ast_datastore *variablestore; 05812 struct ast_variable *var, *prev = NULL; 05813 AST_LIST_HEAD(, ast_var_t) *varlist; 05814 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05815 varlist = ast_calloc(1, sizeof(*varlist)); 05816 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05817 if (variablestore && varlist) { 05818 variablestore->data = varlist; 05819 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05820 AST_LIST_HEAD_INIT(varlist); 05821 for (var = i->iaxvars; var; var = var->next) { 05822 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05823 if (prev) 05824 ast_free(prev); 05825 prev = var; 05826 if (!newvar) { 05827 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05828 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05829 } else { 05830 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05831 } 05832 } 05833 if (prev) 05834 ast_free(prev); 05835 i->iaxvars = NULL; 05836 ast_channel_datastore_add(i->owner, variablestore); 05837 } else { 05838 if (variablestore) { 05839 ast_datastore_free(variablestore); 05840 } 05841 if (varlist) { 05842 ast_free(varlist); 05843 } 05844 } 05845 } 05846 05847 if (state != AST_STATE_DOWN) { 05848 if (ast_pbx_start(tmp)) { 05849 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05850 ast_hangup(tmp); 05851 i->owner = NULL; 05852 return NULL; 05853 } 05854 } 05855 05856 ast_module_ref(ast_module_info->self); 05857 return tmp; 05858 }
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 3561 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03562 { 03563 #ifdef SCHED_MULTITHREADED 03564 if (schedule_action(__attempt_transmit, data)) 03565 #endif 03566 __attempt_transmit(data); 03567 return 0; 03568 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 9027 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().
09028 { 09029 /* Schedule sending the authentication failure in one second, to prevent 09030 guessing */ 09031 if (iaxs[callno]) { 09032 iaxs[callno]->authfail = failcode; 09033 if (delayreject) { 09034 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 09035 sched, 1000, auth_reject, (void *)(long)callno); 09036 } else 09037 auth_reject((void *)(long)callno); 09038 } 09039 return 0; 09040 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 9013 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().
09014 { 09015 int callno = (int)(long)(data); 09016 ast_mutex_lock(&iaxsl[callno]); 09017 if (iaxs[callno]) 09018 iaxs[callno]->authid = -1; 09019 ast_mutex_unlock(&iaxsl[callno]); 09020 #ifdef SCHED_MULTITHREADED 09021 if (schedule_action(__auth_reject, data)) 09022 #endif 09023 __auth_reject(data); 09024 return 0; 09025 }
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 8112 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().
08113 { 08114 int res = -1; 08115 int x; 08116 if (!ast_strlen_zero(keyn)) { 08117 if (!(authmethods & IAX_AUTH_RSA)) { 08118 if (ast_strlen_zero(secret)) 08119 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)); 08120 } else if (ast_strlen_zero(challenge)) { 08121 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 08122 } else { 08123 char sig[256]; 08124 struct ast_key *key; 08125 key = ast_key_get(keyn, AST_KEY_PRIVATE); 08126 if (!key) { 08127 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 08128 } else { 08129 if (ast_sign(key, (char*)challenge, sig)) { 08130 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 08131 res = -1; 08132 } else { 08133 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 08134 res = 0; 08135 } 08136 } 08137 } 08138 } 08139 /* Fall back */ 08140 if (res && !ast_strlen_zero(secret)) { 08141 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 08142 struct MD5Context md5; 08143 unsigned char digest[16]; 08144 char digres[128]; 08145 MD5Init(&md5); 08146 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 08147 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 08148 MD5Final(digest, &md5); 08149 /* If they support md5, authenticate with it. */ 08150 for (x=0;x<16;x++) 08151 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 08152 if (pvt) { 08153 build_encryption_keys(digest, pvt); 08154 } 08155 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 08156 res = 0; 08157 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 08158 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 08159 res = 0; 08160 } else 08161 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 08162 } 08163 return res; 08164 }
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 8170 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().
08171 { 08172 struct iax2_peer *peer = NULL; 08173 /* Start pessimistic */ 08174 int res = -1; 08175 int authmethods = 0; 08176 struct iax_ie_data ied; 08177 uint16_t callno = p->callno; 08178 08179 memset(&ied, 0, sizeof(ied)); 08180 08181 if (ies->username) 08182 ast_string_field_set(p, username, ies->username); 08183 if (ies->challenge) 08184 ast_string_field_set(p, challenge, ies->challenge); 08185 if (ies->authmethods) 08186 authmethods = ies->authmethods; 08187 if (authmethods & IAX_AUTH_MD5) 08188 merge_encryption(p, ies->encmethods); 08189 else 08190 p->encmethods = 0; 08191 08192 /* Check for override RSA authentication first */ 08193 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 08194 /* Normal password authentication */ 08195 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 08196 } else { 08197 struct ao2_iterator i = ao2_iterator_init(peers, 0); 08198 while ((peer = ao2_iterator_next(&i))) { 08199 struct sockaddr_in peer_addr; 08200 08201 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 08202 08203 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 08204 /* No peer specified at our end, or this is the peer */ 08205 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 08206 /* No username specified in peer rule, or this is the right username */ 08207 && (!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))) 08208 /* No specified host, or this is our host */ 08209 ) { 08210 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 08211 if (!res) { 08212 peer_unref(peer); 08213 break; 08214 } 08215 } 08216 peer_unref(peer); 08217 } 08218 ao2_iterator_destroy(&i); 08219 if (!peer) { 08220 /* We checked our list and didn't find one. It's unlikely, but possible, 08221 that we're trying to authenticate *to* a realtime peer */ 08222 const char *peer_name = ast_strdupa(p->peer); 08223 ast_mutex_unlock(&iaxsl[callno]); 08224 if ((peer = realtime_peer(peer_name, NULL))) { 08225 ast_mutex_lock(&iaxsl[callno]); 08226 if (!(p = iaxs[callno])) { 08227 peer_unref(peer); 08228 return -1; 08229 } 08230 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 08231 peer_unref(peer); 08232 } 08233 if (!peer) { 08234 ast_mutex_lock(&iaxsl[callno]); 08235 if (!(p = iaxs[callno])) 08236 return -1; 08237 } 08238 } 08239 } 08240 08241 if (ies->encmethods) { 08242 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 08243 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 08244 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n"); 08245 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 08246 } 08247 if (!res) { 08248 struct ast_datastore *variablestore; 08249 struct ast_variable *var, *prev = NULL; 08250 AST_LIST_HEAD(, ast_var_t) *varlist; 08251 varlist = ast_calloc(1, sizeof(*varlist)); 08252 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 08253 if (variablestore && varlist && p->owner) { 08254 variablestore->data = varlist; 08255 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 08256 AST_LIST_HEAD_INIT(varlist); 08257 for (var = ies->vars; var; var = var->next) { 08258 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 08259 if (prev) 08260 ast_free(prev); 08261 prev = var; 08262 if (!newvar) { 08263 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 08264 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08265 } else { 08266 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 08267 } 08268 } 08269 if (prev) 08270 ast_free(prev); 08271 ies->vars = NULL; 08272 ast_channel_datastore_add(p->owner, variablestore); 08273 } else { 08274 if (p->owner) 08275 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08276 if (variablestore) 08277 ast_datastore_free(variablestore); 08278 if (varlist) 08279 ast_free(varlist); 08280 } 08281 } 08282 08283 if (!res) 08284 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08285 return res; 08286 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7818 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().
07819 { 07820 struct iax_ie_data ied; 07821 int res = -1, authreq_restrict = 0; 07822 char challenge[10]; 07823 struct chan_iax2_pvt *p = iaxs[call_num]; 07824 07825 memset(&ied, 0, sizeof(ied)); 07826 07827 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07828 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07829 struct iax2_user *user, tmp_user = { 07830 .name = p->username, 07831 }; 07832 07833 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07834 if (user) { 07835 if (user->curauthreq == user->maxauthreq) 07836 authreq_restrict = 1; 07837 else 07838 user->curauthreq++; 07839 user = user_unref(user); 07840 } 07841 } 07842 07843 /* If the AUTHREQ limit test failed, send back an error */ 07844 if (authreq_restrict) { 07845 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07846 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07847 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07848 return 0; 07849 } 07850 07851 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07852 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07853 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07854 ast_string_field_set(p, challenge, challenge); 07855 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07856 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07857 } 07858 if (p->encmethods) 07859 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07860 07861 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07862 07863 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07864 07865 if (p->encmethods) 07866 ast_set_flag64(p, IAX_ENCRYPTED); 07867 07868 return res; 07869 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7871 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().
07872 { 07873 char requeststr[256]; 07874 char md5secret[256] = ""; 07875 char secret[256] = ""; 07876 char rsasecret[256] = ""; 07877 int res = -1; 07878 int x; 07879 struct iax2_user *user, tmp_user = { 07880 .name = p->username, 07881 }; 07882 07883 if (p->authrej) { 07884 return res; 07885 } 07886 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07887 if (user) { 07888 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07889 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07890 ast_clear_flag64(p, IAX_MAXAUTHREQ); 07891 } 07892 ast_string_field_set(p, host, user->name); 07893 user = user_unref(user); 07894 } 07895 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 07896 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n"); 07897 return res; 07898 } 07899 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07900 return res; 07901 if (ies->password) 07902 ast_copy_string(secret, ies->password, sizeof(secret)); 07903 if (ies->md5_result) 07904 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07905 if (ies->rsa_result) 07906 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07907 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07908 struct ast_key *key; 07909 char *keyn; 07910 char tmpkey[256]; 07911 char *stringp=NULL; 07912 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07913 stringp=tmpkey; 07914 keyn = strsep(&stringp, ":"); 07915 while(keyn) { 07916 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07917 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07918 res = 0; 07919 break; 07920 } else if (!key) 07921 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07922 keyn = strsep(&stringp, ":"); 07923 } 07924 } else if (p->authmethods & IAX_AUTH_MD5) { 07925 struct MD5Context md5; 07926 unsigned char digest[16]; 07927 char *tmppw, *stringp; 07928 07929 tmppw = ast_strdupa(p->secret); 07930 stringp = tmppw; 07931 while((tmppw = strsep(&stringp, ";"))) { 07932 MD5Init(&md5); 07933 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07934 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07935 MD5Final(digest, &md5); 07936 /* If they support md5, authenticate with it. */ 07937 for (x=0;x<16;x++) 07938 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07939 if (!strcasecmp(requeststr, md5secret)) { 07940 res = 0; 07941 break; 07942 } 07943 } 07944 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07945 if (!strcmp(secret, p->secret)) 07946 res = 0; 07947 } 07948 return res; 07949 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4681 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call().
04682 { 04683 #ifdef SCHED_MULTITHREADED 04684 if (schedule_action(__auto_congest, data)) 04685 #endif 04686 __auto_congest(data); 04687 return 0; 04688 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 9057 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().
09058 { 09059 int callno = (int)(long)(data); 09060 ast_mutex_lock(&iaxsl[callno]); 09061 if (iaxs[callno]) { 09062 iaxs[callno]->autoid = -1; 09063 } 09064 ast_mutex_unlock(&iaxsl[callno]); 09065 #ifdef SCHED_MULTITHREADED 09066 if (schedule_action(__auto_hangup, data)) 09067 #endif 09068 __auto_hangup(data); 09069 return 0; 09070 }
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 12257 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), and iax2_context::context.
Referenced by build_user().
12258 { 12259 struct iax2_context *con; 12260 12261 if ((con = ast_calloc(1, sizeof(*con)))) 12262 ast_copy_string(con->context, context, sizeof(con->context)); 12263 12264 return con; 12265 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6199 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().
06200 { 06201 /* it is required to hold the corresponding decrypt key to our encrypt key 06202 * in the pvt struct because queued frames occasionally need to be decrypted and 06203 * re-encrypted when updated for a retransmission */ 06204 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 06205 ast_aes_set_encrypt_key(digest, &pvt->ecx); 06206 ast_aes_set_decrypt_key(digest, &pvt->mydcx); 06207 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6193 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().
06194 { 06195 build_ecx_key(digest, pvt); 06196 ast_aes_set_decrypt_key(digest, &pvt->dcx); 06197 }
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 12406 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().
12407 { 12408 struct iax2_peer *peer = NULL; 12409 struct ast_ha *oldha = NULL; 12410 int maskfound = 0; 12411 int found = 0; 12412 int firstpass = 1; 12413 struct iax2_peer tmp_peer = { 12414 .name = name, 12415 }; 12416 12417 if (!temponly) { 12418 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 12419 if (peer && !ast_test_flag64(peer, IAX_DELME)) 12420 firstpass = 0; 12421 } 12422 12423 if (peer) { 12424 found++; 12425 if (firstpass) { 12426 oldha = peer->ha; 12427 peer->ha = NULL; 12428 } 12429 unlink_peer(peer); 12430 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 12431 peer->expire = -1; 12432 peer->pokeexpire = -1; 12433 peer->sockfd = defaultsockfd; 12434 peer->addr.ss.ss_family = AF_INET; 12435 peer->addr.len = sizeof(struct sockaddr_in); 12436 if (ast_string_field_init(peer, 32)) 12437 peer = peer_unref(peer); 12438 } 12439 12440 if (peer) { 12441 if (firstpass) { 12442 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12443 peer->encmethods = iax2_encryption; 12444 peer->adsi = adsi; 12445 ast_string_field_set(peer,secret,""); 12446 if (!found) { 12447 ast_string_field_set(peer, name, name); 12448 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12449 peer->expiry = min_reg_expire; 12450 } 12451 peer->prefs = prefs; 12452 peer->capability = iax2_capability; 12453 peer->smoothing = 0; 12454 peer->pokefreqok = DEFAULT_FREQ_OK; 12455 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 12456 peer->maxcallno = 0; 12457 peercnt_modify(0, 0, &peer->addr); 12458 peer->calltoken_required = CALLTOKEN_DEFAULT; 12459 ast_string_field_set(peer,context,""); 12460 ast_string_field_set(peer,peercontext,""); 12461 ast_clear_flag64(peer, IAX_HASCALLERID); 12462 ast_string_field_set(peer, cid_name, ""); 12463 ast_string_field_set(peer, cid_num, ""); 12464 ast_string_field_set(peer, mohinterpret, mohinterpret); 12465 ast_string_field_set(peer, mohsuggest, mohsuggest); 12466 } 12467 12468 if (!v) { 12469 v = alt; 12470 alt = NULL; 12471 } 12472 while(v) { 12473 if (!strcasecmp(v->name, "secret")) { 12474 ast_string_field_set(peer, secret, v->value); 12475 } else if (!strcasecmp(v->name, "mailbox")) { 12476 ast_string_field_set(peer, mailbox, v->value); 12477 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12478 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12479 ast_string_field_set(peer, mailbox, name); 12480 } 12481 } else if (!strcasecmp(v->name, "mohinterpret")) { 12482 ast_string_field_set(peer, mohinterpret, v->value); 12483 } else if (!strcasecmp(v->name, "mohsuggest")) { 12484 ast_string_field_set(peer, mohsuggest, v->value); 12485 } else if (!strcasecmp(v->name, "dbsecret")) { 12486 ast_string_field_set(peer, dbsecret, v->value); 12487 } else if (!strcasecmp(v->name, "trunk")) { 12488 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12489 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12490 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12491 ast_clear_flag64(peer, IAX_TRUNK); 12492 } 12493 } else if (!strcasecmp(v->name, "auth")) { 12494 peer->authmethods = get_auth_methods(v->value); 12495 } else if (!strcasecmp(v->name, "encryption")) { 12496 peer->encmethods |= get_encrypt_methods(v->value); 12497 if (!peer->encmethods) { 12498 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12499 } 12500 } else if (!strcasecmp(v->name, "forceencryption")) { 12501 if (ast_false(v->value)) { 12502 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12503 } else { 12504 peer->encmethods |= get_encrypt_methods(v->value); 12505 if (peer->encmethods) { 12506 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12507 } 12508 } 12509 } else if (!strcasecmp(v->name, "transfer")) { 12510 if (!strcasecmp(v->value, "mediaonly")) { 12511 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12512 } else if (ast_true(v->value)) { 12513 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12514 } else 12515 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12516 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12517 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12518 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12519 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12520 } else if (!strcasecmp(v->name, "host")) { 12521 if (!strcasecmp(v->value, "dynamic")) { 12522 /* They'll register with us */ 12523 ast_set_flag64(peer, IAX_DYNAMIC); 12524 if (!found) { 12525 /* Initialize stuff iff we're not found, otherwise 12526 we keep going with what we had */ 12527 if (ast_sockaddr_port(&peer->addr)) { 12528 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr)); 12529 } 12530 ast_sockaddr_setnull(&peer->addr); 12531 } 12532 } else { 12533 /* Non-dynamic. Make sure we become that way if we're not */ 12534 ast_sched_thread_del(sched, peer->expire); 12535 ast_clear_flag64(peer, IAX_DYNAMIC); 12536 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12537 return peer_unref(peer); 12538 if (!ast_sockaddr_port(&peer->addr)) { 12539 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12540 } 12541 } 12542 if (!maskfound) 12543 inet_aton("255.255.255.255", &peer->mask); 12544 } else if (!strcasecmp(v->name, "defaultip")) { 12545 struct ast_sockaddr peer_defaddr_tmp; 12546 12547 peer_defaddr_tmp.ss.ss_family = AF_INET; 12548 if (ast_get_ip(&peer_defaddr_tmp, v->value)) { 12549 return peer_unref(peer); 12550 } 12551 ast_sockaddr_to_sin(&peer_defaddr_tmp, 12552 &peer->defaddr); 12553 } else if (!strcasecmp(v->name, "sourceaddress")) { 12554 peer_set_srcaddr(peer, v->value); 12555 } else if (!strcasecmp(v->name, "permit") || 12556 !strcasecmp(v->name, "deny")) { 12557 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12558 } else if (!strcasecmp(v->name, "mask")) { 12559 maskfound++; 12560 inet_aton(v->value, &peer->mask); 12561 } else if (!strcasecmp(v->name, "context")) { 12562 ast_string_field_set(peer, context, v->value); 12563 } else if (!strcasecmp(v->name, "regexten")) { 12564 ast_string_field_set(peer, regexten, v->value); 12565 } else if (!strcasecmp(v->name, "peercontext")) { 12566 ast_string_field_set(peer, peercontext, v->value); 12567 } else if (!strcasecmp(v->name, "port")) { 12568 if (ast_test_flag64(peer, IAX_DYNAMIC)) { 12569 peer->defaddr.sin_port = htons(atoi(v->value)); 12570 } else { 12571 ast_sockaddr_set_port(&peer->addr, atoi(v->value)); 12572 } 12573 } else if (!strcasecmp(v->name, "username")) { 12574 ast_string_field_set(peer, username, v->value); 12575 } else if (!strcasecmp(v->name, "allow")) { 12576 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12577 } else if (!strcasecmp(v->name, "disallow")) { 12578 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12579 } else if (!strcasecmp(v->name, "callerid")) { 12580 if (!ast_strlen_zero(v->value)) { 12581 char name2[80]; 12582 char num2[80]; 12583 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12584 ast_string_field_set(peer, cid_name, name2); 12585 ast_string_field_set(peer, cid_num, num2); 12586 } else { 12587 ast_string_field_set(peer, cid_name, ""); 12588 ast_string_field_set(peer, cid_num, ""); 12589 } 12590 ast_set_flag64(peer, IAX_HASCALLERID); 12591 } else if (!strcasecmp(v->name, "fullname")) { 12592 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12593 ast_set_flag64(peer, IAX_HASCALLERID); 12594 } else if (!strcasecmp(v->name, "cid_number")) { 12595 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12596 ast_set_flag64(peer, IAX_HASCALLERID); 12597 } else if (!strcasecmp(v->name, "sendani")) { 12598 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12599 } else if (!strcasecmp(v->name, "inkeys")) { 12600 ast_string_field_set(peer, inkeys, v->value); 12601 } else if (!strcasecmp(v->name, "outkey")) { 12602 ast_string_field_set(peer, outkey, v->value); 12603 } else if (!strcasecmp(v->name, "qualify")) { 12604 if (!strcasecmp(v->value, "no")) { 12605 peer->maxms = 0; 12606 } else if (!strcasecmp(v->value, "yes")) { 12607 peer->maxms = DEFAULT_MAXMS; 12608 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12609 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); 12610 peer->maxms = 0; 12611 } 12612 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12613 peer->smoothing = ast_true(v->value); 12614 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12615 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12616 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); 12617 } 12618 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12619 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12620 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); 12621 } 12622 } else if (!strcasecmp(v->name, "timezone")) { 12623 ast_string_field_set(peer, zonetag, v->value); 12624 } else if (!strcasecmp(v->name, "adsi")) { 12625 peer->adsi = ast_true(v->value); 12626 } else if (!strcasecmp(v->name, "connectedline")) { 12627 if (ast_true(v->value)) { 12628 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12629 } else if (!strcasecmp(v->value, "send")) { 12630 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12631 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12632 } else if (!strcasecmp(v->value, "receive")) { 12633 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12634 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12635 } else { 12636 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12637 } 12638 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12639 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12640 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12641 } else { 12642 peercnt_modify(1, peer->maxcallno, &peer->addr); 12643 } 12644 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12645 /* default is required unless in optional ip list */ 12646 if (ast_false(v->value)) { 12647 peer->calltoken_required = CALLTOKEN_NO; 12648 } else if (!strcasecmp(v->value, "auto")) { 12649 peer->calltoken_required = CALLTOKEN_AUTO; 12650 } else if (ast_true(v->value)) { 12651 peer->calltoken_required = CALLTOKEN_YES; 12652 } else { 12653 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12654 } 12655 } /* else if (strcasecmp(v->name,"type")) */ 12656 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12657 v = v->next; 12658 if (!v) { 12659 v = alt; 12660 alt = NULL; 12661 } 12662 } 12663 if (!peer->authmethods) 12664 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12665 ast_clear_flag64(peer, IAX_DELME); 12666 } 12667 12668 if (oldha) 12669 ast_free_ha(oldha); 12670 12671 if (!ast_strlen_zero(peer->mailbox)) { 12672 char *mailbox, *context; 12673 context = mailbox = ast_strdupa(peer->mailbox); 12674 strsep(&context, "@"); 12675 if (ast_strlen_zero(context)) 12676 context = "default"; 12677 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12678 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12679 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12680 AST_EVENT_IE_END); 12681 } 12682 12683 return peer; 12684 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 6183 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
06184 { 06185 long tmp; 06186 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 06187 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 06188 buf += sizeof(tmp); 06189 len -= sizeof(tmp); 06190 } 06191 }
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 12700 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().
12701 { 12702 struct iax2_user *user = NULL; 12703 struct iax2_context *con, *conl = NULL; 12704 struct ast_ha *oldha = NULL; 12705 struct iax2_context *oldcon = NULL; 12706 int format; 12707 int firstpass=1; 12708 int oldcurauthreq = 0; 12709 char *varname = NULL, *varval = NULL; 12710 struct ast_variable *tmpvar = NULL; 12711 struct iax2_user tmp_user = { 12712 .name = name, 12713 }; 12714 12715 if (!temponly) { 12716 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12717 if (user && !ast_test_flag64(user, IAX_DELME)) 12718 firstpass = 0; 12719 } 12720 12721 if (user) { 12722 if (firstpass) { 12723 oldcurauthreq = user->curauthreq; 12724 oldha = user->ha; 12725 oldcon = user->contexts; 12726 user->ha = NULL; 12727 user->contexts = NULL; 12728 } 12729 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12730 ao2_unlink(users, user); 12731 } else { 12732 user = ao2_alloc(sizeof(*user), user_destructor); 12733 } 12734 12735 if (user) { 12736 if (firstpass) { 12737 ast_string_field_free_memory(user); 12738 memset(user, 0, sizeof(struct iax2_user)); 12739 if (ast_string_field_init(user, 32)) { 12740 user = user_unref(user); 12741 goto cleanup; 12742 } 12743 user->maxauthreq = maxauthreq; 12744 user->curauthreq = oldcurauthreq; 12745 user->prefs = prefs; 12746 user->capability = iax2_capability; 12747 user->encmethods = iax2_encryption; 12748 user->adsi = adsi; 12749 user->calltoken_required = CALLTOKEN_DEFAULT; 12750 ast_string_field_set(user, name, name); 12751 ast_string_field_set(user, language, language); 12752 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); 12753 ast_clear_flag64(user, IAX_HASCALLERID); 12754 ast_string_field_set(user, cid_name, ""); 12755 ast_string_field_set(user, cid_num, ""); 12756 ast_string_field_set(user, accountcode, accountcode); 12757 ast_string_field_set(user, mohinterpret, mohinterpret); 12758 ast_string_field_set(user, mohsuggest, mohsuggest); 12759 } 12760 if (!v) { 12761 v = alt; 12762 alt = NULL; 12763 } 12764 while(v) { 12765 if (!strcasecmp(v->name, "context")) { 12766 con = build_context(v->value); 12767 if (con) { 12768 if (conl) 12769 conl->next = con; 12770 else 12771 user->contexts = con; 12772 conl = con; 12773 } 12774 } else if (!strcasecmp(v->name, "permit") || 12775 !strcasecmp(v->name, "deny")) { 12776 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12777 } else if (!strcasecmp(v->name, "setvar")) { 12778 varname = ast_strdupa(v->value); 12779 if ((varval = strchr(varname, '='))) { 12780 *varval = '\0'; 12781 varval++; 12782 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12783 tmpvar->next = user->vars; 12784 user->vars = tmpvar; 12785 } 12786 } 12787 } else if (!strcasecmp(v->name, "allow")) { 12788 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12789 } else if (!strcasecmp(v->name, "disallow")) { 12790 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12791 } else if (!strcasecmp(v->name, "trunk")) { 12792 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 12793 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 12794 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12795 ast_clear_flag64(user, IAX_TRUNK); 12796 } 12797 } else if (!strcasecmp(v->name, "auth")) { 12798 user->authmethods = get_auth_methods(v->value); 12799 } else if (!strcasecmp(v->name, "encryption")) { 12800 user->encmethods |= get_encrypt_methods(v->value); 12801 if (!user->encmethods) { 12802 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12803 } 12804 } else if (!strcasecmp(v->name, "forceencryption")) { 12805 if (ast_false(v->value)) { 12806 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12807 } else { 12808 user->encmethods |= get_encrypt_methods(v->value); 12809 if (user->encmethods) { 12810 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 12811 } 12812 } 12813 } else if (!strcasecmp(v->name, "transfer")) { 12814 if (!strcasecmp(v->value, "mediaonly")) { 12815 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12816 } else if (ast_true(v->value)) { 12817 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12818 } else 12819 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12820 } else if (!strcasecmp(v->name, "codecpriority")) { 12821 if(!strcasecmp(v->value, "caller")) 12822 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 12823 else if(!strcasecmp(v->value, "disabled")) 12824 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12825 else if(!strcasecmp(v->value, "reqonly")) { 12826 ast_set_flag64(user, IAX_CODEC_NOCAP); 12827 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12828 } 12829 } else if (!strcasecmp(v->name, "immediate")) { 12830 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 12831 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12832 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 12833 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12834 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12835 } else if (!strcasecmp(v->name, "dbsecret")) { 12836 ast_string_field_set(user, dbsecret, v->value); 12837 } else if (!strcasecmp(v->name, "secret")) { 12838 if (!ast_strlen_zero(user->secret)) { 12839 char *old = ast_strdupa(user->secret); 12840 12841 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12842 } else 12843 ast_string_field_set(user, secret, v->value); 12844 } else if (!strcasecmp(v->name, "callerid")) { 12845 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12846 char name2[80]; 12847 char num2[80]; 12848 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12849 ast_string_field_set(user, cid_name, name2); 12850 ast_string_field_set(user, cid_num, num2); 12851 ast_set_flag64(user, IAX_HASCALLERID); 12852 } else { 12853 ast_clear_flag64(user, IAX_HASCALLERID); 12854 ast_string_field_set(user, cid_name, ""); 12855 ast_string_field_set(user, cid_num, ""); 12856 } 12857 } else if (!strcasecmp(v->name, "fullname")) { 12858 if (!ast_strlen_zero(v->value)) { 12859 ast_string_field_set(user, cid_name, v->value); 12860 ast_set_flag64(user, IAX_HASCALLERID); 12861 } else { 12862 ast_string_field_set(user, cid_name, ""); 12863 if (ast_strlen_zero(user->cid_num)) 12864 ast_clear_flag64(user, IAX_HASCALLERID); 12865 } 12866 } else if (!strcasecmp(v->name, "cid_number")) { 12867 if (!ast_strlen_zero(v->value)) { 12868 ast_string_field_set(user, cid_num, v->value); 12869 ast_set_flag64(user, IAX_HASCALLERID); 12870 } else { 12871 ast_string_field_set(user, cid_num, ""); 12872 if (ast_strlen_zero(user->cid_name)) 12873 ast_clear_flag64(user, IAX_HASCALLERID); 12874 } 12875 } else if (!strcasecmp(v->name, "accountcode")) { 12876 ast_string_field_set(user, accountcode, v->value); 12877 } else if (!strcasecmp(v->name, "mohinterpret")) { 12878 ast_string_field_set(user, mohinterpret, v->value); 12879 } else if (!strcasecmp(v->name, "mohsuggest")) { 12880 ast_string_field_set(user, mohsuggest, v->value); 12881 } else if (!strcasecmp(v->name, "parkinglot")) { 12882 ast_string_field_set(user, parkinglot, v->value); 12883 } else if (!strcasecmp(v->name, "language")) { 12884 ast_string_field_set(user, language, v->value); 12885 } else if (!strcasecmp(v->name, "amaflags")) { 12886 format = ast_cdr_amaflags2int(v->value); 12887 if (format < 0) { 12888 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12889 } else { 12890 user->amaflags = format; 12891 } 12892 } else if (!strcasecmp(v->name, "inkeys")) { 12893 ast_string_field_set(user, inkeys, v->value); 12894 } else if (!strcasecmp(v->name, "maxauthreq")) { 12895 user->maxauthreq = atoi(v->value); 12896 if (user->maxauthreq < 0) 12897 user->maxauthreq = 0; 12898 } else if (!strcasecmp(v->name, "adsi")) { 12899 user->adsi = ast_true(v->value); 12900 } else if (!strcasecmp(v->name, "connectedline")) { 12901 if (ast_true(v->value)) { 12902 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12903 } else if (!strcasecmp(v->value, "send")) { 12904 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 12905 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 12906 } else if (!strcasecmp(v->value, "receive")) { 12907 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 12908 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 12909 } else { 12910 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12911 } 12912 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12913 /* default is required unless in optional ip list */ 12914 if (ast_false(v->value)) { 12915 user->calltoken_required = CALLTOKEN_NO; 12916 } else if (!strcasecmp(v->value, "auto")) { 12917 user->calltoken_required = CALLTOKEN_AUTO; 12918 } else if (ast_true(v->value)) { 12919 user->calltoken_required = CALLTOKEN_YES; 12920 } else { 12921 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12922 } 12923 } /* else if (strcasecmp(v->name,"type")) */ 12924 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12925 v = v->next; 12926 if (!v) { 12927 v = alt; 12928 alt = NULL; 12929 } 12930 } 12931 if (!user->authmethods) { 12932 if (!ast_strlen_zero(user->secret)) { 12933 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12934 if (!ast_strlen_zero(user->inkeys)) 12935 user->authmethods |= IAX_AUTH_RSA; 12936 } else if (!ast_strlen_zero(user->inkeys)) { 12937 user->authmethods = IAX_AUTH_RSA; 12938 } else { 12939 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12940 } 12941 } 12942 ast_clear_flag64(user, IAX_DELME); 12943 } 12944 cleanup: 12945 if (oldha) 12946 ast_free_ha(oldha); 12947 if (oldcon) 12948 free_context(oldcon); 12949 return user; 12950 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13597 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().
13598 { 13599 struct sockaddr_in sin; 13600 int x; 13601 int callno; 13602 struct iax_ie_data ied; 13603 struct create_addr_info cai; 13604 struct parsed_dial_string pds; 13605 char *tmpstr; 13606 13607 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13608 /* Look for an *exact match* call. Once a call is negotiated, it can only 13609 look up entries for a single context */ 13610 if (!ast_mutex_trylock(&iaxsl[x])) { 13611 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13612 return x; 13613 ast_mutex_unlock(&iaxsl[x]); 13614 } 13615 } 13616 13617 /* No match found, we need to create a new one */ 13618 13619 memset(&cai, 0, sizeof(cai)); 13620 memset(&ied, 0, sizeof(ied)); 13621 memset(&pds, 0, sizeof(pds)); 13622 13623 tmpstr = ast_strdupa(data); 13624 parse_dial_string(tmpstr, &pds); 13625 13626 if (ast_strlen_zero(pds.peer)) { 13627 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13628 return -1; 13629 } 13630 13631 /* Populate our address from the given */ 13632 if (create_addr(pds.peer, NULL, &sin, &cai)) 13633 return -1; 13634 13635 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13636 pds.peer, pds.username, pds.password, pds.context); 13637 13638 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13639 if (callno < 1) { 13640 ast_log(LOG_WARNING, "Unable to create call\n"); 13641 return -1; 13642 } 13643 13644 ast_string_field_set(iaxs[callno], dproot, data); 13645 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13646 13647 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13648 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13649 /* the string format is slightly different from a standard dial string, 13650 because the context appears in the 'exten' position 13651 */ 13652 if (pds.exten) 13653 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13654 if (pds.username) 13655 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13656 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13657 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13658 /* Keep password handy */ 13659 if (pds.password) 13660 ast_string_field_set(iaxs[callno], secret, pds.password); 13661 if (pds.key) 13662 ast_string_field_set(iaxs[callno], outkey, pds.key); 13663 /* Start the call going */ 13664 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13665 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13666 13667 return callno; 13668 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 6036 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().
06037 { 06038 /* Returns where in "receive time" we are. That is, how many ms 06039 since we received (or would have received) the frame with timestamp 0 */ 06040 int ms; 06041 #ifdef IAXTESTS 06042 int jit; 06043 #endif /* IAXTESTS */ 06044 /* Setup rxcore if necessary */ 06045 if (ast_tvzero(p->rxcore)) { 06046 p->rxcore = ast_tvnow(); 06047 if (iaxdebug) 06048 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 06049 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 06050 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 06051 #if 1 06052 if (iaxdebug) 06053 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 06054 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 06055 #endif 06056 } 06057 06058 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 06059 #ifdef IAXTESTS 06060 if (test_jit) { 06061 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 06062 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 06063 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 06064 jit = -jit; 06065 ms += jit; 06066 } 06067 } 06068 if (test_late) { 06069 ms += test_late; 06070 test_late = 0; 06071 } 06072 #endif /* IAXTESTS */ 06073 return ms; 06074 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 5904 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().
05905 { 05906 int ms; 05907 int voice = 0; 05908 int genuine = 0; 05909 int adjust; 05910 int rate = ast_format_rate(f->subclass.codec) / 1000; 05911 struct timeval *delivery = NULL; 05912 05913 05914 /* What sort of frame do we have?: voice is self-explanatory 05915 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05916 non-genuine frames are CONTROL frames [ringing etc], DTMF 05917 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05918 the others need a timestamp slaved to the voice frames so that they go in sequence 05919 */ 05920 if (f->frametype == AST_FRAME_VOICE) { 05921 voice = 1; 05922 delivery = &f->delivery; 05923 } else if (f->frametype == AST_FRAME_IAX) { 05924 genuine = 1; 05925 } else if (f->frametype == AST_FRAME_CNG) { 05926 p->notsilenttx = 0; 05927 } 05928 05929 if (ast_tvzero(p->offset)) { 05930 p->offset = ast_tvnow(); 05931 /* Round to nearest 20ms for nice looking traces */ 05932 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05933 } 05934 /* If the timestamp is specified, just send it as is */ 05935 if (ts) 05936 return ts; 05937 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05938 if (delivery && !ast_tvzero(*delivery)) { 05939 ms = ast_tvdiff_ms(*delivery, p->offset); 05940 if (ms < 0) { 05941 ms = 0; 05942 } 05943 if (iaxdebug) 05944 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05945 } else { 05946 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05947 if (ms < 0) 05948 ms = 0; 05949 if (voice) { 05950 /* On a voice frame, use predicted values if appropriate */ 05951 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05952 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05953 /* AN EXPLANATION: 05954 When we send voice, we usually send "calculated" timestamps worked out 05955 on the basis of the number of samples sent. When we send other frames, 05956 we usually send timestamps worked out from the real clock. 05957 The problem is that they can tend to drift out of step because the 05958 source channel's clock and our clock may not be exactly at the same rate. 05959 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05960 for this call. Moving it adjusts timestamps for non-voice frames. 05961 We make the adjustment in the style of a moving average. Each time we 05962 adjust p->offset by 10% of the difference between our clock-derived 05963 timestamp and the predicted timestamp. That's why you see "10000" 05964 below even though IAX2 timestamps are in milliseconds. 05965 The use of a moving average avoids offset moving too radically. 05966 Generally, "adjust" roams back and forth around 0, with offset hardly 05967 changing at all. But if a consistent different starts to develop it 05968 will be eliminated over the course of 10 frames (200-300msecs) 05969 */ 05970 adjust = (ms - p->nextpred); 05971 if (adjust < 0) 05972 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05973 else if (adjust > 0) 05974 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05975 05976 if (!p->nextpred) { 05977 p->nextpred = ms; /*f->samples / rate;*/ 05978 if (p->nextpred <= p->lastsent) 05979 p->nextpred = p->lastsent + 3; 05980 } 05981 ms = p->nextpred; 05982 } else { 05983 /* in this case, just use the actual 05984 * time, since we're either way off 05985 * (shouldn't happen), or we're ending a 05986 * silent period -- and seed the next 05987 * predicted time. Also, round ms to the 05988 * next multiple of frame size (so our 05989 * silent periods are multiples of 05990 * frame size too) */ 05991 05992 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05993 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05994 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05995 05996 if (f->samples >= rate) /* check to make sure we don't core dump */ 05997 { 05998 int diff = ms % (f->samples / rate); 05999 if (diff) 06000 ms += f->samples/rate - diff; 06001 } 06002 06003 p->nextpred = ms; 06004 p->notsilenttx = 1; 06005 } 06006 } else if ( f->frametype == AST_FRAME_VIDEO ) { 06007 /* 06008 * IAX2 draft 03 says that timestamps MUST be in order. 06009 * It does not say anything about several frames having the same timestamp 06010 * When transporting video, we can have a frame that spans multiple iax packets 06011 * (so called slices), so it would make sense to use the same timestamp for all of 06012 * them 06013 * We do want to make sure that frames don't go backwards though 06014 */ 06015 if ( (unsigned int)ms < p->lastsent ) 06016 ms = p->lastsent; 06017 } else { 06018 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 06019 it's a genuine frame */ 06020 if (genuine) { 06021 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 06022 if (ms <= p->lastsent) 06023 ms = p->lastsent + 3; 06024 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 06025 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 06026 ms = p->lastsent + 3; 06027 } 06028 } 06029 } 06030 p->lastsent = ms; 06031 if (voice) 06032 p->nextpred = p->nextpred + f->samples / rate; 06033 return ms; 06034 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | now | |||
) | [static] |
Definition at line 5860 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().
05861 { 05862 unsigned long int mssincetx; /* unsigned to handle overflows */ 05863 long int ms, pred; 05864 05865 tpeer->trunkact = *now; 05866 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05867 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05868 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05869 tpeer->txtrunktime = *now; 05870 tpeer->lastsent = 999999; 05871 } 05872 /* Update last transmit time now */ 05873 tpeer->lasttxtime = *now; 05874 05875 /* Calculate ms offset */ 05876 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05877 /* Predict from last value */ 05878 pred = tpeer->lastsent + sampms; 05879 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05880 ms = pred; 05881 05882 /* We never send the same timestamp twice, so fudge a little if we must */ 05883 if (ms == tpeer->lastsent) 05884 ms = tpeer->lastsent + 1; 05885 tpeer->lastsent = ms; 05886 return ms; 05887 }
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 7550 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().
07551 { 07552 /* Start pessimistic */ 07553 int res = -1; 07554 int version = 2; 07555 struct iax2_user *user = NULL, *best = NULL; 07556 int bestscore = 0; 07557 int gotcapability = 0; 07558 struct ast_variable *v = NULL, *tmpvar = NULL; 07559 struct ao2_iterator i; 07560 struct ast_sockaddr addr; 07561 07562 if (!iaxs[callno]) 07563 return res; 07564 if (ies->called_number) 07565 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07566 if (ies->calling_number) { 07567 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07568 ast_shrink_phone_number(ies->calling_number); 07569 } 07570 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07571 } 07572 if (ies->calling_name) 07573 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07574 if (ies->calling_ani) 07575 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07576 if (ies->dnid) 07577 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07578 if (ies->rdnis) 07579 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07580 if (ies->called_context) 07581 ast_string_field_set(iaxs[callno], context, ies->called_context); 07582 if (ies->language) 07583 ast_string_field_set(iaxs[callno], language, ies->language); 07584 if (ies->username) 07585 ast_string_field_set(iaxs[callno], username, ies->username); 07586 if (ies->calling_ton > -1) 07587 iaxs[callno]->calling_ton = ies->calling_ton; 07588 if (ies->calling_tns > -1) 07589 iaxs[callno]->calling_tns = ies->calling_tns; 07590 if (ies->calling_pres > -1) 07591 iaxs[callno]->calling_pres = ies->calling_pres; 07592 if (ies->format) 07593 iaxs[callno]->peerformat = ies->format; 07594 if (ies->adsicpe) 07595 iaxs[callno]->peeradsicpe = ies->adsicpe; 07596 if (ies->capability) { 07597 gotcapability = 1; 07598 iaxs[callno]->peercapability = ies->capability; 07599 } 07600 if (ies->version) 07601 version = ies->version; 07602 07603 /* Use provided preferences until told otherwise for actual preferences */ 07604 if (ies->codec_prefs) { 07605 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07606 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07607 } 07608 07609 if (!gotcapability) 07610 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07611 if (version > IAX_PROTO_VERSION) { 07612 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07613 ast_inet_ntoa(sin->sin_addr), version); 07614 return res; 07615 } 07616 /* Search the userlist for a compatible entry, and fill in the rest */ 07617 ast_sockaddr_from_sin(&addr, sin); 07618 i = ao2_iterator_init(users, 0); 07619 while ((user = ao2_iterator_next(&i))) { 07620 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07621 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07622 && ast_apply_ha(user->ha, &addr) == AST_SENSE_ALLOW /* Access is permitted from this IP */ 07623 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07624 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07625 if (!ast_strlen_zero(iaxs[callno]->username)) { 07626 /* Exact match, stop right now. */ 07627 if (best) 07628 user_unref(best); 07629 best = user; 07630 break; 07631 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07632 /* No required authentication */ 07633 if (user->ha) { 07634 /* There was host authentication and we passed, bonus! */ 07635 if (bestscore < 4) { 07636 bestscore = 4; 07637 if (best) 07638 user_unref(best); 07639 best = user; 07640 continue; 07641 } 07642 } else { 07643 /* No host access, but no secret, either, not bad */ 07644 if (bestscore < 3) { 07645 bestscore = 3; 07646 if (best) 07647 user_unref(best); 07648 best = user; 07649 continue; 07650 } 07651 } 07652 } else { 07653 if (user->ha) { 07654 /* Authentication, but host access too, eh, it's something.. */ 07655 if (bestscore < 2) { 07656 bestscore = 2; 07657 if (best) 07658 user_unref(best); 07659 best = user; 07660 continue; 07661 } 07662 } else { 07663 /* Authentication and no host access... This is our baseline */ 07664 if (bestscore < 1) { 07665 bestscore = 1; 07666 if (best) 07667 user_unref(best); 07668 best = user; 07669 continue; 07670 } 07671 } 07672 } 07673 } 07674 user_unref(user); 07675 } 07676 ao2_iterator_destroy(&i); 07677 user = best; 07678 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07679 user = realtime_user(iaxs[callno]->username, sin); 07680 if (user && (ast_apply_ha(user->ha, &addr) == AST_SENSE_DENY /* Access is denied from this IP */ 07681 || (!ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07682 !apply_context(user->contexts, iaxs[callno]->context)))) { /* Context is permitted */ 07683 user = user_unref(user); 07684 } 07685 } 07686 if (user) { 07687 /* We found our match (use the first) */ 07688 /* copy vars */ 07689 for (v = user->vars ; v ; v = v->next) { 07690 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07691 tmpvar->next = iaxs[callno]->vars; 07692 iaxs[callno]->vars = tmpvar; 07693 } 07694 } 07695 /* If a max AUTHREQ restriction is in place, activate it */ 07696 if (user->maxauthreq > 0) 07697 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07698 iaxs[callno]->prefs = user->prefs; 07699 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07700 iaxs[callno]->encmethods = user->encmethods; 07701 /* Store the requested username if not specified */ 07702 if (ast_strlen_zero(iaxs[callno]->username)) 07703 ast_string_field_set(iaxs[callno], username, user->name); 07704 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07705 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07706 iaxs[callno]->capability = user->capability; 07707 /* And use the default context */ 07708 if (ast_strlen_zero(iaxs[callno]->context)) { 07709 if (user->contexts) 07710 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07711 else 07712 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07713 } 07714 /* And any input keys */ 07715 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07716 /* And the permitted authentication methods */ 07717 iaxs[callno]->authmethods = user->authmethods; 07718 iaxs[callno]->adsi = user->adsi; 07719 /* If the user has callerid, override the remote caller id. */ 07720 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07721 iaxs[callno]->calling_tns = 0; 07722 iaxs[callno]->calling_ton = 0; 07723 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07724 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07725 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07726 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07727 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07728 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07729 } /* else user is allowed to set their own CID settings */ 07730 if (!ast_strlen_zero(user->accountcode)) 07731 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07732 if (!ast_strlen_zero(user->mohinterpret)) 07733 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07734 if (!ast_strlen_zero(user->mohsuggest)) 07735 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07736 if (!ast_strlen_zero(user->parkinglot)) 07737 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07738 if (user->amaflags) 07739 iaxs[callno]->amaflags = user->amaflags; 07740 if (!ast_strlen_zero(user->language)) 07741 ast_string_field_set(iaxs[callno], language, user->language); 07742 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07743 /* Keep this check last */ 07744 if (!ast_strlen_zero(user->dbsecret)) { 07745 char *family, *key=NULL; 07746 char buf[80]; 07747 family = ast_strdupa(user->dbsecret); 07748 key = strchr(family, '/'); 07749 if (key) { 07750 *key = '\0'; 07751 key++; 07752 } 07753 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07754 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07755 else 07756 ast_string_field_set(iaxs[callno], secret, buf); 07757 } else 07758 ast_string_field_set(iaxs[callno], secret, user->secret); 07759 res = 0; 07760 user = user_unref(user); 07761 } else { 07762 /* user was not found, but we should still fake an AUTHREQ. 07763 * Set authmethods to the last known authmethod used by the system 07764 * Set a fake secret, it's not looked at, just required to attempt authentication. 07765 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07766 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07767 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07768 iaxs[callno]->authrej = 1; 07769 if (!ast_strlen_zero(iaxs[callno]->username)) { 07770 /* only send the AUTHREQ if a username was specified. */ 07771 res = 0; 07772 } 07773 } 07774 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07775 return res; 07776 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 9427 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09428 { 09429 unsigned int ourver; 09430 char rsi[80]; 09431 snprintf(rsi, sizeof(rsi), "si-%s", si); 09432 if (iax_provision_version(&ourver, rsi, 1)) 09433 return 0; 09434 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09435 if (ourver != ver) 09436 iax2_provision(sin, sockfd, NULL, rsi, 1); 09437 return 0; 09438 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 12283 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
12284 { 12285 int sd; 12286 int res; 12287 12288 sd = socket(AF_INET, SOCK_DGRAM, 0); 12289 if (sd < 0) { 12290 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 12291 return -1; 12292 } 12293 12294 res = bind(sd, sa, salen); 12295 if (res < 0) { 12296 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 12297 close(sd); 12298 return 1; 12299 } 12300 12301 close(sd); 12302 return 0; 12303 }
static void cleanup_thread_list | ( | void * | head | ) | [static] |
Definition at line 14336 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().
14337 { 14338 AST_LIST_HEAD(iax2_thread_list, iax2_thread); 14339 struct iax2_thread_list *list_head = head; 14340 struct iax2_thread *thread; 14341 14342 AST_LIST_LOCK(list_head); 14343 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) { 14344 pthread_t thread_id = thread->threadid; 14345 14346 thread->stop = 1; 14347 signal_condition(&thread->lock, &thread->cond); 14348 14349 AST_LIST_UNLOCK(list_head); 14350 pthread_join(thread_id, NULL); 14351 AST_LIST_LOCK(list_head); 14352 } 14353 AST_LIST_UNLOCK(list_head); 14354 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8340 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().
08341 { 08342 char exten[256] = ""; 08343 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08344 struct iax2_dpcache *dp = NULL; 08345 08346 if (ies->called_number) 08347 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08348 08349 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08350 status = CACHE_FLAG_EXISTS; 08351 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08352 status = CACHE_FLAG_CANEXIST; 08353 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08354 status = CACHE_FLAG_NONEXISTENT; 08355 08356 if (ies->refresh) 08357 expiry = ies->refresh; 08358 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08359 matchmore = CACHE_FLAG_MATCHMORE; 08360 08361 AST_LIST_LOCK(&dpcache); 08362 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08363 if (strcmp(dp->exten, exten)) 08364 continue; 08365 AST_LIST_REMOVE_CURRENT(peer_list); 08366 dp->callno = 0; 08367 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08368 if (dp->flags & CACHE_FLAG_PENDING) { 08369 dp->flags &= ~CACHE_FLAG_PENDING; 08370 dp->flags |= status; 08371 dp->flags |= matchmore; 08372 } 08373 /* Wake up waiters */ 08374 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08375 if (dp->waiters[x] > -1) { 08376 if (write(dp->waiters[x], "asdf", 4) < 0) { 08377 } 08378 } 08379 } 08380 } 08381 AST_LIST_TRAVERSE_SAFE_END; 08382 AST_LIST_UNLOCK(&dpcache); 08383 08384 return 0; 08385 }
static char * complete_iax2_peers | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
uint64_t | flags | |||
) | [static] |
Definition at line 3828 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().
03829 { 03830 int which = 0; 03831 struct iax2_peer *peer; 03832 char *res = NULL; 03833 int wordlen = strlen(word); 03834 struct ao2_iterator i; 03835 03836 i = ao2_iterator_init(peers, 0); 03837 while ((peer = ao2_iterator_next(&i))) { 03838 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03839 && (!flags || ast_test_flag64(peer, flags))) { 03840 res = ast_strdup(peer->name); 03841 peer_unref(peer); 03842 break; 03843 } 03844 peer_unref(peer); 03845 } 03846 ao2_iterator_destroy(&i); 03847 03848 return res; 03849 }
static char * complete_iax2_unregister | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 6903 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().
06904 { 06905 int which = 0; 06906 struct iax2_peer *p = NULL; 06907 char *res = NULL; 06908 int wordlen = strlen(word); 06909 06910 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06911 if (pos == 2) { 06912 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06913 while ((p = ao2_iterator_next(&i))) { 06914 if (!strncasecmp(p->name, word, wordlen) && 06915 ++which > state && p->expire > 0) { 06916 res = ast_strdup(p->name); 06917 peer_unref(p); 06918 break; 06919 } 06920 peer_unref(p); 06921 } 06922 ao2_iterator_destroy(&i); 06923 } 06924 06925 return res; 06926 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8387 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().
08388 { 08389 int peercallno = 0; 08390 struct chan_iax2_pvt *pvt = iaxs[callno]; 08391 struct iax_frame *cur; 08392 jb_frame frame; 08393 08394 if (ies->callno) 08395 peercallno = ies->callno; 08396 08397 if (peercallno < 1) { 08398 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08399 return -1; 08400 } 08401 remove_by_transfercallno(pvt); 08402 /* since a transfer has taken place, the address will change. 08403 * This must be accounted for in the peercnts table. Remove 08404 * the old address and add the new one */ 08405 peercnt_remove_by_addr(&pvt->addr); 08406 peercnt_add(&pvt->transfer); 08407 /* now copy over the new address */ 08408 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08409 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08410 /* Reset sequence numbers */ 08411 pvt->oseqno = 0; 08412 pvt->rseqno = 0; 08413 pvt->iseqno = 0; 08414 pvt->aseqno = 0; 08415 08416 if (pvt->peercallno) { 08417 remove_by_peercallno(pvt); 08418 } 08419 pvt->peercallno = peercallno; 08420 /*this is where the transfering call swiches hash tables */ 08421 store_by_peercallno(pvt); 08422 pvt->transferring = TRANSFER_NONE; 08423 pvt->svoiceformat = -1; 08424 pvt->voiceformat = 0; 08425 pvt->svideoformat = -1; 08426 pvt->videoformat = 0; 08427 pvt->transfercallno = 0; 08428 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08429 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08430 /* reset jitterbuffer */ 08431 while(jb_getall(pvt->jb,&frame) == JB_OK) 08432 iax2_frame_free(frame.data); 08433 jb_reset(pvt->jb); 08434 pvt->lag = 0; 08435 pvt->last = 0; 08436 pvt->lastsent = 0; 08437 pvt->nextpred = 0; 08438 pvt->pingtime = DEFAULT_RETRY_TIME; 08439 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08440 /* We must cancel any packets that would have been transmitted 08441 because now we're talking to someone new. It's okay, they 08442 were transmitted to someone that didn't care anyway. */ 08443 cur->retries = -1; 08444 } 08445 return 0; 08446 }
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 9440 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().
09441 { 09442 jb_info stats; 09443 jb_getinfo(pvt->jb, &stats); 09444 09445 memset(iep, 0, sizeof(*iep)); 09446 09447 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09448 if(stats.frames_in == 0) stats.frames_in = 1; 09449 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09450 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09451 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09452 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09453 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09454 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 4567 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().
04568 { 04569 struct iax2_peer *peer; 04570 int res = -1; 04571 struct ast_codec_pref ourprefs; 04572 struct sockaddr_in peer_addr; 04573 04574 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04575 cai->sockfd = defaultsockfd; 04576 cai->maxtime = 0; 04577 sin->sin_family = AF_INET; 04578 04579 if (!(peer = find_peer(peername, 1))) { 04580 struct ast_sockaddr sin_tmp; 04581 04582 cai->found = 0; 04583 sin_tmp.ss.ss_family = AF_INET; 04584 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) { 04585 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04586 return -1; 04587 } 04588 ast_sockaddr_to_sin(&sin_tmp, sin); 04589 if (sin->sin_port == 0) { 04590 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04591 } 04592 /* use global iax prefs for unknown peer/user */ 04593 /* But move the calling channel's native codec to the top of the preference list */ 04594 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04595 if (c) 04596 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04597 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04598 return 0; 04599 } 04600 04601 cai->found = 1; 04602 04603 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 04604 04605 /* if the peer has no address (current or default), return failure */ 04606 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 04607 goto return_unref; 04608 } 04609 04610 /* if the peer is being monitored and is currently unreachable, return failure */ 04611 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04612 goto return_unref; 04613 04614 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04615 cai->maxtime = peer->maxms; 04616 cai->capability = peer->capability; 04617 cai->encmethods = peer->encmethods; 04618 cai->sockfd = peer->sockfd; 04619 cai->adsi = peer->adsi; 04620 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04621 /* Move the calling channel's native codec to the top of the preference list */ 04622 if (c) { 04623 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats); 04624 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04625 } 04626 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04627 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04628 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04629 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04630 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04631 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04632 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04633 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04634 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04635 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04636 if (ast_strlen_zero(peer->dbsecret)) { 04637 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04638 } else { 04639 char *family; 04640 char *key = NULL; 04641 04642 family = ast_strdupa(peer->dbsecret); 04643 key = strchr(family, '/'); 04644 if (key) 04645 *key++ = '\0'; 04646 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04647 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04648 goto return_unref; 04649 } 04650 } 04651 04652 if (peer_addr.sin_addr.s_addr) { 04653 sin->sin_addr = peer_addr.sin_addr; 04654 sin->sin_port = peer_addr.sin_port; 04655 } else { 04656 sin->sin_addr = peer->defaddr.sin_addr; 04657 sin->sin_port = peer->defaddr.sin_port; 04658 } 04659 04660 res = 0; 04661 04662 return_unref: 04663 peer_unref(peer); 04664 04665 return res; 04666 }
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 6257 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().
06258 { 06259 int padding; 06260 unsigned char *workspace; 06261 06262 workspace = ast_alloca(*datalen); 06263 memset(f, 0, sizeof(*f)); 06264 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06265 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06266 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06267 return -1; 06268 /* Decrypt */ 06269 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06270 06271 padding = 16 + (workspace[15] & 0x0f); 06272 if (iaxdebug) 06273 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 06274 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06275 return -1; 06276 06277 *datalen -= padding; 06278 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06279 f->frametype = fh->type; 06280 if (f->frametype == AST_FRAME_VIDEO) { 06281 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06282 } else if (f->frametype == AST_FRAME_VOICE) { 06283 f->subclass.codec = uncompress_subclass(fh->csub); 06284 } else { 06285 f->subclass.integer = uncompress_subclass(fh->csub); 06286 } 06287 } else { 06288 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06289 if (iaxdebug) 06290 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06291 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06292 return -1; 06293 /* Decrypt */ 06294 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06295 padding = 16 + (workspace[15] & 0x0f); 06296 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06297 return -1; 06298 *datalen -= padding; 06299 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06300 } 06301 return 0; 06302 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 6343 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().
06344 { 06345 int res=-1; 06346 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06347 /* Search for possible keys, given secrets */ 06348 struct MD5Context md5; 06349 unsigned char digest[16]; 06350 char *tmppw, *stringp; 06351 06352 tmppw = ast_strdupa(iaxs[callno]->secret); 06353 stringp = tmppw; 06354 while ((tmppw = strsep(&stringp, ";"))) { 06355 MD5Init(&md5); 06356 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06357 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06358 MD5Final(digest, &md5); 06359 build_encryption_keys(digest, iaxs[callno]); 06360 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06361 if (!res) { 06362 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06363 break; 06364 } 06365 } 06366 } else 06367 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06368 return res; 06369 }
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 9587 of file chan_iax2.c.
References ast_calloc, 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, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
09588 { 09589 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09590 struct ast_iax2_full_hdr *fh, *cur_fh; 09591 09592 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09593 return; 09594 09595 pkt_buf->len = from_here->buf_len; 09596 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09597 09598 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09599 ast_mutex_lock(&to_here->lock); 09600 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09601 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09602 if (fh->oseqno < cur_fh->oseqno) { 09603 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09604 break; 09605 } 09606 } 09607 AST_LIST_TRAVERSE_SAFE_END 09608 09609 if (!cur_pkt_buf) 09610 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09611 09612 ast_mutex_unlock(&to_here->lock); 09613 }
static void delete_users | ( | void | ) | [static] |
Definition at line 12970 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().
12971 { 12972 struct iax2_registry *reg; 12973 12974 ao2_callback(users, 0, user_delme_cb, NULL); 12975 12976 AST_LIST_LOCK(®istrations); 12977 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 12978 if (sched) { 12979 ast_sched_thread_del(sched, reg->expire); 12980 } 12981 if (reg->callno) { 12982 int callno = reg->callno; 12983 ast_mutex_lock(&iaxsl[callno]); 12984 if (iaxs[callno]) { 12985 iaxs[callno]->reg = NULL; 12986 iax2_destroy(callno); 12987 } 12988 ast_mutex_unlock(&iaxsl[callno]); 12989 } 12990 if (reg->dnsmgr) 12991 ast_dnsmgr_release(reg->dnsmgr); 12992 ast_free(reg); 12993 } 12994 AST_LIST_UNLOCK(®istrations); 12995 12996 ao2_callback(peers, 0, peer_delme_cb, NULL); 12997 }
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 9242 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().
09243 { 09244 unsigned short dpstatus = 0; 09245 struct iax_ie_data ied1; 09246 int mm; 09247 09248 memset(&ied1, 0, sizeof(ied1)); 09249 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 09250 /* Must be started */ 09251 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 09252 dpstatus = IAX_DPSTATUS_EXISTS; 09253 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 09254 dpstatus = IAX_DPSTATUS_CANEXIST; 09255 } else { 09256 dpstatus = IAX_DPSTATUS_NONEXISTENT; 09257 } 09258 if (ast_ignore_pattern(context, callednum)) 09259 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 09260 if (mm) 09261 dpstatus |= IAX_DPSTATUS_MATCHMORE; 09262 if (!skiplock) 09263 ast_mutex_lock(&iaxsl[callno]); 09264 if (iaxs[callno]) { 09265 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 09266 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 09267 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 09268 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 09269 } 09270 if (!skiplock) 09271 ast_mutex_unlock(&iaxsl[callno]); 09272 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 9274 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 6304 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().
06305 { 06306 int padding; 06307 unsigned char *workspace; 06308 workspace = ast_alloca(*datalen + 32); 06309 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06310 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06311 if (iaxdebug) 06312 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06313 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06314 padding = 16 + (padding & 0xf); 06315 memcpy(workspace, poo, padding); 06316 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06317 workspace[15] &= 0xf0; 06318 workspace[15] |= (padding & 0xf); 06319 if (iaxdebug) 06320 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 06321 *datalen += padding; 06322 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06323 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06324 memcpy(poo, workspace + *datalen - 32, 32); 06325 } else { 06326 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06327 if (iaxdebug) 06328 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06329 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06330 padding = 16 + (padding & 0xf); 06331 memcpy(workspace, poo, padding); 06332 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06333 workspace[15] &= 0xf0; 06334 workspace[15] |= (padding & 0x0f); 06335 *datalen += padding; 06336 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06337 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06338 memcpy(poo, workspace + *datalen - 32, 32); 06339 } 06340 return 0; 06341 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8655 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().
08656 { 08657 #ifdef SCHED_MULTITHREADED 08658 if (schedule_action(__expire_registry, data)) 08659 #endif 08660 __expire_registry(data); 08661 return 0; 08662 }
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 13670 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().
13671 { 13672 struct iax2_dpcache *dp = NULL; 13673 struct timeval now = ast_tvnow(); 13674 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13675 struct ast_channel *c = NULL; 13676 struct ast_frame *f = NULL; 13677 13678 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13679 if (ast_tvcmp(now, dp->expiry) > 0) { 13680 AST_LIST_REMOVE_CURRENT(cache_list); 13681 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13682 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13683 else 13684 ast_free(dp); 13685 continue; 13686 } 13687 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13688 break; 13689 } 13690 AST_LIST_TRAVERSE_SAFE_END; 13691 13692 if (!dp) { 13693 /* No matching entry. Create a new one. */ 13694 /* First, can we make a callno? */ 13695 if ((callno = cache_get_callno_locked(data)) < 0) { 13696 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13697 return NULL; 13698 } 13699 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13700 ast_mutex_unlock(&iaxsl[callno]); 13701 return NULL; 13702 } 13703 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13704 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13705 dp->expiry = ast_tvnow(); 13706 dp->orig = dp->expiry; 13707 /* Expires in 30 mins by default */ 13708 dp->expiry.tv_sec += iaxdefaultdpcache; 13709 dp->flags = CACHE_FLAG_PENDING; 13710 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13711 dp->waiters[x] = -1; 13712 /* Insert into the lists */ 13713 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13714 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13715 /* Send the request if we're already up */ 13716 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13717 iax2_dprequest(dp, callno); 13718 ast_mutex_unlock(&iaxsl[callno]); 13719 } 13720 13721 /* By here we must have a dp */ 13722 if (dp->flags & CACHE_FLAG_PENDING) { 13723 struct timeval start; 13724 int ms; 13725 /* Okay, here it starts to get nasty. We need a pipe now to wait 13726 for a reply to come back so long as it's pending */ 13727 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13728 /* Find an empty slot */ 13729 if (dp->waiters[x] < 0) 13730 break; 13731 } 13732 if (x >= ARRAY_LEN(dp->waiters)) { 13733 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13734 return NULL; 13735 } 13736 if (pipe(com)) { 13737 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13738 return NULL; 13739 } 13740 dp->waiters[x] = com[1]; 13741 /* Okay, now we wait */ 13742 timeout = iaxdefaulttimeout * 1000; 13743 /* Temporarily unlock */ 13744 AST_LIST_UNLOCK(&dpcache); 13745 /* Defer any dtmf */ 13746 if (chan) 13747 old = ast_channel_defer_dtmf(chan); 13748 doabort = 0; 13749 start = ast_tvnow(); 13750 while ((ms = ast_remaining_ms(start, timeout))) { 13751 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms); 13752 if (outfd > -1) 13753 break; 13754 if (!c) 13755 continue; 13756 if (!(f = ast_read(c))) { 13757 doabort = 1; 13758 break; 13759 } 13760 ast_frfree(f); 13761 } 13762 if (!ms) { 13763 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13764 } 13765 AST_LIST_LOCK(&dpcache); 13766 dp->waiters[x] = -1; 13767 close(com[1]); 13768 close(com[0]); 13769 if (doabort) { 13770 /* Don't interpret anything, just abort. Not sure what th epoint 13771 of undeferring dtmf on a hung up channel is but hey whatever */ 13772 if (!old && chan) 13773 ast_channel_undefer_dtmf(chan); 13774 return NULL; 13775 } 13776 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13777 /* Now to do non-independent analysis the results of our wait */ 13778 if (dp->flags & CACHE_FLAG_PENDING) { 13779 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13780 pending. Don't let it take as long to timeout. */ 13781 dp->flags &= ~CACHE_FLAG_PENDING; 13782 dp->flags |= CACHE_FLAG_TIMEOUT; 13783 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 13784 systems without leaving it unavailable once the server comes back online */ 13785 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 13786 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13787 if (dp->waiters[x] > -1) { 13788 if (write(dp->waiters[x], "asdf", 4) < 0) { 13789 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13790 } 13791 } 13792 } 13793 } 13794 } 13795 /* Our caller will obtain the rest */ 13796 if (!old && chan) 13797 ast_channel_undefer_dtmf(chan); 13798 } 13799 return dp; 13800 }
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 6076 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().
06077 { 06078 struct iax2_trunk_peer *tpeer = NULL; 06079 06080 /* Finds and locks trunk peer */ 06081 AST_LIST_LOCK(&tpeers); 06082 06083 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 06084 if (!inaddrcmp(&tpeer->addr, sin)) { 06085 ast_mutex_lock(&tpeer->lock); 06086 break; 06087 } 06088 } 06089 06090 if (!tpeer) { 06091 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 06092 ast_mutex_init(&tpeer->lock); 06093 tpeer->lastsent = 9999; 06094 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 06095 tpeer->trunkact = ast_tvnow(); 06096 ast_mutex_lock(&tpeer->lock); 06097 tpeer->sockfd = fd; 06098 #ifdef SO_NO_CHECK 06099 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 06100 #endif 06101 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06102 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 06103 } 06104 } 06105 06106 AST_LIST_UNLOCK(&tpeers); 06107 06108 return tpeer; 06109 }
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 5889 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05890 { 05891 long ms; /* NOT unsigned */ 05892 if (ast_tvzero(iaxs[callno]->rxcore)) { 05893 /* Initialize rxcore time if appropriate */ 05894 iaxs[callno]->rxcore = ast_tvnow(); 05895 /* Round to nearest 20ms so traces look pretty */ 05896 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05897 } 05898 /* Calculate difference between trunk and channel */ 05899 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05900 /* Return as the sum of trunk time and the difference between trunk and real time */ 05901 return ms + ts; 05902 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 12112 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
12113 { 12114 struct iax2_context *conl; 12115 while(con) { 12116 conl = con; 12117 con = con->next; 12118 ast_free(conl); 12119 } 12120 }
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 13923 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.
13924 { 13925 struct iax2_peer *peer; 13926 char *peername, *colname; 13927 13928 peername = ast_strdupa(data); 13929 13930 /* if our channel, return the IP address of the endpoint of current channel */ 13931 if (!strcmp(peername,"CURRENTCHANNEL")) { 13932 unsigned short callno; 13933 if (chan->tech != &iax2_tech) 13934 return -1; 13935 callno = PTR_TO_CALLNO(chan->tech_pvt); 13936 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 13937 return 0; 13938 } 13939 13940 if ((colname = strchr(peername, ','))) 13941 *colname++ = '\0'; 13942 else 13943 colname = "ip"; 13944 13945 if (!(peer = find_peer(peername, 1))) 13946 return -1; 13947 13948 if (!strcasecmp(colname, "ip")) { 13949 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 13950 } else if (!strcasecmp(colname, "status")) { 13951 peer_status(peer, buf, len); 13952 } else if (!strcasecmp(colname, "mailbox")) { 13953 ast_copy_string(buf, peer->mailbox, len); 13954 } else if (!strcasecmp(colname, "context")) { 13955 ast_copy_string(buf, peer->context, len); 13956 } else if (!strcasecmp(colname, "expire")) { 13957 snprintf(buf, len, "%d", peer->expire); 13958 } else if (!strcasecmp(colname, "dynamic")) { 13959 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 13960 } else if (!strcasecmp(colname, "callerid_name")) { 13961 ast_copy_string(buf, peer->cid_name, len); 13962 } else if (!strcasecmp(colname, "callerid_num")) { 13963 ast_copy_string(buf, peer->cid_num, len); 13964 } else if (!strcasecmp(colname, "codecs")) { 13965 ast_getformatname_multiple(buf, len -1, peer->capability); 13966 } else if (!strncasecmp(colname, "codec[", 6)) { 13967 char *codecnum, *ptr; 13968 int codec = 0; 13969 13970 /* skip over "codec" to the '[' */ 13971 codecnum = colname + 5; 13972 *codecnum = '\0'; 13973 codecnum++; 13974 if ((ptr = strchr(codecnum, ']'))) { 13975 *ptr = '\0'; 13976 } 13977 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 13978 ast_copy_string(buf, ast_getformatname(codec), len); 13979 } else { 13980 buf[0] = '\0'; 13981 } 13982 } else { 13983 buf[0] = '\0'; 13984 } 13985 13986 peer_unref(peer); 13987 13988 return 0; 13989 }
static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 12267 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
12268 { 12269 int methods = 0; 12270 if (strstr(value, "rsa")) 12271 methods |= IAX_AUTH_RSA; 12272 if (strstr(value, "md5")) 12273 methods |= IAX_AUTH_MD5; 12274 if (strstr(value, "plaintext")) 12275 methods |= IAX_AUTH_PLAINTEXT; 12276 return methods; 12277 }
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 4138 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
04139 { 04140 #ifdef SCHED_MULTITHREADED 04141 if (schedule_action(__get_from_jb, data)) 04142 #endif 04143 __get_from_jb(data); 04144 return 0; 04145 }
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 4876 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().
04878 { 04879 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04880 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04881 struct ast_str *buf = ast_str_alloca(256); 04882 time_t t = time(NULL); 04883 char hash[41]; /* 40 char sha1 hash */ 04884 int subclass = uncompress_subclass(fh->csub); 04885 04886 /* ----- Case 1 ----- */ 04887 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04888 struct iax_ie_data ied = { 04889 .buf = { 0 }, 04890 .pos = 0, 04891 }; 04892 04893 /* create the hash with their address data and our timestamp */ 04894 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04895 ast_sha1_hash(hash, ast_str_buffer(buf)); 04896 04897 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04898 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04899 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04900 04901 return 1; 04902 04903 /* ----- Case 2 ----- */ 04904 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04905 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04906 char *rec_ts = NULL; /* received timestamp */ 04907 unsigned int rec_time; /* received time_t */ 04908 04909 /* split the timestamp from the hash data */ 04910 rec_hash = strchr((char *) ies->calltokendata, '?'); 04911 if (rec_hash) { 04912 *rec_hash++ = '\0'; 04913 rec_ts = (char *) ies->calltokendata; 04914 } 04915 04916 /* check that we have valid data before we do any comparisons */ 04917 if (!rec_hash || !rec_ts) { 04918 goto reject; 04919 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04920 goto reject; 04921 } 04922 04923 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04924 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04925 ast_sha1_hash(hash, ast_str_buffer(buf)); 04926 04927 /* compare hashes and then check timestamp delay */ 04928 if (strcmp(hash, rec_hash)) { 04929 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04930 goto reject; /* received hash does not match ours, reject */ 04931 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04932 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04933 goto reject; /* too much delay, reject */ 04934 } 04935 04936 /* at this point the call token is valid, returning 0 04937 * will allow socket_process to continue as usual */ 04938 requirecalltoken_mark_auto(ies->username, subclass); 04939 return 0; 04940 04941 /* ----- Case 3 ----- */ 04942 } else { /* calltokens are not supported for this client, how do we respond? */ 04943 if (calltoken_required(sin, ies->username, subclass)) { 04944 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")); 04945 goto reject; 04946 } 04947 return 0; /* calltoken is not required for this addr, so permit it. */ 04948 } 04949 04950 reject: 04951 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04952 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04953 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04954 } else { 04955 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04956 } 04957 04958 return 1; 04959 }
static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 11959 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.
11960 { 11961 int force = 0; 11962 int res; 11963 11964 switch (cmd) { 11965 case CLI_INIT: 11966 e->command = "iax2 provision"; 11967 e->usage = 11968 "Usage: iax2 provision <host> <template> [forced]\n" 11969 " Provisions the given peer or IP address using a template\n" 11970 " matching either 'template' or '*' if the template is not\n" 11971 " found. If 'forced' is specified, even empty provisioning\n" 11972 " fields will be provisioned as empty fields.\n"; 11973 return NULL; 11974 case CLI_GENERATE: 11975 if (a->pos == 3) 11976 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 11977 return NULL; 11978 } 11979 11980 if (a->argc < 4) 11981 return CLI_SHOWUSAGE; 11982 if (a->argc > 4) { 11983 if (!strcasecmp(a->argv[4], "forced")) 11984 force = 1; 11985 else 11986 return CLI_SHOWUSAGE; 11987 } 11988 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 11989 if (res < 0) 11990 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 11991 else if (res < 1) 11992 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 11993 else 11994 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 11995 return CLI_SUCCESS; 11996 }
static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3570 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.
03571 { 03572 struct iax2_peer *peer = NULL; 03573 struct iax2_user *user = NULL; 03574 static const char * const choices[] = { "all", NULL }; 03575 char *cmplt; 03576 03577 switch (cmd) { 03578 case CLI_INIT: 03579 e->command = "iax2 prune realtime"; 03580 e->usage = 03581 "Usage: iax2 prune realtime [<peername>|all]\n" 03582 " Prunes object(s) from the cache\n"; 03583 return NULL; 03584 case CLI_GENERATE: 03585 if (a->pos == 3) { 03586 cmplt = ast_cli_complete(a->word, choices, a->n); 03587 if (!cmplt) 03588 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03589 return cmplt; 03590 } 03591 return NULL; 03592 } 03593 if (a->argc != 4) 03594 return CLI_SHOWUSAGE; 03595 if (!strcmp(a->argv[3], "all")) { 03596 prune_users(); 03597 prune_peers(); 03598 ast_cli(a->fd, "Cache flushed successfully.\n"); 03599 return CLI_SUCCESS; 03600 } 03601 peer = find_peer(a->argv[3], 0); 03602 user = find_user(a->argv[3]); 03603 if (peer || user) { 03604 if (peer) { 03605 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 03606 ast_set_flag64(peer, IAX_RTAUTOCLEAR); 03607 expire_registry(peer_ref(peer)); 03608 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03609 } else { 03610 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03611 } 03612 peer_unref(peer); 03613 } 03614 if (user) { 03615 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 03616 ast_set_flag64(user, IAX_RTAUTOCLEAR); 03617 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03618 } else { 03619 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03620 } 03621 ao2_unlink(users,user); 03622 user_unref(user); 03623 } 03624 } else { 03625 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03626 } 03627 03628 return CLI_SUCCESS; 03629 }
static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 13574 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
13575 { 13576 switch (cmd) { 13577 case CLI_INIT: 13578 e->command = "iax2 reload"; 13579 e->usage = 13580 "Usage: iax2 reload\n" 13581 " Reloads IAX configuration from iax.conf\n"; 13582 return NULL; 13583 case CLI_GENERATE: 13584 return NULL; 13585 } 13586 13587 reload_config(); 13588 13589 return CLI_SUCCESS; 13590 }
static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7347 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.
07348 { 07349 switch (cmd) { 07350 case CLI_INIT: 07351 e->command = "iax2 set debug {on|off|peer}"; 07352 e->usage = 07353 "Usage: iax2 set debug {on|off|peer peername}\n" 07354 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07355 return NULL; 07356 case CLI_GENERATE: 07357 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07358 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07359 return NULL; 07360 } 07361 07362 if (a->argc < e->args || a->argc > e->args + 1) 07363 return CLI_SHOWUSAGE; 07364 07365 if (!strcasecmp(a->argv[3], "peer")) { 07366 struct iax2_peer *peer; 07367 struct sockaddr_in peer_addr; 07368 07369 07370 if (a->argc != e->args + 1) 07371 return CLI_SHOWUSAGE; 07372 07373 peer = find_peer(a->argv[4], 1); 07374 07375 if (!peer) { 07376 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07377 return CLI_FAILURE; 07378 } 07379 07380 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 07381 07382 debugaddr.sin_addr = peer_addr.sin_addr; 07383 debugaddr.sin_port = peer_addr.sin_port; 07384 07385 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07386 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07387 07388 ao2_ref(peer, -1); 07389 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07390 iaxdebug = 1; 07391 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07392 } else { 07393 iaxdebug = 0; 07394 memset(&debugaddr, 0, sizeof(debugaddr)); 07395 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07396 } 07397 return CLI_SUCCESS; 07398 }
static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7426 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.
07427 { 07428 switch (cmd) { 07429 case CLI_INIT: 07430 e->command = "iax2 set debug jb {on|off}"; 07431 e->usage = 07432 "Usage: iax2 set debug jb {on|off}\n" 07433 " Enables/Disables jitterbuffer debugging information\n"; 07434 return NULL; 07435 case CLI_GENERATE: 07436 return NULL; 07437 } 07438 07439 if (a->argc != e->args) 07440 return CLI_SHOWUSAGE; 07441 07442 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07443 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07444 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07445 } else { 07446 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07447 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07448 } 07449 return CLI_SUCCESS; 07450 }
static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7400 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.
07401 { 07402 switch (cmd) { 07403 case CLI_INIT: 07404 e->command = "iax2 set debug trunk {on|off}"; 07405 e->usage = 07406 "Usage: iax2 set debug trunk {on|off}\n" 07407 " Enables/Disables debugging of IAX trunking\n"; 07408 return NULL; 07409 case CLI_GENERATE: 07410 return NULL; 07411 } 07412 07413 if (a->argc != e->args) 07414 return CLI_SHOWUSAGE; 07415 07416 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07417 iaxtrunkdebug = 1; 07418 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07419 } else { 07420 iaxtrunkdebug = 0; 07421 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07422 } 07423 return CLI_SUCCESS; 07424 }
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 3897 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.
03898 { 03899 int mtuv; 03900 03901 switch (cmd) { 03902 case CLI_INIT: 03903 e->command = "iax2 set mtu"; 03904 e->usage = 03905 "Usage: iax2 set mtu <value>\n" 03906 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03907 " zero to disable. Disabling means that the operating system\n" 03908 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03909 " packet exceeds the UDP payload size. This is substantially\n" 03910 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03911 " greater for G.711 samples.\n"; 03912 return NULL; 03913 case CLI_GENERATE: 03914 return NULL; 03915 } 03916 03917 if (a->argc != 4) 03918 return CLI_SHOWUSAGE; 03919 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03920 mtuv = MAX_TRUNK_MTU; 03921 else 03922 mtuv = atoi(a->argv[3]); 03923 03924 if (mtuv == 0) { 03925 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03926 global_max_trunk_mtu = 0; 03927 return CLI_SUCCESS; 03928 } 03929 if (mtuv < 172 || mtuv > 4000) { 03930 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03931 return CLI_SHOWUSAGE; 03932 } 03933 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03934 global_max_trunk_mtu = mtuv; 03935 return CLI_SUCCESS; 03936 }
static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3938 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.
03939 { 03940 struct iax2_dpcache *dp = NULL; 03941 char tmp[1024], *pc = NULL; 03942 int s, x, y; 03943 struct timeval now = ast_tvnow(); 03944 03945 switch (cmd) { 03946 case CLI_INIT: 03947 e->command = "iax2 show cache"; 03948 e->usage = 03949 "Usage: iax2 show cache\n" 03950 " Display currently cached IAX Dialplan results.\n"; 03951 return NULL; 03952 case CLI_GENERATE: 03953 return NULL; 03954 } 03955 03956 AST_LIST_LOCK(&dpcache); 03957 03958 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03959 03960 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 03961 s = dp->expiry.tv_sec - now.tv_sec; 03962 tmp[0] = '\0'; 03963 if (dp->flags & CACHE_FLAG_EXISTS) 03964 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03965 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03966 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03967 if (dp->flags & CACHE_FLAG_CANEXIST) 03968 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03969 if (dp->flags & CACHE_FLAG_PENDING) 03970 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03971 if (dp->flags & CACHE_FLAG_TIMEOUT) 03972 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03973 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03974 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03975 if (dp->flags & CACHE_FLAG_MATCHMORE) 03976 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03977 if (dp->flags & CACHE_FLAG_UNKNOWN) 03978 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03979 /* Trim trailing pipe */ 03980 if (!ast_strlen_zero(tmp)) { 03981 tmp[strlen(tmp) - 1] = '\0'; 03982 } else { 03983 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03984 } 03985 y = 0; 03986 pc = strchr(dp->peercontext, '@'); 03987 if (!pc) { 03988 pc = dp->peercontext; 03989 } else { 03990 pc++; 03991 } 03992 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 03993 if (dp->waiters[x] > -1) 03994 y++; 03995 } 03996 if (s > 0) { 03997 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03998 } else { 03999 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 04000 } 04001 } 04002 04003 AST_LIST_UNLOCK(&dpcache); 04004 04005 return CLI_SUCCESS; 04006 }
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 7174 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.
07175 { 07176 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 07177 #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" 07178 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 07179 int x; 07180 int numchans = 0; 07181 char first_message[10] = { 0, }; 07182 char last_message[10] = { 0, }; 07183 07184 switch (cmd) { 07185 case CLI_INIT: 07186 e->command = "iax2 show channels"; 07187 e->usage = 07188 "Usage: iax2 show channels\n" 07189 " Lists all currently active IAX channels.\n"; 07190 return NULL; 07191 case CLI_GENERATE: 07192 return NULL; 07193 } 07194 07195 if (a->argc != 3) 07196 return CLI_SHOWUSAGE; 07197 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 07198 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07199 ast_mutex_lock(&iaxsl[x]); 07200 if (iaxs[x]) { 07201 int lag, jitter, localdelay; 07202 jb_info jbinfo; 07203 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07204 jb_getinfo(iaxs[x]->jb, &jbinfo); 07205 jitter = jbinfo.jitter; 07206 localdelay = jbinfo.current - jbinfo.min; 07207 } else { 07208 jitter = -1; 07209 localdelay = 0; 07210 } 07211 07212 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07213 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07214 lag = iaxs[x]->remote_rr.delay; 07215 ast_cli(a->fd, FORMAT, 07216 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07217 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 07218 S_OR(iaxs[x]->username, "(None)"), 07219 iaxs[x]->callno, iaxs[x]->peercallno, 07220 iaxs[x]->oseqno, iaxs[x]->iseqno, 07221 lag, 07222 jitter, 07223 localdelay, 07224 ast_getformatname(iaxs[x]->voiceformat), 07225 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07226 first_message, 07227 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07228 last_message); 07229 numchans++; 07230 } 07231 ast_mutex_unlock(&iaxsl[x]); 07232 } 07233 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07234 return CLI_SUCCESS; 07235 #undef FORMAT 07236 #undef FORMAT2 07237 #undef FORMATB 07238 }
static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6960 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.
06961 { 06962 struct iax_firmware *cur = NULL; 06963 06964 switch (cmd) { 06965 case CLI_INIT: 06966 e->command = "iax2 show firmware"; 06967 e->usage = 06968 "Usage: iax2 show firmware\n" 06969 " Lists all known IAX firmware images.\n"; 06970 return NULL; 06971 case CLI_GENERATE: 06972 return NULL; 06973 } 06974 06975 if (a->argc != 3 && a->argc != 4) 06976 return CLI_SHOWUSAGE; 06977 06978 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 06979 AST_LIST_LOCK(&firmwares); 06980 AST_LIST_TRAVERSE(&firmwares, cur, list) { 06981 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 06982 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 06983 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 06984 } 06985 } 06986 AST_LIST_UNLOCK(&firmwares); 06987 06988 return CLI_SUCCESS; 06989 }
static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7324 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.
07325 { 07326 int numchans = 0; 07327 07328 switch (cmd) { 07329 case CLI_INIT: 07330 e->command = "iax2 show netstats"; 07331 e->usage = 07332 "Usage: iax2 show netstats\n" 07333 " Lists network status for all currently active IAX channels.\n"; 07334 return NULL; 07335 case CLI_GENERATE: 07336 return NULL; 07337 } 07338 if (a->argc != 3) 07339 return CLI_SHOWUSAGE; 07340 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 07341 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 07342 numchans = ast_cli_netstats(NULL, a->fd, 1); 07343 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07344 return CLI_SUCCESS; 07345 }
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 3745 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.
03746 { 03747 char status[30]; 03748 char cbuf[256]; 03749 struct iax2_peer *peer; 03750 char codec_buf[512]; 03751 struct ast_str *encmethods = ast_str_alloca(256); 03752 int x = 0, codec = 0, load_realtime = 0; 03753 03754 switch (cmd) { 03755 case CLI_INIT: 03756 e->command = "iax2 show peer"; 03757 e->usage = 03758 "Usage: iax2 show peer <name>\n" 03759 " Display details on specific IAX peer\n"; 03760 return NULL; 03761 case CLI_GENERATE: 03762 if (a->pos == 3) 03763 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03764 return NULL; 03765 } 03766 03767 if (a->argc < 4) 03768 return CLI_SHOWUSAGE; 03769 03770 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03771 03772 peer = find_peer(a->argv[3], load_realtime); 03773 if (peer) { 03774 struct sockaddr_in peer_addr; 03775 03776 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 03777 03778 encmethods_to_str(peer->encmethods, &encmethods); 03779 ast_cli(a->fd, "\n\n"); 03780 ast_cli(a->fd, " * Name : %s\n", peer->name); 03781 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03782 ast_cli(a->fd, " Context : %s\n", peer->context); 03783 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03784 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03785 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03786 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03787 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03788 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 03789 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03790 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03791 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03792 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03793 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)); 03794 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03795 ast_cli(a->fd, " Username : %s\n", peer->username); 03796 ast_cli(a->fd, " Codecs : "); 03797 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03798 ast_cli(a->fd, "%s\n", codec_buf); 03799 03800 ast_cli(a->fd, " Codec Order : ("); 03801 for(x = 0; x < 32 ; x++) { 03802 codec = ast_codec_pref_index(&peer->prefs,x); 03803 if(!codec) 03804 break; 03805 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03806 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03807 ast_cli(a->fd, "|"); 03808 } 03809 03810 if (!x) 03811 ast_cli(a->fd, "none"); 03812 ast_cli(a->fd, ")\n"); 03813 03814 ast_cli(a->fd, " Status : "); 03815 peer_status(peer, status, sizeof(status)); 03816 ast_cli(a->fd, "%s\n",status); 03817 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"); 03818 ast_cli(a->fd, "\n"); 03819 peer_unref(peer); 03820 } else { 03821 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03822 ast_cli(a->fd, "\n"); 03823 } 03824 03825 return CLI_SUCCESS; 03826 }
static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6928 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.
06929 { 06930 switch (cmd) { 06931 case CLI_INIT: 06932 e->command = "iax2 show peers"; 06933 e->usage = 06934 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06935 " Lists all known IAX2 peers.\n" 06936 " Optional 'registered' argument lists only peers with known addresses.\n" 06937 " Optional regular expression pattern is used to filter the peer list.\n"; 06938 return NULL; 06939 case CLI_GENERATE: 06940 return NULL; 06941 } 06942 06943 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) { 06944 case RESULT_SHOWUSAGE: 06945 return CLI_SHOWUSAGE; 06946 case RESULT_FAILURE: 06947 return CLI_FAILURE; 06948 default: 06949 return CLI_SUCCESS; 06950 } 06951 }
static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7083 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.
07084 { 07085 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 07086 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 07087 struct iax2_registry *reg = NULL; 07088 char host[80]; 07089 char perceived[80]; 07090 int counter = 0; 07091 07092 switch (cmd) { 07093 case CLI_INIT: 07094 e->command = "iax2 show registry"; 07095 e->usage = 07096 "Usage: iax2 show registry\n" 07097 " Lists all registration requests and status.\n"; 07098 return NULL; 07099 case CLI_GENERATE: 07100 return NULL; 07101 } 07102 if (a->argc != 3) 07103 return CLI_SHOWUSAGE; 07104 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 07105 AST_LIST_LOCK(®istrations); 07106 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07107 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07108 if (reg->us.sin_addr.s_addr) 07109 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07110 else 07111 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07112 ast_cli(a->fd, FORMAT, host, 07113 (reg->dnsmgr) ? "Y" : "N", 07114 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 07115 counter++; 07116 } 07117 AST_LIST_UNLOCK(®istrations); 07118 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 07119 return CLI_SUCCESS; 07120 #undef FORMAT 07121 #undef FORMAT2 07122 }
static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3851 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.
03852 { 03853 struct iax_frame *cur; 03854 int cnt = 0, dead = 0, final = 0, i = 0; 03855 03856 switch (cmd) { 03857 case CLI_INIT: 03858 e->command = "iax2 show stats"; 03859 e->usage = 03860 "Usage: iax2 show stats\n" 03861 " Display statistics on IAX channel driver.\n"; 03862 return NULL; 03863 case CLI_GENERATE: 03864 return NULL; 03865 } 03866 03867 if (a->argc != 3) 03868 return CLI_SHOWUSAGE; 03869 03870 for (i = 0; i < ARRAY_LEN(frame_queue); i++) { 03871 ast_mutex_lock(&iaxsl[i]); 03872 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) { 03873 if (cur->retries < 0) 03874 dead++; 03875 if (cur->final) 03876 final++; 03877 cnt++; 03878 } 03879 ast_mutex_unlock(&iaxsl[i]); 03880 } 03881 03882 ast_cli(a->fd, " IAX Statistics\n"); 03883 ast_cli(a->fd, "---------------------\n"); 03884 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03885 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03886 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03887 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03888 03889 trunk_timed = trunk_untimed = 0; 03890 if (trunk_maxmtu > trunk_nmaxmtu) 03891 trunk_nmaxmtu = trunk_maxmtu; 03892 03893 return CLI_SUCCESS; 03894 }
static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6790 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.
06791 { 06792 struct iax2_thread *thread = NULL; 06793 time_t t; 06794 int threadcount = 0, dynamiccount = 0; 06795 char type; 06796 06797 switch (cmd) { 06798 case CLI_INIT: 06799 e->command = "iax2 show threads"; 06800 e->usage = 06801 "Usage: iax2 show threads\n" 06802 " Lists status of IAX helper threads\n"; 06803 return NULL; 06804 case CLI_GENERATE: 06805 return NULL; 06806 } 06807 if (a->argc != 3) 06808 return CLI_SHOWUSAGE; 06809 06810 ast_cli(a->fd, "IAX2 Thread Information\n"); 06811 time(&t); 06812 ast_cli(a->fd, "Idle Threads:\n"); 06813 AST_LIST_LOCK(&idle_list); 06814 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06815 #ifdef DEBUG_SCHED_MULTITHREAD 06816 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06817 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06818 #else 06819 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06820 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06821 #endif 06822 threadcount++; 06823 } 06824 AST_LIST_UNLOCK(&idle_list); 06825 ast_cli(a->fd, "Active Threads:\n"); 06826 AST_LIST_LOCK(&active_list); 06827 AST_LIST_TRAVERSE(&active_list, thread, list) { 06828 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06829 type = 'D'; 06830 else 06831 type = 'P'; 06832 #ifdef DEBUG_SCHED_MULTITHREAD 06833 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06834 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06835 #else 06836 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06837 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06838 #endif 06839 threadcount++; 06840 } 06841 AST_LIST_UNLOCK(&active_list); 06842 ast_cli(a->fd, "Dynamic Threads:\n"); 06843 AST_LIST_LOCK(&dynamic_list); 06844 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06845 #ifdef DEBUG_SCHED_MULTITHREAD 06846 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06847 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06848 #else 06849 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06850 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06851 #endif 06852 dynamiccount++; 06853 } 06854 AST_LIST_UNLOCK(&dynamic_list); 06855 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06856 return CLI_SUCCESS; 06857 }
static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6581 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().
06582 { 06583 regex_t regexbuf; 06584 int havepattern = 0; 06585 06586 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06587 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06588 06589 struct iax2_user *user = NULL; 06590 char auth[90]; 06591 char *pstr = ""; 06592 struct ao2_iterator i; 06593 06594 switch (cmd) { 06595 case CLI_INIT: 06596 e->command = "iax2 show users [like]"; 06597 e->usage = 06598 "Usage: iax2 show users [like <pattern>]\n" 06599 " Lists all known IAX2 users.\n" 06600 " Optional regular expression pattern is used to filter the user list.\n"; 06601 return NULL; 06602 case CLI_GENERATE: 06603 return NULL; 06604 } 06605 06606 switch (a->argc) { 06607 case 5: 06608 if (!strcasecmp(a->argv[3], "like")) { 06609 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06610 return CLI_SHOWUSAGE; 06611 havepattern = 1; 06612 } else 06613 return CLI_SHOWUSAGE; 06614 case 3: 06615 break; 06616 default: 06617 return CLI_SHOWUSAGE; 06618 } 06619 06620 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06621 i = ao2_iterator_init(users, 0); 06622 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 06623 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06624 continue; 06625 06626 if (!ast_strlen_zero(user->secret)) { 06627 ast_copy_string(auth,user->secret, sizeof(auth)); 06628 } else if (!ast_strlen_zero(user->inkeys)) { 06629 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06630 } else 06631 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06632 06633 if(ast_test_flag64(user, IAX_CODEC_NOCAP)) 06634 pstr = "REQ Only"; 06635 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS)) 06636 pstr = "Disabled"; 06637 else 06638 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06639 06640 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06641 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06642 user->ha ? "Yes" : "No", pstr); 06643 } 06644 ao2_iterator_destroy(&i); 06645 06646 if (havepattern) 06647 regfree(®exbuf); 06648 06649 return CLI_SUCCESS; 06650 #undef FORMAT 06651 #undef FORMAT2 06652 }
static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3631 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.
03632 { 03633 switch (cmd) { 03634 case CLI_INIT: 03635 e->command = "iax2 test losspct"; 03636 e->usage = 03637 "Usage: iax2 test losspct <percentage>\n" 03638 " For testing, throws away <percentage> percent of incoming packets\n"; 03639 return NULL; 03640 case CLI_GENERATE: 03641 return NULL; 03642 } 03643 if (a->argc != 4) 03644 return CLI_SHOWUSAGE; 03645 03646 test_losspct = atoi(a->argv[3]); 03647 03648 return CLI_SUCCESS; 03649 }
static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6859 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.
06860 { 06861 struct iax2_peer *p; 06862 06863 switch (cmd) { 06864 case CLI_INIT: 06865 e->command = "iax2 unregister"; 06866 e->usage = 06867 "Usage: iax2 unregister <peername>\n" 06868 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06869 return NULL; 06870 case CLI_GENERATE: 06871 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06872 } 06873 06874 if (a->argc != 3) 06875 return CLI_SHOWUSAGE; 06876 06877 p = find_peer(a->argv[2], 1); 06878 if (p) { 06879 if (p->expire > 0) { 06880 struct iax2_peer tmp_peer = { 06881 .name = a->argv[2], 06882 }; 06883 struct iax2_peer *peer; 06884 06885 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06886 if (peer) { 06887 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06888 peer_unref(peer); /* ref from ao2_find() */ 06889 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06890 } else { 06891 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06892 } 06893 } else { 06894 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06895 } 06896 peer_unref(p); 06897 } else { 06898 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06899 } 06900 return CLI_SUCCESS; 06901 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9557 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().
09558 { 09559 struct iax2_pkt_buf *pkt_buf; 09560 09561 ast_mutex_lock(&thread->lock); 09562 09563 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09564 ast_mutex_unlock(&thread->lock); 09565 09566 thread->buf = pkt_buf->buf; 09567 thread->buf_len = pkt_buf->len; 09568 thread->buf_size = pkt_buf->len + 1; 09569 09570 socket_process(thread); 09571 09572 thread->buf = NULL; 09573 ast_free(pkt_buf); 09574 09575 ast_mutex_lock(&thread->lock); 09576 } 09577 09578 ast_mutex_unlock(&thread->lock); 09579 }
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 8449 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().
08450 { 08451 struct iax2_registry *reg; 08452 /* Start pessimistic */ 08453 char peer[256] = ""; 08454 char msgstatus[60]; 08455 int refresh = 60; 08456 char ourip[256] = "<Unspecified>"; 08457 struct sockaddr_in oldus; 08458 struct sockaddr_in us; 08459 int oldmsgs; 08460 struct sockaddr_in reg_addr; 08461 08462 memset(&us, 0, sizeof(us)); 08463 if (ies->apparent_addr) { 08464 memmove(&us, ies->apparent_addr, sizeof(us)); 08465 } 08466 if (ies->username) { 08467 ast_copy_string(peer, ies->username, sizeof(peer)); 08468 } 08469 if (ies->refresh) { 08470 refresh = ies->refresh; 08471 } 08472 if (ies->calling_number) { 08473 /* We don't do anything with it really, but maybe we should */ 08474 } 08475 reg = iaxs[callno]->reg; 08476 if (!reg) { 08477 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08478 return -1; 08479 } 08480 memcpy(&oldus, ®->us, sizeof(oldus)); 08481 oldmsgs = reg->messages; 08482 ast_sockaddr_to_sin(®->addr, ®_addr); 08483 if (inaddrcmp(®_addr, sin)) { 08484 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08485 return -1; 08486 } 08487 memcpy(®->us, &us, sizeof(reg->us)); 08488 if (ies->msgcount >= 0) { 08489 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08490 } 08491 /* always refresh the registration at the interval requested by the server 08492 we are registering to 08493 */ 08494 reg->refresh = refresh; 08495 reg->expire = iax2_sched_replace(reg->expire, sched, 08496 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08497 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08498 if (reg->messages > 255) { 08499 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08500 } else if (reg->messages > 1) { 08501 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages); 08502 } else if (reg->messages > 0) { 08503 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus)); 08504 } else { 08505 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus)); 08506 } 08507 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08508 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08509 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08510 } 08511 reg->regstate = REG_STATE_REGISTERED; 08512 return 0; 08513 }
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 5631 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.
05632 { 05633 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05634 ast_debug(1, "Answering IAX2 call\n"); 05635 ast_mutex_lock(&iaxsl[callno]); 05636 if (iaxs[callno]) 05637 iax2_ami_channelupdate(iaxs[callno]); 05638 ast_mutex_unlock(&iaxsl[callno]); 05639 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05640 }
static int iax2_append_register | ( | const char * | hostname, | |
const char * | username, | |||
const char * | secret, | |||
const char * | porta | |||
) | [static] |
Definition at line 8515 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().
08517 { 08518 struct iax2_registry *reg; 08519 08520 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08521 return -1; 08522 08523 reg->addr.ss.ss_family = AF_INET; 08524 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08525 ast_free(reg); 08526 return -1; 08527 } 08528 08529 ast_copy_string(reg->username, username, sizeof(reg->username)); 08530 08531 if (secret) 08532 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08533 08534 reg->expire = -1; 08535 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08536 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); 08537 08538 AST_LIST_LOCK(®istrations); 08539 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08540 AST_LIST_UNLOCK(®istrations); 08541 08542 return 0; 08543 }
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 5471 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_SRCUPDATE, 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().
05472 { 05473 struct ast_channel *cs[3]; 05474 struct ast_channel *who, *other; 05475 int to = -1; 05476 int res = -1; 05477 int transferstarted=0; 05478 struct ast_frame *f; 05479 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05480 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05481 struct timeval waittimer = {0, 0}; 05482 05483 /* We currently do not support native bridging if a timeoutms value has been provided */ 05484 if (timeoutms > 0) { 05485 return AST_BRIDGE_FAILED; 05486 } 05487 05488 timeoutms = -1; 05489 05490 lock_both(callno0, callno1); 05491 if (!iaxs[callno0] || !iaxs[callno1]) { 05492 unlock_both(callno0, callno1); 05493 return AST_BRIDGE_FAILED; 05494 } 05495 /* Put them in native bridge mode */ 05496 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05497 iaxs[callno0]->bridgecallno = callno1; 05498 iaxs[callno1]->bridgecallno = callno0; 05499 } 05500 unlock_both(callno0, callno1); 05501 05502 /* If not, try to bridge until we can execute a transfer, if we can */ 05503 cs[0] = c0; 05504 cs[1] = c1; 05505 for (/* ever */;;) { 05506 /* Check in case we got masqueraded into */ 05507 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05508 ast_verb(3, "Can't masquerade, we're different...\n"); 05509 /* Remove from native mode */ 05510 if (c0->tech == &iax2_tech) { 05511 ast_mutex_lock(&iaxsl[callno0]); 05512 iaxs[callno0]->bridgecallno = 0; 05513 ast_mutex_unlock(&iaxsl[callno0]); 05514 } 05515 if (c1->tech == &iax2_tech) { 05516 ast_mutex_lock(&iaxsl[callno1]); 05517 iaxs[callno1]->bridgecallno = 0; 05518 ast_mutex_unlock(&iaxsl[callno1]); 05519 } 05520 return AST_BRIDGE_FAILED_NOWARN; 05521 } 05522 if (c0->nativeformats != c1->nativeformats) { 05523 char buf0[256]; 05524 char buf1[256]; 05525 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats); 05526 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats); 05527 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1); 05528 /* Remove from native mode */ 05529 lock_both(callno0, callno1); 05530 if (iaxs[callno0]) 05531 iaxs[callno0]->bridgecallno = 0; 05532 if (iaxs[callno1]) 05533 iaxs[callno1]->bridgecallno = 0; 05534 unlock_both(callno0, callno1); 05535 return AST_BRIDGE_FAILED_NOWARN; 05536 } 05537 /* check if transfered and if we really want native bridging */ 05538 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) { 05539 /* Try the transfer */ 05540 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05541 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA))) 05542 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05543 transferstarted = 1; 05544 } 05545 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05546 /* Call has been transferred. We're no longer involved */ 05547 struct timeval now = ast_tvnow(); 05548 if (ast_tvzero(waittimer)) { 05549 waittimer = now; 05550 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05551 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05552 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05553 *fo = NULL; 05554 *rc = c0; 05555 res = AST_BRIDGE_COMPLETE; 05556 break; 05557 } 05558 } 05559 to = 1000; 05560 who = ast_waitfor_n(cs, 2, &to); 05561 /* XXX This will need to be updated to calculate 05562 * timeout correctly once timeoutms is allowed to be 05563 * > 0. Right now, this can go badly if the waitfor 05564 * times out in less than a millisecond 05565 */ 05566 if (timeoutms > -1) { 05567 timeoutms -= (1000 - to); 05568 if (timeoutms < 0) 05569 timeoutms = 0; 05570 } 05571 if (!who) { 05572 if (!timeoutms) { 05573 res = AST_BRIDGE_RETRY; 05574 break; 05575 } 05576 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05577 res = AST_BRIDGE_FAILED; 05578 break; 05579 } 05580 continue; 05581 } 05582 f = ast_read(who); 05583 if (!f) { 05584 *fo = NULL; 05585 *rc = who; 05586 res = AST_BRIDGE_COMPLETE; 05587 break; 05588 } 05589 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) { 05590 *fo = f; 05591 *rc = who; 05592 res = AST_BRIDGE_COMPLETE; 05593 break; 05594 } 05595 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05596 if ((f->frametype == AST_FRAME_VOICE) || 05597 (f->frametype == AST_FRAME_TEXT) || 05598 (f->frametype == AST_FRAME_VIDEO) || 05599 (f->frametype == AST_FRAME_IMAGE) || 05600 (f->frametype == AST_FRAME_DTMF) || 05601 (f->frametype == AST_FRAME_CONTROL)) { 05602 /* monitored dtmf take out of the bridge. 05603 * check if we monitor the specific source. 05604 */ 05605 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05606 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 05607 *rc = who; 05608 *fo = f; 05609 res = AST_BRIDGE_COMPLETE; 05610 /* Remove from native mode */ 05611 break; 05612 } 05613 /* everything else goes to the other side */ 05614 ast_write(other, f); 05615 } 05616 ast_frfree(f); 05617 /* Swap who gets priority */ 05618 cs[2] = cs[0]; 05619 cs[0] = cs[1]; 05620 cs[1] = cs[2]; 05621 } 05622 lock_both(callno0, callno1); 05623 if(iaxs[callno0]) 05624 iaxs[callno0]->bridgecallno = 0; 05625 if(iaxs[callno1]) 05626 iaxs[callno1]->bridgecallno = 0; 05627 unlock_both(callno0, callno1); 05628 return res; 05629 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 5019 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.
05020 { 05021 struct sockaddr_in sin; 05022 char *l=NULL, *n=NULL, *tmpstr; 05023 struct iax_ie_data ied; 05024 char *defaultrdest = "s"; 05025 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05026 struct parsed_dial_string pds; 05027 struct create_addr_info cai; 05028 struct ast_var_t *var; 05029 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 05030 const char* osp_token_ptr; 05031 unsigned int osp_token_length; 05032 unsigned char osp_block_index; 05033 unsigned int osp_block_length; 05034 unsigned char osp_buffer[256]; 05035 05036 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 05037 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 05038 return -1; 05039 } 05040 05041 memset(&cai, 0, sizeof(cai)); 05042 cai.encmethods = iax2_encryption; 05043 05044 memset(&pds, 0, sizeof(pds)); 05045 tmpstr = ast_strdupa(dest); 05046 parse_dial_string(tmpstr, &pds); 05047 05048 if (ast_strlen_zero(pds.peer)) { 05049 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 05050 return -1; 05051 } 05052 if (!pds.exten) { 05053 pds.exten = defaultrdest; 05054 } 05055 if (create_addr(pds.peer, c, &sin, &cai)) { 05056 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 05057 return -1; 05058 } 05059 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) { 05060 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n"); 05061 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05062 return -1; 05063 } 05064 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 05065 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 05066 return -1; 05067 } 05068 if (!pds.username && !ast_strlen_zero(cai.username)) 05069 pds.username = cai.username; 05070 if (!pds.password && !ast_strlen_zero(cai.secret)) 05071 pds.password = cai.secret; 05072 if (!pds.key && !ast_strlen_zero(cai.outkey)) 05073 pds.key = cai.outkey; 05074 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 05075 pds.context = cai.peercontext; 05076 05077 /* Keep track of the context for outgoing calls too */ 05078 ast_copy_string(c->context, cai.context, sizeof(c->context)); 05079 05080 if (pds.port) 05081 sin.sin_port = htons(atoi(pds.port)); 05082 05083 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL; 05084 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL; 05085 05086 /* Now build request */ 05087 memset(&ied, 0, sizeof(ied)); 05088 05089 /* On new call, first IE MUST be IAX version of caller */ 05090 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 05091 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 05092 if (pds.options && strchr(pds.options, 'a')) { 05093 /* Request auto answer */ 05094 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 05095 } 05096 05097 /* WARNING: this breaks down at 190 bits! */ 05098 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 05099 05100 if (l) { 05101 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 05102 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05103 ast_party_id_presentation(&c->connected.id)); 05104 } else if (n) { 05105 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05106 ast_party_id_presentation(&c->connected.id)); 05107 } else { 05108 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 05109 } 05110 05111 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan); 05112 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select); 05113 05114 if (n) 05115 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 05116 if (ast_test_flag64(iaxs[callno], IAX_SENDANI) 05117 && c->connected.ani.number.valid 05118 && c->connected.ani.number.str) { 05119 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str); 05120 } 05121 05122 if (!ast_strlen_zero(c->language)) 05123 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 05124 if (!ast_strlen_zero(c->dialed.number.str)) { 05125 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str); 05126 } 05127 if (c->redirecting.from.number.valid 05128 && !ast_strlen_zero(c->redirecting.from.number.str)) { 05129 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str); 05130 } 05131 05132 if (pds.context) 05133 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 05134 05135 if (pds.username) 05136 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 05137 05138 if (cai.encmethods) 05139 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 05140 05141 ast_mutex_lock(&iaxsl[callno]); 05142 05143 if (!ast_strlen_zero(c->context)) 05144 ast_string_field_set(iaxs[callno], context, c->context); 05145 05146 if (pds.username) 05147 ast_string_field_set(iaxs[callno], username, pds.username); 05148 05149 iaxs[callno]->encmethods = cai.encmethods; 05150 05151 iaxs[callno]->adsi = cai.adsi; 05152 05153 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 05154 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 05155 05156 if (pds.key) 05157 ast_string_field_set(iaxs[callno], outkey, pds.key); 05158 if (pds.password) 05159 ast_string_field_set(iaxs[callno], secret, pds.password); 05160 05161 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats); 05162 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats); 05163 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability); 05164 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability); 05165 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 05166 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 05167 05168 if (iaxs[callno]->maxtime) { 05169 /* Initialize pingtime and auto-congest time */ 05170 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 05171 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 05172 } else if (autokill) { 05173 iaxs[callno]->pingtime = autokill / 2; 05174 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 05175 } 05176 05177 /* Check if there is an OSP token */ 05178 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 05179 if (!ast_strlen_zero(osp_token_ptr)) { 05180 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 05181 osp_block_index = 0; 05182 while (osp_token_length > 0) { 05183 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 05184 osp_buffer[0] = osp_block_index; 05185 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 05186 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 05187 osp_block_index++; 05188 osp_token_ptr += osp_block_length; 05189 osp_token_length -= osp_block_length; 05190 } 05191 } else 05192 ast_log(LOG_WARNING, "OSP token is too long\n"); 05193 } else if (iaxdebug) 05194 ast_debug(1, "OSP token is undefined\n"); 05195 05196 /* send the command using the appropriate socket for this peer */ 05197 iaxs[callno]->sockfd = cai.sockfd; 05198 05199 /* Add remote vars */ 05200 if (variablestore) { 05201 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 05202 ast_debug(1, "Found an IAX variable store on this channel\n"); 05203 AST_LIST_LOCK(variablelist); 05204 AST_LIST_TRAVERSE(variablelist, var, entries) { 05205 char tmp[256]; 05206 int i; 05207 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 05208 /* Automatically divide the value up into sized chunks */ 05209 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 05210 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 05211 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 05212 } 05213 } 05214 AST_LIST_UNLOCK(variablelist); 05215 } 05216 05217 /* Transmit the string in a "NEW" request */ 05218 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 05219 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 05220 05221 ast_mutex_unlock(&iaxsl[callno]); 05222 ast_setstate(c, AST_STATE_RINGING); 05223 05224 return 0; 05225 }
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 13826 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.
13827 { 13828 int res = 0; 13829 struct iax2_dpcache *dp = NULL; 13830 #if 0 13831 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13832 #endif 13833 if ((priority != 1) && (priority != 2)) 13834 return 0; 13835 13836 AST_LIST_LOCK(&dpcache); 13837 if ((dp = find_cache(chan, data, context, exten, priority))) { 13838 if (dp->flags & CACHE_FLAG_CANEXIST) 13839 res = 1; 13840 } else { 13841 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13842 } 13843 AST_LIST_UNLOCK(&dpcache); 13844 13845 return res; 13846 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4690 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().
04691 { 04692 struct timeval t = ast_tvnow(); 04693 struct ast_tm tm; 04694 unsigned int tmp; 04695 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04696 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04697 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04698 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04699 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04700 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04701 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04702 return tmp; 04703 }
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 14032 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().
14033 { 14034 struct parsed_dial_string pds; 14035 char *tmp = ast_strdupa(data); 14036 struct iax2_peer *p; 14037 int res = AST_DEVICE_INVALID; 14038 14039 memset(&pds, 0, sizeof(pds)); 14040 parse_dial_string(tmp, &pds); 14041 14042 if (ast_strlen_zero(pds.peer)) { 14043 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 14044 return res; 14045 } 14046 14047 ast_debug(3, "Checking device state for device %s\n", pds.peer); 14048 14049 /* SLD: FIXME: second call to find_peer during registration */ 14050 if (!(p = find_peer(pds.peer, 1))) 14051 return res; 14052 14053 res = AST_DEVICE_UNAVAILABLE; 14054 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 14055 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 14056 14057 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) && 14058 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 14059 /* Peer is registered, or have default IP address 14060 and a valid registration */ 14061 if (p->historicms == 0 || p->historicms <= p->maxms) 14062 /* let the core figure out whether it is in use or not */ 14063 res = AST_DEVICE_UNKNOWN; 14064 } 14065 14066 peer_unref(p); 14067 14068 return res; 14069 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 4291 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04292 { 04293 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04294 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 4296 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04297 { 04298 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04299 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11817 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().
11818 { 11819 struct iax_ie_data ied; 11820 if (iaxdebug) 11821 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11822 11823 if (reg->dnsmgr && 11824 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) { 11825 /* Maybe the IP has changed, force DNS refresh */ 11826 ast_dnsmgr_refresh(reg->dnsmgr); 11827 } 11828 11829 /* 11830 * if IP has Changed, free allocated call to create a new one with new IP 11831 * call has the pointer to IP and must be updated to the new one 11832 */ 11833 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11834 int callno = reg->callno; 11835 ast_mutex_lock(&iaxsl[callno]); 11836 iax2_destroy(callno); 11837 ast_mutex_unlock(&iaxsl[callno]); 11838 reg->callno = 0; 11839 } 11840 if (!ast_sockaddr_ipv4(®->addr)) { 11841 if (iaxdebug) 11842 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11843 /* Setup the next registration attempt */ 11844 reg->expire = iax2_sched_replace(reg->expire, sched, 11845 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11846 return -1; 11847 } 11848 11849 if (!reg->callno) { 11850 struct sockaddr_in reg_addr; 11851 11852 ast_debug(3, "Allocate call number\n"); 11853 11854 ast_sockaddr_to_sin(®->addr, ®_addr); 11855 11856 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0); 11857 if (reg->callno < 1) { 11858 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11859 return -1; 11860 } else 11861 ast_debug(3, "Registration created on call %d\n", reg->callno); 11862 iaxs[reg->callno]->reg = reg; 11863 ast_mutex_unlock(&iaxsl[reg->callno]); 11864 } 11865 /* Setup the next registration a little early */ 11866 reg->expire = iax2_sched_replace(reg->expire, sched, 11867 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11868 /* Send the request */ 11869 memset(&ied, 0, sizeof(ied)); 11870 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11871 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11872 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11873 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11874 reg->regstate = REG_STATE_REGSENT; 11875 return 0; 11876 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8297 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
08298 { 08299 #ifdef SCHED_MULTITHREADED 08300 if (schedule_action(__iax2_do_register_s, data)) 08301 #endif 08302 __iax2_do_register_s(data); 08303 return 0; 08304 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 9072 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().
09073 { 09074 struct iax_ie_data ied; 09075 /* Auto-hangup with 30 seconds of inactivity */ 09076 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 09077 sched, 30000, auto_hangup, (void *)(long)callno); 09078 memset(&ied, 0, sizeof(ied)); 09079 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 09080 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 09081 dp->flags |= CACHE_FLAG_TRANSMITTED; 09082 }
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 13872 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().
13873 { 13874 char odata[256]; 13875 char req[256]; 13876 char *ncontext; 13877 struct iax2_dpcache *dp = NULL; 13878 struct ast_app *dial = NULL; 13879 #if 0 13880 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); 13881 #endif 13882 if (priority == 2) { 13883 /* Indicate status, can be overridden in dialplan */ 13884 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13885 if (dialstatus) { 13886 dial = pbx_findapp(dialstatus); 13887 if (dial) 13888 pbx_exec(chan, dial, ""); 13889 } 13890 return -1; 13891 } else if (priority != 1) 13892 return -1; 13893 13894 AST_LIST_LOCK(&dpcache); 13895 if ((dp = find_cache(chan, data, context, exten, priority))) { 13896 if (dp->flags & CACHE_FLAG_EXISTS) { 13897 ast_copy_string(odata, data, sizeof(odata)); 13898 ncontext = strchr(odata, '/'); 13899 if (ncontext) { 13900 *ncontext = '\0'; 13901 ncontext++; 13902 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13903 } else { 13904 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13905 } 13906 ast_verb(3, "Executing Dial('%s')\n", req); 13907 } else { 13908 AST_LIST_UNLOCK(&dpcache); 13909 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13910 return -1; 13911 } 13912 } 13913 AST_LIST_UNLOCK(&dpcache); 13914 13915 if ((dial = pbx_findapp("Dial"))) 13916 return pbx_exec(chan, dial, req); 13917 else 13918 ast_log(LOG_WARNING, "No dial application registered\n"); 13919 13920 return -1; 13921 }
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 13803 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.
13804 { 13805 int res = 0; 13806 struct iax2_dpcache *dp = NULL; 13807 #if 0 13808 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13809 #endif 13810 if ((priority != 1) && (priority != 2)) 13811 return 0; 13812 13813 AST_LIST_LOCK(&dpcache); 13814 if ((dp = find_cache(chan, data, context, exten, priority))) { 13815 if (dp->flags & CACHE_FLAG_EXISTS) 13816 res = 1; 13817 } else { 13818 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13819 } 13820 AST_LIST_UNLOCK(&dpcache); 13821 13822 return res; 13823 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 4318 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.
04319 { 04320 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04321 ast_mutex_lock(&iaxsl[callno]); 04322 if (iaxs[callno]) 04323 iaxs[callno]->owner = newchan; 04324 else 04325 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04326 ast_mutex_unlock(&iaxsl[callno]); 04327 return 0; 04328 }
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 5706 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().
05707 { 05708 struct iax2_peer *peer; 05709 int res = 0; 05710 struct ao2_iterator i; 05711 05712 i = ao2_iterator_init(peers, 0); 05713 while ((peer = ao2_iterator_next(&i))) { 05714 struct sockaddr_in peer_addr; 05715 05716 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 05717 05718 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05719 (peer_addr.sin_port == sin.sin_port)) { 05720 res = ast_test_flag64(peer, IAX_TRUNK); 05721 peer_unref(peer); 05722 break; 05723 } 05724 peer_unref(peer); 05725 } 05726 ao2_iterator_destroy(&i); 05727 05728 return res; 05729 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5227 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.
05228 { 05229 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05230 struct iax_ie_data ied; 05231 int alreadygone; 05232 memset(&ied, 0, sizeof(ied)); 05233 ast_mutex_lock(&iaxsl[callno]); 05234 if (callno && iaxs[callno]) { 05235 ast_debug(1, "We're hanging up %s now...\n", c->name); 05236 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE); 05237 /* Send the hangup unless we have had a transmission error or are already gone */ 05238 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 05239 if (!iaxs[callno]->error && !alreadygone) { 05240 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 05241 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 05242 } 05243 if (!iaxs[callno]) { 05244 ast_mutex_unlock(&iaxsl[callno]); 05245 return 0; 05246 } 05247 } 05248 /* Explicitly predestroy it */ 05249 iax2_predestroy(callno); 05250 /* If we were already gone to begin with, destroy us now */ 05251 if (iaxs[callno] && alreadygone) { 05252 ast_debug(1, "Really destroying %s now...\n", c->name); 05253 iax2_destroy(callno); 05254 } else if (iaxs[callno]) { 05255 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 05256 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05257 iax2_destroy(callno); 05258 } 05259 } 05260 } else if (c->tech_pvt) { 05261 /* If this call no longer exists, but the channel still 05262 * references it we need to set the channel's tech_pvt to null 05263 * to avoid ast_channel_free() trying to free it. 05264 */ 05265 c->tech_pvt = NULL; 05266 } 05267 ast_mutex_unlock(&iaxsl[callno]); 05268 ast_verb(3, "Hungup '%s'\n", c->name); 05269 return 0; 05270 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5642 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().
05643 { 05644 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05645 struct chan_iax2_pvt *pvt; 05646 int res = 0; 05647 05648 if (iaxdebug) 05649 ast_debug(1, "Indicating condition %d\n", condition); 05650 05651 ast_mutex_lock(&iaxsl[callno]); 05652 pvt = iaxs[callno]; 05653 05654 if (wait_for_peercallno(pvt)) { 05655 res = -1; 05656 goto done; 05657 } 05658 05659 switch (condition) { 05660 case AST_CONTROL_HOLD: 05661 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05662 ast_moh_start(c, data, pvt->mohinterpret); 05663 goto done; 05664 } 05665 break; 05666 case AST_CONTROL_UNHOLD: 05667 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05668 ast_moh_stop(c); 05669 goto done; 05670 } 05671 break; 05672 case AST_CONTROL_CONNECTED_LINE: 05673 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) 05674 goto done; 05675 break; 05676 } 05677 05678 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05679 05680 done: 05681 ast_mutex_unlock(&iaxsl[callno]); 05682 05683 return res; 05684 }
static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5389 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().
05390 { 05391 int res = 0; 05392 struct chan_iax2_pvt *pvt = (void *) vpvt; 05393 struct MD5Context md5; 05394 char key[17] = ""; 05395 struct iax_ie_data ied = { 05396 .pos = 0, 05397 }; 05398 05399 ast_mutex_lock(&iaxsl[pvt->callno]); 05400 pvt->keyrotateid = 05401 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05402 05403 snprintf(key, sizeof(key), "%lX", ast_random()); 05404 05405 MD5Init(&md5); 05406 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05407 MD5Final((unsigned char *) key, &md5); 05408 05409 IAX_DEBUGDIGEST("Sending", key); 05410 05411 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05412 05413 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05414 05415 build_ecx_key((unsigned char *) key, pvt); 05416 05417 ast_mutex_unlock(&iaxsl[pvt->callno]); 05418 05419 return res; 05420 }
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 13849 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.
13850 { 13851 int res = 0; 13852 struct iax2_dpcache *dp = NULL; 13853 #if 0 13854 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13855 #endif 13856 if ((priority != 1) && (priority != 2)) 13857 return 0; 13858 13859 AST_LIST_LOCK(&dpcache); 13860 if ((dp = find_cache(chan, data, context, exten, priority))) { 13861 if (dp->flags & CACHE_FLAG_MATCHMORE) 13862 res = 1; 13863 } else { 13864 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13865 } 13866 AST_LIST_UNLOCK(&dpcache); 13867 13868 return res; 13869 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12021 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
12022 { 12023 struct iax2_peer *peer = (struct iax2_peer *)data; 12024 peer->pokeexpire = -1; 12025 #ifdef SCHED_MULTITHREADED 12026 if (schedule_action(__iax2_poke_noanswer, data)) 12027 #endif 12028 __iax2_poke_noanswer(data); 12029 peer_unref(peer); 12030 return 0; 12031 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 12042 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().
12043 { 12044 int callno; 12045 struct sockaddr_in peer_addr; 12046 12047 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) { 12048 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 12049 immediately after clearing things out */ 12050 peer->lastms = 0; 12051 peer->historicms = 0; 12052 peer->pokeexpire = -1; 12053 peer->callno = 0; 12054 return 0; 12055 } 12056 12057 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 12058 12059 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 12060 if ((callno = peer->callno) > 0) { 12061 ast_log(LOG_NOTICE, "Still have a callno...\n"); 12062 ast_mutex_lock(&iaxsl[callno]); 12063 iax2_destroy(callno); 12064 ast_mutex_unlock(&iaxsl[callno]); 12065 } 12066 if (heldcall) 12067 ast_mutex_unlock(&iaxsl[heldcall]); 12068 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0); 12069 if (heldcall) 12070 ast_mutex_lock(&iaxsl[heldcall]); 12071 if (peer->callno < 1) { 12072 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 12073 return -1; 12074 } 12075 12076 /* Speed up retransmission times for this qualify call */ 12077 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 12078 iaxs[peer->callno]->peerpoke = peer; 12079 12080 if (peer->pokeexpire > -1) { 12081 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 12082 peer->pokeexpire = -1; 12083 peer_unref(peer); 12084 } 12085 } 12086 12087 /* Queue up a new task to handle no reply */ 12088 /* If the host is already unreachable then use the unreachable interval instead */ 12089 if (peer->lastms < 0) 12090 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 12091 else 12092 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 12093 12094 if (peer->pokeexpire == -1) 12095 peer_unref(peer); 12096 12097 /* And send the poke */ 12098 ast_mutex_lock(&iaxsl[callno]); 12099 if (iaxs[callno]) { 12100 struct iax_ie_data ied = { 12101 .buf = { 0 }, 12102 .pos = 0, 12103 }; 12104 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 12105 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 12106 } 12107 ast_mutex_unlock(&iaxsl[callno]); 12108 12109 return 0; 12110 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12033 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
12034 { 12035 struct iax2_peer *peer = obj; 12036 12037 iax2_poke_peer(peer, 0); 12038 12039 return 0; 12040 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9109 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
09110 { 09111 struct iax2_peer *peer = (struct iax2_peer *)data; 09112 peer->pokeexpire = -1; 09113 #ifdef SCHED_MULTITHREADED 09114 if (schedule_action(__iax2_poke_peer_s, data)) 09115 #endif 09116 __iax2_poke_peer_s(data); 09117 return 0; 09118 }
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 11672 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().
11673 { 11674 struct iax2_thread *thread = data; 11675 struct timeval wait; 11676 struct timespec ts; 11677 int put_into_idle = 0; 11678 int first_time = 1; 11679 int old_state; 11680 11681 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1); 11682 11683 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); 11684 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11685 11686 for (;;) { 11687 /* Wait for something to signal us to be awake */ 11688 ast_mutex_lock(&thread->lock); 11689 11690 if (thread->stop) { 11691 ast_mutex_unlock(&thread->lock); 11692 break; 11693 } 11694 11695 /* Flag that we're ready to accept signals */ 11696 if (first_time) { 11697 signal_condition(&thread->init_lock, &thread->init_cond); 11698 first_time = 0; 11699 } 11700 11701 /* Put into idle list if applicable */ 11702 if (put_into_idle) { 11703 insert_idle_thread(thread); 11704 } 11705 11706 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11707 struct iax2_thread *t = NULL; 11708 /* Wait to be signalled or time out */ 11709 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11710 ts.tv_sec = wait.tv_sec; 11711 ts.tv_nsec = wait.tv_usec * 1000; 11712 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11713 /* This thread was never put back into the available dynamic 11714 * thread list, so just go away. */ 11715 if (!put_into_idle || thread->stop) { 11716 ast_mutex_unlock(&thread->lock); 11717 break; 11718 } 11719 AST_LIST_LOCK(&dynamic_list); 11720 /* Account for the case where this thread is acquired *right* after a timeout */ 11721 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11722 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11723 AST_LIST_UNLOCK(&dynamic_list); 11724 if (t) { 11725 /* This dynamic thread timed out waiting for a task and was 11726 * not acquired immediately after the timeout, 11727 * so it's time to go away. */ 11728 ast_mutex_unlock(&thread->lock); 11729 break; 11730 } 11731 /* Someone grabbed our thread *right* after we timed out. 11732 * Wait for them to set us up with something to do and signal 11733 * us to continue. */ 11734 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11735 ts.tv_sec = wait.tv_sec; 11736 ts.tv_nsec = wait.tv_usec * 1000; 11737 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11738 ast_mutex_unlock(&thread->lock); 11739 break; 11740 } 11741 } 11742 } else { 11743 ast_cond_wait(&thread->cond, &thread->lock); 11744 } 11745 11746 /* Go back into our respective list */ 11747 put_into_idle = 1; 11748 11749 ast_mutex_unlock(&thread->lock); 11750 11751 if (thread->stop) { 11752 break; 11753 } 11754 11755 if (thread->iostate == IAX_IOSTATE_IDLE) 11756 continue; 11757 11758 /* See what we need to do */ 11759 switch (thread->iostate) { 11760 case IAX_IOSTATE_READY: 11761 thread->actions++; 11762 thread->iostate = IAX_IOSTATE_PROCESSING; 11763 socket_process(thread); 11764 handle_deferred_full_frames(thread); 11765 break; 11766 case IAX_IOSTATE_SCHEDREADY: 11767 thread->actions++; 11768 thread->iostate = IAX_IOSTATE_PROCESSING; 11769 #ifdef SCHED_MULTITHREADED 11770 thread->schedfunc(thread->scheddata); 11771 #endif 11772 default: 11773 break; 11774 } 11775 time(&thread->checktime); 11776 thread->iostate = IAX_IOSTATE_IDLE; 11777 #ifdef DEBUG_SCHED_MULTITHREAD 11778 thread->curfunc[0]='\0'; 11779 #endif 11780 11781 /* The network thread added us to the active_thread list when we were given 11782 * frames to process, Now that we are done, we must remove ourselves from 11783 * the active list, and return to the idle list */ 11784 AST_LIST_LOCK(&active_list); 11785 AST_LIST_REMOVE(&active_list, thread, list); 11786 AST_LIST_UNLOCK(&active_list); 11787 11788 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11789 handle_deferred_full_frames(thread); 11790 } 11791 11792 /*! 11793 * \note For some reason, idle threads are exiting without being removed 11794 * from an idle list, which is causing memory corruption. Forcibly remove 11795 * it from the list, if it's there. 11796 */ 11797 AST_LIST_LOCK(&idle_list); 11798 AST_LIST_REMOVE(&idle_list, thread, list); 11799 AST_LIST_UNLOCK(&idle_list); 11800 11801 AST_LIST_LOCK(&dynamic_list); 11802 AST_LIST_REMOVE(&dynamic_list, thread, list); 11803 AST_LIST_UNLOCK(&dynamic_list); 11804 11805 if (!thread->stop) { 11806 /* Nobody asked me to stop so nobody is waiting to join me. */ 11807 pthread_detach(pthread_self()); 11808 } 11809 11810 /* I am exiting here on my own volition, I need to clean up my own data structures 11811 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11812 */ 11813 pthread_cleanup_pop(1); 11814 return NULL; 11815 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11660 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().
11661 { 11662 struct iax2_thread *thread = data; 11663 ast_mutex_destroy(&thread->lock); 11664 ast_cond_destroy(&thread->cond); 11665 ast_mutex_destroy(&thread->init_lock); 11666 ast_cond_destroy(&thread->init_cond); 11667 ast_free(thread); 11668 /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */ 11669 ast_atomic_dec_and_test(&iaxactivethreadcount); 11670 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
const char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 11878 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().
11879 { 11880 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11881 is found for template */ 11882 struct iax_ie_data provdata; 11883 struct iax_ie_data ied; 11884 unsigned int sig; 11885 struct sockaddr_in sin; 11886 int callno; 11887 struct create_addr_info cai; 11888 11889 memset(&cai, 0, sizeof(cai)); 11890 11891 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11892 11893 if (iax_provision_build(&provdata, &sig, template, force)) { 11894 ast_debug(1, "No provisioning found for template '%s'\n", template); 11895 return 0; 11896 } 11897 11898 if (end) { 11899 memcpy(&sin, end, sizeof(sin)); 11900 cai.sockfd = sockfd; 11901 } else if (create_addr(dest, NULL, &sin, &cai)) 11902 return -1; 11903 11904 /* Build the rest of the message */ 11905 memset(&ied, 0, sizeof(ied)); 11906 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11907 11908 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11909 if (!callno) 11910 return -1; 11911 11912 if (iaxs[callno]) { 11913 /* Schedule autodestruct in case they don't ever give us anything back */ 11914 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11915 sched, 15000, auto_hangup, (void *)(long)callno); 11916 ast_set_flag64(iaxs[callno], IAX_PROVISION); 11917 /* Got a call number now, so go ahead and send the provisioning information */ 11918 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11919 } 11920 ast_mutex_unlock(&iaxsl[callno]); 11921 11922 return 1; 11923 }
static int iax2_queryoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int * | datalen | |||
) | [static] |
Definition at line 5366 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.
05367 { 05368 switch (option) { 05369 case AST_OPTION_SECURE_SIGNALING: 05370 case AST_OPTION_SECURE_MEDIA: 05371 { 05372 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05373 ast_mutex_lock(&iaxsl[callno]); 05374 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0; 05375 ast_mutex_unlock(&iaxsl[callno]); 05376 return 0; 05377 } 05378 default: 05379 return -1; 05380 } 05381 }
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 5383 of file chan_iax2.c.
References ast_debug, and ast_null_frame.
05384 { 05385 ast_debug(1, "I should never be called!\n"); 05386 return &ast_null_frame; 05387 }
static int iax2_register | ( | const char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 8545 of file chan_iax2.c.
References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, and secret.
Referenced by set_config().
08546 { 08547 char copy[256]; 08548 char *username, *hostname, *secret; 08549 char *porta; 08550 char *stringp=NULL; 08551 08552 if (!value) 08553 return -1; 08554 08555 ast_copy_string(copy, value, sizeof(copy)); 08556 stringp = copy; 08557 username = strsep(&stringp, "@"); 08558 hostname = strsep(&stringp, "@"); 08559 08560 if (!hostname) { 08561 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08562 return -1; 08563 } 08564 08565 stringp = username; 08566 username = strsep(&stringp, ":"); 08567 secret = strsep(&stringp, ":"); 08568 stringp = hostname; 08569 hostname = strsep(&stringp, ":"); 08570 porta = strsep(&stringp, ":"); 08571 08572 if (porta && !atoi(porta)) { 08573 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08574 return -1; 08575 } 08576 08577 return iax2_append_register(hostname, username, secret, porta); 08578 }
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 12122 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.
12123 { 12124 int callno; 12125 int res; 12126 format_t fmt, native; 12127 struct sockaddr_in sin; 12128 struct ast_channel *c; 12129 struct parsed_dial_string pds; 12130 struct create_addr_info cai; 12131 char *tmpstr; 12132 12133 memset(&pds, 0, sizeof(pds)); 12134 tmpstr = ast_strdupa(data); 12135 parse_dial_string(tmpstr, &pds); 12136 12137 if (ast_strlen_zero(pds.peer)) { 12138 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12139 return NULL; 12140 } 12141 12142 memset(&cai, 0, sizeof(cai)); 12143 cai.capability = iax2_capability; 12144 12145 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12146 12147 /* Populate our address from the given */ 12148 if (create_addr(pds.peer, NULL, &sin, &cai)) { 12149 *cause = AST_CAUSE_UNREGISTERED; 12150 return NULL; 12151 } 12152 12153 if (pds.port) 12154 sin.sin_port = htons(atoi(pds.port)); 12155 12156 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12157 if (callno < 1) { 12158 ast_log(LOG_WARNING, "Unable to create call\n"); 12159 *cause = AST_CAUSE_CONGESTION; 12160 return NULL; 12161 } 12162 12163 /* If this is a trunk, update it now */ 12164 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12165 if (ast_test_flag64(&cai, IAX_TRUNK)) { 12166 int new_callno; 12167 if ((new_callno = make_trunk(callno, 1)) != -1) 12168 callno = new_callno; 12169 } 12170 iaxs[callno]->maxtime = cai.maxtime; 12171 if (cai.found) 12172 ast_string_field_set(iaxs[callno], host, pds.peer); 12173 12174 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found); 12175 12176 ast_mutex_unlock(&iaxsl[callno]); 12177 12178 if (c) { 12179 /* Choose a format we can live with */ 12180 if (c->nativeformats & format) 12181 c->nativeformats &= format; 12182 else { 12183 native = c->nativeformats; 12184 fmt = format; 12185 res = ast_translator_best_choice(&fmt, &native); 12186 if (res < 0) { 12187 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 12188 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 12189 ast_hangup(c); 12190 return NULL; 12191 } 12192 c->nativeformats = native; 12193 } 12194 c->readformat = ast_best_codec(c->nativeformats); 12195 c->writeformat = c->readformat; 12196 } 12197 12198 return c; 12199 }
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 6371 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().
06372 { 06373 /* Queue a packet for delivery on a given private structure. Use "ts" for 06374 timestamp, or calculate if ts is 0. Send immediately without retransmission 06375 or delayed, with retransmission */ 06376 struct ast_iax2_full_hdr *fh; 06377 struct ast_iax2_mini_hdr *mh; 06378 struct ast_iax2_video_hdr *vh; 06379 struct { 06380 struct iax_frame fr2; 06381 unsigned char buffer[4096]; 06382 } frb; 06383 struct iax_frame *fr; 06384 int res; 06385 int sendmini=0; 06386 unsigned int lastsent; 06387 unsigned int fts; 06388 06389 frb.fr2.afdatalen = sizeof(frb.buffer); 06390 06391 if (!pvt) { 06392 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06393 return -1; 06394 } 06395 06396 lastsent = pvt->lastsent; 06397 06398 /* Calculate actual timestamp */ 06399 fts = calc_timestamp(pvt, ts, f); 06400 06401 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06402 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06403 * increment the "predicted timestamps" for voice, if we're predicting */ 06404 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06405 return 0; 06406 #if 0 06407 ast_log(LOG_NOTICE, 06408 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06409 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06410 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06411 pvt->keyrotateid != -1 ? "" : "no " 06412 ); 06413 #endif 06414 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06415 iax2_key_rotate(pvt); 06416 } 06417 06418 if ((ast_test_flag64(pvt, IAX_TRUNK) || 06419 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06420 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06421 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06422 (f->frametype == AST_FRAME_VOICE) 06423 /* is a voice frame */ && 06424 (f->subclass.codec == pvt->svoiceformat) 06425 /* is the same type */ ) { 06426 /* Force immediate rather than delayed transmission */ 06427 now = 1; 06428 /* Mark that mini-style frame is appropriate */ 06429 sendmini = 1; 06430 } 06431 if ( f->frametype == AST_FRAME_VIDEO ) { 06432 /* 06433 * If the lower 15 bits of the timestamp roll over, or if 06434 * the video format changed then send a full frame. 06435 * Otherwise send a mini video frame 06436 */ 06437 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06438 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat) 06439 ) { 06440 now = 1; 06441 sendmini = 1; 06442 } else { 06443 now = 0; 06444 sendmini = 0; 06445 } 06446 pvt->lastvsent = fts; 06447 } 06448 if (f->frametype == AST_FRAME_IAX) { 06449 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06450 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX; 06451 if (!pvt->first_iax_message) { 06452 pvt->first_iax_message = pvt->last_iax_message; 06453 } 06454 } 06455 /* Allocate an iax_frame */ 06456 if (now) { 06457 fr = &frb.fr2; 06458 } else 06459 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)); 06460 if (!fr) { 06461 ast_log(LOG_WARNING, "Out of memory\n"); 06462 return -1; 06463 } 06464 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06465 iax_frame_wrap(fr, f); 06466 06467 fr->ts = fts; 06468 fr->callno = pvt->callno; 06469 fr->transfer = transfer; 06470 fr->final = final; 06471 fr->encmethods = 0; 06472 if (!sendmini) { 06473 /* We need a full frame */ 06474 if (seqno > -1) 06475 fr->oseqno = seqno; 06476 else 06477 fr->oseqno = pvt->oseqno++; 06478 fr->iseqno = pvt->iseqno; 06479 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06480 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06481 fh->ts = htonl(fr->ts); 06482 fh->oseqno = fr->oseqno; 06483 if (transfer) { 06484 fh->iseqno = 0; 06485 } else 06486 fh->iseqno = fr->iseqno; 06487 /* Keep track of the last thing we've acknowledged */ 06488 if (!transfer) 06489 pvt->aseqno = fr->iseqno; 06490 fh->type = fr->af.frametype & 0xFF; 06491 06492 if (fr->af.frametype == AST_FRAME_VIDEO) { 06493 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6); 06494 } else if (fr->af.frametype == AST_FRAME_VOICE) { 06495 fh->csub = compress_subclass(fr->af.subclass.codec); 06496 } else { 06497 fh->csub = compress_subclass(fr->af.subclass.integer); 06498 } 06499 06500 if (transfer) { 06501 fr->dcallno = pvt->transfercallno; 06502 } else 06503 fr->dcallno = pvt->peercallno; 06504 fh->dcallno = htons(fr->dcallno); 06505 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06506 fr->data = fh; 06507 fr->retries = 0; 06508 /* Retry after 2x the ping time has passed */ 06509 fr->retrytime = pvt->pingtime * 2; 06510 if (fr->retrytime < MIN_RETRY_TIME) 06511 fr->retrytime = MIN_RETRY_TIME; 06512 if (fr->retrytime > MAX_RETRY_TIME) 06513 fr->retrytime = MAX_RETRY_TIME; 06514 /* Acks' don't get retried */ 06515 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK)) 06516 fr->retries = -1; 06517 else if (f->frametype == AST_FRAME_VOICE) 06518 pvt->svoiceformat = f->subclass.codec; 06519 else if (f->frametype == AST_FRAME_VIDEO) 06520 pvt->svideoformat = f->subclass.codec & ~0x1LL; 06521 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06522 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06523 if (fr->transfer) 06524 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06525 else 06526 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06527 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06528 fr->encmethods = pvt->encmethods; 06529 fr->ecx = pvt->ecx; 06530 fr->mydcx = pvt->mydcx; 06531 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06532 } else 06533 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06534 } 06535 06536 if (now) { 06537 res = send_packet(fr); 06538 } else 06539 res = iax2_transmit(fr); 06540 } else { 06541 if (ast_test_flag64(pvt, IAX_TRUNK)) { 06542 iax2_trunk_queue(pvt, fr); 06543 res = 0; 06544 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06545 /* Video frame have no sequence number */ 06546 fr->oseqno = -1; 06547 fr->iseqno = -1; 06548 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06549 vh->zeros = 0; 06550 vh->callno = htons(0x8000 | fr->callno); 06551 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0)); 06552 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06553 fr->data = vh; 06554 fr->retries = -1; 06555 res = send_packet(fr); 06556 } else { 06557 /* Mini-frames have no sequence number */ 06558 fr->oseqno = -1; 06559 fr->iseqno = -1; 06560 /* Mini frame will do */ 06561 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06562 mh->callno = htons(fr->callno); 06563 mh->ts = htons(fr->ts & 0xFFFF); 06564 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06565 fr->data = mh; 06566 fr->retries = -1; 06567 if (pvt->transferring == TRANSFER_MEDIAPASS) 06568 fr->transfer = 1; 06569 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06570 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06571 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06572 } else 06573 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06574 } 06575 res = send_packet(fr); 06576 } 06577 } 06578 return res; 06579 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4313 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04314 { 04315 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04316 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 4308 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.
04309 { 04310 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1); 04311 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 4301 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04302 { 04303 04304 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04305 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04306 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 5294 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().
05295 { 05296 struct ast_option_header *h; 05297 int res; 05298 05299 switch (option) { 05300 case AST_OPTION_TXGAIN: 05301 case AST_OPTION_RXGAIN: 05302 /* these two cannot be sent, because they require a result */ 05303 errno = ENOSYS; 05304 return -1; 05305 case AST_OPTION_OPRMODE: 05306 errno = EINVAL; 05307 return -1; 05308 case AST_OPTION_SECURE_SIGNALING: 05309 case AST_OPTION_SECURE_MEDIA: 05310 { 05311 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05312 ast_mutex_lock(&iaxsl[callno]); 05313 if ((*(int *) data)) { 05314 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05315 } else { 05316 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05317 } 05318 ast_mutex_unlock(&iaxsl[callno]); 05319 return 0; 05320 } 05321 /* These options are sent to the other side across the network where 05322 * they will be passed to whatever channel is bridged there. Don't 05323 * do anything silly like pass an option that transmits pointers to 05324 * memory on this machine to a remote machine to use */ 05325 case AST_OPTION_TONE_VERIFY: 05326 case AST_OPTION_TDD: 05327 case AST_OPTION_RELAXDTMF: 05328 case AST_OPTION_AUDIO_MODE: 05329 case AST_OPTION_DIGIT_DETECT: 05330 case AST_OPTION_FAX_DETECT: 05331 { 05332 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05333 struct chan_iax2_pvt *pvt; 05334 05335 ast_mutex_lock(&iaxsl[callno]); 05336 pvt = iaxs[callno]; 05337 05338 if (wait_for_peercallno(pvt)) { 05339 ast_mutex_unlock(&iaxsl[callno]); 05340 return -1; 05341 } 05342 05343 ast_mutex_unlock(&iaxsl[callno]); 05344 05345 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05346 return -1; 05347 } 05348 05349 h->flag = AST_OPTION_FLAG_REQUEST; 05350 h->option = htons(option); 05351 memcpy(h->data, data, datalen); 05352 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05353 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05354 datalen + sizeof(*h), -1); 05355 ast_free(h); 05356 return res; 05357 } 05358 default: 05359 return -1; 05360 } 05361 05362 /* Just in case someone does a break instead of a return */ 05363 return -1; 05364 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 5422 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().
05423 { 05424 int res; 05425 struct iax_ie_data ied0; 05426 struct iax_ie_data ied1; 05427 unsigned int transferid = (unsigned int)ast_random(); 05428 05429 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05430 ast_debug(1, "transfers are not supported for encrypted calls at this time\n"); 05431 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER); 05432 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER); 05433 return 0; 05434 } 05435 05436 memset(&ied0, 0, sizeof(ied0)); 05437 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05438 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05439 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05440 05441 memset(&ied1, 0, sizeof(ied1)); 05442 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05443 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05444 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05445 05446 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05447 if (res) 05448 return -1; 05449 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05450 if (res) 05451 return -1; 05452 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05453 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05454 return 0; 05455 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 5686 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.
05687 { 05688 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05689 struct iax_ie_data ied = { "", }; 05690 char tmp[256], *context; 05691 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 05692 ast_copy_string(tmp, dest, sizeof(tmp)); 05693 context = strchr(tmp, '@'); 05694 if (context) { 05695 *context = '\0'; 05696 context++; 05697 } 05698 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05699 if (context) 05700 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05701 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05702 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message)); 05703 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05704 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4284 of file chan_iax2.c.
References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().
Referenced by iax2_send().
04285 { 04286 fr->sentyet = 0; 04287 04288 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr); 04289 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 9163 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
09164 { 09165 /* Drop when trunk is about 5 seconds idle */ 09166 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 09167 return 1; 09168 return 0; 09169 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 6111 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().
06112 { 06113 struct ast_frame *f; 06114 struct iax2_trunk_peer *tpeer; 06115 void *tmp, *ptr; 06116 struct timeval now; 06117 struct ast_iax2_meta_trunk_entry *met; 06118 struct ast_iax2_meta_trunk_mini *mtm; 06119 06120 f = &fr->af; 06121 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 06122 if (tpeer) { 06123 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 06124 /* Need to reallocate space */ 06125 if (tpeer->trunkdataalloc < trunkmaxsize) { 06126 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 06127 ast_mutex_unlock(&tpeer->lock); 06128 return -1; 06129 } 06130 06131 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 06132 tpeer->trunkdata = tmp; 06133 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); 06134 } else { 06135 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)); 06136 ast_mutex_unlock(&tpeer->lock); 06137 return -1; 06138 } 06139 } 06140 06141 /* Append to meta frame */ 06142 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 06143 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) { 06144 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06145 mtm->len = htons(f->datalen); 06146 mtm->mini.callno = htons(pvt->callno); 06147 mtm->mini.ts = htons(0xffff & fr->ts); 06148 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06149 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 06150 } else { 06151 met = (struct ast_iax2_meta_trunk_entry *)ptr; 06152 /* Store call number and length in meta header */ 06153 met->callno = htons(pvt->callno); 06154 met->len = htons(f->datalen); 06155 /* Advance pointers/decrease length past trunk entry header */ 06156 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06157 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 06158 } 06159 /* Copy actual trunk data */ 06160 memcpy(ptr, f->data.ptr, f->datalen); 06161 tpeer->trunkdatalen += f->datalen; 06162 06163 tpeer->calls++; 06164 06165 /* track the largest mtu we actually have sent */ 06166 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 06167 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 06168 06169 /* if we have enough for a full MTU, ship it now without waiting */ 06170 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 06171 now = ast_tvnow(); 06172 send_trunk(tpeer, &now); 06173 trunk_untimed ++; 06174 } 06175 06176 ast_mutex_unlock(&tpeer->lock); 06177 } 06178 return 0; 06179 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 9084 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().
09085 { 09086 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 09087 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 7452 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.
07453 { 07454 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07455 int res = -1; 07456 ast_mutex_lock(&iaxsl[callno]); 07457 if (iaxs[callno]) { 07458 /* If there's an outstanding error, return failure now */ 07459 if (!iaxs[callno]->error) { 07460 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) 07461 res = 0; 07462 /* Don't waste bandwidth sending null frames */ 07463 else if (f->frametype == AST_FRAME_NULL) 07464 res = 0; 07465 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH)) 07466 res = 0; 07467 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07468 res = 0; 07469 else 07470 /* Simple, just queue for transmission */ 07471 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07472 } else { 07473 ast_debug(1, "Write error: %s\n", strerror(errno)); 07474 } 07475 } 07476 /* If it's already gone, just return */ 07477 ast_mutex_unlock(&iaxsl[callno]); 07478 return res; 07479 }
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 9337 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().
09338 { 09339 struct iax_dual *d; 09340 struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */ 09341 pthread_t th; 09342 09343 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 09344 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name); 09345 d = ast_calloc(1, sizeof(*d)); 09346 if (!chan1m || !chan2m || !d) { 09347 if (chan1m) { 09348 ast_hangup(chan1m); 09349 } 09350 if (chan2m) { 09351 ast_hangup(chan2m); 09352 } 09353 ast_free(d); 09354 return -1; 09355 } 09356 d->park_exten = ast_strdup(park_exten); 09357 d->park_context = ast_strdup(park_context); 09358 if (!d->park_exten || !d->park_context) { 09359 ast_hangup(chan1m); 09360 ast_hangup(chan2m); 09361 ast_free(d->park_exten); 09362 ast_free(d->park_context); 09363 ast_free(d); 09364 return -1; 09365 } 09366 09367 /* Make formats okay */ 09368 chan1m->readformat = chan1->readformat; 09369 chan1m->writeformat = chan1->writeformat; 09370 09371 /* Prepare for taking over the channel */ 09372 if (ast_channel_masquerade(chan1m, chan1)) { 09373 ast_hangup(chan1m); 09374 ast_hangup(chan2m); 09375 ast_free(d->park_exten); 09376 ast_free(d->park_context); 09377 ast_free(d); 09378 return -1; 09379 } 09380 09381 /* Setup the extensions and such */ 09382 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 09383 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 09384 chan1m->priority = chan1->priority; 09385 09386 ast_do_masquerade(chan1m); 09387 09388 /* We make a clone of the peer channel too, so we can play 09389 back the announcement */ 09390 09391 /* Make formats okay */ 09392 chan2m->readformat = chan2->readformat; 09393 chan2m->writeformat = chan2->writeformat; 09394 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot); 09395 09396 /* Prepare for taking over the channel */ 09397 if (ast_channel_masquerade(chan2m, chan2)) { 09398 ast_hangup(chan1m); 09399 ast_hangup(chan2m); 09400 ast_free(d->park_exten); 09401 ast_free(d->park_context); 09402 ast_free(d); 09403 return -1; 09404 } 09405 09406 /* Setup the extensions and such */ 09407 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 09408 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 09409 chan2m->priority = chan2->priority; 09410 09411 ast_do_masquerade(chan2m); 09412 09413 d->chan1 = chan1m; /* Transferee */ 09414 d->chan2 = chan2m; /* Transferer */ 09415 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) { 09416 /* Could not start thread */ 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 return 0; 09425 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 9310 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().
09311 { 09312 struct iax_dual *d; 09313 int res; 09314 int ext = 0; 09315 09316 d = stuff; 09317 09318 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n", 09319 d->chan2->name, d->chan1->name); 09320 09321 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext); 09322 if (res) { 09323 /* Parking failed. */ 09324 ast_hangup(d->chan1); 09325 } else { 09326 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 09327 } 09328 ast_hangup(d->chan2); 09329 09330 ast_free(d->park_exten); 09331 ast_free(d->park_context); 09332 ast_free(d); 09333 return NULL; 09334 }
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 14731 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().
14732 { 14733 static const char config[] = "iax.conf"; 14734 int x = 0; 14735 struct iax2_registry *reg = NULL; 14736 14737 if (load_objects()) { 14738 return AST_MODULE_LOAD_FAILURE; 14739 } 14740 14741 memset(iaxs, 0, sizeof(iaxs)); 14742 14743 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14744 ast_mutex_init(&iaxsl[x]); 14745 } 14746 14747 if (!(sched = ast_sched_thread_create())) { 14748 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 14749 return AST_MODULE_LOAD_FAILURE; 14750 } 14751 14752 if (!(io = io_context_create())) { 14753 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 14754 sched = ast_sched_thread_destroy(sched); 14755 return AST_MODULE_LOAD_FAILURE; 14756 } 14757 14758 if (!(netsock = ast_netsock_list_alloc())) { 14759 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 14760 io_context_destroy(io); 14761 sched = ast_sched_thread_destroy(sched); 14762 return AST_MODULE_LOAD_FAILURE; 14763 } 14764 ast_netsock_init(netsock); 14765 14766 outsock = ast_netsock_list_alloc(); 14767 if (!outsock) { 14768 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 14769 io_context_destroy(io); 14770 sched = ast_sched_thread_destroy(sched); 14771 return AST_MODULE_LOAD_FAILURE; 14772 } 14773 ast_netsock_init(outsock); 14774 14775 randomcalltokendata = ast_random(); 14776 14777 iax_set_output(iax_debug_output); 14778 iax_set_error(iax_error_output); 14779 jb_setoutput(jb_error_output, jb_warning_output, NULL); 14780 14781 if ((timer = ast_timer_open())) { 14782 ast_timer_set_rate(timer, 1000 / trunkfreq); 14783 } 14784 14785 if (set_config(config, 0) == -1) { 14786 if (timer) { 14787 ast_timer_close(timer); 14788 timer = NULL; 14789 } 14790 return AST_MODULE_LOAD_DECLINE; 14791 } 14792 14793 #ifdef TEST_FRAMEWORK 14794 AST_TEST_REGISTER(test_iax2_peers_get); 14795 AST_TEST_REGISTER(test_iax2_users_get); 14796 #endif 14797 14798 /* Register AstData providers */ 14799 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers)); 14800 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14801 14802 ast_register_application_xml(papp, iax2_prov_app); 14803 14804 ast_custom_function_register(&iaxpeer_function); 14805 ast_custom_function_register(&iaxvar_function); 14806 14807 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers); 14808 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list); 14809 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats); 14810 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry); 14811 14812 if (ast_channel_register(&iax2_tech)) { 14813 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 14814 __unload_module(); 14815 return AST_MODULE_LOAD_FAILURE; 14816 } 14817 14818 if (ast_register_switch(&iax2_switch)) { 14819 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 14820 } 14821 14822 if (start_network_thread()) { 14823 ast_log(LOG_ERROR, "Unable to start network thread\n"); 14824 __unload_module(); 14825 return AST_MODULE_LOAD_FAILURE; 14826 } else { 14827 ast_verb(2, "IAX Ready and Listening\n"); 14828 } 14829 14830 AST_LIST_LOCK(®istrations); 14831 AST_LIST_TRAVERSE(®istrations, reg, entry) 14832 iax2_do_register(reg); 14833 AST_LIST_UNLOCK(®istrations); 14834 14835 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 14836 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 14837 14838 14839 reload_firmware(0); 14840 iax_provision_reload(0); 14841 14842 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 14843 14844 network_change_event_subscribe(); 14845 14846 return AST_MODULE_LOAD_SUCCESS; 14847 }
static int load_objects | ( | void | ) | [static] |
Definition at line 14493 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().
14494 { 14495 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 14496 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 14497 14498 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 14499 goto container_fail; 14500 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 14501 goto container_fail; 14502 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 14503 goto container_fail; 14504 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 14505 goto container_fail; 14506 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 14507 goto container_fail; 14508 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14509 goto container_fail; 14510 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14511 goto container_fail; 14512 } else if (create_callno_pools()) { 14513 goto container_fail; 14514 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) { 14515 goto container_fail; 14516 } 14517 14518 return 0; 14519 14520 container_fail: 14521 if (peers) { 14522 ao2_ref(peers, -1); 14523 } 14524 if (users) { 14525 ao2_ref(users, -1); 14526 } 14527 if (iax_peercallno_pvts) { 14528 ao2_ref(iax_peercallno_pvts, -1); 14529 } 14530 if (iax_transfercallno_pvts) { 14531 ao2_ref(iax_transfercallno_pvts, -1); 14532 } 14533 if (peercnts) { 14534 ao2_ref(peercnts, -1); 14535 } 14536 if (callno_limits) { 14537 ao2_ref(callno_limits, -1); 14538 } 14539 if (calltoken_ignores) { 14540 ao2_ref(calltoken_ignores, -1); 14541 } 14542 if (callno_pool) { 14543 ao2_ref(callno_pool, -1); 14544 } 14545 if (callno_pool_trunk) { 14546 ao2_ref(callno_pool_trunk, -1); 14547 } 14548 return AST_MODULE_LOAD_FAILURE; 14549 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5457 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
05458 { 05459 ast_mutex_lock(&iaxsl[callno0]); 05460 while (ast_mutex_trylock(&iaxsl[callno1])) { 05461 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05462 } 05463 }
static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9497 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().
09498 { 09499 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09500 jb_info jbinfo; 09501 09502 ast_mutex_lock(&iaxsl[callno]); 09503 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 09504 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) { 09505 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09506 localjitter = jbinfo.jitter; 09507 localdelay = jbinfo.current - jbinfo.min; 09508 locallost = jbinfo.frames_lost; 09509 locallosspct = jbinfo.losspct/1000; 09510 localdropped = jbinfo.frames_dropped; 09511 localooo = jbinfo.frames_ooo; 09512 localpackets = jbinfo.frames_in; 09513 } 09514 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", 09515 iaxs[callno]->owner->name, 09516 iaxs[callno]->pingtime, 09517 localjitter, 09518 localdelay, 09519 locallost, 09520 locallosspct, 09521 localdropped, 09522 localooo, 09523 localpackets, 09524 iaxs[callno]->remote_rr.jitter, 09525 iaxs[callno]->remote_rr.delay, 09526 iaxs[callno]->remote_rr.losscnt, 09527 iaxs[callno]->remote_rr.losspct/1000, 09528 iaxs[callno]->remote_rr.dropped, 09529 iaxs[callno]->remote_rr.ooo, 09530 iaxs[callno]->remote_rr.packets); 09531 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", 09532 iaxs[callno]->owner->name, 09533 iaxs[callno]->pingtime, 09534 localjitter, 09535 localdelay, 09536 locallost, 09537 locallosspct, 09538 localdropped, 09539 localooo, 09540 localpackets, 09541 iaxs[callno]->remote_rr.jitter, 09542 iaxs[callno]->remote_rr.delay, 09543 iaxs[callno]->remote_rr.losscnt, 09544 iaxs[callno]->remote_rr.losspct/1000, 09545 iaxs[callno]->remote_rr.dropped, 09546 iaxs[callno]->remote_rr.ooo, 09547 iaxs[callno]->remote_rr.packets); 09548 } 09549 ast_mutex_unlock(&iaxsl[callno]); 09550 }
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 6953 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
06954 { 06955 ast_cli_netstats(s, -1, 0); 06956 astman_append(s, "\r\n"); 06957 return RESULT_SUCCESS; 06958 }
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 7016 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().
07017 { 07018 struct iax2_peer *peer = NULL; 07019 int peer_count = 0; 07020 char nm[20]; 07021 char status[20]; 07022 const char *id = astman_get_header(m,"ActionID"); 07023 char idtext[256] = ""; 07024 struct ast_str *encmethods = ast_str_alloca(256); 07025 struct ao2_iterator i; 07026 07027 if (!ast_strlen_zero(id)) 07028 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07029 07030 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 07031 07032 07033 i = ao2_iterator_init(peers, 0); 07034 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 07035 encmethods_to_str(peer->encmethods, &encmethods); 07036 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 07037 if (!ast_strlen_zero(peer->username)) { 07038 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 07039 } else { 07040 astman_append(s, "ObjectName: %s\r\n", peer->name); 07041 } 07042 astman_append(s, "ChanObjectType: peer\r\n"); 07043 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr)); 07044 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 07045 astman_append(s, "Mask: %s\r\n", nm); 07046 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr)); 07047 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 07048 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 07049 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 07050 peer_status(peer, status, sizeof(status)); 07051 astman_append(s, "Status: %s\r\n\r\n", status); 07052 peer_count++; 07053 } 07054 ao2_iterator_destroy(&i); 07055 07056 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 07057 return RESULT_SUCCESS; 07058 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
callback to display iax peers in manager
Definition at line 6992 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().
06993 { 06994 static const char * const a[] = { "iax2", "show", "peers" }; 06995 const char *id = astman_get_header(m,"ActionID"); 06996 char idtext[256] = ""; 06997 int total = 0; 06998 06999 if (!ast_strlen_zero(id)) 07000 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07001 07002 astman_send_listack(s, m, "Peer status list will follow", "start"); 07003 /* List the peers in separate manager events */ 07004 __iax2_show_peers(-1, &total, s, 3, a); 07005 /* Send final confirmation */ 07006 astman_append(s, 07007 "Event: PeerlistComplete\r\n" 07008 "EventList: Complete\r\n" 07009 "ListItems: %d\r\n" 07010 "%s" 07011 "\r\n", total, idtext); 07012 return 0; 07013 }
static int manager_iax2_show_registry | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 7124 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().
07125 { 07126 const char *id = astman_get_header(m, "ActionID"); 07127 struct iax2_registry *reg = NULL; 07128 char idtext[256] = ""; 07129 char host[80] = ""; 07130 char perceived[80] = ""; 07131 int total = 0; 07132 07133 if (!ast_strlen_zero(id)) 07134 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07135 07136 astman_send_listack(s, m, "Registrations will follow", "start"); 07137 07138 AST_LIST_LOCK(®istrations); 07139 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07140 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07141 07142 if (reg->us.sin_addr.s_addr) { 07143 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07144 } else { 07145 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07146 } 07147 07148 astman_append(s, 07149 "Event: RegistryEntry\r\n" 07150 "%s" 07151 "Host: %s\r\n" 07152 "DNSmanager: %s\r\n" 07153 "Username: %s\r\n" 07154 "Perceived: %s\r\n" 07155 "Refresh: %d\r\n" 07156 "State: %s\r\n" 07157 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 07158 reg->refresh, regstate2str(reg->regstate)); 07159 07160 total++; 07161 } 07162 AST_LIST_UNLOCK(®istrations); 07163 07164 astman_append(s, 07165 "Event: RegistrationsComplete\r\n" 07166 "EventList: Complete\r\n" 07167 "ListItems: %d\r\n" 07168 "%s" 07169 "\r\n", total, idtext); 07170 07171 return 0; 07172 }
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 6209 of file chan_iax2.c.
References ast_aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
06210 { 06211 #if 0 06212 /* Debug with "fake encryption" */ 06213 int x; 06214 if (len % 16) 06215 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06216 for (x=0;x<len;x++) 06217 dst[x] = src[x] ^ 0xff; 06218 #else 06219 unsigned char lastblock[16] = { 0 }; 06220 int x; 06221 while(len > 0) { 06222 ast_aes_decrypt(src, dst, dcx); 06223 for (x=0;x<16;x++) 06224 dst[x] ^= lastblock[x]; 06225 memcpy(lastblock, src, sizeof(lastblock)); 06226 dst += 16; 06227 src += 16; 06228 len -= 16; 06229 } 06230 #endif 06231 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_encrypt_key * | ecx | |||
) | [static] |
Definition at line 6233 of file chan_iax2.c.
References ast_aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
06234 { 06235 #if 0 06236 /* Debug with "fake encryption" */ 06237 int x; 06238 if (len % 16) 06239 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06240 for (x=0;x<len;x++) 06241 dst[x] = src[x] ^ 0xff; 06242 #else 06243 unsigned char curblock[16] = { 0 }; 06244 int x; 06245 while(len > 0) { 06246 for (x=0;x<16;x++) 06247 curblock[x] ^= src[x]; 06248 ast_aes_encrypt(curblock, dst, ecx); 06249 memcpy(curblock, dst, sizeof(curblock)); 06250 dst += 16; 06251 src += 16; 06252 len -= 16; 06253 } 06254 #endif 06255 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 7797 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().
07798 { 07799 /* Select exactly one common encryption if there are any */ 07800 p->encmethods &= enc; 07801 if (p->encmethods) { 07802 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07803 p->keyrotateid = -2; 07804 } 07805 if (p->encmethods & IAX_ENCRYPT_AES128) 07806 p->encmethods = IAX_ENCRYPT_AES128; 07807 else 07808 p->encmethods = 0; 07809 } 07810 }
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 12201 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().
12202 { 12203 if (timer) { 12204 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 12205 } 12206 12207 for (;;) { 12208 pthread_testcancel(); 12209 /* Wake up once a second just in case SIGURG was sent while 12210 * we weren't in poll(), to make sure we don't hang when trying 12211 * to unload. */ 12212 if (ast_io_wait(io, 1000) <= 0) { 12213 break; 12214 } 12215 } 12216 12217 return NULL; 12218 }
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 4979 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().
04980 { 04981 if (ast_strlen_zero(data)) 04982 return; 04983 04984 pds->peer = strsep(&data, "/"); 04985 pds->exten = strsep(&data, "/"); 04986 pds->options = data; 04987 04988 if (pds->exten) { 04989 data = pds->exten; 04990 pds->exten = strsep(&data, "@"); 04991 pds->context = data; 04992 } 04993 04994 if (strchr(pds->peer, '@')) { 04995 data = pds->peer; 04996 pds->username = strsep(&data, "@"); 04997 pds->peer = data; 04998 } 04999 05000 if (pds->username) { 05001 data = pds->username; 05002 pds->username = strsep(&data, ":"); 05003 pds->password = data; 05004 } 05005 05006 data = pds->peer; 05007 pds->peer = strsep(&data, ":"); 05008 pds->port = data; 05009 05010 /* check for a key name wrapped in [] in the secret position, if found, 05011 move it to the key field instead 05012 */ 05013 if (pds->password && (pds->password[0] == '[')) { 05014 pds->key = ast_strip_quoted(pds->password, "[", "]"); 05015 pds->password = NULL; 05016 } 05017 }
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 12952 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
12953 { 12954 struct iax2_peer *peer = obj; 12955 12956 ast_set_flag64(peer, IAX_DELME); 12957 12958 return 0; 12959 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 12381 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().
12382 { 12383 struct iax2_peer *peer = obj; 12384 int callno = peer->callno; 12385 12386 ast_free_ha(peer->ha); 12387 12388 if (callno > 0) { 12389 ast_mutex_lock(&iaxsl[callno]); 12390 iax2_destroy(callno); 12391 ast_mutex_unlock(&iaxsl[callno]); 12392 } 12393 12394 register_peer_exten(peer, 0); 12395 12396 if (peer->dnsmgr) 12397 ast_dnsmgr_release(peer->dnsmgr); 12398 12399 if (peer->mwi_event_sub) 12400 ast_event_unsubscribe(peer->mwi_event_sub); 12401 12402 ast_string_field_free_memory(peer); 12403 }
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 14447 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
14448 { 14449 struct iax2_peer *peer = obj; 14450 14451 if (peer->sockfd < 0) 14452 peer->sockfd = defaultsockfd; 14453 14454 return 0; 14455 }
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 12308 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().
12309 { 12310 struct sockaddr_in sin; 12311 struct ast_sockaddr sin_tmp; 12312 int nonlocal = 1; 12313 int port = IAX_DEFAULT_PORTNO; 12314 int sockfd = defaultsockfd; 12315 char *tmp; 12316 char *addr; 12317 char *portstr; 12318 12319 tmp = ast_strdupa(srcaddr); 12320 addr = strsep(&tmp, ":"); 12321 portstr = tmp; 12322 12323 if (portstr) { 12324 port = atoi(portstr); 12325 if (port < 1) 12326 port = IAX_DEFAULT_PORTNO; 12327 } 12328 12329 sin_tmp.ss.ss_family = AF_INET; 12330 if (!ast_get_ip(&sin_tmp, addr)) { 12331 struct ast_netsock *sock; 12332 int res; 12333 12334 ast_sockaddr_to_sin(&sin_tmp, &sin); 12335 sin.sin_port = 0; 12336 sin.sin_family = AF_INET; 12337 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 12338 if (res == 0) { 12339 /* ip address valid. */ 12340 sin.sin_port = htons(port); 12341 if (!(sock = ast_netsock_find(netsock, &sin))) 12342 sock = ast_netsock_find(outsock, &sin); 12343 if (sock) { 12344 sockfd = ast_netsock_sockfd(sock); 12345 nonlocal = 0; 12346 } else { 12347 unsigned int orig_saddr = sin.sin_addr.s_addr; 12348 /* INADDR_ANY matches anyway! */ 12349 sin.sin_addr.s_addr = INADDR_ANY; 12350 if (ast_netsock_find(netsock, &sin)) { 12351 sin.sin_addr.s_addr = orig_saddr; 12352 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 12353 if (sock) { 12354 sockfd = ast_netsock_sockfd(sock); 12355 ast_netsock_unref(sock); 12356 nonlocal = 0; 12357 } else { 12358 nonlocal = 2; 12359 } 12360 } 12361 } 12362 } 12363 } 12364 12365 peer->sockfd = sockfd; 12366 12367 if (nonlocal == 1) { 12368 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 12369 srcaddr, peer->name); 12370 return -1; 12371 } else if (nonlocal == 2) { 12372 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 12373 srcaddr, peer->name); 12374 return -1; 12375 } else { 12376 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 12377 return 0; 12378 } 12379 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3722 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().
03723 { 03724 int res = 0; 03725 if (peer->maxms) { 03726 if (peer->lastms < 0) { 03727 ast_copy_string(status, "UNREACHABLE", statuslen); 03728 } else if (peer->lastms > peer->maxms) { 03729 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03730 res = 1; 03731 } else if (peer->lastms) { 03732 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03733 res = 1; 03734 } else { 03735 ast_copy_string(status, "UNKNOWN", statuslen); 03736 } 03737 } else { 03738 ast_copy_string(status, "Unmonitored", statuslen); 03739 res = -1; 03740 } 03741 return res; 03742 }
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 14581 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.
14583 { 14584 struct ast_data *data_peer; 14585 struct iax2_peer *peer; 14586 struct ao2_iterator i; 14587 char status[20]; 14588 struct ast_str *encmethods = ast_str_alloca(256); 14589 14590 i = ao2_iterator_init(peers, 0); 14591 while ((peer = ao2_iterator_next(&i))) { 14592 data_peer = ast_data_add_node(data_root, "peer"); 14593 if (!data_peer) { 14594 peer_unref(peer); 14595 continue; 14596 } 14597 14598 ast_data_add_structure(iax2_peer, data_peer, peer); 14599 14600 ast_data_add_codecs(data_peer, "codecs", peer->capability); 14601 14602 peer_status(peer, status, sizeof(status)); 14603 ast_data_add_str(data_peer, "status", status); 14604 14605 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr)); 14606 14607 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask)); 14608 14609 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr)); 14610 14611 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK)); 14612 14613 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC)); 14614 14615 encmethods_to_str(peer->encmethods, &encmethods); 14616 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no"); 14617 14618 peer_unref(peer); 14619 14620 if (!ast_data_search_match(search, data_peer)) { 14621 ast_data_remove_node(data_root, data_peer); 14622 } 14623 } 14624 ao2_iterator_destroy(&i); 14625 14626 return 0; 14627 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 13531 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().
13532 { 13533 struct ao2_iterator i; 13534 struct iax2_peer *peer; 13535 13536 i = ao2_iterator_init(peers, 0); 13537 while ((peer = ao2_iterator_next(&i))) { 13538 iax2_poke_peer(peer, 0); 13539 peer_unref(peer); 13540 } 13541 ao2_iterator_destroy(&i); 13542 }
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 13015 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().
13016 { 13017 struct iax2_peer *peer; 13018 struct ao2_iterator i; 13019 13020 i = ao2_iterator_init(peers, 0); 13021 while ((peer = ao2_iterator_next(&i))) { 13022 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 13023 unlink_peer(peer); 13024 } 13025 peer_unref(peer); 13026 } 13027 ao2_iterator_destroy(&i); 13028 }
static void prune_users | ( | void | ) | [static] |
Definition at line 12999 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().
13000 { 13001 struct iax2_user *user; 13002 struct ao2_iterator i; 13003 13004 i = ao2_iterator_init(users, 0); 13005 while ((user = ao2_iterator_next(&i))) { 13006 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 13007 ao2_unlink(users, user); 13008 } 13009 user_unref(user); 13010 } 13011 ao2_iterator_destroy(&i); 13012 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14464 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by load_objects().
14465 { 14466 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14467 14468 /* The frames_received field is used to hold whether we're matching 14469 * against a full frame or not ... */ 14470 14471 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 14472 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14473 }
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 14457 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_objects().
14458 { 14459 const struct chan_iax2_pvt *pvt = obj; 14460 14461 return pvt->peercallno; 14462 }
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 7778 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().
07779 { 07780 struct ast_iax2_full_hdr fh; 07781 fh.scallno = htons(src | IAX_FLAG_FULL); 07782 fh.dcallno = htons(dst); 07783 fh.ts = 0; 07784 fh.oseqno = 0; 07785 fh.iseqno = 0; 07786 fh.type = AST_FRAME_IAX; 07787 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07788 iax_outputframe(NULL, &fh, 0, sin, 0); 07789 #if 0 07790 if (option_debug) 07791 #endif 07792 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07793 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07794 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07795 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 4334 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().
04335 { 04336 struct ast_variable *var = NULL; 04337 struct ast_variable *tmp; 04338 struct iax2_peer *peer=NULL; 04339 time_t regseconds = 0, nowtime; 04340 int dynamic=0; 04341 04342 if (peername) { 04343 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04344 if (!var && sin) 04345 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04346 } else if (sin) { 04347 char porta[25]; 04348 sprintf(porta, "%d", ntohs(sin->sin_port)); 04349 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04350 if (var) { 04351 /* We'll need the peer name in order to build the structure! */ 04352 for (tmp = var; tmp; tmp = tmp->next) { 04353 if (!strcasecmp(tmp->name, "name")) 04354 peername = tmp->value; 04355 } 04356 } 04357 } 04358 if (!var && peername) { /* Last ditch effort */ 04359 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04360 /*!\note 04361 * If this one loaded something, then we need to ensure that the host 04362 * field matched. The only reason why we can't have this as a criteria 04363 * is because we only have the IP address and the host field might be 04364 * set as a name (and the reverse PTR might not match). 04365 */ 04366 if (var && sin) { 04367 for (tmp = var; tmp; tmp = tmp->next) { 04368 if (!strcasecmp(tmp->name, "host")) { 04369 struct ast_hostent ahp; 04370 struct hostent *hp; 04371 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04372 /* No match */ 04373 ast_variables_destroy(var); 04374 var = NULL; 04375 } 04376 break; 04377 } 04378 } 04379 } 04380 } 04381 if (!var) 04382 return NULL; 04383 04384 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04385 04386 if (!peer) { 04387 ast_variables_destroy(var); 04388 return NULL; 04389 } 04390 04391 for (tmp = var; tmp; tmp = tmp->next) { 04392 /* Make sure it's not a user only... */ 04393 if (!strcasecmp(tmp->name, "type")) { 04394 if (strcasecmp(tmp->value, "friend") && 04395 strcasecmp(tmp->value, "peer")) { 04396 /* Whoops, we weren't supposed to exist! */ 04397 peer = peer_unref(peer); 04398 break; 04399 } 04400 } else if (!strcasecmp(tmp->name, "regseconds")) { 04401 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04402 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04403 if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) { 04404 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name); 04405 } 04406 } else if (!strcasecmp(tmp->name, "port")) { 04407 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value)); 04408 } else if (!strcasecmp(tmp->name, "host")) { 04409 if (!strcasecmp(tmp->value, "dynamic")) 04410 dynamic = 1; 04411 } 04412 } 04413 04414 ast_variables_destroy(var); 04415 04416 if (!peer) 04417 return NULL; 04418 04419 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04420 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04421 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) { 04422 if (peer->expire > -1) { 04423 if (!ast_sched_thread_del(sched, peer->expire)) { 04424 peer->expire = -1; 04425 peer_unref(peer); 04426 } 04427 } 04428 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04429 if (peer->expire == -1) 04430 peer_unref(peer); 04431 } 04432 ao2_link(peers, peer); 04433 if (ast_test_flag64(peer, IAX_DYNAMIC)) 04434 reg_source_db(peer); 04435 } else { 04436 ast_set_flag64(peer, IAX_TEMPONLY); 04437 } 04438 04439 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04440 time(&nowtime); 04441 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04442 memset(&peer->addr, 0, sizeof(peer->addr)); 04443 realtime_update_peer(peer->name, &peer->addr, 0); 04444 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04445 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04446 } 04447 else { 04448 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04449 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04450 } 04451 } 04452 04453 return peer; 04454 }
static void realtime_update_peer | ( | const char * | peername, | |
struct ast_sockaddr * | sockaddr, | |||
time_t | regtime | |||
) | [static] |
Definition at line 4527 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().
04528 { 04529 char port[10]; 04530 char regseconds[20]; 04531 const char *sysname = ast_config_AST_SYSTEM_NAME; 04532 char *syslabel = NULL; 04533 04534 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04535 sysname = NULL; 04536 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME)) 04537 syslabel = "regserver"; 04538 04539 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04540 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr)); 04541 ast_update_realtime("iaxpeers", "name", peername, 04542 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 04543 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */ 04544 }
static struct iax2_user * realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 4456 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().
04457 { 04458 struct ast_variable *var; 04459 struct ast_variable *tmp; 04460 struct iax2_user *user=NULL; 04461 04462 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04463 if (!var) 04464 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04465 if (!var && sin) { 04466 char porta[6]; 04467 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04468 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04469 if (!var) 04470 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04471 } 04472 if (!var) { /* Last ditch effort */ 04473 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04474 /*!\note 04475 * If this one loaded something, then we need to ensure that the host 04476 * field matched. The only reason why we can't have this as a criteria 04477 * is because we only have the IP address and the host field might be 04478 * set as a name (and the reverse PTR might not match). 04479 */ 04480 if (var) { 04481 for (tmp = var; tmp; tmp = tmp->next) { 04482 if (!strcasecmp(tmp->name, "host")) { 04483 struct ast_hostent ahp; 04484 struct hostent *hp; 04485 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04486 /* No match */ 04487 ast_variables_destroy(var); 04488 var = NULL; 04489 } 04490 break; 04491 } 04492 } 04493 } 04494 } 04495 if (!var) 04496 return NULL; 04497 04498 tmp = var; 04499 while(tmp) { 04500 /* Make sure it's not a peer only... */ 04501 if (!strcasecmp(tmp->name, "type")) { 04502 if (strcasecmp(tmp->value, "friend") && 04503 strcasecmp(tmp->value, "user")) { 04504 return NULL; 04505 } 04506 } 04507 tmp = tmp->next; 04508 } 04509 04510 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)); 04511 04512 ast_variables_destroy(var); 04513 04514 if (!user) 04515 return NULL; 04516 04517 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04518 ast_set_flag64(user, IAX_RTCACHEFRIENDS); 04519 ao2_link(users, user); 04520 } else { 04521 ast_set_flag64(user, IAX_TEMPONLY); 04522 } 04523 04524 return user; 04525 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8666 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().
08667 { 08668 char data[80]; 08669 char *expiry; 08670 08671 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) { 08672 return; 08673 } 08674 08675 expiry = strrchr(data, ':'); 08676 if (!expiry) { 08677 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data); 08678 return; 08679 } 08680 *expiry++ = '\0'; 08681 08682 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) { 08683 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data); 08684 return; 08685 } 08686 08687 p->expiry = atoi(expiry); 08688 08689 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name, 08690 ast_sockaddr_stringify(&p->addr), p->expiry); 08691 08692 iax2_poke_peer(p, 0); 08693 if (p->expire > -1) { 08694 if (!ast_sched_thread_del(sched, p->expire)) { 08695 p->expire = -1; 08696 peer_unref(p); 08697 } 08698 } 08699 08700 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08701 08702 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08703 if (p->expire == -1) { 08704 peer_unref(p); 08705 } 08706 08707 if (iax2_regfunk) { 08708 iax2_regfunk(p->name, 1); 08709 } 08710 08711 register_peer_exten(p, 1); 08712 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 8581 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().
08582 { 08583 char multi[256]; 08584 char *stringp, *ext; 08585 if (!ast_strlen_zero(regcontext)) { 08586 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08587 stringp = multi; 08588 while((ext = strsep(&stringp, "&"))) { 08589 if (onoff) { 08590 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08591 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08592 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08593 } else 08594 ast_context_remove_extension(regcontext, ext, 1, NULL); 08595 } 08596 } 08597 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 7952 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().
07953 { 07954 char requeststr[256] = ""; 07955 char peer[256] = ""; 07956 char md5secret[256] = ""; 07957 char rsasecret[256] = ""; 07958 char secret[256] = ""; 07959 struct iax2_peer *p = NULL; 07960 struct ast_key *key; 07961 char *keyn; 07962 int x; 07963 int expire = 0; 07964 int res = -1; 07965 struct ast_sockaddr addr; 07966 07967 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07968 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 07969 if (ies->username) 07970 ast_copy_string(peer, ies->username, sizeof(peer)); 07971 if (ies->password) 07972 ast_copy_string(secret, ies->password, sizeof(secret)); 07973 if (ies->md5_result) 07974 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07975 if (ies->rsa_result) 07976 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07977 if (ies->refresh) 07978 expire = ies->refresh; 07979 07980 if (ast_strlen_zero(peer)) { 07981 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 07982 return -1; 07983 } 07984 07985 /* SLD: first call to lookup peer during registration */ 07986 ast_mutex_unlock(&iaxsl[callno]); 07987 p = find_peer(peer, 1); 07988 ast_mutex_lock(&iaxsl[callno]); 07989 if (!p || !iaxs[callno]) { 07990 if (iaxs[callno]) { 07991 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 07992 /* Anything, as long as it's non-blank */ 07993 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07994 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 07995 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 07996 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 07997 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 07998 * to be plaintext, indicating it is an authmethod used by other peers on the system. 07999 * 08000 * If none of these cases exist, res will be returned as 0 without authentication indicating 08001 * an AUTHREQ needs to be sent out. */ 08002 08003 if (ast_strlen_zero(iaxs[callno]->challenge) && 08004 !(!ast_strlen_zero(secret) && plaintext)) { 08005 /* by setting res to 0, an REGAUTH will be sent */ 08006 res = 0; 08007 } 08008 } 08009 if (authdebug && !p) 08010 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08011 goto return_unref; 08012 } 08013 08014 if (!ast_test_flag64(p, IAX_DYNAMIC)) { 08015 if (authdebug) 08016 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08017 goto return_unref; 08018 } 08019 08020 ast_sockaddr_from_sin(&addr, sin); 08021 if (!ast_apply_ha(p->ha, &addr)) { 08022 if (authdebug) 08023 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08024 goto return_unref; 08025 } 08026 ast_string_field_set(iaxs[callno], secret, p->secret); 08027 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 08028 /* Check secret against what we have on file */ 08029 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08030 if (!ast_strlen_zero(p->inkeys)) { 08031 char tmpkeys[256]; 08032 char *stringp=NULL; 08033 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 08034 stringp=tmpkeys; 08035 keyn = strsep(&stringp, ":"); 08036 while(keyn) { 08037 key = ast_key_get(keyn, AST_KEY_PUBLIC); 08038 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 08039 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08040 break; 08041 } else if (!key) 08042 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 08043 keyn = strsep(&stringp, ":"); 08044 } 08045 if (!keyn) { 08046 if (authdebug) 08047 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 08048 goto return_unref; 08049 } 08050 } else { 08051 if (authdebug) 08052 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 08053 goto return_unref; 08054 } 08055 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08056 struct MD5Context md5; 08057 unsigned char digest[16]; 08058 char *tmppw, *stringp; 08059 08060 tmppw = ast_strdupa(p->secret); 08061 stringp = tmppw; 08062 while((tmppw = strsep(&stringp, ";"))) { 08063 MD5Init(&md5); 08064 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 08065 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08066 MD5Final(digest, &md5); 08067 for (x=0;x<16;x++) 08068 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 08069 if (!strcasecmp(requeststr, md5secret)) 08070 break; 08071 } 08072 if (tmppw) { 08073 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08074 } else { 08075 if (authdebug) 08076 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 08077 goto return_unref; 08078 } 08079 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 08080 /* They've provided a plain text password and we support that */ 08081 if (strcmp(secret, p->secret)) { 08082 if (authdebug) 08083 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08084 goto return_unref; 08085 } else 08086 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08087 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 08088 /* if challenge has been sent, but no challenge response if given, reject. */ 08089 goto return_unref; 08090 } 08091 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08092 08093 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 08094 res = 0; 08095 08096 return_unref: 08097 if (iaxs[callno]) { 08098 ast_string_field_set(iaxs[callno], peer, peer); 08099 08100 /* Choose lowest expiry number */ 08101 if (expire && (expire < iaxs[callno]->expiry)) { 08102 iaxs[callno]->expiry = expire; 08103 } 08104 } 08105 08106 if (p) { 08107 peer_unref(p); 08108 } 08109 return res; 08110 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8888 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().
08889 { 08890 struct iax_ie_data ied; 08891 struct iax2_peer *p; 08892 char challenge[10]; 08893 const char *peer_name; 08894 int sentauthmethod; 08895 08896 peer_name = ast_strdupa(iaxs[callno]->peer); 08897 08898 /* SLD: third call to find_peer in registration */ 08899 ast_mutex_unlock(&iaxsl[callno]); 08900 if ((p = find_peer(peer_name, 1))) { 08901 last_authmethod = p->authmethods; 08902 } 08903 08904 ast_mutex_lock(&iaxsl[callno]); 08905 if (!iaxs[callno]) 08906 goto return_unref; 08907 08908 memset(&ied, 0, sizeof(ied)); 08909 /* The selection of which delayed reject is sent may leak information, 08910 * if it sets a static response. For example, if a host is known to only 08911 * use MD5 authentication, then an RSA response would indicate that the 08912 * peer does not exist, and vice-versa. 08913 * Therefore, we use whatever the last peer used (which may vary over the 08914 * course of a server, which should leak minimal information). */ 08915 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08916 if (!p) { 08917 iaxs[callno]->authmethods = sentauthmethod; 08918 } 08919 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08920 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08921 /* Build the challenge */ 08922 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08923 ast_string_field_set(iaxs[callno], challenge, challenge); 08924 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08925 } 08926 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08927 08928 return_unref: 08929 if (p) { 08930 peer_unref(p); 08931 } 08932 08933 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08934 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8936 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().
08937 { 08938 struct iax2_registry *reg; 08939 /* Start pessimistic */ 08940 struct iax_ie_data ied; 08941 char peer[256] = ""; 08942 char challenge[256] = ""; 08943 int res; 08944 int authmethods = 0; 08945 if (ies->authmethods) 08946 authmethods = ies->authmethods; 08947 if (ies->username) 08948 ast_copy_string(peer, ies->username, sizeof(peer)); 08949 if (ies->challenge) 08950 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 08951 memset(&ied, 0, sizeof(ied)); 08952 reg = iaxs[callno]->reg; 08953 if (reg) { 08954 struct sockaddr_in reg_addr; 08955 08956 ast_sockaddr_to_sin(®->addr, ®_addr); 08957 08958 if (inaddrcmp(®_addr, sin)) { 08959 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08960 return -1; 08961 } 08962 if (ast_strlen_zero(reg->secret)) { 08963 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 08964 reg->regstate = REG_STATE_NOAUTH; 08965 return -1; 08966 } 08967 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08968 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08969 if (reg->secret[0] == '[') { 08970 char tmpkey[256]; 08971 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 08972 tmpkey[strlen(tmpkey) - 1] = '\0'; 08973 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 08974 } else 08975 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 08976 if (!res) { 08977 reg->regstate = REG_STATE_AUTHSENT; 08978 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 08979 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08980 } else 08981 return -1; 08982 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 08983 } else 08984 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 08985 return -1; 08986 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 7061 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().
07062 { 07063 switch(regstate) { 07064 case REG_STATE_UNREGISTERED: 07065 return "Unregistered"; 07066 case REG_STATE_REGSENT: 07067 return "Request Sent"; 07068 case REG_STATE_AUTHSENT: 07069 return "Auth. Sent"; 07070 case REG_STATE_REGISTERED: 07071 return "Registered"; 07072 case REG_STATE_REJECTED: 07073 return "Rejected"; 07074 case REG_STATE_TIMEOUT: 07075 return "Timeout"; 07076 case REG_STATE_NOAUTH: 07077 return "No Authentication"; 07078 default: 07079 return "Unknown"; 07080 } 07081 }
static int reload | ( | void | ) | [static] |
Definition at line 13592 of file chan_iax2.c.
References reload_config().
13593 { 13594 return reload_config(); 13595 }
static int reload_config | ( | void | ) | [static] |
Definition at line 13543 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().
13544 { 13545 static const char config[] = "iax.conf"; 13546 struct iax2_registry *reg; 13547 13548 if (set_config(config, 1) > 0) { 13549 prune_peers(); 13550 prune_users(); 13551 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13552 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13553 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 13554 trunk_timed = trunk_untimed = 0; 13555 trunk_nmaxmtu = trunk_maxmtu = 0; 13556 memset(&debugaddr, '\0', sizeof(debugaddr)); 13557 13558 AST_LIST_LOCK(®istrations); 13559 AST_LIST_TRAVERSE(®istrations, reg, entry) 13560 iax2_do_register(reg); 13561 AST_LIST_UNLOCK(®istrations); 13562 13563 /* Qualify hosts, too */ 13564 poke_all_peers(); 13565 } 13566 13567 reload_firmware(0); 13568 iax_provision_reload(1); 13569 ast_unload_realtime("iaxpeers"); 13570 13571 return 0; 13572 }
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 4836 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().
04837 { 04838 struct iax2_user *user = NULL; 04839 struct iax2_peer *peer = NULL; 04840 04841 if (ast_strlen_zero(name)) { 04842 return; /* no username given */ 04843 } 04844 04845 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04846 user->calltoken_required = CALLTOKEN_YES; 04847 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04848 peer->calltoken_required = CALLTOKEN_YES; 04849 } 04850 04851 if (peer) { 04852 peer_unref(peer); 04853 } 04854 if (user) { 04855 user_unref(user); 04856 } 04857 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4754 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().
04755 { 04756 struct chan_iax2_pvt *pvt = iaxs[callno]; 04757 int frametype = f->af.frametype; 04758 int subclass = f->af.subclass.integer; 04759 struct { 04760 struct ast_iax2_full_hdr fh; 04761 struct iax_ie_data ied; 04762 } data = { 04763 .ied.buf = { 0 }, 04764 .ied.pos = 0, 04765 }; 04766 /* total len - header len gives us the frame's IE len */ 04767 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04768 04769 if (!pvt) { 04770 return; /* this should not be possible if called from socket_process() */ 04771 } 04772 04773 /* 04774 * Check to make sure last frame sent is valid for call token resend 04775 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04776 * 2. Frame should _NOT_ already have a destination callno 04777 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04778 * 4. Pvt must have a calltoken_ie_len which represents the number of 04779 * bytes at the end of the frame used for the previous calltoken ie. 04780 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04781 * 6. Total length of f->data must be _LESS_ than size of our data struct 04782 * because f->data must be able to fit within data. 04783 */ 04784 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04785 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04786 (f->datalen > sizeof(data))) { 04787 04788 return; /* ignore resend, token was not valid for the dialog */ 04789 } 04790 04791 /* token is valid 04792 * 1. Copy frame data over 04793 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04794 * NOTE: Having the ie always be last is not protocol specified, 04795 * it is only an implementation choice. Since we only expect the ie to 04796 * be last for frames we have sent, this can no way be affected by 04797 * another end point. 04798 * 3. Remove frame from queue 04799 * 4. Free old frame 04800 * 5. Clear previous seqnos 04801 * 6. Resend with CALLTOKEN ie. 04802 */ 04803 04804 /* ---1.--- */ 04805 memcpy(&data, f->data, f->datalen); 04806 data.ied.pos = ie_data_pos; 04807 04808 /* ---2.--- */ 04809 /* move to the beginning of the calltoken ie so we can write over it */ 04810 data.ied.pos -= pvt->calltoken_ie_len; 04811 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04812 04813 /* make sure to update token length incase it ever has to be stripped off again */ 04814 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04815 04816 /* ---3.--- */ 04817 AST_LIST_REMOVE(&frame_queue[callno], f, list); 04818 04819 /* ---4.--- */ 04820 iax2_frame_free(f); 04821 04822 /* ---5.--- */ 04823 pvt->oseqno = 0; 04824 pvt->rseqno = 0; 04825 pvt->iseqno = 0; 04826 pvt->aseqno = 0; 04827 if (pvt->peercallno) { 04828 remove_by_peercallno(pvt); 04829 pvt->peercallno = 0; 04830 } 04831 04832 /* ---6.--- */ 04833 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04834 }
Definition at line 9467 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().
09468 { 09469 int i; 09470 unsigned int length, offset = 0; 09471 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09472 09473 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09474 length = ies->ospblocklength[i]; 09475 if (length != 0) { 09476 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09477 /* OSP token block length wrong, clear buffer */ 09478 offset = 0; 09479 break; 09480 } else { 09481 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09482 offset += length; 09483 } 09484 } else { 09485 break; 09486 } 09487 } 09488 *(full_osptoken + offset) = '\0'; 09489 if (strlen(full_osptoken) != offset) { 09490 /* OSP token length wrong, clear buffer */ 09491 *full_osptoken = '\0'; 09492 } 09493 09494 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09495 }
Definition at line 9456 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().
09457 { 09458 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09459 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09460 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09461 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09462 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09463 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09464 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09465 }
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 4153 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().
04154 { 04155 int type, len; 04156 int ret; 04157 int needfree = 0; 04158 struct ast_channel *owner = NULL; 04159 struct ast_channel *bridge = NULL; 04160 04161 /* 04162 * Clear fr->af.data if there is no data in the buffer. Things 04163 * like AST_CONTROL_HOLD without a suggested music class must 04164 * have a NULL pointer. 04165 */ 04166 if (!fr->af.datalen) { 04167 memset(&fr->af.data, 0, sizeof(fr->af.data)); 04168 } 04169 04170 /* Attempt to recover wrapped timestamps */ 04171 unwrap_timestamp(fr); 04172 04173 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 04174 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 04175 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 04176 else { 04177 #if 0 04178 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 04179 #endif 04180 fr->af.delivery = ast_tv(0,0); 04181 } 04182 04183 type = JB_TYPE_CONTROL; 04184 len = 0; 04185 04186 if(fr->af.frametype == AST_FRAME_VOICE) { 04187 type = JB_TYPE_VOICE; 04188 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000); 04189 } else if(fr->af.frametype == AST_FRAME_CNG) { 04190 type = JB_TYPE_SILENCE; 04191 } 04192 04193 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04194 if (tsout) 04195 *tsout = fr->ts; 04196 __do_deliver(fr); 04197 return -1; 04198 } 04199 04200 iax2_lock_owner(fr->callno); 04201 if (!iaxs[fr->callno]) { 04202 /* The call dissappeared so discard this frame that we could not send. */ 04203 iax2_frame_free(fr); 04204 return -1; 04205 } 04206 if ((owner = iaxs[fr->callno]->owner)) 04207 bridge = ast_bridged_channel(owner); 04208 04209 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04210 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04211 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04212 jb_frame frame; 04213 04214 ast_channel_unlock(owner); 04215 04216 /* deliver any frames in the jb */ 04217 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04218 __do_deliver(frame.data); 04219 /* __do_deliver() can make the call disappear */ 04220 if (!iaxs[fr->callno]) 04221 return -1; 04222 } 04223 04224 jb_reset(iaxs[fr->callno]->jb); 04225 04226 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid); 04227 04228 /* deliver this frame now */ 04229 if (tsout) 04230 *tsout = fr->ts; 04231 __do_deliver(fr); 04232 return -1; 04233 } 04234 if (owner) { 04235 ast_channel_unlock(owner); 04236 } 04237 04238 /* insert into jitterbuffer */ 04239 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04240 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04241 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04242 if (ret == JB_DROP) { 04243 needfree++; 04244 } else if (ret == JB_SCHED) { 04245 update_jbsched(iaxs[fr->callno]); 04246 } 04247 if (tsout) 04248 *tsout = fr->ts; 04249 if (needfree) { 04250 /* Free our iax frame */ 04251 iax2_frame_free(fr); 04252 return -1; 04253 } 04254 return 0; 04255 }
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 4716 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().
04719 { 04720 struct { 04721 struct ast_iax2_full_hdr f; 04722 struct iax_ie_data ied; 04723 } data; 04724 size_t size = sizeof(struct ast_iax2_full_hdr); 04725 04726 if (ied) { 04727 size += ied->pos; 04728 memcpy(&data.ied, ied->buf, ied->pos); 04729 } 04730 04731 data.f.scallno = htons(0x8000 | callno); 04732 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS); 04733 data.f.ts = htonl(ts); 04734 data.f.iseqno = seqno; 04735 data.f.oseqno = 0; 04736 data.f.type = AST_FRAME_IAX; 04737 data.f.csub = compress_subclass(command); 04738 04739 iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr)); 04740 04741 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04742 }
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 7500 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().
07501 { 07502 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07503 }
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 7519 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().
07520 { 07521 int call_num = i->callno; 07522 /* It is assumed that the callno has already been locked */ 07523 iax2_predestroy(i->callno); 07524 if (!iaxs[call_num]) 07525 return -1; 07526 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07527 }
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 7529 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07530 { 07531 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07532 }
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 7505 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().
07506 { 07507 int res; 07508 ast_mutex_lock(&iaxsl[callno]); 07509 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07510 ast_mutex_unlock(&iaxsl[callno]); 07511 return res; 07512 }
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 7534 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07535 { 07536 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07537 }
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 9120 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().
09121 { 09122 int res = 0; 09123 struct iax_frame *fr; 09124 struct ast_iax2_meta_hdr *meta; 09125 struct ast_iax2_meta_trunk_hdr *mth; 09126 int calls = 0; 09127 09128 /* Point to frame */ 09129 fr = (struct iax_frame *)tpeer->trunkdata; 09130 /* Point to meta data */ 09131 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 09132 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 09133 if (tpeer->trunkdatalen) { 09134 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 09135 meta->zeros = 0; 09136 meta->metacmd = IAX_META_TRUNK; 09137 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) 09138 meta->cmddata = IAX_META_TRUNK_MINI; 09139 else 09140 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 09141 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 09142 /* And the rest of the ast_iax2 header */ 09143 fr->direction = DIRECTION_OUTGRESS; 09144 fr->retrans = -1; 09145 fr->transfer = 0; 09146 /* Any appropriate call will do */ 09147 fr->data = fr->afdata; 09148 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 09149 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 09150 calls = tpeer->calls; 09151 #if 0 09152 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)); 09153 #endif 09154 /* Reset transmit trunk side data */ 09155 tpeer->trunkdatalen = 0; 09156 tpeer->calls = 0; 09157 } 09158 if (res < 0) 09159 return res; 09160 return calls; 09161 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 13047 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().
13048 { 13049 struct ast_config *cfg, *ucfg; 13050 format_t capability = iax2_capability; 13051 struct ast_variable *v; 13052 char *cat; 13053 const char *utype; 13054 const char *tosval; 13055 int format; 13056 int portno = IAX_DEFAULT_PORTNO; 13057 int x; 13058 int mtuv; 13059 int subscribe_network_change = 1; 13060 struct iax2_user *user; 13061 struct iax2_peer *peer; 13062 struct ast_netsock *ns; 13063 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 13064 #if 0 13065 static unsigned short int last_port=0; 13066 #endif 13067 13068 cfg = ast_config_load(config_file, config_flags); 13069 13070 if (!cfg) { 13071 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 13072 return -1; 13073 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 13074 ucfg = ast_config_load("users.conf", config_flags); 13075 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 13076 return 0; 13077 /* Otherwise we need to reread both files */ 13078 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13079 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 13080 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13081 ast_config_destroy(ucfg); 13082 return 0; 13083 } 13084 if (!cfg) { 13085 /* should have been able to load the config here */ 13086 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file); 13087 return -1; 13088 } 13089 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 13090 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13091 return 0; 13092 } else { /* iax.conf changed, gotta reread users.conf, too */ 13093 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13094 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 13095 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 13096 ast_config_destroy(cfg); 13097 return 0; 13098 } 13099 } 13100 13101 if (reload) { 13102 set_config_destroy(); 13103 } 13104 13105 /* Reset global codec prefs */ 13106 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 13107 13108 /* Reset Global Flags */ 13109 memset(&globalflags, 0, sizeof(globalflags)); 13110 ast_set_flag64(&globalflags, IAX_RTUPDATE); 13111 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13112 13113 #ifdef SO_NO_CHECK 13114 nochecksums = 0; 13115 #endif 13116 /* Reset default parking lot */ 13117 default_parkinglot[0] = '\0'; 13118 13119 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13120 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13121 global_max_trunk_mtu = MAX_TRUNK_MTU; 13122 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 13123 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 13124 13125 maxauthreq = 3; 13126 13127 srvlookup = 0; 13128 13129 v = ast_variable_browse(cfg, "general"); 13130 13131 /* Seed initial tos value */ 13132 tosval = ast_variable_retrieve(cfg, "general", "tos"); 13133 if (tosval) { 13134 if (ast_str2tos(tosval, &qos.tos)) 13135 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 13136 } 13137 /* Seed initial cos value */ 13138 tosval = ast_variable_retrieve(cfg, "general", "cos"); 13139 if (tosval) { 13140 if (ast_str2cos(tosval, &qos.cos)) 13141 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 13142 } 13143 while(v) { 13144 if (!strcasecmp(v->name, "bindport")){ 13145 if (reload) 13146 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 13147 else 13148 portno = atoi(v->value); 13149 } else if (!strcasecmp(v->name, "pingtime")) 13150 ping_time = atoi(v->value); 13151 else if (!strcasecmp(v->name, "iaxthreadcount")) { 13152 if (reload) { 13153 if (atoi(v->value) != iaxthreadcount) 13154 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 13155 } else { 13156 iaxthreadcount = atoi(v->value); 13157 if (iaxthreadcount < 1) { 13158 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 13159 iaxthreadcount = 1; 13160 } else if (iaxthreadcount > 256) { 13161 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 13162 iaxthreadcount = 256; 13163 } 13164 } 13165 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 13166 if (reload) { 13167 AST_LIST_LOCK(&dynamic_list); 13168 iaxmaxthreadcount = atoi(v->value); 13169 AST_LIST_UNLOCK(&dynamic_list); 13170 } else { 13171 iaxmaxthreadcount = atoi(v->value); 13172 if (iaxmaxthreadcount < 0) { 13173 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 13174 iaxmaxthreadcount = 0; 13175 } else if (iaxmaxthreadcount > 256) { 13176 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 13177 iaxmaxthreadcount = 256; 13178 } 13179 } 13180 } else if (!strcasecmp(v->name, "nochecksums")) { 13181 #ifdef SO_NO_CHECK 13182 if (ast_true(v->value)) 13183 nochecksums = 1; 13184 else 13185 nochecksums = 0; 13186 #else 13187 if (ast_true(v->value)) 13188 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 13189 #endif 13190 } 13191 else if (!strcasecmp(v->name, "maxjitterbuffer")) 13192 maxjitterbuffer = atoi(v->value); 13193 else if (!strcasecmp(v->name, "resyncthreshold")) 13194 resyncthreshold = atoi(v->value); 13195 else if (!strcasecmp(v->name, "maxjitterinterps")) 13196 maxjitterinterps = atoi(v->value); 13197 else if (!strcasecmp(v->name, "jittertargetextra")) 13198 jittertargetextra = atoi(v->value); 13199 else if (!strcasecmp(v->name, "lagrqtime")) 13200 lagrq_time = atoi(v->value); 13201 else if (!strcasecmp(v->name, "maxregexpire")) 13202 max_reg_expire = atoi(v->value); 13203 else if (!strcasecmp(v->name, "minregexpire")) 13204 min_reg_expire = atoi(v->value); 13205 else if (!strcasecmp(v->name, "bindaddr")) { 13206 if (reload) { 13207 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 13208 } else { 13209 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 13210 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 13211 } else { 13212 if (strchr(v->value, ':')) 13213 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 13214 else 13215 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 13216 if (defaultsockfd < 0) 13217 defaultsockfd = ast_netsock_sockfd(ns); 13218 ast_netsock_unref(ns); 13219 } 13220 } 13221 } else if (!strcasecmp(v->name, "authdebug")) { 13222 authdebug = ast_true(v->value); 13223 } else if (!strcasecmp(v->name, "encryption")) { 13224 iax2_encryption |= get_encrypt_methods(v->value); 13225 if (!iax2_encryption) { 13226 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13227 } 13228 } else if (!strcasecmp(v->name, "forceencryption")) { 13229 if (ast_false(v->value)) { 13230 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13231 } else { 13232 iax2_encryption |= get_encrypt_methods(v->value); 13233 if (iax2_encryption) { 13234 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13235 } 13236 } 13237 } else if (!strcasecmp(v->name, "transfer")) { 13238 if (!strcasecmp(v->value, "mediaonly")) { 13239 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13240 } else if (ast_true(v->value)) { 13241 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13242 } else 13243 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13244 } else if (!strcasecmp(v->name, "codecpriority")) { 13245 if(!strcasecmp(v->value, "caller")) 13246 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST); 13247 else if(!strcasecmp(v->value, "disabled")) 13248 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13249 else if(!strcasecmp(v->value, "reqonly")) { 13250 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP); 13251 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13252 } 13253 } else if (!strcasecmp(v->name, "jitterbuffer")) 13254 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 13255 else if (!strcasecmp(v->name, "forcejitterbuffer")) 13256 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 13257 else if (!strcasecmp(v->name, "delayreject")) 13258 delayreject = ast_true(v->value); 13259 else if (!strcasecmp(v->name, "allowfwdownload")) 13260 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 13261 else if (!strcasecmp(v->name, "rtcachefriends")) 13262 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 13263 else if (!strcasecmp(v->name, "rtignoreregexpire")) 13264 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 13265 else if (!strcasecmp(v->name, "rtupdate")) 13266 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE); 13267 else if (!strcasecmp(v->name, "rtsavesysname")) 13268 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME); 13269 else if (!strcasecmp(v->name, "trunktimestamps")) 13270 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 13271 else if (!strcasecmp(v->name, "rtautoclear")) { 13272 int i = atoi(v->value); 13273 if(i > 0) 13274 global_rtautoclear = i; 13275 else 13276 i = 0; 13277 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 13278 } else if (!strcasecmp(v->name, "trunkfreq")) { 13279 trunkfreq = atoi(v->value); 13280 if (trunkfreq < 10) { 13281 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n"); 13282 trunkfreq = 10; 13283 } else if (trunkfreq > 1000) { 13284 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n"); 13285 trunkfreq = 1000; 13286 } 13287 if (timer) { 13288 ast_timer_set_rate(timer, 1000 / trunkfreq); 13289 } 13290 } else if (!strcasecmp(v->name, "trunkmtu")) { 13291 mtuv = atoi(v->value); 13292 if (mtuv == 0 ) 13293 global_max_trunk_mtu = 0; 13294 else if (mtuv >= 172 && mtuv < 4000) 13295 global_max_trunk_mtu = mtuv; 13296 else 13297 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 13298 mtuv, v->lineno); 13299 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 13300 trunkmaxsize = atoi(v->value); 13301 if (trunkmaxsize == 0) 13302 trunkmaxsize = MAX_TRUNKDATA; 13303 } else if (!strcasecmp(v->name, "autokill")) { 13304 if (sscanf(v->value, "%30d", &x) == 1) { 13305 if (x >= 0) 13306 autokill = x; 13307 else 13308 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 13309 } else if (ast_true(v->value)) { 13310 autokill = DEFAULT_MAXMS; 13311 } else { 13312 autokill = 0; 13313 } 13314 } else if (!strcasecmp(v->name, "bandwidth")) { 13315 if (!strcasecmp(v->value, "low")) { 13316 capability = IAX_CAPABILITY_LOWBANDWIDTH; 13317 } else if (!strcasecmp(v->value, "medium")) { 13318 capability = IAX_CAPABILITY_MEDBANDWIDTH; 13319 } else if (!strcasecmp(v->value, "high")) { 13320 capability = IAX_CAPABILITY_FULLBANDWIDTH; 13321 } else 13322 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 13323 } else if (!strcasecmp(v->name, "allow")) { 13324 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 13325 } else if (!strcasecmp(v->name, "disallow")) { 13326 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 13327 } else if (!strcasecmp(v->name, "register")) { 13328 iax2_register(v->value, v->lineno); 13329 } else if (!strcasecmp(v->name, "iaxcompat")) { 13330 iaxcompat = ast_true(v->value); 13331 } else if (!strcasecmp(v->name, "regcontext")) { 13332 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 13333 /* Create context if it doesn't exist already */ 13334 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 13335 } else if (!strcasecmp(v->name, "tos")) { 13336 if (ast_str2tos(v->value, &qos.tos)) 13337 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 13338 } else if (!strcasecmp(v->name, "cos")) { 13339 if (ast_str2cos(v->value, &qos.cos)) 13340 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 13341 } else if (!strcasecmp(v->name, "parkinglot")) { 13342 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 13343 } else if (!strcasecmp(v->name, "accountcode")) { 13344 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 13345 } else if (!strcasecmp(v->name, "mohinterpret")) { 13346 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 13347 } else if (!strcasecmp(v->name, "mohsuggest")) { 13348 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 13349 } else if (!strcasecmp(v->name, "amaflags")) { 13350 format = ast_cdr_amaflags2int(v->value); 13351 if (format < 0) { 13352 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13353 } else { 13354 amaflags = format; 13355 } 13356 } else if (!strcasecmp(v->name, "language")) { 13357 ast_copy_string(language, v->value, sizeof(language)); 13358 } else if (!strcasecmp(v->name, "maxauthreq")) { 13359 maxauthreq = atoi(v->value); 13360 if (maxauthreq < 0) 13361 maxauthreq = 0; 13362 } else if (!strcasecmp(v->name, "adsi")) { 13363 adsi = ast_true(v->value); 13364 } else if (!strcasecmp(v->name, "srvlookup")) { 13365 srvlookup = ast_true(v->value); 13366 } else if (!strcasecmp(v->name, "connectedline")) { 13367 if (ast_true(v->value)) { 13368 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13369 } else if (!strcasecmp(v->value, "send")) { 13370 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13371 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13372 } else if (!strcasecmp(v->value, "receive")) { 13373 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13374 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13375 } else { 13376 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13377 } 13378 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 13379 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 13380 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 13381 } 13382 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 13383 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 13384 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); 13385 } 13386 } else if (!strcasecmp(v->name, "calltokenoptional")) { 13387 if (add_calltoken_ignore(v->value)) { 13388 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 13389 } 13390 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 13391 if (ast_true(v->value)) { 13392 subscribe_network_change = 1; 13393 } else if (ast_false(v->value)) { 13394 subscribe_network_change = 0; 13395 } else { 13396 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 13397 } 13398 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 13399 if (ast_true(v->value)) { 13400 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13401 } else if (ast_false(v->value)) { 13402 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID); 13403 } else { 13404 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 13405 } 13406 }/*else if (strcasecmp(v->name,"type")) */ 13407 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13408 v = v->next; 13409 } 13410 13411 if (subscribe_network_change) { 13412 network_change_event_subscribe(); 13413 } else { 13414 network_change_event_unsubscribe(); 13415 } 13416 13417 if (defaultsockfd < 0) { 13418 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 13419 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 13420 } else { 13421 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 13422 defaultsockfd = ast_netsock_sockfd(ns); 13423 ast_netsock_unref(ns); 13424 } 13425 } 13426 if (reload) { 13427 ast_netsock_release(outsock); 13428 outsock = ast_netsock_list_alloc(); 13429 if (!outsock) { 13430 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13431 return -1; 13432 } 13433 ast_netsock_init(outsock); 13434 } 13435 13436 if (min_reg_expire > max_reg_expire) { 13437 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 13438 min_reg_expire, max_reg_expire, max_reg_expire); 13439 min_reg_expire = max_reg_expire; 13440 } 13441 iax2_capability = capability; 13442 13443 if (ucfg) { 13444 struct ast_variable *gen; 13445 int genhasiax; 13446 int genregisteriax; 13447 const char *hasiax, *registeriax; 13448 13449 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 13450 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 13451 gen = ast_variable_browse(ucfg, "general"); 13452 cat = ast_category_browse(ucfg, NULL); 13453 while (cat) { 13454 if (strcasecmp(cat, "general")) { 13455 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 13456 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 13457 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 13458 /* Start with general parameters, then specific parameters, user and peer */ 13459 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 13460 if (user) { 13461 ao2_link(users, user); 13462 user = user_unref(user); 13463 } 13464 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 13465 if (peer) { 13466 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13467 reg_source_db(peer); 13468 ao2_link(peers, peer); 13469 peer = peer_unref(peer); 13470 } 13471 } 13472 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 13473 char tmp[256]; 13474 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 13475 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 13476 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 13477 if (!host) 13478 host = ast_variable_retrieve(ucfg, "general", "host"); 13479 if (!username) 13480 username = ast_variable_retrieve(ucfg, "general", "username"); 13481 if (!secret) 13482 secret = ast_variable_retrieve(ucfg, "general", "secret"); 13483 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 13484 if (!ast_strlen_zero(secret)) 13485 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 13486 else 13487 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 13488 iax2_register(tmp, 0); 13489 } 13490 } 13491 } 13492 cat = ast_category_browse(ucfg, cat); 13493 } 13494 ast_config_destroy(ucfg); 13495 } 13496 13497 cat = ast_category_browse(cfg, NULL); 13498 while(cat) { 13499 if (strcasecmp(cat, "general")) { 13500 utype = ast_variable_retrieve(cfg, cat, "type"); 13501 if (!strcasecmp(cat, "callnumberlimits")) { 13502 build_callno_limits(ast_variable_browse(cfg, cat)); 13503 } else if (utype) { 13504 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 13505 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 13506 if (user) { 13507 ao2_link(users, user); 13508 user = user_unref(user); 13509 } 13510 } 13511 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 13512 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 13513 if (peer) { 13514 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13515 reg_source_db(peer); 13516 ao2_link(peers, peer); 13517 peer = peer_unref(peer); 13518 } 13519 } else if (strcasecmp(utype, "user")) { 13520 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 13521 } 13522 } else 13523 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 13524 } 13525 cat = ast_category_browse(cfg, cat); 13526 } 13527 ast_config_destroy(cfg); 13528 return 1; 13529 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 13030 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().
13031 { 13032 strcpy(accountcode, ""); 13033 strcpy(language, ""); 13034 strcpy(mohinterpret, ""); 13035 strcpy(mohsuggest, ""); 13036 trunkmaxsize = MAX_TRUNKDATA; 13037 amaflags = 0; 13038 delayreject = 0; 13039 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | 13040 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13041 delete_users(); 13042 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 13043 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 13044 }
static void set_hangup_source_and_cause | ( | int | callno, | |
unsigned char | causecode | |||
) | [static] |
Definition at line 9893 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().
09894 { 09895 iax2_lock_owner(callno); 09896 if (iaxs[callno] && iaxs[callno]->owner) { 09897 struct ast_channel *owner; 09898 const char *name; 09899 09900 owner = iaxs[callno]->owner; 09901 if (causecode) { 09902 owner->hangupcause = causecode; 09903 } 09904 name = ast_strdupa(owner->name); 09905 ast_channel_ref(owner); 09906 ast_channel_unlock(owner); 09907 ast_mutex_unlock(&iaxsl[callno]); 09908 ast_set_hangupsource(owner, name, 0); 09909 ast_channel_unref(owner); 09910 ast_mutex_lock(&iaxsl[callno]); 09911 } 09912 }
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 9914 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_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, 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_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().
09915 { 09916 struct sockaddr_in sin; 09917 int res; 09918 int updatehistory=1; 09919 int new = NEW_PREVENT; 09920 int dcallno = 0; 09921 char decrypted = 0; 09922 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09923 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09924 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09925 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09926 struct iax_frame *fr; 09927 struct iax_frame *cur; 09928 struct ast_frame f = { 0, }; 09929 struct ast_channel *c = NULL; 09930 struct iax2_dpcache *dp; 09931 struct iax2_peer *peer; 09932 struct iax_ies ies; 09933 struct iax_ie_data ied0, ied1; 09934 format_t format; 09935 int fd; 09936 int exists; 09937 int minivid = 0; 09938 char empty[32]=""; /* Safety measure */ 09939 struct iax_frame *duped_fr; 09940 char host_pref_buf[128]; 09941 char caller_pref_buf[128]; 09942 struct ast_codec_pref pref; 09943 char *using_prefs = "mine"; 09944 09945 /* allocate an iax_frame with 4096 bytes of data buffer */ 09946 fr = ast_alloca(sizeof(*fr) + 4096); 09947 memset(fr, 0, sizeof(*fr)); 09948 fr->afdatalen = 4096; /* From ast_alloca() above */ 09949 09950 /* Copy frequently used parameters to the stack */ 09951 res = thread->buf_len; 09952 fd = thread->iofd; 09953 memcpy(&sin, &thread->iosin, sizeof(sin)); 09954 09955 if (res < sizeof(*mh)) { 09956 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09957 return 1; 09958 } 09959 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09960 if (res < sizeof(*vh)) { 09961 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)); 09962 return 1; 09963 } 09964 09965 /* This is a video frame, get call number */ 09966 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 09967 minivid = 1; 09968 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 09969 return socket_process_meta(res, meta, &sin, fd, fr); 09970 09971 #ifdef DEBUG_SUPPORT 09972 if (res >= sizeof(*fh)) 09973 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 09974 #endif 09975 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09976 if (res < sizeof(*fh)) { 09977 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)); 09978 return 1; 09979 } 09980 09981 /* Get the destination call number */ 09982 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 09983 09984 09985 /* check to make sure this full frame isn't encrypted before we attempt 09986 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 09987 * callno is not found here, that just means one hasn't been allocated for 09988 * this connection yet. */ 09989 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 09990 ast_mutex_lock(&iaxsl[fr->callno]); 09991 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { 09992 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09993 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09994 ast_mutex_unlock(&iaxsl[fr->callno]); 09995 return 1; 09996 } 09997 decrypted = 1; 09998 } 09999 ast_mutex_unlock(&iaxsl[fr->callno]); 10000 } 10001 10002 /* Retrieve the type and subclass */ 10003 f.frametype = fh->type; 10004 if (f.frametype == AST_FRAME_VIDEO) { 10005 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 10006 } else if (f.frametype == AST_FRAME_VOICE) { 10007 f.subclass.codec = uncompress_subclass(fh->csub); 10008 } else { 10009 f.subclass.integer = uncompress_subclass(fh->csub); 10010 } 10011 10012 /* Deal with POKE/PONG without allocating a callno */ 10013 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) { 10014 /* Reply back with a PONG, but don't care about the result. */ 10015 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10016 return 1; 10017 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) { 10018 /* Ignore */ 10019 return 1; 10020 } 10021 10022 f.datalen = res - sizeof(*fh); 10023 if (f.datalen) { 10024 if (f.frametype == AST_FRAME_IAX) { 10025 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 10026 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 10027 ast_variables_destroy(ies.vars); 10028 return 1; 10029 } 10030 f.data.ptr = NULL; 10031 f.datalen = 0; 10032 } else { 10033 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 10034 memset(&ies, 0, sizeof(ies)); 10035 } 10036 } else { 10037 if (f.frametype == AST_FRAME_IAX) 10038 f.data.ptr = NULL; 10039 else 10040 f.data.ptr = empty; 10041 memset(&ies, 0, sizeof(ies)); 10042 } 10043 10044 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) { 10045 /* only set NEW_ALLOW if calltoken checks out */ 10046 if (handle_call_token(fh, &ies, &sin, fd)) { 10047 ast_variables_destroy(ies.vars); 10048 return 1; 10049 } 10050 10051 if (ies.calltoken && ies.calltokendata) { 10052 /* if we've gotten this far, and the calltoken ie data exists, 10053 * then calltoken validation _MUST_ have taken place. If calltoken 10054 * data is provided, it is always validated reguardless of any 10055 * calltokenoptional or requirecalltoken options */ 10056 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 10057 } else { 10058 new = NEW_ALLOW; 10059 } 10060 } 10061 } else { 10062 /* Don't know anything about it yet */ 10063 f.frametype = AST_FRAME_NULL; 10064 f.subclass.integer = 0; 10065 memset(&ies, 0, sizeof(ies)); 10066 } 10067 10068 if (!fr->callno) { 10069 int check_dcallno = 0; 10070 10071 /* 10072 * We enforce accurate destination call numbers for ACKs. This forces the other 10073 * end to know the destination call number before call setup can complete. 10074 * 10075 * Discussed in the following thread: 10076 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 10077 */ 10078 10079 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) { 10080 check_dcallno = 1; 10081 } 10082 10083 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 10084 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) { 10085 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10086 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) { 10087 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10088 } 10089 ast_variables_destroy(ies.vars); 10090 return 1; 10091 } 10092 } 10093 10094 if (fr->callno > 0) 10095 ast_mutex_lock(&iaxsl[fr->callno]); 10096 10097 if (!fr->callno || !iaxs[fr->callno]) { 10098 /* A call arrived for a nonexistent destination. Unless it's an "inval" 10099 frame, reply with an inval */ 10100 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10101 /* We can only raw hangup control frames */ 10102 if (((f.subclass.integer != IAX_COMMAND_INVAL) && 10103 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10104 (f.subclass.integer != IAX_COMMAND_TXACC) && 10105 (f.subclass.integer != IAX_COMMAND_FWDOWNL))|| 10106 (f.frametype != AST_FRAME_IAX)) 10107 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 10108 fd); 10109 } 10110 if (fr->callno > 0) 10111 ast_mutex_unlock(&iaxsl[fr->callno]); 10112 ast_variables_destroy(ies.vars); 10113 return 1; 10114 } 10115 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 10116 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10117 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10118 ast_variables_destroy(ies.vars); 10119 ast_mutex_unlock(&iaxsl[fr->callno]); 10120 return 1; 10121 } 10122 decrypted = 1; 10123 } 10124 10125 #ifdef DEBUG_SUPPORT 10126 if (decrypted) { 10127 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 10128 } 10129 #endif 10130 10131 10132 /* count this frame */ 10133 iaxs[fr->callno]->frames_received++; 10134 10135 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 10136 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */ 10137 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */ 10138 unsigned short new_peercallno; 10139 10140 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 10141 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 10142 if (iaxs[fr->callno]->peercallno) { 10143 remove_by_peercallno(iaxs[fr->callno]); 10144 } 10145 iaxs[fr->callno]->peercallno = new_peercallno; 10146 store_by_peercallno(iaxs[fr->callno]); 10147 } 10148 } 10149 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10150 if (iaxdebug) 10151 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer); 10152 /* Check if it's out of order (and not an ACK or INVAL) */ 10153 fr->oseqno = fh->oseqno; 10154 fr->iseqno = fh->iseqno; 10155 fr->ts = ntohl(fh->ts); 10156 #ifdef IAXTESTS 10157 if (test_resync) { 10158 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 10159 fr->ts += test_resync; 10160 } 10161 #endif /* IAXTESTS */ 10162 #if 0 10163 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 10164 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 10165 (f.subclass == IAX_COMMAND_NEW || 10166 f.subclass == IAX_COMMAND_AUTHREQ || 10167 f.subclass == IAX_COMMAND_ACCEPT || 10168 f.subclass == IAX_COMMAND_REJECT)) ) ) 10169 #endif 10170 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 10171 updatehistory = 0; 10172 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 10173 (iaxs[fr->callno]->iseqno || 10174 ((f.subclass.integer != IAX_COMMAND_TXCNT) && 10175 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10176 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10177 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10178 (f.subclass.integer != IAX_COMMAND_TXACC)) || 10179 (f.frametype != AST_FRAME_IAX))) { 10180 if ( 10181 ((f.subclass.integer != IAX_COMMAND_ACK) && 10182 (f.subclass.integer != IAX_COMMAND_INVAL) && 10183 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10184 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10185 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10186 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10187 (f.subclass.integer != IAX_COMMAND_TXACC) && 10188 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10189 (f.frametype != AST_FRAME_IAX)) { 10190 /* If it's not an ACK packet, it's out of order. */ 10191 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 10192 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer); 10193 /* Check to see if we need to request retransmission, 10194 * and take sequence number wraparound into account */ 10195 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 10196 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 10197 if ((f.frametype != AST_FRAME_IAX) || 10198 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) { 10199 ast_debug(1, "Acking anyway\n"); 10200 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 10201 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 10202 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10203 } 10204 } else { 10205 /* Send a VNAK requesting retransmission */ 10206 iax2_vnak(fr->callno); 10207 } 10208 ast_variables_destroy(ies.vars); 10209 ast_mutex_unlock(&iaxsl[fr->callno]); 10210 return 1; 10211 } 10212 } else { 10213 /* Increment unless it's an ACK or VNAK */ 10214 if (((f.subclass.integer != IAX_COMMAND_ACK) && 10215 (f.subclass.integer != IAX_COMMAND_INVAL) && 10216 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10217 (f.subclass.integer != IAX_COMMAND_TXACC) && 10218 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10219 (f.frametype != AST_FRAME_IAX)) 10220 iaxs[fr->callno]->iseqno++; 10221 } 10222 /* Ensure text frames are NULL-terminated */ 10223 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 10224 if (res < thread->buf_size) 10225 thread->buf[res++] = '\0'; 10226 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 10227 thread->buf[res - 1] = '\0'; 10228 } 10229 10230 /* Handle implicit ACKing unless this is an INVAL, and only if this is 10231 from the real peer, not the transfer peer */ 10232 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10233 ((f.subclass.integer != IAX_COMMAND_INVAL) || 10234 (f.frametype != AST_FRAME_IAX))) { 10235 unsigned char x; 10236 int call_to_destroy; 10237 /* First we have to qualify that the ACKed value is within our window */ 10238 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 10239 x = fr->iseqno; 10240 else 10241 x = iaxs[fr->callno]->oseqno; 10242 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 10243 /* The acknowledgement is within our window. Time to acknowledge everything 10244 that it says to */ 10245 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 10246 /* Ack the packet with the given timestamp */ 10247 if (iaxdebug) 10248 ast_debug(1, "Cancelling transmission of packet %d\n", x); 10249 call_to_destroy = 0; 10250 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10251 /* If it's our call, and our timestamp, mark -1 retries */ 10252 if (x == cur->oseqno) { 10253 cur->retries = -1; 10254 /* Destroy call if this is the end */ 10255 if (cur->final) 10256 call_to_destroy = fr->callno; 10257 } 10258 } 10259 if (call_to_destroy) { 10260 if (iaxdebug) 10261 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 10262 ast_mutex_lock(&iaxsl[call_to_destroy]); 10263 iax2_destroy(call_to_destroy); 10264 ast_mutex_unlock(&iaxsl[call_to_destroy]); 10265 } 10266 } 10267 /* Note how much we've received acknowledgement for */ 10268 if (iaxs[fr->callno]) 10269 iaxs[fr->callno]->rseqno = fr->iseqno; 10270 else { 10271 /* Stop processing now */ 10272 ast_variables_destroy(ies.vars); 10273 ast_mutex_unlock(&iaxsl[fr->callno]); 10274 return 1; 10275 } 10276 } else { 10277 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 10278 } 10279 } 10280 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10281 ((f.frametype != AST_FRAME_IAX) || 10282 ((f.subclass.integer != IAX_COMMAND_TXACC) && 10283 (f.subclass.integer != IAX_COMMAND_TXCNT)))) { 10284 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 10285 ast_variables_destroy(ies.vars); 10286 ast_mutex_unlock(&iaxsl[fr->callno]); 10287 return 1; 10288 } 10289 10290 /* when we receive the first full frame for a new incoming channel, 10291 it is safe to start the PBX on the channel because we have now 10292 completed a 3-way handshake with the peer */ 10293 if ((f.frametype == AST_FRAME_VOICE) || 10294 (f.frametype == AST_FRAME_VIDEO) || 10295 (f.frametype == AST_FRAME_IAX)) { 10296 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 10297 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10298 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL, 10299 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) { 10300 ast_variables_destroy(ies.vars); 10301 ast_mutex_unlock(&iaxsl[fr->callno]); 10302 return 1; 10303 } 10304 } 10305 10306 if (ies.vars) { 10307 struct ast_datastore *variablestore = NULL; 10308 struct ast_variable *var, *prev = NULL; 10309 AST_LIST_HEAD(, ast_var_t) *varlist; 10310 10311 iax2_lock_owner(fr->callno); 10312 if (!iaxs[fr->callno]) { 10313 ast_variables_destroy(ies.vars); 10314 ast_mutex_unlock(&iaxsl[fr->callno]); 10315 return 1; 10316 } 10317 if ((c = iaxs[fr->callno]->owner)) { 10318 varlist = ast_calloc(1, sizeof(*varlist)); 10319 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10320 10321 if (variablestore && varlist) { 10322 variablestore->data = varlist; 10323 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10324 AST_LIST_HEAD_INIT(varlist); 10325 ast_debug(1, "I can haz IAX vars?\n"); 10326 for (var = ies.vars; var; var = var->next) { 10327 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10328 if (prev) { 10329 ast_free(prev); 10330 } 10331 prev = var; 10332 if (!newvar) { 10333 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10334 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10335 } else { 10336 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10337 } 10338 } 10339 if (prev) { 10340 ast_free(prev); 10341 } 10342 ies.vars = NULL; 10343 ast_channel_datastore_add(c, variablestore); 10344 } else { 10345 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10346 if (variablestore) { 10347 ast_datastore_free(variablestore); 10348 } 10349 if (varlist) { 10350 ast_free(varlist); 10351 } 10352 } 10353 ast_channel_unlock(c); 10354 } else { 10355 /* No channel yet, so transfer the variables directly over to the pvt, 10356 * for later inheritance. */ 10357 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 10358 for (var = ies.vars; var && var->next; var = var->next); 10359 if (var) { 10360 var->next = iaxs[fr->callno]->iaxvars; 10361 iaxs[fr->callno]->iaxvars = ies.vars; 10362 ies.vars = NULL; 10363 } 10364 } 10365 } 10366 10367 if (ies.vars) { 10368 ast_debug(1, "I have IAX variables, but they were not processed\n"); 10369 } 10370 } 10371 10372 /* once we receive our first IAX Full Frame that is not CallToken related, send all 10373 * queued signaling frames that were being held. */ 10374 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 10375 send_signaling(iaxs[fr->callno]); 10376 } 10377 10378 if (f.frametype == AST_FRAME_VOICE) { 10379 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) { 10380 iaxs[fr->callno]->voiceformat = f.subclass.codec; 10381 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec)); 10382 if (iaxs[fr->callno]->owner) { 10383 iax2_lock_owner(fr->callno); 10384 if (iaxs[fr->callno]) { 10385 if (iaxs[fr->callno]->owner) { 10386 format_t orignative; 10387 10388 orignative = iaxs[fr->callno]->owner->nativeformats; 10389 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec; 10390 if (iaxs[fr->callno]->owner->readformat) 10391 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10392 iaxs[fr->callno]->owner->nativeformats = orignative; 10393 ast_channel_unlock(iaxs[fr->callno]->owner); 10394 } 10395 } else { 10396 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 10397 /* Free remote variables (if any) */ 10398 if (ies.vars) { 10399 ast_variables_destroy(ies.vars); 10400 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 10401 ies.vars = NULL; 10402 } 10403 ast_mutex_unlock(&iaxsl[fr->callno]); 10404 return 1; 10405 } 10406 } 10407 } 10408 } 10409 if (f.frametype == AST_FRAME_VIDEO) { 10410 if (f.subclass.codec != iaxs[fr->callno]->videoformat) { 10411 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL)); 10412 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL; 10413 } 10414 } 10415 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 10416 if (f.subclass.integer == AST_CONTROL_BUSY) { 10417 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 10418 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) { 10419 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 10420 } 10421 } 10422 if (f.frametype == AST_FRAME_IAX) { 10423 ast_sched_thread_del(sched, iaxs[fr->callno]->initid); 10424 /* Handle the IAX pseudo frame itself */ 10425 if (iaxdebug) 10426 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer); 10427 10428 /* Update last ts unless the frame's timestamp originated with us. */ 10429 if (iaxs[fr->callno]->last < fr->ts && 10430 f.subclass.integer != IAX_COMMAND_ACK && 10431 f.subclass.integer != IAX_COMMAND_PONG && 10432 f.subclass.integer != IAX_COMMAND_LAGRP) { 10433 iaxs[fr->callno]->last = fr->ts; 10434 if (iaxdebug) 10435 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10436 } 10437 iaxs[fr->callno]->last_iax_message = f.subclass.integer; 10438 if (!iaxs[fr->callno]->first_iax_message) { 10439 iaxs[fr->callno]->first_iax_message = f.subclass.integer; 10440 } 10441 switch(f.subclass.integer) { 10442 case IAX_COMMAND_ACK: 10443 /* Do nothing */ 10444 break; 10445 case IAX_COMMAND_QUELCH: 10446 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10447 /* Generate Manager Hold event, if necessary*/ 10448 if (iaxs[fr->callno]->owner) { 10449 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10450 "Status: On\r\n" 10451 "Channel: %s\r\n" 10452 "Uniqueid: %s\r\n", 10453 iaxs[fr->callno]->owner->name, 10454 iaxs[fr->callno]->owner->uniqueid); 10455 } 10456 10457 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH); 10458 if (ies.musiconhold) { 10459 iax2_lock_owner(fr->callno); 10460 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 10461 break; 10462 } 10463 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10464 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 10465 10466 /* 10467 * We already hold the owner lock so we do not 10468 * need to check iaxs[fr->callno] after it returns. 10469 */ 10470 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 10471 S_OR(moh_suggest, NULL), 10472 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 10473 } 10474 ast_channel_unlock(iaxs[fr->callno]->owner); 10475 } 10476 } 10477 break; 10478 case IAX_COMMAND_UNQUELCH: 10479 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10480 iax2_lock_owner(fr->callno); 10481 if (!iaxs[fr->callno]) { 10482 break; 10483 } 10484 /* Generate Manager Unhold event, if necessary */ 10485 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { 10486 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10487 "Status: Off\r\n" 10488 "Channel: %s\r\n" 10489 "Uniqueid: %s\r\n", 10490 iaxs[fr->callno]->owner->name, 10491 iaxs[fr->callno]->owner->uniqueid); 10492 } 10493 10494 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH); 10495 if (!iaxs[fr->callno]->owner) { 10496 break; 10497 } 10498 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10499 /* 10500 * We already hold the owner lock so we do not 10501 * need to check iaxs[fr->callno] after it returns. 10502 */ 10503 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10504 } 10505 ast_channel_unlock(iaxs[fr->callno]->owner); 10506 } 10507 break; 10508 case IAX_COMMAND_TXACC: 10509 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10510 /* Ack the packet with the given timestamp */ 10511 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10512 /* Cancel any outstanding txcnt's */ 10513 if (cur->transfer) { 10514 cur->retries = -1; 10515 } 10516 } 10517 memset(&ied1, 0, sizeof(ied1)); 10518 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10519 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10520 iaxs[fr->callno]->transferring = TRANSFER_READY; 10521 } 10522 break; 10523 case IAX_COMMAND_NEW: 10524 /* Ignore if it's already up */ 10525 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10526 break; 10527 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10528 ast_mutex_unlock(&iaxsl[fr->callno]); 10529 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10530 ast_mutex_lock(&iaxsl[fr->callno]); 10531 if (!iaxs[fr->callno]) { 10532 break; 10533 } 10534 } 10535 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10536 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) { 10537 int new_callno; 10538 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10539 fr->callno = new_callno; 10540 } 10541 /* For security, always ack immediately */ 10542 if (delayreject) 10543 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10544 if (check_access(fr->callno, &sin, &ies)) { 10545 /* They're not allowed on */ 10546 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10547 if (authdebug) 10548 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); 10549 break; 10550 } 10551 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10552 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10553 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10554 break; 10555 } 10556 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10557 const char *context, *exten, *cid_num; 10558 10559 context = ast_strdupa(iaxs[fr->callno]->context); 10560 exten = ast_strdupa(iaxs[fr->callno]->exten); 10561 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10562 10563 /* This might re-enter the IAX code and need the lock */ 10564 ast_mutex_unlock(&iaxsl[fr->callno]); 10565 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10566 ast_mutex_lock(&iaxsl[fr->callno]); 10567 10568 if (!iaxs[fr->callno]) { 10569 break; 10570 } 10571 } else 10572 exists = 0; 10573 /* Get OSP token if it does exist */ 10574 save_osptoken(fr, &ies); 10575 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10576 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10577 memset(&ied0, 0, sizeof(ied0)); 10578 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10579 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10580 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10581 if (!iaxs[fr->callno]) { 10582 break; 10583 } 10584 if (authdebug) 10585 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); 10586 } else { 10587 /* Select an appropriate format */ 10588 10589 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10590 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10591 using_prefs = "reqonly"; 10592 } else { 10593 using_prefs = "disabled"; 10594 } 10595 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10596 memset(&pref, 0, sizeof(pref)); 10597 strcpy(caller_pref_buf, "disabled"); 10598 strcpy(host_pref_buf, "disabled"); 10599 } else { 10600 using_prefs = "mine"; 10601 /* If the information elements are in here... use them */ 10602 if (ies.codec_prefs) 10603 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10604 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10605 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10606 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10607 pref = iaxs[fr->callno]->rprefs; 10608 using_prefs = "caller"; 10609 } else { 10610 pref = iaxs[fr->callno]->prefs; 10611 } 10612 } else 10613 pref = iaxs[fr->callno]->prefs; 10614 10615 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10616 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10617 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10618 } 10619 if (!format) { 10620 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10621 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10622 if (!format) { 10623 memset(&ied0, 0, sizeof(ied0)); 10624 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10625 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10626 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10627 if (!iaxs[fr->callno]) { 10628 break; 10629 } 10630 if (authdebug) { 10631 char tmp[256], tmp2[256], tmp3[256]; 10632 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10633 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 10634 ast_inet_ntoa(sin.sin_addr), 10635 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10636 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10637 } else { 10638 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10639 ast_inet_ntoa(sin.sin_addr), 10640 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10641 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10642 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10643 } 10644 } 10645 } else { 10646 /* Pick one... */ 10647 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10648 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10649 format = 0; 10650 } else { 10651 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10652 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10653 memset(&pref, 0, sizeof(pref)); 10654 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10655 strcpy(caller_pref_buf,"disabled"); 10656 strcpy(host_pref_buf,"disabled"); 10657 } else { 10658 using_prefs = "mine"; 10659 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10660 /* Do the opposite of what we tried above. */ 10661 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10662 pref = iaxs[fr->callno]->prefs; 10663 } else { 10664 pref = iaxs[fr->callno]->rprefs; 10665 using_prefs = "caller"; 10666 } 10667 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10668 } else /* if no codec_prefs IE do it the old way */ 10669 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10670 } 10671 } 10672 10673 if (!format) { 10674 char tmp[256], tmp2[256], tmp3[256]; 10675 memset(&ied0, 0, sizeof(ied0)); 10676 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10677 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10678 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 10679 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10680 if (!iaxs[fr->callno]) { 10681 break; 10682 } 10683 if (authdebug) { 10684 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10685 ast_inet_ntoa(sin.sin_addr), 10686 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10687 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10688 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10689 } 10690 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10691 break; 10692 } 10693 } 10694 } 10695 if (format) { 10696 /* No authentication required, let them in */ 10697 memset(&ied1, 0, sizeof(ied1)); 10698 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10699 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 10700 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10701 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10702 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10703 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10704 "%srequested format = %s,\n" 10705 "%srequested prefs = %s,\n" 10706 "%sactual format = %s,\n" 10707 "%shost prefs = %s,\n" 10708 "%spriority = %s\n", 10709 ast_inet_ntoa(sin.sin_addr), 10710 VERBOSE_PREFIX_4, 10711 ast_getformatname(iaxs[fr->callno]->peerformat), 10712 VERBOSE_PREFIX_4, 10713 caller_pref_buf, 10714 VERBOSE_PREFIX_4, 10715 ast_getformatname(format), 10716 VERBOSE_PREFIX_4, 10717 host_pref_buf, 10718 VERBOSE_PREFIX_4, 10719 using_prefs); 10720 10721 iaxs[fr->callno]->chosenformat = format; 10722 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10723 } else { 10724 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10725 /* If this is a TBD call, we're ready but now what... */ 10726 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10727 } 10728 } 10729 } 10730 break; 10731 } 10732 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10733 merge_encryption(iaxs[fr->callno],ies.encmethods); 10734 else 10735 iaxs[fr->callno]->encmethods = 0; 10736 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10737 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10738 break; 10739 case IAX_COMMAND_DPREQ: 10740 /* Request status in the dialplan */ 10741 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10742 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10743 if (iaxcompat) { 10744 /* Spawn a thread for the lookup */ 10745 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10746 } else { 10747 /* Just look it up */ 10748 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10749 } 10750 } 10751 break; 10752 case IAX_COMMAND_HANGUP: 10753 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10754 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10755 /* Set hangup cause according to remote and hangupsource */ 10756 if (iaxs[fr->callno]->owner) { 10757 set_hangup_source_and_cause(fr->callno, ies.causecode); 10758 if (!iaxs[fr->callno]) { 10759 break; 10760 } 10761 } 10762 10763 /* Send ack immediately, before we destroy */ 10764 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10765 iax2_destroy(fr->callno); 10766 break; 10767 case IAX_COMMAND_REJECT: 10768 /* Set hangup cause according to remote and hangup source */ 10769 if (iaxs[fr->callno]->owner) { 10770 set_hangup_source_and_cause(fr->callno, ies.causecode); 10771 if (!iaxs[fr->callno]) { 10772 break; 10773 } 10774 } 10775 10776 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10777 if (iaxs[fr->callno]->owner && authdebug) 10778 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10779 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10780 ies.cause ? ies.cause : "<Unknown>"); 10781 ast_debug(1, "Immediately destroying %d, having received reject\n", 10782 fr->callno); 10783 } 10784 /* Send ack immediately, before we destroy */ 10785 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10786 fr->ts, NULL, 0, fr->iseqno); 10787 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) 10788 iaxs[fr->callno]->error = EPERM; 10789 iax2_destroy(fr->callno); 10790 break; 10791 case IAX_COMMAND_TRANSFER: 10792 { 10793 struct ast_channel *bridged_chan; 10794 struct ast_channel *owner; 10795 10796 iax2_lock_owner(fr->callno); 10797 if (!iaxs[fr->callno]) { 10798 /* Initiating call went away before we could transfer. */ 10799 break; 10800 } 10801 owner = iaxs[fr->callno]->owner; 10802 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 10803 if (bridged_chan && ies.called_number) { 10804 const char *context; 10805 10806 context = ast_strdupa(iaxs[fr->callno]->context); 10807 10808 ast_channel_ref(owner); 10809 ast_channel_ref(bridged_chan); 10810 ast_channel_unlock(owner); 10811 ast_mutex_unlock(&iaxsl[fr->callno]); 10812 10813 /* Set BLINDTRANSFER channel variables */ 10814 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name); 10815 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name); 10816 10817 /* DO NOT hold any locks while calling ast_parking_ext_valid() */ 10818 if (ast_parking_ext_valid(ies.called_number, owner, context)) { 10819 ast_debug(1, "Parking call '%s'\n", bridged_chan->name); 10820 if (iax_park(bridged_chan, owner, ies.called_number, context)) { 10821 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 10822 bridged_chan->name); 10823 } 10824 } else { 10825 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) { 10826 ast_log(LOG_WARNING, 10827 "Async goto of '%s' to '%s@%s' failed\n", 10828 bridged_chan->name, ies.called_number, context); 10829 } else { 10830 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", 10831 bridged_chan->name, ies.called_number, context); 10832 } 10833 } 10834 ast_channel_unref(owner); 10835 ast_channel_unref(bridged_chan); 10836 10837 ast_mutex_lock(&iaxsl[fr->callno]); 10838 } else { 10839 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10840 if (owner) { 10841 ast_channel_unlock(owner); 10842 } 10843 } 10844 10845 break; 10846 } 10847 case IAX_COMMAND_ACCEPT: 10848 /* Ignore if call is already up or needs authentication or is a TBD */ 10849 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10850 break; 10851 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10852 /* Send ack immediately, before we destroy */ 10853 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10854 iax2_destroy(fr->callno); 10855 break; 10856 } 10857 if (ies.format) { 10858 iaxs[fr->callno]->peerformat = ies.format; 10859 } else { 10860 if (iaxs[fr->callno]->owner) 10861 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10862 else 10863 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10864 } 10865 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)); 10866 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10867 memset(&ied0, 0, sizeof(ied0)); 10868 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10869 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10870 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10871 if (!iaxs[fr->callno]) { 10872 break; 10873 } 10874 if (authdebug) { 10875 char tmp1[256], tmp2[256]; 10876 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n", 10877 ast_inet_ntoa(sin.sin_addr), 10878 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10879 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10880 } 10881 } else { 10882 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10883 iax2_lock_owner(fr->callno); 10884 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10885 /* Switch us to use a compatible format */ 10886 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 10887 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 10888 10889 /* Setup read/write formats properly. */ 10890 if (iaxs[fr->callno]->owner->writeformat) 10891 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 10892 if (iaxs[fr->callno]->owner->readformat) 10893 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10894 ast_channel_unlock(iaxs[fr->callno]->owner); 10895 } 10896 } 10897 if (iaxs[fr->callno]) { 10898 AST_LIST_LOCK(&dpcache); 10899 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10900 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10901 iax2_dprequest(dp, fr->callno); 10902 AST_LIST_UNLOCK(&dpcache); 10903 } 10904 break; 10905 case IAX_COMMAND_POKE: 10906 /* Send back a pong packet with the original timestamp */ 10907 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10908 break; 10909 case IAX_COMMAND_PING: 10910 { 10911 struct iax_ie_data pingied; 10912 construct_rr(iaxs[fr->callno], &pingied); 10913 /* Send back a pong packet with the original timestamp */ 10914 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10915 } 10916 break; 10917 case IAX_COMMAND_PONG: 10918 /* Calculate ping time */ 10919 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10920 /* save RR info */ 10921 save_rr(fr, &ies); 10922 10923 /* Good time to write jb stats for this call */ 10924 log_jitterstats(fr->callno); 10925 10926 if (iaxs[fr->callno]->peerpoke) { 10927 peer = iaxs[fr->callno]->peerpoke; 10928 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10929 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10930 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10931 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); 10932 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 10933 } 10934 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10935 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10936 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10937 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); 10938 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 10939 } 10940 } 10941 peer->lastms = iaxs[fr->callno]->pingtime; 10942 if (peer->smoothing && (peer->lastms > -1)) 10943 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10944 else if (peer->smoothing && peer->lastms < 0) 10945 peer->historicms = (0 + peer->historicms) / 2; 10946 else 10947 peer->historicms = iaxs[fr->callno]->pingtime; 10948 10949 /* Remove scheduled iax2_poke_noanswer */ 10950 if (peer->pokeexpire > -1) { 10951 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 10952 peer_unref(peer); 10953 peer->pokeexpire = -1; 10954 } 10955 } 10956 /* Schedule the next cycle */ 10957 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 10958 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10959 else 10960 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 10961 if (peer->pokeexpire == -1) 10962 peer_unref(peer); 10963 /* and finally send the ack */ 10964 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10965 /* And wrap up the qualify call */ 10966 iax2_destroy(fr->callno); 10967 peer->callno = 0; 10968 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 10969 } 10970 break; 10971 case IAX_COMMAND_LAGRQ: 10972 case IAX_COMMAND_LAGRP: 10973 f.src = "LAGRQ"; 10974 f.mallocd = 0; 10975 f.offset = 0; 10976 f.samples = 0; 10977 iax_frame_wrap(fr, &f); 10978 if (f.subclass.integer == IAX_COMMAND_LAGRQ) { 10979 /* Received a LAGRQ - echo back a LAGRP */ 10980 fr->af.subclass.integer = IAX_COMMAND_LAGRP; 10981 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 10982 } else { 10983 /* Received LAGRP in response to our LAGRQ */ 10984 unsigned int ts; 10985 /* This is a reply we've been given, actually measure the difference */ 10986 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 10987 iaxs[fr->callno]->lag = ts - fr->ts; 10988 if (iaxdebug) 10989 ast_debug(1, "Peer %s lag measured as %dms\n", 10990 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 10991 } 10992 break; 10993 case IAX_COMMAND_AUTHREQ: 10994 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10995 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>"); 10996 break; 10997 } 10998 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 10999 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 11000 .subclass.integer = AST_CONTROL_HANGUP, 11001 }; 11002 ast_log(LOG_WARNING, 11003 "I don't know how to authenticate %s to %s\n", 11004 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 11005 iax2_queue_frame(fr->callno, &hangup_fr); 11006 } 11007 break; 11008 case IAX_COMMAND_AUTHREP: 11009 /* For security, always ack immediately */ 11010 if (delayreject) 11011 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11012 /* Ignore once we've started */ 11013 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11014 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>"); 11015 break; 11016 } 11017 if (authenticate_verify(iaxs[fr->callno], &ies)) { 11018 if (authdebug) 11019 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); 11020 memset(&ied0, 0, sizeof(ied0)); 11021 auth_fail(fr->callno, IAX_COMMAND_REJECT); 11022 break; 11023 } 11024 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 11025 /* This might re-enter the IAX code and need the lock */ 11026 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 11027 } else 11028 exists = 0; 11029 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 11030 if (authdebug) 11031 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); 11032 memset(&ied0, 0, sizeof(ied0)); 11033 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11034 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11035 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11036 if (!iaxs[fr->callno]) { 11037 break; 11038 } 11039 } else { 11040 /* Select an appropriate format */ 11041 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11042 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11043 using_prefs = "reqonly"; 11044 } else { 11045 using_prefs = "disabled"; 11046 } 11047 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 11048 memset(&pref, 0, sizeof(pref)); 11049 strcpy(caller_pref_buf, "disabled"); 11050 strcpy(host_pref_buf, "disabled"); 11051 } else { 11052 using_prefs = "mine"; 11053 if (ies.codec_prefs) 11054 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 11055 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11056 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11057 pref = iaxs[fr->callno]->rprefs; 11058 using_prefs = "caller"; 11059 } else { 11060 pref = iaxs[fr->callno]->prefs; 11061 } 11062 } else /* if no codec_prefs IE do it the old way */ 11063 pref = iaxs[fr->callno]->prefs; 11064 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 11065 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 11066 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 11067 } 11068 if (!format) { 11069 char tmp1[256], tmp2[256], tmp3[256]; 11070 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11071 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n", 11072 ast_getformatname(iaxs[fr->callno]->peerformat), 11073 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability)); 11074 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 11075 } 11076 if (!format) { 11077 if (authdebug) { 11078 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11079 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr), 11080 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11081 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11082 } else { 11083 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11084 ast_inet_ntoa(sin.sin_addr), 11085 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11086 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11087 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11088 } 11089 } 11090 memset(&ied0, 0, sizeof(ied0)); 11091 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11092 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11093 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11094 if (!iaxs[fr->callno]) { 11095 break; 11096 } 11097 } else { 11098 /* Pick one... */ 11099 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11100 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 11101 format = 0; 11102 } else { 11103 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11104 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 11105 memset(&pref, 0, sizeof(pref)); 11106 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 11107 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11108 strcpy(caller_pref_buf,"disabled"); 11109 strcpy(host_pref_buf,"disabled"); 11110 } else { 11111 using_prefs = "mine"; 11112 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11113 /* Do the opposite of what we tried above. */ 11114 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11115 pref = iaxs[fr->callno]->prefs; 11116 } else { 11117 pref = iaxs[fr->callno]->rprefs; 11118 using_prefs = "caller"; 11119 } 11120 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 11121 } else /* if no codec_prefs IE do it the old way */ 11122 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11123 } 11124 } 11125 if (!format) { 11126 char tmp1[256], tmp2[256], tmp3[256]; 11127 ast_log(LOG_ERROR, "No best format in %s???\n", 11128 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 11129 if (authdebug) { 11130 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11131 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 11132 ast_inet_ntoa(sin.sin_addr), 11133 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11134 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11135 } else { 11136 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11137 ast_inet_ntoa(sin.sin_addr), 11138 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11139 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11140 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11141 } 11142 } 11143 memset(&ied0, 0, sizeof(ied0)); 11144 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11145 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11146 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11147 if (!iaxs[fr->callno]) { 11148 break; 11149 } 11150 } 11151 } 11152 } 11153 if (format) { 11154 /* Authentication received */ 11155 memset(&ied1, 0, sizeof(ied1)); 11156 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 11157 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 11158 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 11159 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 11160 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11161 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 11162 "%srequested format = %s,\n" 11163 "%srequested prefs = %s,\n" 11164 "%sactual format = %s,\n" 11165 "%shost prefs = %s,\n" 11166 "%spriority = %s\n", 11167 ast_inet_ntoa(sin.sin_addr), 11168 VERBOSE_PREFIX_4, 11169 ast_getformatname(iaxs[fr->callno]->peerformat), 11170 VERBOSE_PREFIX_4, 11171 caller_pref_buf, 11172 VERBOSE_PREFIX_4, 11173 ast_getformatname(format), 11174 VERBOSE_PREFIX_4, 11175 host_pref_buf, 11176 VERBOSE_PREFIX_4, 11177 using_prefs); 11178 11179 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11180 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1))) 11181 iax2_destroy(fr->callno); 11182 else if (ies.vars) { 11183 struct ast_datastore *variablestore; 11184 struct ast_variable *var, *prev = NULL; 11185 AST_LIST_HEAD(, ast_var_t) *varlist; 11186 varlist = ast_calloc(1, sizeof(*varlist)); 11187 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11188 if (variablestore && varlist) { 11189 variablestore->data = varlist; 11190 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11191 AST_LIST_HEAD_INIT(varlist); 11192 ast_debug(1, "I can haz IAX vars? w00t\n"); 11193 for (var = ies.vars; var; var = var->next) { 11194 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11195 if (prev) 11196 ast_free(prev); 11197 prev = var; 11198 if (!newvar) { 11199 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11200 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11201 } else { 11202 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11203 } 11204 } 11205 if (prev) 11206 ast_free(prev); 11207 ies.vars = NULL; 11208 ast_channel_datastore_add(c, variablestore); 11209 } else { 11210 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11211 if (variablestore) 11212 ast_datastore_free(variablestore); 11213 if (varlist) 11214 ast_free(varlist); 11215 } 11216 } 11217 } else { 11218 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11219 /* If this is a TBD call, we're ready but now what... */ 11220 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 11221 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) { 11222 goto immediatedial; 11223 } 11224 } 11225 } 11226 } 11227 break; 11228 case IAX_COMMAND_DIAL: 11229 immediatedial: 11230 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 11231 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11232 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 11233 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 11234 if (authdebug) 11235 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); 11236 memset(&ied0, 0, sizeof(ied0)); 11237 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11238 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11239 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11240 if (!iaxs[fr->callno]) { 11241 break; 11242 } 11243 } else { 11244 char tmp[256]; 11245 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11246 ast_verb(3, "Accepting DIAL from %s, formats = %s\n", 11247 ast_inet_ntoa(sin.sin_addr), 11248 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat)); 11249 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11250 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 11251 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1))) 11252 iax2_destroy(fr->callno); 11253 else if (ies.vars) { 11254 struct ast_datastore *variablestore; 11255 struct ast_variable *var, *prev = NULL; 11256 AST_LIST_HEAD(, ast_var_t) *varlist; 11257 varlist = ast_calloc(1, sizeof(*varlist)); 11258 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11259 ast_debug(1, "I can haz IAX vars? w00t\n"); 11260 if (variablestore && varlist) { 11261 variablestore->data = varlist; 11262 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11263 AST_LIST_HEAD_INIT(varlist); 11264 for (var = ies.vars; var; var = var->next) { 11265 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11266 if (prev) 11267 ast_free(prev); 11268 prev = var; 11269 if (!newvar) { 11270 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11271 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11272 } else { 11273 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11274 } 11275 } 11276 if (prev) 11277 ast_free(prev); 11278 ies.vars = NULL; 11279 ast_channel_datastore_add(c, variablestore); 11280 } else { 11281 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11282 if (variablestore) 11283 ast_datastore_free(variablestore); 11284 if (varlist) 11285 ast_free(varlist); 11286 } 11287 } 11288 } 11289 } 11290 break; 11291 case IAX_COMMAND_INVAL: 11292 iaxs[fr->callno]->error = ENOTCONN; 11293 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 11294 iax2_destroy(fr->callno); 11295 ast_debug(1, "Destroying call %d\n", fr->callno); 11296 break; 11297 case IAX_COMMAND_VNAK: 11298 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 11299 /* Force retransmission */ 11300 vnak_retransmit(fr->callno, fr->iseqno); 11301 break; 11302 case IAX_COMMAND_REGREQ: 11303 case IAX_COMMAND_REGREL: 11304 /* For security, always ack immediately */ 11305 if (delayreject) 11306 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11307 if (register_verify(fr->callno, &sin, &ies)) { 11308 if (!iaxs[fr->callno]) { 11309 break; 11310 } 11311 /* Send delayed failure */ 11312 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 11313 break; 11314 } 11315 if (!iaxs[fr->callno]) { 11316 break; 11317 } 11318 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 11319 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 11320 11321 if (f.subclass.integer == IAX_COMMAND_REGREL) { 11322 memset(&sin, 0, sizeof(sin)); 11323 sin.sin_family = AF_INET; 11324 } 11325 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) { 11326 ast_log(LOG_WARNING, "Registry error\n"); 11327 } 11328 if (!iaxs[fr->callno]) { 11329 break; 11330 } 11331 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 11332 ast_mutex_unlock(&iaxsl[fr->callno]); 11333 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 11334 ast_mutex_lock(&iaxsl[fr->callno]); 11335 } 11336 break; 11337 } 11338 registry_authrequest(fr->callno); 11339 break; 11340 case IAX_COMMAND_REGACK: 11341 if (iax2_ack_registry(&ies, &sin, fr->callno)) 11342 ast_log(LOG_WARNING, "Registration failure\n"); 11343 /* Send ack immediately, before we destroy */ 11344 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11345 iax2_destroy(fr->callno); 11346 break; 11347 case IAX_COMMAND_REGREJ: 11348 if (iaxs[fr->callno]->reg) { 11349 if (authdebug) { 11350 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)); 11351 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>"); 11352 } 11353 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 11354 } 11355 /* Send ack immediately, before we destroy */ 11356 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11357 iax2_destroy(fr->callno); 11358 break; 11359 case IAX_COMMAND_REGAUTH: 11360 /* Authentication request */ 11361 if (registry_rerequest(&ies, fr->callno, &sin)) { 11362 memset(&ied0, 0, sizeof(ied0)); 11363 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 11364 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 11365 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11366 } 11367 break; 11368 case IAX_COMMAND_TXREJ: 11369 iaxs[fr->callno]->transferring = 0; 11370 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11371 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 11372 if (iaxs[fr->callno]->bridgecallno) { 11373 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 11374 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 11375 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 11376 } 11377 } 11378 break; 11379 case IAX_COMMAND_TXREADY: 11380 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 11381 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 11382 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 11383 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 11384 else 11385 iaxs[fr->callno]->transferring = TRANSFER_READY; 11386 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11387 if (iaxs[fr->callno]->bridgecallno) { 11388 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 11389 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 11390 /* They're both ready, now release them. */ 11391 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 11392 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11393 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11394 11395 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 11396 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 11397 11398 memset(&ied0, 0, sizeof(ied0)); 11399 memset(&ied1, 0, sizeof(ied1)); 11400 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11401 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11402 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 11403 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 11404 } else { 11405 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11406 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11407 11408 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 11409 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 11410 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 11411 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 11412 11413 /* Stop doing lag & ping requests */ 11414 stop_stuff(fr->callno); 11415 stop_stuff(iaxs[fr->callno]->bridgecallno); 11416 11417 memset(&ied0, 0, sizeof(ied0)); 11418 memset(&ied1, 0, sizeof(ied1)); 11419 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11420 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11421 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 11422 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 11423 } 11424 11425 } 11426 } 11427 } 11428 break; 11429 case IAX_COMMAND_TXREQ: 11430 try_transfer(iaxs[fr->callno], &ies); 11431 break; 11432 case IAX_COMMAND_TXCNT: 11433 if (iaxs[fr->callno]->transferring) 11434 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 11435 break; 11436 case IAX_COMMAND_TXREL: 11437 /* Send ack immediately, rather than waiting until we've changed addresses */ 11438 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11439 complete_transfer(fr->callno, &ies); 11440 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 11441 break; 11442 case IAX_COMMAND_TXMEDIA: 11443 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 11444 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 11445 /* Cancel any outstanding frames and start anew */ 11446 if (cur->transfer) { 11447 cur->retries = -1; 11448 } 11449 } 11450 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 11451 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 11452 } 11453 break; 11454 case IAX_COMMAND_RTKEY: 11455 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 11456 ast_log(LOG_WARNING, 11457 "we've been told to rotate our encryption key, " 11458 "but this isn't an encrypted call. bad things will happen.\n" 11459 ); 11460 break; 11461 } 11462 11463 IAX_DEBUGDIGEST("Receiving", ies.challenge); 11464 11465 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 11466 break; 11467 case IAX_COMMAND_DPREP: 11468 complete_dpreply(iaxs[fr->callno], &ies); 11469 break; 11470 case IAX_COMMAND_UNSUPPORT: 11471 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 11472 break; 11473 case IAX_COMMAND_FWDOWNL: 11474 /* Firmware download */ 11475 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 11476 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 11477 break; 11478 } 11479 memset(&ied0, 0, sizeof(ied0)); 11480 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 11481 if (res < 0) 11482 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11483 else if (res > 0) 11484 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11485 else 11486 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11487 break; 11488 case IAX_COMMAND_CALLTOKEN: 11489 { 11490 struct iax_frame *cur; 11491 /* find last sent frame */ 11492 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) { 11493 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 11494 } 11495 break; 11496 } 11497 default: 11498 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno); 11499 memset(&ied0, 0, sizeof(ied0)); 11500 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer); 11501 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11502 } 11503 /* Free remote variables (if any) */ 11504 if (ies.vars) { 11505 ast_variables_destroy(ies.vars); 11506 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11507 ies.vars = NULL; 11508 } 11509 11510 /* Don't actually pass these frames along */ 11511 if ((f.subclass.integer != IAX_COMMAND_ACK) && 11512 (f.subclass.integer != IAX_COMMAND_TXCNT) && 11513 (f.subclass.integer != IAX_COMMAND_TXACC) && 11514 (f.subclass.integer != IAX_COMMAND_INVAL) && 11515 (f.subclass.integer != IAX_COMMAND_VNAK)) { 11516 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11517 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11518 } 11519 ast_mutex_unlock(&iaxsl[fr->callno]); 11520 return 1; 11521 } 11522 /* Unless this is an ACK or INVAL frame, ack it */ 11523 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11524 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11525 } else if (minivid) { 11526 f.frametype = AST_FRAME_VIDEO; 11527 if (iaxs[fr->callno]->videoformat > 0) 11528 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0); 11529 else { 11530 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11531 iax2_vnak(fr->callno); 11532 ast_variables_destroy(ies.vars); 11533 ast_mutex_unlock(&iaxsl[fr->callno]); 11534 return 1; 11535 } 11536 f.datalen = res - sizeof(*vh); 11537 if (f.datalen) 11538 f.data.ptr = thread->buf + sizeof(*vh); 11539 else 11540 f.data.ptr = NULL; 11541 #ifdef IAXTESTS 11542 if (test_resync) { 11543 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11544 } else 11545 #endif /* IAXTESTS */ 11546 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11547 } else { 11548 /* A mini frame */ 11549 f.frametype = AST_FRAME_VOICE; 11550 if (iaxs[fr->callno]->voiceformat > 0) 11551 f.subclass.codec = iaxs[fr->callno]->voiceformat; 11552 else { 11553 ast_debug(1, "Received mini frame before first full voice frame\n"); 11554 iax2_vnak(fr->callno); 11555 ast_variables_destroy(ies.vars); 11556 ast_mutex_unlock(&iaxsl[fr->callno]); 11557 return 1; 11558 } 11559 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11560 if (f.datalen < 0) { 11561 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11562 ast_variables_destroy(ies.vars); 11563 ast_mutex_unlock(&iaxsl[fr->callno]); 11564 return 1; 11565 } 11566 if (f.datalen) 11567 f.data.ptr = thread->buf + sizeof(*mh); 11568 else 11569 f.data.ptr = NULL; 11570 #ifdef IAXTESTS 11571 if (test_resync) { 11572 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11573 } else 11574 #endif /* IAXTESTS */ 11575 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11576 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11577 } 11578 /* Don't pass any packets until we're started */ 11579 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11580 ast_variables_destroy(ies.vars); 11581 ast_mutex_unlock(&iaxsl[fr->callno]); 11582 return 1; 11583 } 11584 /* Don't allow connected line updates unless we are configured to */ 11585 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) { 11586 struct ast_party_connected_line connected; 11587 11588 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) { 11589 ast_variables_destroy(ies.vars); 11590 ast_mutex_unlock(&iaxsl[fr->callno]); 11591 return 1; 11592 } 11593 11594 /* Initialize defaults */ 11595 ast_party_connected_line_init(&connected); 11596 connected.id.number.presentation = iaxs[fr->callno]->calling_pres; 11597 connected.id.name.presentation = iaxs[fr->callno]->calling_pres; 11598 11599 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) { 11600 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str); 11601 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str); 11602 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id); 11603 11604 iax2_lock_owner(fr->callno); 11605 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 11606 ast_set_callerid(iaxs[fr->callno]->owner, 11607 S_COR(connected.id.number.valid, connected.id.number.str, ""), 11608 S_COR(connected.id.name.valid, connected.id.name.str, ""), 11609 NULL); 11610 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation; 11611 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation; 11612 ast_channel_unlock(iaxs[fr->callno]->owner); 11613 } 11614 } 11615 ast_party_connected_line_free(&connected); 11616 } 11617 /* Common things */ 11618 f.src = "IAX2"; 11619 f.mallocd = 0; 11620 f.offset = 0; 11621 f.len = 0; 11622 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11623 f.samples = ast_codec_get_samples(&f); 11624 /* We need to byteswap incoming slinear samples from network byte order */ 11625 if (f.subclass.codec == AST_FORMAT_SLINEAR) 11626 ast_frame_byteswap_be(&f); 11627 } else 11628 f.samples = 0; 11629 iax_frame_wrap(fr, &f); 11630 11631 /* If this is our most recent packet, use it as our basis for timestamping */ 11632 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11633 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11634 fr->outoforder = 0; 11635 } else { 11636 if (iaxdebug && iaxs[fr->callno]) 11637 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); 11638 fr->outoforder = -1; 11639 } 11640 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11641 duped_fr = iaxfrdup2(fr); 11642 if (duped_fr) { 11643 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11644 } 11645 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11646 iaxs[fr->callno]->last = fr->ts; 11647 #if 1 11648 if (iaxdebug) 11649 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 11650 #endif 11651 } 11652 11653 /* Always run again */ 11654 ast_variables_destroy(ies.vars); 11655 ast_mutex_unlock(&iaxsl[fr->callno]); 11656 return 1; 11657 }
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 9694 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().
09696 { 09697 unsigned char metatype; 09698 struct ast_iax2_meta_trunk_mini *mtm; 09699 struct ast_iax2_meta_trunk_hdr *mth; 09700 struct ast_iax2_meta_trunk_entry *mte; 09701 struct iax2_trunk_peer *tpeer; 09702 unsigned int ts; 09703 void *ptr; 09704 struct timeval rxtrunktime; 09705 struct ast_frame f = { 0, }; 09706 09707 if (packet_len < sizeof(*meta)) { 09708 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09709 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09710 return 1; 09711 } 09712 09713 if (meta->metacmd != IAX_META_TRUNK) 09714 return 1; 09715 09716 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09717 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09718 (int) (sizeof(*meta) + sizeof(*mth))); 09719 return 1; 09720 } 09721 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09722 ts = ntohl(mth->ts); 09723 metatype = meta->cmddata; 09724 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09725 ptr = mth->data; 09726 tpeer = find_tpeer(sin, sockfd); 09727 if (!tpeer) { 09728 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09729 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09730 return 1; 09731 } 09732 tpeer->trunkact = ast_tvnow(); 09733 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09734 tpeer->rxtrunktime = tpeer->trunkact; 09735 rxtrunktime = tpeer->rxtrunktime; 09736 ast_mutex_unlock(&tpeer->lock); 09737 while (packet_len >= sizeof(*mte)) { 09738 /* Process channels */ 09739 unsigned short callno, trunked_ts, len; 09740 09741 if (metatype == IAX_META_TRUNK_MINI) { 09742 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09743 ptr += sizeof(*mtm); 09744 packet_len -= sizeof(*mtm); 09745 len = ntohs(mtm->len); 09746 callno = ntohs(mtm->mini.callno); 09747 trunked_ts = ntohs(mtm->mini.ts); 09748 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09749 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09750 ptr += sizeof(*mte); 09751 packet_len -= sizeof(*mte); 09752 len = ntohs(mte->len); 09753 callno = ntohs(mte->callno); 09754 trunked_ts = 0; 09755 } else { 09756 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09757 break; 09758 } 09759 /* Stop if we don't have enough data */ 09760 if (len > packet_len) 09761 break; 09762 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09763 if (!fr->callno) 09764 continue; 09765 09766 /* If it's a valid call, deliver the contents. If not, we 09767 drop it, since we don't have a scallno to use for an INVAL */ 09768 /* Process as a mini frame */ 09769 memset(&f, 0, sizeof(f)); 09770 f.frametype = AST_FRAME_VOICE; 09771 if (!iaxs[fr->callno]) { 09772 /* drop it */ 09773 } else if (iaxs[fr->callno]->voiceformat == 0) { 09774 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09775 iax2_vnak(fr->callno); 09776 } else { 09777 f.subclass.codec = iaxs[fr->callno]->voiceformat; 09778 f.datalen = len; 09779 if (f.datalen >= 0) { 09780 if (f.datalen) 09781 f.data.ptr = ptr; 09782 else 09783 f.data.ptr = NULL; 09784 if (trunked_ts) 09785 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09786 else 09787 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09788 /* Don't pass any packets until we're started */ 09789 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09790 struct iax_frame *duped_fr; 09791 09792 /* Common things */ 09793 f.src = "IAX2"; 09794 f.mallocd = 0; 09795 f.offset = 0; 09796 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09797 f.samples = ast_codec_get_samples(&f); 09798 else 09799 f.samples = 0; 09800 fr->outoforder = 0; 09801 iax_frame_wrap(fr, &f); 09802 duped_fr = iaxfrdup2(fr); 09803 if (duped_fr) 09804 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09805 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09806 iaxs[fr->callno]->last = fr->ts; 09807 } 09808 } else { 09809 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09810 } 09811 } 09812 ast_mutex_unlock(&iaxsl[fr->callno]); 09813 ptr += len; 09814 packet_len -= len; 09815 } 09816 09817 return 1; 09818 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9615 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().
09616 { 09617 struct iax2_thread *thread; 09618 socklen_t len; 09619 time_t t; 09620 static time_t last_errtime = 0; 09621 struct ast_iax2_full_hdr *fh; 09622 09623 if (!(thread = find_idle_thread())) { 09624 time(&t); 09625 if (t != last_errtime) 09626 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09627 last_errtime = t; 09628 usleep(1); 09629 return 1; 09630 } 09631 09632 len = sizeof(thread->iosin); 09633 thread->iofd = fd; 09634 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09635 thread->buf_size = sizeof(thread->readbuf); 09636 thread->buf = thread->readbuf; 09637 if (thread->buf_len < 0) { 09638 if (errno != ECONNREFUSED && errno != EAGAIN) 09639 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09640 handle_error(); 09641 thread->iostate = IAX_IOSTATE_IDLE; 09642 signal_condition(&thread->lock, &thread->cond); 09643 return 1; 09644 } 09645 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09646 thread->iostate = IAX_IOSTATE_IDLE; 09647 signal_condition(&thread->lock, &thread->cond); 09648 return 1; 09649 } 09650 09651 /* Determine if this frame is a full frame; if so, and any thread is currently 09652 processing a full frame for the same callno from this peer, then drop this 09653 frame (and the peer will retransmit it) */ 09654 fh = (struct ast_iax2_full_hdr *) thread->buf; 09655 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09656 struct iax2_thread *cur = NULL; 09657 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09658 09659 AST_LIST_LOCK(&active_list); 09660 AST_LIST_TRAVERSE(&active_list, cur, list) { 09661 if ((cur->ffinfo.callno == callno) && 09662 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09663 break; 09664 } 09665 if (cur) { 09666 /* we found another thread processing a full frame for this call, 09667 so queue it up for processing later. */ 09668 defer_full_frame(thread, cur); 09669 AST_LIST_UNLOCK(&active_list); 09670 thread->iostate = IAX_IOSTATE_IDLE; 09671 signal_condition(&thread->lock, &thread->cond); 09672 return 1; 09673 } else { 09674 /* this thread is going to process this frame, so mark it */ 09675 thread->ffinfo.callno = callno; 09676 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09677 thread->ffinfo.type = fh->type; 09678 thread->ffinfo.csub = fh->csub; 09679 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09680 } 09681 AST_LIST_UNLOCK(&active_list); 09682 } 09683 09684 /* Mark as ready and send on its way */ 09685 thread->iostate = IAX_IOSTATE_READY; 09686 #ifdef DEBUG_SCHED_MULTITHREAD 09687 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09688 #endif 09689 signal_condition(&thread->lock, &thread->cond); 09690 09691 return 1; 09692 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 9285 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().
09286 { 09287 pthread_t newthread; 09288 struct dpreq_data *dpr; 09289 09290 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 09291 return; 09292 09293 dpr->callno = callno; 09294 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 09295 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 09296 if (callerid) 09297 dpr->callerid = ast_strdup(callerid); 09298 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 09299 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 09300 } 09301 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 12220 of file chan_iax2.c.
References ast_calloc, ast_cond_destroy, ast_cond_init, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, 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().
12221 { 12222 struct iax2_thread *thread; 12223 int threadcount = 0; 12224 int x; 12225 for (x = 0; x < iaxthreadcount; x++) { 12226 thread = ast_calloc(1, sizeof(*thread)); 12227 if (thread) { 12228 thread->type = IAX_THREAD_TYPE_POOL; 12229 thread->threadnum = ++threadcount; 12230 ast_mutex_init(&thread->lock); 12231 ast_cond_init(&thread->cond, NULL); 12232 ast_mutex_init(&thread->init_lock); 12233 ast_cond_init(&thread->init_cond, NULL); 12234 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 12235 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 12236 ast_mutex_destroy(&thread->lock); 12237 ast_cond_destroy(&thread->cond); 12238 ast_mutex_destroy(&thread->init_lock); 12239 ast_cond_destroy(&thread->init_cond); 12240 ast_free(thread); 12241 thread = NULL; 12242 continue; 12243 } 12244 AST_LIST_LOCK(&idle_list); 12245 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 12246 AST_LIST_UNLOCK(&idle_list); 12247 } 12248 } 12249 if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) { 12250 ast_log(LOG_ERROR, "Failed to create new thread!\n"); 12251 return -1; 12252 } 12253 ast_verb(2, "%d helper threads started\n", threadcount); 12254 return 0; 12255 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 8988 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
08989 { 08990 iax2_destroy_helper(iaxs[callno]); 08991 }
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 9171 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().
09172 { 09173 int res, processed = 0, totalcalls = 0; 09174 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 09175 struct timeval now = ast_tvnow(); 09176 09177 if (iaxtrunkdebug) 09178 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 09179 09180 if (timer) { 09181 if (ast_timer_ack(timer, 1) < 0) { 09182 ast_log(LOG_ERROR, "Timer failed acknowledge\n"); 09183 return 0; 09184 } 09185 } 09186 09187 /* For each peer that supports trunking... */ 09188 AST_LIST_LOCK(&tpeers); 09189 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 09190 processed++; 09191 res = 0; 09192 ast_mutex_lock(&tpeer->lock); 09193 /* We can drop a single tpeer per pass. That makes all this logic 09194 substantially easier */ 09195 if (!drop && iax2_trunk_expired(tpeer, &now)) { 09196 /* Take it out of the list, but don't free it yet, because it 09197 could be in use */ 09198 AST_LIST_REMOVE_CURRENT(list); 09199 drop = tpeer; 09200 } else { 09201 res = send_trunk(tpeer, &now); 09202 trunk_timed++; 09203 if (iaxtrunkdebug) 09204 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); 09205 } 09206 totalcalls += res; 09207 res = 0; 09208 ast_mutex_unlock(&tpeer->lock); 09209 } 09210 AST_LIST_TRAVERSE_SAFE_END; 09211 AST_LIST_UNLOCK(&tpeers); 09212 09213 if (drop) { 09214 ast_mutex_lock(&drop->lock); 09215 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 09216 because by the time they could get tpeerlock, we've already grabbed it */ 09217 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 09218 if (drop->trunkdata) { 09219 ast_free(drop->trunkdata); 09220 drop->trunkdata = NULL; 09221 } 09222 ast_mutex_unlock(&drop->lock); 09223 ast_mutex_destroy(&drop->lock); 09224 ast_free(drop); 09225 09226 } 09227 09228 if (iaxtrunkdebug) 09229 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 09230 iaxtrunkdebug = 0; 09231 09232 return 1; 09233 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14482 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by load_objects().
14483 { 14484 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14485 14486 /* The frames_received field is used to hold whether we're matching 14487 * against a full frame or not ... */ 14488 14489 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 14490 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14491 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14475 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
14476 { 14477 const struct chan_iax2_pvt *pvt = obj; 14478 14479 return pvt->transfercallno; 14480 }
static int transmit_frame | ( | void * | data | ) | [static] |
Definition at line 4257 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().
04258 { 04259 struct iax_frame *fr = data; 04260 04261 ast_mutex_lock(&iaxsl[fr->callno]); 04262 04263 fr->sentyet = 1; 04264 04265 if (iaxs[fr->callno]) { 04266 send_packet(fr); 04267 } 04268 04269 if (fr->retries < 0) { 04270 ast_mutex_unlock(&iaxsl[fr->callno]); 04271 /* No retransmit requested */ 04272 iax_frame_free(fr); 04273 } else { 04274 /* We need reliable delivery. Schedule a retransmission */ 04275 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list); 04276 fr->retries++; 04277 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr); 04278 ast_mutex_unlock(&iaxsl[fr->callno]); 04279 } 04280 04281 return 0; 04282 }
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 8306 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().
08307 { 08308 int newcall = 0; 08309 char newip[256]; 08310 struct iax_ie_data ied; 08311 struct sockaddr_in new = { 0, }; 08312 08313 memset(&ied, 0, sizeof(ied)); 08314 if (ies->apparent_addr) 08315 memmove(&new, ies->apparent_addr, sizeof(new)); 08316 if (ies->callno) 08317 newcall = ies->callno; 08318 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 08319 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08320 return -1; 08321 } 08322 pvt->transfercallno = newcall; 08323 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 08324 inet_aton(newip, &pvt->transfer.sin_addr); 08325 pvt->transfer.sin_family = AF_INET; 08326 pvt->transferid = ies->transferid; 08327 /* only store by transfercallno if this is a new transfer, 08328 * just in case we get a duplicate TXREQ */ 08329 if (pvt->transferring == TRANSFER_NONE) { 08330 store_by_transfercallno(pvt); 08331 } 08332 pvt->transferring = TRANSFER_BEGIN; 08333 08334 if (ies->transferid) 08335 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 08336 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 08337 return 0; 08338 }
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 8600 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().
08601 { 08602 if (peer->expire > -1) { 08603 if (!ast_sched_thread_del(sched, peer->expire)) { 08604 peer->expire = -1; 08605 peer_unref(peer); 08606 } 08607 } 08608 08609 if (peer->pokeexpire > -1) { 08610 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 08611 peer->pokeexpire = -1; 08612 peer_unref(peer); 08613 } 08614 } 08615 08616 ao2_unlink(peers, peer); 08617 }
static int unload_module | ( | void | ) | [static] |
Definition at line 14440 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
14441 { 14442 ast_custom_function_unregister(&iaxpeer_function); 14443 ast_custom_function_unregister(&iaxvar_function); 14444 return __unload_module(); 14445 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5465 of file chan_iax2.c.
References ast_mutex_unlock, and iaxsl.
Referenced by iax2_bridge().
05466 { 05467 ast_mutex_unlock(&iaxsl[callno1]); 05468 ast_mutex_unlock(&iaxsl[callno0]); 05469 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4010 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().
04011 { 04012 /* Video mini frames only encode the lower 15 bits of the session 04013 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 04014 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 04015 const int lower_mask = (1 << ts_shift) - 1; 04016 const int upper_mask = ~lower_mask; 04017 const int last_upper = iaxs[fr->callno]->last & upper_mask; 04018 04019 if ( (fr->ts & upper_mask) == last_upper ) { 04020 const int x = fr->ts - iaxs[fr->callno]->last; 04021 const int threshold = (ts_shift == 15) ? 25000 : 50000; 04022 04023 if (x < -threshold) { 04024 /* Sudden big jump backwards in timestamp: 04025 What likely happened here is that miniframe timestamp has circled but we haven't 04026 gotten the update from the main packet. We'll just pretend that we did, and 04027 update the timestamp appropriately. */ 04028 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 04029 if (iaxdebug) 04030 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 04031 } else if (x > threshold) { 04032 /* Sudden apparent big jump forwards in timestamp: 04033 What's likely happened is this is an old miniframe belonging to the previous 04034 top 15 or 16-bit timestamp that has turned up out of order. 04035 Adjust the timestamp appropriately. */ 04036 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 04037 if (iaxdebug) 04038 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 04039 } 04040 } 04041 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4045 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().
04046 { 04047 int when; 04048 04049 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 04050 04051 when = jb_next(pvt->jb) - when; 04052 04053 if (when <= 0) { 04054 /* XXX should really just empty until when > 0.. */ 04055 when = 1; 04056 } 04057 04058 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 04059 CALLNO_TO_PTR(pvt->callno)); 04060 }
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 8720 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().
08721 { 08722 /* Called from IAX thread only, with proper iaxsl lock */ 08723 struct iax_ie_data ied = { 08724 .pos = 0, 08725 }; 08726 struct iax2_peer *p; 08727 int msgcount; 08728 char data[80]; 08729 int version; 08730 const char *peer_name; 08731 int res = -1; 08732 struct ast_sockaddr sockaddr; 08733 08734 ast_sockaddr_from_sin(&sockaddr, sin); 08735 08736 peer_name = ast_strdupa(iaxs[callno]->peer); 08737 08738 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08739 ast_mutex_unlock(&iaxsl[callno]); 08740 if (!(p = find_peer(peer_name, 1))) { 08741 ast_mutex_lock(&iaxsl[callno]); 08742 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08743 return -1; 08744 } 08745 ast_mutex_lock(&iaxsl[callno]); 08746 if (!iaxs[callno]) 08747 goto return_unref; 08748 08749 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08750 if (sin->sin_addr.s_addr) { 08751 time_t nowtime; 08752 time(&nowtime); 08753 realtime_update_peer(peer_name, &sockaddr, nowtime); 08754 } else { 08755 realtime_update_peer(peer_name, &sockaddr, 0); 08756 } 08757 } 08758 08759 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) { 08760 if (iax2_regfunk) { 08761 iax2_regfunk(p->name, 1); 08762 } 08763 08764 /* modify entry in peercnts table as _not_ registered */ 08765 peercnt_modify(0, 0, &p->addr); 08766 08767 /* Stash the IP address from which they registered */ 08768 ast_sockaddr_from_sin(&p->addr, sin); 08769 08770 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08771 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08772 ast_db_put("IAX/Registry", p->name, data); 08773 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08774 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08775 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08776 register_peer_exten(p, 1); 08777 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08778 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) { 08779 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08780 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08781 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08782 register_peer_exten(p, 0); 08783 ast_db_del("IAX/Registry", p->name); 08784 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08785 } 08786 /* Update the host */ 08787 /* Verify that the host is really there */ 08788 iax2_poke_peer(p, callno); 08789 } 08790 08791 /* modify entry in peercnts table as registered */ 08792 if (p->maxcallno) { 08793 peercnt_modify(1, p->maxcallno, &p->addr); 08794 } 08795 08796 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08797 if (!iaxs[callno]) { 08798 res = -1; 08799 goto return_unref; 08800 } 08801 08802 /* Store socket fd */ 08803 p->sockfd = fd; 08804 /* Setup the expiry */ 08805 if (p->expire > -1) { 08806 if (!ast_sched_thread_del(sched, p->expire)) { 08807 p->expire = -1; 08808 peer_unref(p); 08809 } 08810 } 08811 /* treat an unspecified refresh interval as the minimum */ 08812 if (!refresh) 08813 refresh = min_reg_expire; 08814 if (refresh > max_reg_expire) { 08815 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08816 p->name, max_reg_expire, refresh); 08817 p->expiry = max_reg_expire; 08818 } else if (refresh < min_reg_expire) { 08819 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08820 p->name, min_reg_expire, refresh); 08821 p->expiry = min_reg_expire; 08822 } else { 08823 p->expiry = refresh; 08824 } 08825 if (p->expiry && sin->sin_addr.s_addr) { 08826 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08827 if (p->expire == -1) 08828 peer_unref(p); 08829 } 08830 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08831 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08832 if (sin->sin_addr.s_addr) { 08833 struct sockaddr_in peer_addr; 08834 08835 ast_sockaddr_to_sin(&p->addr, &peer_addr); 08836 08837 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08838 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr); 08839 if (!ast_strlen_zero(p->mailbox)) { 08840 struct ast_event *event; 08841 int new, old; 08842 char *mailbox, *context; 08843 08844 context = mailbox = ast_strdupa(p->mailbox); 08845 strsep(&context, "@"); 08846 if (ast_strlen_zero(context)) 08847 context = "default"; 08848 08849 event = ast_event_get_cached(AST_EVENT_MWI, 08850 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08851 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08852 AST_EVENT_IE_END); 08853 if (event) { 08854 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08855 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08856 ast_event_destroy(event); 08857 } else { /* Fall back on checking the mailbox directly */ 08858 ast_app_inboxcount(p->mailbox, &new, &old); 08859 } 08860 08861 if (new > 255) { 08862 new = 255; 08863 } 08864 if (old > 255) { 08865 old = 255; 08866 } 08867 msgcount = (old << 8) | new; 08868 08869 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08870 } 08871 if (ast_test_flag64(p, IAX_HASCALLERID)) { 08872 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08873 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08874 } 08875 } 08876 version = iax_check_version(devtype); 08877 if (version) 08878 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08879 08880 res = 0; 08881 08882 return_unref: 08883 peer_unref(p); 08884 08885 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08886 }
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 12961 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
12962 { 12963 struct iax2_user *user = obj; 12964 12965 ast_set_flag64(user, IAX_DELME); 12966 12967 return 0; 12968 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12686 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().
12687 { 12688 struct iax2_user *user = obj; 12689 12690 ast_free_ha(user->ha); 12691 free_context(user->contexts); 12692 if(user->vars) { 12693 ast_variables_destroy(user->vars); 12694 user->vars = NULL; 12695 } 12696 ast_string_field_free_memory(user); 12697 }
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 14645 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().
14647 { 14648 struct ast_data *data_user, *data_authmethods, *data_enum_node; 14649 struct iax2_user *user; 14650 struct ao2_iterator i; 14651 char auth[90]; 14652 char *pstr = ""; 14653 14654 i = ao2_iterator_init(users, 0); 14655 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 14656 data_user = ast_data_add_node(data_root, "user"); 14657 if (!data_user) { 14658 continue; 14659 } 14660 14661 ast_data_add_structure(iax2_user, data_user, user); 14662 14663 ast_data_add_codecs(data_user, "codecs", user->capability); 14664 14665 if (!ast_strlen_zero(user->secret)) { 14666 ast_copy_string(auth, user->secret, sizeof(auth)); 14667 } else if (!ast_strlen_zero(user->inkeys)) { 14668 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys); 14669 } else { 14670 ast_copy_string(auth, "no secret", sizeof(auth)); 14671 } 14672 ast_data_add_password(data_user, "secret", auth); 14673 14674 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT); 14675 14676 /* authmethods */ 14677 data_authmethods = ast_data_add_node(data_user, "authmethods"); 14678 if (!data_authmethods) { 14679 ast_data_remove_node(data_root, data_user); 14680 continue; 14681 } 14682 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA); 14683 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5); 14684 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT); 14685 14686 /* amaflags */ 14687 data_enum_node = ast_data_add_node(data_user, "amaflags"); 14688 if (!data_enum_node) { 14689 ast_data_remove_node(data_root, data_user); 14690 continue; 14691 } 14692 ast_data_add_int(data_enum_node, "value", user->amaflags); 14693 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags)); 14694 14695 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0); 14696 14697 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) { 14698 pstr = "REQ only"; 14699 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) { 14700 pstr = "disabled"; 14701 } else { 14702 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host"; 14703 } 14704 ast_data_add_str(data_user, "codec-preferences", pstr); 14705 14706 if (!ast_data_search_match(search, data_user)) { 14707 ast_data_remove_node(data_root, data_user); 14708 } 14709 } 14710 ao2_iterator_destroy(&i); 14711 14712 return 0; 14713 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 9089 of file chan_iax2.c.
References AST_LIST_TRAVERSE, f, iax_frame::oseqno, iax_frame::retries, and send_packet().
Referenced by socket_process().
09090 { 09091 struct iax_frame *f; 09092 09093 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) { 09094 /* Send a copy immediately */ 09095 if (((unsigned char) (f->oseqno - last) < 128) && 09096 (f->retries >= 0)) { 09097 send_packet(f); 09098 } 09099 } 09100 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5275 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().
05276 { 05277 unsigned short callno = pvt->callno; 05278 05279 if (!pvt->peercallno) { 05280 /* We don't know the remote side's call number, yet. :( */ 05281 int count = 10; 05282 while (count-- && pvt && !pvt->peercallno) { 05283 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05284 pvt = iaxs[callno]; 05285 } 05286 if (!pvt || !pvt->peercallno) { 05287 return -1; 05288 } 05289 } 05290 05291 return 0; 05292 }
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 14185 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 14725 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 14071 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 13991 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 9887 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 11925 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 14715 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 14720 of file chan_iax2.c.