Implementation of Inter-Asterisk eXchange Version 2 as specified in RFC 5456. More...
#include "asterisk.h"
#include <sys/mman.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <signal.h>
#include <strings.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <regex.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/md5.h"
#include "asterisk/cdr.h"
#include "asterisk/crypto.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/musiconhold.h"
#include "asterisk/features.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/localtime.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/netsock.h"
#include "asterisk/stringfields.h"
#include "asterisk/linkedlists.h"
#include "asterisk/event.h"
#include "asterisk/astobj2.h"
#include "asterisk/timing.h"
#include "asterisk/taskprocessor.h"
#include "asterisk/test.h"
#include "asterisk/data.h"
#include "asterisk/netsock2.h"
#include "iax2.h"
#include "iax2-parser.h"
#include "iax2-provision.h"
#include "jitterbuf.h"
Go to the source code of this file.
Data Structures | |
struct | addr_range |
struct | callno_entry |
struct | chan_iax2_pvt |
struct | create_addr_info |
struct | dpreq_data |
struct | iax2_context |
struct | iax2_dpcache |
struct | iax2_peer |
struct | iax2_pkt_buf |
struct | iax2_registry |
struct | iax2_thread |
struct | iax2_trunk_peer |
struct | iax2_user |
struct | iax_dual |
struct | iax_firmware |
struct | iax_rr |
struct | parsed_dial_string |
struct | signaling_queue_entry |
Defines | |
#define | ACN_FORMAT1 "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
#define | ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
#define | CALLTOKEN_IE_FORMAT "%u?%s" |
#define | DATA_EXPORT_IAX2_PEER(MEMBER) |
#define | DATA_EXPORT_IAX2_USER(MEMBER) |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | DONT_RESCHEDULE -2 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26) |
#define | IAX_ALREADYGONE (uint64_t)(1 << 9) |
#define | IAX_CALLENCRYPTED(pvt) (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_CODEC_NOCAP (uint64_t)(1 << 16) |
#define | IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
#define | IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
#define | IAX_DEBUGDIGEST(msg, key) |
#define | IAX_DELAYPBXSTART (uint64_t)(1 << 25) |
#define | IAX_DELME (uint64_t)(1 << 1) |
#define | IAX_DYNAMIC (uint64_t)(1 << 6) |
#define | IAX_ENCRYPTED (uint64_t)(1 << 12) |
#define | IAX_FORCE_ENCRYPT (uint64_t)(1 << 30) |
#define | IAX_FORCEJITTERBUF (uint64_t)(1 << 20) |
#define | IAX_HASCALLERID (uint64_t)(1 << 0) |
#define | IAX_IMMEDIATE (uint64_t)(1 << 27) |
#define | IAX_KEYPOPULATED (uint64_t)(1 << 13) |
#define | IAX_MAXAUTHREQ (uint64_t)(1 << 24) |
#define | IAX_NOTRANSFER (uint64_t)(1 << 4) |
#define | IAX_PROVISION (uint64_t)(1 << 10) |
#define | IAX_QUELCH (uint64_t)(1 << 11) |
#define | IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29) |
#define | IAX_RTAUTOCLEAR (uint64_t)(1 << 19) |
#define | IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
#define | IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
#define | IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
#define | IAX_RTUPDATE (uint64_t)(1 << 18) |
#define | IAX_SENDANI (uint64_t)(1 << 7) |
#define | IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28) |
#define | IAX_SHRINKCALLERID (uint64_t)(1 << 31) |
#define | IAX_TEMPONLY (uint64_t)(1 << 2) |
#define | IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
#define | IAX_TRUNK (uint64_t)(1 << 3) |
#define | IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
#define | IAX_USEJITTERBUF (uint64_t)(1 << 5) |
#define | MARK_IAX_SUBCLASS_TX 0x8000 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 563 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNK_MTU 1240 |
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240. | |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START (IAX_MAX_CALLS / 2) |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
#define | update_max_nontrunk() do { } while (0) |
#define | update_max_trunk() do { } while (0) |
Enumerations | |
enum | { CACHE_FLAG_EXISTS = (1 << 0), CACHE_FLAG_NONEXISTENT = (1 << 1), CACHE_FLAG_CANEXIST = (1 << 2), CACHE_FLAG_PENDING = (1 << 3), CACHE_FLAG_TIMEOUT = (1 << 4), CACHE_FLAG_TRANSMITTED = (1 << 5), CACHE_FLAG_UNKNOWN = (1 << 6), CACHE_FLAG_MATCHMORE = (1 << 7) } |
enum | { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 } |
enum | calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 } |
Call token validation settings. More... | |
enum | iax2_state { IAX_STATE_STARTED = (1 << 0), IAX_STATE_AUTHENTICATED = (1 << 1), IAX_STATE_TBD = (1 << 2) } |
enum | iax2_thread_iostate { IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_SCHEDREADY } |
enum | iax2_thread_type { IAX_THREAD_TYPE_POOL, IAX_THREAD_TYPE_DYNAMIC } |
enum | iax_reg_state { REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH } |
enum | iax_transfer_state { TRANSFER_NONE = 0, TRANSFER_BEGIN, TRANSFER_READY, TRANSFER_RELEASED, TRANSFER_PASSTHROUGH, TRANSFER_MBEGIN, TRANSFER_MREADY, TRANSFER_MRELEASED, TRANSFER_MPASSTHROUGH, TRANSFER_MEDIA, TRANSFER_MEDIAPASS } |
Functions | |
static void | __attempt_transmit (const void *data) |
static void | __auth_reject (const void *nothing) |
static void | __auto_congest (const void *nothing) |
static void | __auto_hangup (const void *nothing) |
static int | __do_deliver (void *data) |
static void | __expire_registry (const void *data) |
static int | __find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int return_locked, int check_dcallno) |
static void | __get_from_jb (const void *p) |
static void | __iax2_do_register_s (const void *data) |
static void | __iax2_poke_noanswer (const void *data) |
static void | __iax2_poke_peer_s (const void *data) |
static int | __iax2_show_peers (int fd, int *total, struct mansession *s, const int argc, const char *const argv[]) |
static int | __schedule_action (void(*func)(const void *data), const void *data, const char *funcname) |
static int | __send_command (struct chan_iax2_pvt *i, char type, int command, unsigned int ts, const unsigned char *data, int datalen, int seqno, int now, int transfer, int final) |
static void | __send_lagrq (const void *data) |
static void | __send_ping (const void *data) |
static int | __unload_module (void) |
static int | acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen) |
static int | acf_iaxvar_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | acf_iaxvar_write (struct ast_channel *chan, const char *cmd, char *data, const char *value) |
static int | add_calltoken_ignore (const char *addr) |
static void | add_empty_calltoken_ie (struct chan_iax2_pvt *pvt, struct iax_ie_data *ied) |
static int | addr_range_cmp_cb (void *obj, void *arg, int flags) |
static int | addr_range_delme_cb (void *obj, void *arg, int flags) |
static int | addr_range_hash_cb (const void *obj, const int flags) |
static int | addr_range_match_address_cb (void *obj, void *arg, int flags) |
static int | apply_context (struct iax2_context *con, const char *context) |
static int | ast_cli_netstats (struct mansession *s, int fd, int limit_fmt) |
AST_DATA_STRUCTURE (iax2_user, DATA_EXPORT_IAX2_USER) | |
AST_DATA_STRUCTURE (iax2_peer, DATA_EXPORT_IAX2_PEER) | |
static struct ast_channel * | ast_iax2_new (int callno, int state, format_t capability, const char *linkedid, unsigned int cachable) |
Create new call, interface with the PBX core. | |
static | AST_LIST_HEAD_NOLOCK (iax_frame) |
a list of frames that may need to be retransmitted | |
static | AST_LIST_HEAD_STATIC (dynamic_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (active_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (idle_list, iax2_thread) |
static | AST_LIST_HEAD_STATIC (dpcache, iax2_dpcache) |
static | AST_LIST_HEAD_STATIC (firmwares, iax_firmware) |
static | AST_LIST_HEAD_STATIC (registrations, iax2_registry) |
static | AST_LIST_HEAD_STATIC (tpeers, iax2_trunk_peer) |
AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER,"Inter Asterisk eXchange (Ver 2)",.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DRIVER,.nonoptreq="res_crypto",) | |
static int | attempt_transmit (const void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (const void *data) |
static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
static void | build_callno_limits (struct ast_variable *v) |
static struct iax2_context * | build_context (const char *context) |
static void | build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static void | build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static void | build_rand_pad (unsigned char *buf, ssize_t len) |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now) |
static int | callno_hash (const void *obj, const int flags) |
static int | calltoken_required (struct sockaddr_in *sin, const char *name, int subclass) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
Check if address can be used as packet source. | |
static void | cleanup_thread_list (void *head) |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_peers (const char *line, const char *word, int pos, int state, uint64_t flags) |
static char * | complete_iax2_unregister (const char *line, const char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (format_t subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | create_callno_pools (void) |
static int | decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static void | encmethods_to_str (int e, struct ast_str **buf) |
static int | encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (const void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static struct iax2_thread * | find_idle_thread (void) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static struct iax2_user * | find_user (const char *name) |
static unsigned int | fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static void | free_signaling_queue_entry (struct signaling_queue_entry *s) |
static int | function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (const char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (const void *p) |
static struct callno_entry * | get_unused_callno (int trunk, int validated) |
static int | handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd) |
static char * | handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Set trunk MTU from CLI. | |
static char * | handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show one peer in detail. | |
static char * | handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int attribute_pure | iax2_allow_new (int frametype, int subclass, int inbound) |
static void | iax2_ami_channelupdate (struct chan_iax2_pvt *pvt) |
Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers. | |
static int | iax2_answer (struct ast_channel *c) |
static int | iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static void * | iax2_dup_variable_datastore (void *) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static void | iax2_free_variable_datastore (void *) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static int | iax2_is_control_frame_allowed (int subtype) |
static int | iax2_key_rotate (const void *vpvt) |
static void | iax2_lock_owner (int callno) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_poke_noanswer (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
static int | iax2_prov_app (struct ast_channel *chan, const char *data) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force) |
static int | iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen) |
static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (const char *value, int lineno) |
static struct ast_channel * | iax2_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
static int | iax2_sched_add (struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
static int | iax2_sched_replace (int id, struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *text) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static void | iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2, const char *park_exten, const char *park_context) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
static int | load_objects (void) |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static void | log_jitterstats (unsigned short callno) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
static int | manager_iax2_show_peer_list (struct mansession *s, const struct message *m) |
callback to display iax peers in manager format | |
static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
callback to display iax peers in manager | |
static int | manager_iax2_show_registry (struct mansession *s, const struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
static void | network_change_event_cb (const struct ast_event *, void *) |
static int | network_change_event_sched_cb (const void *data) |
static void | network_change_event_subscribe (void) |
static void | network_change_event_unsubscribe (void) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static int | peercnt_add (struct sockaddr_in *sin) |
static int | peercnt_cmp_cb (void *obj, void *arg, int flags) |
static int | peercnt_hash_cb (const void *obj, const int flags) |
static void | peercnt_modify (unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr) |
static void | peercnt_remove (struct peercnt *peercnt) |
static int | peercnt_remove_by_addr (struct sockaddr_in *sin) |
static int | peercnt_remove_cb (const void *obj) |
static int | peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static void | poke_all_peers (void) |
static int | prune_addr_range_cb (void *obj, void *arg, int flags) |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
static void | pvt_destructor (void *obj) |
static int | pvt_hash_cb (const void *obj, const int flags) |
static int | queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f) |
All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number. | |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct ast_sockaddr *sockaddr, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
static int | reload (void) |
static int | reload_config (void) |
static void | reload_firmware (int unload) |
static void | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | remove_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | replace_callno (const void *obj) |
static void | requirecalltoken_mark_auto (const char *name, int subclass) |
static void | resend_with_token (int callno, struct iax_frame *f, const char *newtoken) |
static void | save_osptoken (struct iax_frame *fr, struct iax_ies *ies) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void | sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | scheduled_destroy (const void *vid) |
static int | send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (const void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (const void *data) |
static void | send_signaling (struct chan_iax2_pvt *pvt) |
This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point. | |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (const char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
static void | set_hangup_source_and_cause (int callno, unsigned char causecode) |
static void | set_peercnt_limit (struct peercnt *peercnt) |
static int | set_peercnt_limit_all_cb (void *obj, void *arg, int flags) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | stop_stuff (int callno) |
static void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | store_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags) |
static int | transfercallno_pvt_hash_cb (const void *obj, const int flags) |
static int | transmit_frame (void *data) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static format_t | uncompress_subclass (unsigned char csub) |
static void | unlink_peer (struct iax2_peer *peer) |
static int | unload_module (void) |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static int | update_packet (struct iax_frame *f) |
static int | update_registry (struct sockaddr_in *sin, int callno, char *devtype, int fd, unsigned short refresh) |
static int | user_cmp_cb (void *obj, void *arg, int flags) |
static int | user_delme_cb (void *obj, void *arg, int flags) |
static void | user_destructor (void *obj) |
static int | user_hash_cb (const void *obj, const int flags) |
static struct iax2_user * | user_ref (struct iax2_user *user) |
static struct iax2_user * | user_unref (struct iax2_user *user) |
static int | users_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static void | vnak_retransmit (int callno, int last) |
static int | wait_for_peercallno (struct chan_iax2_pvt *pvt) |
Variables | |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static int | authdebug = 1 |
static int | autokill = 0 |
static struct ao2_container * | callno_pool |
static const unsigned int | CALLNO_POOL_BUCKETS = 2699 |
static struct ao2_container * | callno_pool_trunk |
static struct ast_cli_entry | cli_iax2 [] |
static struct sockaddr_in | debugaddr |
static char | default_parkinglot [AST_MAX_CONTEXT] |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
static int | global_max_trunk_mtu |
static int | global_rtautoclear = 120 |
static struct ast_flags64 | globalflags = { 0 } |
static format_t | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
static struct ast_data_entry | iax2_data_providers [] |
static int | iax2_encryption = 0 |
static int(* | iax2_regfunk )(const char *username, int onoff) = NULL |
static struct ast_switch | iax2_switch |
static struct ast_channel_tech | iax2_tech |
static struct ast_datastore_info | iax2_variable_datastore_info |
static struct ao2_container * | iax_peercallno_pvts |
Another container of iax2_pvt structures. | |
static struct ao2_container * | iax_transfercallno_pvts |
Another container of iax2_pvt structures. | |
static int | iaxactivethreadcount = 0 |
static int | iaxcompat = 0 |
static int | iaxdebug = 0 |
static int | iaxdefaultdpcache = 10 * 60 |
static int | iaxdefaulttimeout = 5 |
static int | iaxdynamicthreadcount = 0 |
static int | iaxdynamicthreadnum = 0 |
static int | iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT |
static struct ast_custom_function | iaxpeer_function |
static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
an array of iax2 pvt structures | |
static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
chan_iax2_pvt structure locks | |
static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
static int | iaxtrunkdebug = 0 |
static struct ast_custom_function | iaxvar_function |
static struct io_context * | io |
static int | jittertargetextra = 40 |
static int | lagrq_time = 10 |
static char | language [MAX_LANGUAGE] = "" |
static int | last_authmethod = 0 |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 3 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | min_reg_expire |
static char | mohinterpret [MAX_MUSICCLASS] |
static char | mohsuggest [MAX_MUSICCLASS] |
static struct ast_netsock_list * | netsock |
static pthread_t | netthreadid = AST_PTHREADT_NULL |
static int | network_change_event_sched_id = -1 |
static struct ast_event_sub * | network_change_event_subscription |
static struct ast_netsock_list * | outsock |
static char * | papp = "IAX2Provision" |
static struct ast_data_handler | peers_data_provider |
static int | ping_time = 21 |
static struct ast_codec_pref | prefs |
struct { | |
unsigned int cos | |
unsigned int tos | |
} | qos |
static char | regcontext [AST_MAX_CONTEXT] = "" |
static int | resyncthreshold = 1000 |
static struct ast_sched_thread * | sched |
static int | srvlookup = 0 |
static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
static int | test_losspct = 0 |
static struct ast_timer * | timer |
static int | trunk_maxmtu |
static int | trunk_nmaxmtu |
static int | trunk_timed |
static int | trunk_untimed |
static int | trunkfreq = 20 |
static int | trunkmaxsize = MAX_TRUNKDATA |
static struct ast_data_handler | users_data_provider |
Implementation of Inter-Asterisk eXchange Version 2 as specified in RFC 5456.
Definition in file chan_iax2.c.
#define ACN_FORMAT1 "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
Referenced by ast_cli_netstats().
#define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
Referenced by ast_cli_netstats().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 243 of file chan_iax2.c.
Referenced by ast_iax2_new(), iax2_call(), iax2_hangup(), and update_jbsched().
#define CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
Referenced by handle_call_token().
#define CALLTOKEN_IE_FORMAT "%u?%s" |
Referenced by handle_call_token().
#define DATA_EXPORT_IAX2_PEER | ( | MEMBER | ) |
Definition at line 14770 of file chan_iax2.c.
#define DATA_EXPORT_IAX2_USER | ( | MEMBER | ) |
Definition at line 14847 of file chan_iax2.c.
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 235 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 251 of file chan_iax2.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 270 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), reload_config(), and users_data_provider_get().
#define DEFAULT_DROP 3 |
Definition at line 249 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 345 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 344 of file chan_iax2.c.
Referenced by build_peer().
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 246 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 343 of file chan_iax2.c.
Referenced by build_peer(), iax2_poke_peer(), reload_config(), and set_config().
#define DEFAULT_RETRY_TIME 1000 |
Definition at line 247 of file chan_iax2.c.
Referenced by __find_callno(), and complete_transfer().
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 245 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 624 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define DONT_RESCHEDULE -2 |
Definition at line 367 of file chan_iax2.c.
Referenced by __send_lagrq(), __send_ping(), iax2_destroy_helper(), send_lagrq(), and send_ping().
#define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" |
#define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" |
#define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define GAMMA (0.01) |
Definition at line 256 of file chan_iax2.c.
#define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
Definition at line 545 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26) |
Allow the FWDOWNL command?
Definition at line 433 of file chan_iax2.c.
Referenced by set_config(), and socket_process().
#define IAX_ALREADYGONE (uint64_t)(1 << 9) |
Already disconnected
Definition at line 416 of file chan_iax2.c.
Referenced by __do_deliver(), __get_from_jb(), iax2_hangup(), iax2_predestroy(), iax2_write(), pvt_destructor(), and socket_process().
#define IAX_CALLENCRYPTED | ( | pvt | ) | (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED)) |
Definition at line 348 of file chan_iax2.c.
Referenced by acf_channel_read(), iax2_send(), iax2_start_transfer(), and socket_process().
#define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 322 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 334 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Definition at line 339 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
Definition at line 324 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CODEC_NOCAP (uint64_t)(1 << 16) |
only consider requested format and ignore capabilities
Definition at line 423 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
#define IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
Force old behaviour by turning off prefs
Definition at line 422 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
#define IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
are we willing to let the other guy choose the codec?
Definition at line 421 of file chan_iax2.c.
Referenced by build_user(), check_access(), handle_cli_iax2_show_users(), set_config(), socket_process(), and users_data_provider_get().
#define IAX_DEBUGDIGEST | ( | msg, | |||
key | ) |
Definition at line 351 of file chan_iax2.c.
Referenced by iax2_key_rotate(), and socket_process().
#define IAX_DELAYPBXSTART (uint64_t)(1 << 25) |
Don't start a PBX on the channel until the peer sends us a response, so that we've achieved a three-way handshake with them before sending voice or anything else
Definition at line 432 of file chan_iax2.c.
Referenced by socket_process().
#define IAX_DELME (uint64_t)(1 << 1) |
Needs to be deleted
Definition at line 408 of file chan_iax2.c.
Referenced by build_peer(), build_user(), peer_delme_cb(), prune_peers(), prune_users(), and user_delme_cb().
#define IAX_DYNAMIC (uint64_t)(1 << 6) |
dynamic peer
Definition at line 413 of file chan_iax2.c.
Referenced by __iax2_show_peers(), build_peer(), function_iaxpeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), realtime_peer(), register_verify(), and set_config().
#define IAX_ENCRYPTED (uint64_t)(1 << 12) |
Whether we should assume encrypted tx/rx
Definition at line 419 of file chan_iax2.c.
Referenced by authenticate_reply(), authenticate_request(), iax2_send(), and socket_process().
#define IAX_FORCE_ENCRYPT (uint64_t)(1 << 30) |
Forces call encryption, if encryption not possible hangup
Definition at line 437 of file chan_iax2.c.
Referenced by __find_callno(), authenticate_reply(), authenticate_verify(), build_peer(), build_user(), check_access(), create_addr(), iax2_call(), iax2_queryoption(), iax2_setoption(), set_config(), and socket_process().
#define IAX_FORCEJITTERBUF (uint64_t)(1 << 20) |
Force jitterbuffer, even when bridged to a channel that can take jitter
Definition at line 427 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), schedule_delivery(), set_config(), and set_config_destroy().
#define IAX_HASCALLERID (uint64_t)(1 << 0) |
CallerID has been specified
Definition at line 407 of file chan_iax2.c.
Referenced by build_peer(), build_user(), check_access(), and update_registry().
#define IAX_IMMEDIATE (uint64_t)(1 << 27) |
Allow immediate off-hook to extension s
Definition at line 434 of file chan_iax2.c.
Referenced by build_user(), check_access(), and socket_process().
#define IAX_KEYPOPULATED (uint64_t)(1 << 13) |
Whether we have a key populated
Definition at line 420 of file chan_iax2.c.
Referenced by authenticate_reply(), decrypt_frame(), and iax2_send().
#define IAX_MAXAUTHREQ (uint64_t)(1 << 24) |
Maximum outstanding AUTHREQ restriction is in place
Definition at line 431 of file chan_iax2.c.
Referenced by authenticate_request(), authenticate_verify(), check_access(), and iax2_destroy_helper().
#define IAX_NOTRANSFER (uint64_t)(1 << 4) |
Don't native bridge
Definition at line 411 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_bridge(), iax2_request(), iax2_start_transfer(), set_config(), and set_config_destroy().
#define IAX_PROVISION (uint64_t)(1 << 10) |
This is a provisioning request
Definition at line 417 of file chan_iax2.c.
Referenced by iax2_provision(), and socket_process().
#define IAX_QUELCH (uint64_t)(1 << 11) |
Whether or not we quelch audio
Definition at line 418 of file chan_iax2.c.
Referenced by iax2_write(), and socket_process().
#define IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29) |
Allow receiving of connected line updates
Definition at line 436 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), set_config(), set_config_destroy(), and socket_process().
#define IAX_RTAUTOCLEAR (uint64_t)(1 << 19) |
erase me on expire
Definition at line 426 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), realtime_peer(), and set_config().
#define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
let realtime stay till your reload
Definition at line 424 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), prune_peers(), prune_users(), realtime_peer(), realtime_user(), set_config(), and update_registry().
#define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
When using realtime, ignore registration expiration
Definition at line 428 of file chan_iax2.c.
Referenced by realtime_peer(), and set_config().
#define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
Save Systname on Realtime Updates
Definition at line 415 of file chan_iax2.c.
Referenced by realtime_update_peer(), and set_config().
#define IAX_RTUPDATE (uint64_t)(1 << 18) |
Send a realtime update
Definition at line 425 of file chan_iax2.c.
Referenced by __expire_registry(), set_config(), and update_registry().
#define IAX_SENDANI (uint64_t)(1 << 7) |
Send ANI along with CallerID
Definition at line 414 of file chan_iax2.c.
Referenced by build_peer(), create_addr(), iax2_call(), and iax2_request().
#define IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28) |
Allow sending of connected line updates
Definition at line 435 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_indicate(), iax2_request(), set_config(), and set_config_destroy().
#define IAX_SHRINKCALLERID (uint64_t)(1 << 31) |
Turn on and off caller id shrinking
Definition at line 438 of file chan_iax2.c.
Referenced by check_access(), and set_config().
#define IAX_TEMPONLY (uint64_t)(1 << 2) |
Temporary (realtime)
Definition at line 409 of file chan_iax2.c.
Referenced by __expire_registry(), realtime_peer(), realtime_user(), reg_source_db(), and update_registry().
#define IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
When doing IAX2 transfers, transfer media only
Definition at line 430 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_bridge(), iax2_request(), set_config(), and set_config_destroy().
#define IAX_TRUNK (uint64_t)(1 << 3) |
Treat as a trunk
Definition at line 410 of file chan_iax2.c.
Referenced by __iax2_show_peers(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_peer(), iax2_getpeertrunk(), iax2_request(), iax2_send(), manager_iax2_show_peer_list(), peers_data_provider_get(), and socket_process().
#define IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
Send trunk timestamps
Definition at line 429 of file chan_iax2.c.
Referenced by iax2_trunk_queue(), send_trunk(), and set_config().
#define IAX_USEJITTERBUF (uint64_t)(1 << 5) |
Use jitter buffer
Definition at line 412 of file chan_iax2.c.
Referenced by __find_callno(), ast_cli_netstats(), build_peer(), build_user(), check_access(), create_addr(), handle_cli_iax2_show_channels(), iax2_request(), log_jitterstats(), schedule_delivery(), set_config(), and set_config_destroy().
#define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 632 of file chan_iax2.c.
Referenced by ast_cli_netstats(), handle_cli_iax2_show_channels(), and iax2_send().
#define MAX_JITTER_BUFFER 50 |
Definition at line 621 of file chan_iax2.c.
#define MAX_PEER_BUCKETS 563 |
Referenced by load_objects().
#define MAX_RETRY_TIME 10000 |
Definition at line 619 of file chan_iax2.c.
Referenced by __attempt_transmit(), and iax2_send().
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 626 of file chan_iax2.c.
Referenced by ast_rtp_raw_write(), calc_timestamp(), and calc_txpeerstamp().
#define MAX_TRUNK_MTU 1240 |
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.
Definition at line 265 of file chan_iax2.c.
Referenced by handle_cli_iax2_set_mtu(), and set_config().
#define MAX_TRUNKDATA 640 * 200 |
40ms, uncompressed linear * 200 channels
Definition at line 289 of file chan_iax2.c.
Referenced by set_config(), and set_config_destroy().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
Referenced by load_module(), and load_objects().
#define MEMORY_SIZE 100 |
Definition at line 248 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 622 of file chan_iax2.c.
#define MIN_RETRY_TIME 100 |
Definition at line 618 of file chan_iax2.c.
Referenced by iax2_send().
#define MIN_REUSE_TIME 60 |
Definition at line 253 of file chan_iax2.c.
Referenced by make_trunk(), and sched_delay_remove().
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 242 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), acf_channel_read(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_queryoption(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
#define SCHED_MULTITHREADED |
Definition at line 231 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1569 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
#define TRUNK_CALL_START (IAX_MAX_CALLS / 2) |
Definition at line 1098 of file chan_iax2.c.
#define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 629 of file chan_iax2.c.
#define update_max_nontrunk | ( | ) | do { } while (0) |
Definition at line 2131 of file chan_iax2.c.
Referenced by __find_callno(), and make_trunk().
#define update_max_trunk | ( | ) | do { } while (0) |
Definition at line 2130 of file chan_iax2.c.
Referenced by iax2_destroy(), and make_trunk().
anonymous enum |
Definition at line 943 of file chan_iax2.c.
00943 { 00944 /*! Extension exists */ 00945 CACHE_FLAG_EXISTS = (1 << 0), 00946 /*! Extension is nonexistent */ 00947 CACHE_FLAG_NONEXISTENT = (1 << 1), 00948 /*! Extension can exist */ 00949 CACHE_FLAG_CANEXIST = (1 << 2), 00950 /*! Waiting to hear back response */ 00951 CACHE_FLAG_PENDING = (1 << 3), 00952 /*! Timed out */ 00953 CACHE_FLAG_TIMEOUT = (1 << 4), 00954 /*! Request transmitted */ 00955 CACHE_FLAG_TRANSMITTED = (1 << 5), 00956 /*! Timeout */ 00957 CACHE_FLAG_UNKNOWN = (1 << 6), 00958 /*! Matchmore */ 00959 CACHE_FLAG_MATCHMORE = (1 << 7), 00960 };
anonymous enum |
Definition at line 2057 of file chan_iax2.c.
02057 { 02058 /* do not allow a new call number, only search ones in use for match */ 02059 NEW_PREVENT = 0, 02060 /* search for match first, then allow a new one to be allocated */ 02061 NEW_ALLOW = 1, 02062 /* do not search for match, force a new call number */ 02063 NEW_FORCE = 2, 02064 /* do not search for match, force a new call number. Signifies call number 02065 * has been calltoken validated */ 02066 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 02067 };
enum calltoken_peer_enum |
Call token validation settings.
Definition at line 446 of file chan_iax2.c.
00446 { 00447 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00448 CALLTOKEN_DEFAULT = 0, 00449 /*! \brief Require call token validation. */ 00450 CALLTOKEN_YES = 1, 00451 /*! \brief Require call token validation after a successful registration 00452 * using call token validation occurs. */ 00453 CALLTOKEN_AUTO = 2, 00454 /*! \brief Do not require call token validation. */ 00455 CALLTOKEN_NO = 3, 00456 };
enum iax2_state |
Definition at line 395 of file chan_iax2.c.
00395 { 00396 IAX_STATE_STARTED = (1 << 0), 00397 IAX_STATE_AUTHENTICATED = (1 << 1), 00398 IAX_STATE_TBD = (1 << 2), 00399 };
enum iax2_thread_iostate |
Definition at line 984 of file chan_iax2.c.
00984 { 00985 IAX_IOSTATE_IDLE, 00986 IAX_IOSTATE_READY, 00987 IAX_IOSTATE_PROCESSING, 00988 IAX_IOSTATE_SCHEDREADY, 00989 };
enum iax2_thread_type |
Definition at line 991 of file chan_iax2.c.
00991 { 00992 IAX_THREAD_TYPE_POOL, 00993 IAX_THREAD_TYPE_DYNAMIC, 00994 };
enum iax_reg_state |
REG_STATE_UNREGISTERED | |
REG_STATE_REGSENT | |
REG_STATE_AUTHSENT | |
REG_STATE_REGISTERED | |
REG_STATE_REJECTED | |
REG_STATE_TIMEOUT | |
REG_STATE_NOAUTH |
Definition at line 577 of file chan_iax2.c.
00577 { 00578 REG_STATE_UNREGISTERED = 0, 00579 REG_STATE_REGSENT, 00580 REG_STATE_AUTHSENT, 00581 REG_STATE_REGISTERED, 00582 REG_STATE_REJECTED, 00583 REG_STATE_TIMEOUT, 00584 REG_STATE_NOAUTH 00585 };
enum iax_transfer_state |
TRANSFER_NONE | |
TRANSFER_BEGIN | |
TRANSFER_READY | |
TRANSFER_RELEASED | |
TRANSFER_PASSTHROUGH | |
TRANSFER_MBEGIN | |
TRANSFER_MREADY | |
TRANSFER_MRELEASED | |
TRANSFER_MPASSTHROUGH | |
TRANSFER_MEDIA | |
TRANSFER_MEDIAPASS |
Definition at line 587 of file chan_iax2.c.
00587 { 00588 TRANSFER_NONE = 0, 00589 TRANSFER_BEGIN, 00590 TRANSFER_READY, 00591 TRANSFER_RELEASED, 00592 TRANSFER_PASSTHROUGH, 00593 TRANSFER_MBEGIN, 00594 TRANSFER_MREADY, 00595 TRANSFER_MRELEASED, 00596 TRANSFER_MPASSTHROUGH, 00597 TRANSFER_MEDIA, 00598 TRANSFER_MEDIAPASS 00599 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3568 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_REMOVE, ast_log(), ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxs, iaxsl, ast_frame_subclass::integer, LOG_WARNING, MAX_RETRY_TIME, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
03569 { 03570 /* Attempt to transmit the frame to the remote peer... 03571 Called without iaxsl held. */ 03572 struct iax_frame *f = (struct iax_frame *)data; 03573 int freeme = 0; 03574 int callno = f->callno; 03575 03576 /* Make sure this call is still active */ 03577 if (callno) 03578 ast_mutex_lock(&iaxsl[callno]); 03579 if (callno && iaxs[callno]) { 03580 if (f->retries < 0) { 03581 /* Already ACK'd */ 03582 freeme = 1; 03583 } else if (f->retries >= max_retries) { 03584 /* Too many attempts. Record an error. */ 03585 if (f->transfer) { 03586 /* Transfer timeout */ 03587 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03588 } else if (f->final) { 03589 iax2_destroy(callno); 03590 } else { 03591 if (iaxs[callno]->owner) { 03592 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %u, subclass = %d, ts=%u, seqno=%d)\n", 03593 ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr), 03594 iaxs[f->callno]->owner->name, 03595 f->af.frametype, 03596 f->af.subclass.integer, 03597 f->ts, 03598 f->oseqno); 03599 } 03600 iaxs[callno]->error = ETIMEDOUT; 03601 if (iaxs[callno]->owner) { 03602 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03603 /* Hangup the fd */ 03604 iax2_queue_frame(callno, &fr); /* XXX */ 03605 /* Remember, owner could disappear */ 03606 if (iaxs[callno] && iaxs[callno]->owner) 03607 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03608 } else { 03609 if (iaxs[callno]->reg) { 03610 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03611 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03612 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03613 } 03614 iax2_destroy(callno); 03615 } 03616 } 03617 freeme = 1; 03618 } else { 03619 /* Update it if it needs it */ 03620 update_packet(f); 03621 /* Attempt transmission */ 03622 send_packet(f); 03623 f->retries++; 03624 /* Try again later after 10 times as long */ 03625 f->retrytime *= 10; 03626 if (f->retrytime > MAX_RETRY_TIME) 03627 f->retrytime = MAX_RETRY_TIME; 03628 /* Transfer messages max out at one second */ 03629 if (f->transfer && (f->retrytime > 1000)) 03630 f->retrytime = 1000; 03631 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03632 } 03633 } else { 03634 /* Make sure it gets freed */ 03635 f->retries = -1; 03636 freeme = 1; 03637 } 03638 03639 if (freeme) { 03640 /* Don't attempt delivery, just remove it from the queue */ 03641 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03642 ast_mutex_unlock(&iaxsl[callno]); 03643 f->retrans = -1; /* this is safe because this is the scheduled function */ 03644 /* Free the IAX frame */ 03645 iax2_frame_free(f); 03646 } else if (callno) { 03647 ast_mutex_unlock(&iaxsl[callno]); 03648 } 03649 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 9112 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().
09113 { 09114 /* Called from IAX thread only, without iaxs lock */ 09115 int callno = (int)(long)(nothing); 09116 struct iax_ie_data ied; 09117 ast_mutex_lock(&iaxsl[callno]); 09118 if (iaxs[callno]) { 09119 memset(&ied, 0, sizeof(ied)); 09120 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 09121 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 09122 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 09123 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 09124 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 09125 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 09126 } 09127 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 09128 } 09129 ast_mutex_unlock(&iaxsl[callno]); 09130 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4758 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
04759 { 04760 int callno = PTR_TO_CALLNO(nothing); 04761 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } }; 04762 ast_mutex_lock(&iaxsl[callno]); 04763 if (iaxs[callno]) { 04764 iaxs[callno]->initid = -1; 04765 iax2_queue_frame(callno, &f); 04766 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04767 } 04768 ast_mutex_unlock(&iaxsl[callno]); 04769 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 9161 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().
09162 { 09163 /* Called from IAX thread only, without iaxs lock */ 09164 int callno = (int)(long)(nothing); 09165 struct iax_ie_data ied; 09166 ast_mutex_lock(&iaxsl[callno]); 09167 if (iaxs[callno]) { 09168 memset(&ied, 0, sizeof(ied)); 09169 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 09170 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 09171 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 09172 } 09173 ast_mutex_unlock(&iaxsl[callno]); 09174 }
static int __do_deliver | ( | void * | data | ) | [static] |
Definition at line 3356 of file chan_iax2.c.
References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag64, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
03357 { 03358 /* Just deliver the packet by using queueing. This is called by 03359 the IAX thread with the iaxsl lock held. */ 03360 struct iax_frame *fr = data; 03361 fr->retrans = -1; 03362 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03363 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE)) 03364 iax2_queue_frame(fr->callno, &fr->af); 03365 /* Free our iax frame */ 03366 iax2_frame_free(fr); 03367 /* And don't run again */ 03368 return 0; 03369 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8737 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().
08738 { 08739 struct iax2_peer *peer = (struct iax2_peer *) data; 08740 08741 if (!peer) 08742 return; 08743 if (peer->expire == -1) { 08744 /* Removed already (possibly through CLI), ignore */ 08745 return; 08746 } 08747 08748 peer->expire = -1; 08749 08750 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08751 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08752 realtime_update_peer(peer->name, &peer->addr, 0); 08753 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08754 /* modify entry in peercnts table as _not_ registered */ 08755 peercnt_modify((unsigned char) 0, 0, &peer->addr); 08756 /* Reset the address */ 08757 memset(&peer->addr, 0, sizeof(peer->addr)); 08758 /* Reset expiry value */ 08759 peer->expiry = min_reg_expire; 08760 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08761 ast_db_del("IAX/Registry", peer->name); 08762 register_peer_exten(peer, 0); 08763 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 08764 if (iax2_regfunk) 08765 iax2_regfunk(peer->name, 0); 08766 08767 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08768 unlink_peer(peer); 08769 08770 peer_unref(peer); 08771 }
static int __find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | return_locked, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 2862 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find, ao2_ref, ast_copy_flags64, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_string_field_set, callno_entry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), iax2_getpeername(), iax2_sched_add(), IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, iax_peercallno_pvts, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, iax_transfercallno_pvts, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, match(), NEW_ALLOW, new_iax(), OBJ_POINTER, parkinglot, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, and update_max_nontrunk.
Referenced by find_callno(), and find_callno_locked().
02863 { 02864 int res = 0; 02865 int x; 02866 /* this call is calltoken validated as long as it is either NEW_FORCE 02867 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02868 int validated = (new > NEW_ALLOW) ? 1 : 0; 02869 char host[80]; 02870 02871 if (new <= NEW_ALLOW) { 02872 if (callno) { 02873 struct chan_iax2_pvt *pvt; 02874 struct chan_iax2_pvt tmp_pvt = { 02875 .callno = dcallno, 02876 .peercallno = callno, 02877 .transfercallno = callno, 02878 /* hack!! */ 02879 .frames_received = check_dcallno, 02880 }; 02881 02882 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02883 /* this works for finding normal call numbers not involving transfering */ 02884 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02885 if (return_locked) { 02886 ast_mutex_lock(&iaxsl[pvt->callno]); 02887 } 02888 res = pvt->callno; 02889 ao2_ref(pvt, -1); 02890 pvt = NULL; 02891 return res; 02892 } 02893 /* this searches for transfer call numbers that might not get caught otherwise */ 02894 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02895 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02896 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02897 if (return_locked) { 02898 ast_mutex_lock(&iaxsl[pvt->callno]); 02899 } 02900 res = pvt->callno; 02901 ao2_ref(pvt, -1); 02902 pvt = NULL; 02903 return res; 02904 } 02905 } 02906 /* This will occur on the first response to a message that we initiated, 02907 * such as a PING. */ 02908 if (dcallno) { 02909 ast_mutex_lock(&iaxsl[dcallno]); 02910 } 02911 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02912 iaxs[dcallno]->peercallno = callno; 02913 res = dcallno; 02914 store_by_peercallno(iaxs[dcallno]); 02915 if (!res || !return_locked) { 02916 ast_mutex_unlock(&iaxsl[dcallno]); 02917 } 02918 return res; 02919 } 02920 if (dcallno) { 02921 ast_mutex_unlock(&iaxsl[dcallno]); 02922 } 02923 #ifdef IAX_OLD_FIND 02924 /* If we get here, we SHOULD NOT find a call structure for this 02925 callno; if we do, it means that there is a call structure that 02926 has a peer callno but did NOT get entered into the hash table, 02927 which is bad. 02928 02929 If we find a call structure using this old, slow method, output a log 02930 message so we'll know about it. After a few months of leaving this in 02931 place, if we don't hear about people seeing these messages, we can 02932 remove this code for good. 02933 */ 02934 02935 for (x = 1; !res && x < maxnontrunkcall; x++) { 02936 ast_mutex_lock(&iaxsl[x]); 02937 if (iaxs[x]) { 02938 /* Look for an exact match */ 02939 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02940 res = x; 02941 } 02942 } 02943 if (!res || !return_locked) 02944 ast_mutex_unlock(&iaxsl[x]); 02945 } 02946 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02947 ast_mutex_lock(&iaxsl[x]); 02948 if (iaxs[x]) { 02949 /* Look for an exact match */ 02950 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02951 res = x; 02952 } 02953 } 02954 if (!res || !return_locked) 02955 ast_mutex_unlock(&iaxsl[x]); 02956 } 02957 #endif 02958 } 02959 if (!res && (new >= NEW_ALLOW)) { 02960 struct callno_entry *callno_entry; 02961 /* It may seem odd that we look through the peer list for a name for 02962 * this *incoming* call. Well, it is weird. However, users don't 02963 * have an IP address/port number that we can match against. So, 02964 * this is just checking for a peer that has that IP/port and 02965 * assuming that we have a user of the same name. This isn't always 02966 * correct, but it will be changed if needed after authentication. */ 02967 if (!iax2_getpeername(*sin, host, sizeof(host))) 02968 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02969 02970 if (peercnt_add(sin)) { 02971 /* This address has hit its callnumber limit. When the limit 02972 * is reached, the connection is not added to the peercnts table.*/ 02973 return 0; 02974 } 02975 02976 if (!(callno_entry = get_unused_callno(0, validated))) { 02977 /* since we ran out of space, remove the peercnt 02978 * entry we added earlier */ 02979 peercnt_remove_by_addr(sin); 02980 ast_log(LOG_WARNING, "No more space\n"); 02981 return 0; 02982 } 02983 x = callno_entry->callno; 02984 ast_mutex_lock(&iaxsl[x]); 02985 02986 iaxs[x] = new_iax(sin, host); 02987 update_max_nontrunk(); 02988 if (iaxs[x]) { 02989 if (iaxdebug) 02990 ast_debug(1, "Creating new call structure %d\n", x); 02991 iaxs[x]->callno_entry = callno_entry; 02992 iaxs[x]->sockfd = sockfd; 02993 iaxs[x]->addr.sin_port = sin->sin_port; 02994 iaxs[x]->addr.sin_family = sin->sin_family; 02995 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02996 iaxs[x]->peercallno = callno; 02997 iaxs[x]->callno = x; 02998 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02999 iaxs[x]->expiry = min_reg_expire; 03000 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 03001 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 03002 iaxs[x]->amaflags = amaflags; 03003 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 03004 ast_string_field_set(iaxs[x], accountcode, accountcode); 03005 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 03006 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 03007 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 03008 03009 if (iaxs[x]->peercallno) { 03010 store_by_peercallno(iaxs[x]); 03011 } 03012 } else { 03013 ast_log(LOG_WARNING, "Out of resources\n"); 03014 ast_mutex_unlock(&iaxsl[x]); 03015 replace_callno(callno_entry); 03016 return 0; 03017 } 03018 if (!return_locked) 03019 ast_mutex_unlock(&iaxsl[x]); 03020 res = x; 03021 } 03022 return res; 03023 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4152 of file chan_iax2.c.
References __do_deliver(), ast_codec_interp_len(), ast_format_rate(), AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_test_flag64, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_frame_subclass::codec, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, iaxs, iaxsl, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
04153 { 04154 int callno = PTR_TO_CALLNO(p); 04155 struct chan_iax2_pvt *pvt = NULL; 04156 struct iax_frame *fr; 04157 jb_frame frame; 04158 int ret; 04159 long ms; 04160 long next; 04161 struct timeval now = ast_tvnow(); 04162 04163 /* Make sure we have a valid private structure before going on */ 04164 ast_mutex_lock(&iaxsl[callno]); 04165 pvt = iaxs[callno]; 04166 if (!pvt) { 04167 /* No go! */ 04168 ast_mutex_unlock(&iaxsl[callno]); 04169 return; 04170 } 04171 04172 pvt->jbid = -1; 04173 04174 /* round up a millisecond since ast_sched_runq does; */ 04175 /* prevents us from spinning while waiting for our now */ 04176 /* to catch up with runq's now */ 04177 now.tv_usec += 1000; 04178 04179 ms = ast_tvdiff_ms(now, pvt->rxcore); 04180 04181 if(ms >= (next = jb_next(pvt->jb))) { 04182 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 04183 switch(ret) { 04184 case JB_OK: 04185 fr = frame.data; 04186 __do_deliver(fr); 04187 /* __do_deliver() can cause the call to disappear */ 04188 pvt = iaxs[callno]; 04189 break; 04190 case JB_INTERP: 04191 { 04192 struct ast_frame af = { 0, }; 04193 04194 /* create an interpolation frame */ 04195 af.frametype = AST_FRAME_VOICE; 04196 af.subclass.codec = pvt->voiceformat; 04197 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 04198 af.src = "IAX2 JB interpolation"; 04199 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 04200 af.offset = AST_FRIENDLY_OFFSET; 04201 04202 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 04203 * which we'd need to malloc, and then it would free it. That seems like a drag */ 04204 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 04205 iax2_queue_frame(callno, &af); 04206 /* iax2_queue_frame() could cause the call to disappear */ 04207 pvt = iaxs[callno]; 04208 } 04209 } 04210 break; 04211 case JB_DROP: 04212 iax2_frame_free(frame.data); 04213 break; 04214 case JB_NOFRAME: 04215 case JB_EMPTY: 04216 /* do nothing */ 04217 break; 04218 default: 04219 /* shouldn't happen */ 04220 break; 04221 } 04222 } 04223 if (pvt) 04224 update_jbsched(pvt); 04225 ast_mutex_unlock(&iaxsl[callno]); 04226 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8408 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08409 { 08410 struct iax2_registry *reg = (struct iax2_registry *)data; 08411 reg->expire = -1; 08412 iax2_do_register(reg); 08413 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12205 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().
12206 { 12207 struct iax2_peer *peer = (struct iax2_peer *)data; 12208 int callno; 12209 12210 if (peer->lastms > -1) { 12211 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 12212 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 12213 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 12214 } 12215 if ((callno = peer->callno) > 0) { 12216 ast_mutex_lock(&iaxsl[callno]); 12217 iax2_destroy(callno); 12218 ast_mutex_unlock(&iaxsl[callno]); 12219 } 12220 peer->callno = 0; 12221 peer->lastms = -1; 12222 /* Try again quickly */ 12223 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 12224 if (peer->pokeexpire == -1) 12225 peer_unref(peer); 12226 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9221 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
09222 { 09223 struct iax2_peer *peer = (struct iax2_peer *)data; 09224 iax2_poke_peer(peer, 0); 09225 peer_unref(peer); 09226 }
static int __iax2_show_peers | ( | int | fd, | |
int * | total, | |||
struct mansession * | s, | |||
const int | argc, | |||
const char *const | argv[] | |||
) | [static] |
Definition at line 6760 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli(), ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), iax2_peer::encmethods, encmethods_to_str(), FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, name, peer_status(), peer_unref(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and status.
Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().
06761 { 06762 regex_t regexbuf; 06763 int havepattern = 0; 06764 int total_peers = 0; 06765 int online_peers = 0; 06766 int offline_peers = 0; 06767 int unmonitored_peers = 0; 06768 struct ao2_iterator i; 06769 06770 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" 06771 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" 06772 06773 struct iax2_peer *peer = NULL; 06774 char name[256]; 06775 struct ast_str *encmethods = ast_str_alloca(256); 06776 int registeredonly=0; 06777 char idtext[256] = ""; 06778 switch (argc) { 06779 case 6: 06780 if (!strcasecmp(argv[3], "registered")) 06781 registeredonly = 1; 06782 else 06783 return RESULT_SHOWUSAGE; 06784 if (!strcasecmp(argv[4], "like")) { 06785 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06786 return RESULT_SHOWUSAGE; 06787 havepattern = 1; 06788 } else 06789 return RESULT_SHOWUSAGE; 06790 break; 06791 case 5: 06792 if (!strcasecmp(argv[3], "like")) { 06793 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06794 return RESULT_SHOWUSAGE; 06795 havepattern = 1; 06796 } else 06797 return RESULT_SHOWUSAGE; 06798 break; 06799 case 4: 06800 if (!strcasecmp(argv[3], "registered")) 06801 registeredonly = 1; 06802 else 06803 return RESULT_SHOWUSAGE; 06804 break; 06805 case 3: 06806 break; 06807 default: 06808 return RESULT_SHOWUSAGE; 06809 } 06810 06811 06812 if (!s) 06813 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status"); 06814 06815 i = ao2_iterator_init(peers, 0); 06816 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 06817 char nm[20]; 06818 char status[20]; 06819 int retstatus; 06820 struct sockaddr_in peer_addr; 06821 06822 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 06823 06824 if (registeredonly && !peer_addr.sin_addr.s_addr) { 06825 continue; 06826 } 06827 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 06828 continue; 06829 } 06830 06831 if (!ast_strlen_zero(peer->username)) 06832 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06833 else 06834 ast_copy_string(name, peer->name, sizeof(name)); 06835 06836 encmethods_to_str(peer->encmethods, &encmethods); 06837 retstatus = peer_status(peer, status, sizeof(status)); 06838 if (retstatus > 0) 06839 online_peers++; 06840 else if (!retstatus) 06841 offline_peers++; 06842 else 06843 unmonitored_peers++; 06844 06845 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06846 06847 if (s) { 06848 astman_append(s, 06849 "Event: PeerEntry\r\n%s" 06850 "Channeltype: IAX2\r\n" 06851 "ObjectName: %s\r\n" 06852 "ChanObjectType: peer\r\n" 06853 "IPaddress: %s\r\n" 06854 "IPport: %d\r\n" 06855 "Dynamic: %s\r\n" 06856 "Trunk: %s\r\n" 06857 "Encryption: %s\r\n" 06858 "Status: %s\r\n\r\n", 06859 idtext, 06860 name, 06861 ast_sockaddr_stringify_addr(&peer->addr), 06862 ast_sockaddr_port(&peer->addr), 06863 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06864 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06865 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06866 status); 06867 } else { 06868 ast_cli(fd, FORMAT, name, 06869 ast_sockaddr_stringify_addr(&peer->addr), 06870 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06871 nm, 06872 ast_sockaddr_port(&peer->addr), 06873 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06874 peer->encmethods ? "(E)" : " ", 06875 status); 06876 } 06877 total_peers++; 06878 } 06879 ao2_iterator_destroy(&i); 06880 06881 if (!s) 06882 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n", 06883 total_peers, online_peers, offline_peers, unmonitored_peers); 06884 06885 if (havepattern) 06886 regfree(®exbuf); 06887 06888 if (total) 06889 *total = total_peers; 06890 06891 return RESULT_SUCCESS; 06892 #undef FORMAT 06893 #undef FORMAT2 06894 }
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 1544 of file chan_iax2.c.
References ast_copy_string(), ast_debug, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, signal_condition(), and thread.
01545 { 01546 struct iax2_thread *thread; 01547 static time_t lasterror; 01548 time_t t; 01549 01550 thread = find_idle_thread(); 01551 if (thread != NULL) { 01552 thread->schedfunc = func; 01553 thread->scheddata = data; 01554 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01555 #ifdef DEBUG_SCHED_MULTITHREAD 01556 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01557 #endif 01558 signal_condition(&thread->lock, &thread->cond); 01559 return 0; 01560 } 01561 time(&t); 01562 if (t != lasterror) { 01563 lasterror = t; 01564 ast_debug(1, "Out of idle IAX2 threads for scheduling! (%s)\n", funcname); 01565 } 01566 01567 return -1; 01568 }
static int __send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 7593 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().
07595 { 07596 struct ast_frame f = { 0, }; 07597 int res = 0; 07598 07599 f.frametype = type; 07600 f.subclass.integer = command; 07601 f.datalen = datalen; 07602 f.src = __FUNCTION__; 07603 f.data.ptr = (void *) data; 07604 07605 if ((res = queue_signalling(i, &f)) <= 0) { 07606 return res; 07607 } 07608 07609 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07610 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1655 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, send_command(), and send_lagrq().
Referenced by send_lagrq().
01656 { 01657 int callno = (long) data; 01658 01659 ast_mutex_lock(&iaxsl[callno]); 01660 01661 if (iaxs[callno]) { 01662 if (iaxs[callno]->peercallno) { 01663 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01664 if (iaxs[callno]->lagid != DONT_RESCHEDULE) { 01665 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01666 } 01667 } 01668 } else { 01669 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01670 } 01671 01672 ast_mutex_unlock(&iaxsl[callno]); 01673 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1588 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, send_command(), and send_ping().
Referenced by send_ping().
01589 { 01590 int callno = (long) data; 01591 01592 ast_mutex_lock(&iaxsl[callno]); 01593 01594 if (iaxs[callno]) { 01595 if (iaxs[callno]->peercallno) { 01596 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01597 if (iaxs[callno]->pingid != DONT_RESCHEDULE) { 01598 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01599 } 01600 } 01601 } else { 01602 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01603 } 01604 01605 ast_mutex_unlock(&iaxsl[callno]); 01606 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 14574 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().
14575 { 14576 struct ast_context *con; 14577 int x; 14578 14579 network_change_event_unsubscribe(); 14580 14581 ast_manager_unregister("IAXpeers"); 14582 ast_manager_unregister("IAXpeerlist"); 14583 ast_manager_unregister("IAXnetstats"); 14584 ast_manager_unregister("IAXregistry"); 14585 ast_unregister_application(papp); 14586 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14587 ast_unregister_switch(&iax2_switch); 14588 ast_channel_unregister(&iax2_tech); 14589 14590 if (netthreadid != AST_PTHREADT_NULL) { 14591 pthread_cancel(netthreadid); 14592 pthread_kill(netthreadid, SIGURG); 14593 pthread_join(netthreadid, NULL); 14594 } 14595 14596 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14597 if (iaxs[x]) { 14598 iax2_destroy(x); 14599 } 14600 } 14601 14602 /* Call for all threads to halt */ 14603 cleanup_thread_list(&active_list); 14604 cleanup_thread_list(&dynamic_list); 14605 cleanup_thread_list(&idle_list); 14606 14607 ast_netsock_release(netsock); 14608 ast_netsock_release(outsock); 14609 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14610 if (iaxs[x]) { 14611 iax2_destroy(x); 14612 } 14613 } 14614 ast_manager_unregister( "IAXpeers" ); 14615 ast_manager_unregister( "IAXpeerlist" ); 14616 ast_manager_unregister( "IAXnetstats" ); 14617 ast_manager_unregister( "IAXregistry" ); 14618 ast_unregister_application(papp); 14619 #ifdef TEST_FRAMEWORK 14620 AST_TEST_UNREGISTER(test_iax2_peers_get); 14621 AST_TEST_UNREGISTER(test_iax2_users_get); 14622 #endif 14623 ast_data_unregister(NULL); 14624 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14625 ast_unregister_switch(&iax2_switch); 14626 ast_channel_unregister(&iax2_tech); 14627 delete_users(); 14628 iax_provision_unload(); 14629 reload_firmware(1); 14630 14631 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14632 ast_mutex_destroy(&iaxsl[x]); 14633 } 14634 14635 ao2_ref(peers, -1); 14636 ao2_ref(users, -1); 14637 ao2_ref(iax_peercallno_pvts, -1); 14638 ao2_ref(iax_transfercallno_pvts, -1); 14639 ao2_ref(peercnts, -1); 14640 ao2_ref(callno_limits, -1); 14641 ao2_ref(calltoken_ignores, -1); 14642 ao2_ref(callno_pool, -1); 14643 ao2_ref(callno_pool_trunk, -1); 14644 if (timer) { 14645 ast_timer_close(timer); 14646 timer = NULL; 14647 } 14648 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 14649 sched = ast_sched_thread_destroy(sched); 14650 14651 con = ast_context_find(regcontext); 14652 if (con) 14653 ast_context_destroy(con, "IAX2"); 14654 ast_unload_realtime("iaxpeers"); 14655 return 0; 14656 }
static int acf_channel_read | ( | struct ast_channel * | chan, | |
const char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 14214 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.
14215 { 14216 struct chan_iax2_pvt *pvt; 14217 unsigned int callno; 14218 int res = 0; 14219 14220 if (!chan || chan->tech != &iax2_tech) { 14221 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 14222 return -1; 14223 } 14224 14225 callno = PTR_TO_CALLNO(chan->tech_pvt); 14226 ast_mutex_lock(&iaxsl[callno]); 14227 if (!(pvt = iaxs[callno])) { 14228 ast_mutex_unlock(&iaxsl[callno]); 14229 return -1; 14230 } 14231 14232 if (!strcasecmp(args, "osptoken")) { 14233 ast_copy_string(buf, pvt->osptoken, buflen); 14234 } else if (!strcasecmp(args, "peerip")) { 14235 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 14236 } else if (!strcasecmp(args, "peername")) { 14237 ast_copy_string(buf, pvt->username, buflen); 14238 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) { 14239 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : ""); 14240 } else { 14241 res = -1; 14242 } 14243 14244 ast_mutex_unlock(&iaxsl[callno]); 14245 14246 return res; 14247 }
static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 9943 of file chan_iax2.c.
References ast_channel_datastore_find(), ast_copy_string(), AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_datastore::data, iax2_variable_datastore_info, LOG_WARNING, ast_var_t::name, ast_var_t::value, and var.
09944 { 09945 struct ast_datastore *variablestore; 09946 AST_LIST_HEAD(, ast_var_t) *varlist; 09947 struct ast_var_t *var; 09948 09949 if (!chan) { 09950 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); 09951 return -1; 09952 } 09953 09954 variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09955 09956 if (!variablestore) { 09957 *buf = '\0'; 09958 return 0; 09959 } 09960 varlist = variablestore->data; 09961 09962 AST_LIST_LOCK(varlist); 09963 AST_LIST_TRAVERSE(varlist, var, entries) { 09964 if (strcmp(var->name, data) == 0) { 09965 ast_copy_string(buf, var->value, len); 09966 break; 09967 } 09968 } 09969 AST_LIST_UNLOCK(varlist); 09970 return 0; 09971 }
static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 9973 of file chan_iax2.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, ast_datastore_free(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_delete(), ast_datastore::data, DATASTORE_INHERIT_FOREVER, iax2_variable_datastore_info, ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_var_t::name, and var.
09974 { 09975 struct ast_datastore *variablestore; 09976 AST_LIST_HEAD(, ast_var_t) *varlist; 09977 struct ast_var_t *var; 09978 09979 if (!chan) { 09980 ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); 09981 return -1; 09982 } 09983 09984 variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09985 09986 if (!variablestore) { 09987 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09988 if (!variablestore) { 09989 ast_log(LOG_ERROR, "Memory allocation error\n"); 09990 return -1; 09991 } 09992 varlist = ast_calloc(1, sizeof(*varlist)); 09993 if (!varlist) { 09994 ast_datastore_free(variablestore); 09995 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09996 return -1; 09997 } 09998 09999 AST_LIST_HEAD_INIT(varlist); 10000 variablestore->data = varlist; 10001 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10002 ast_channel_datastore_add(chan, variablestore); 10003 } else 10004 varlist = variablestore->data; 10005 10006 AST_LIST_LOCK(varlist); 10007 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 10008 if (strcmp(var->name, data) == 0) { 10009 AST_LIST_REMOVE_CURRENT(entries); 10010 ast_var_delete(var); 10011 break; 10012 } 10013 } 10014 AST_LIST_TRAVERSE_SAFE_END; 10015 var = ast_var_assign(data, value); 10016 if (var) 10017 AST_LIST_INSERT_TAIL(varlist, var, entries); 10018 else 10019 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 10020 AST_LIST_UNLOCK(varlist); 10021 return 0; 10022 }
static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2597 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), ast_strlen_zero(), addr_range::delme, addr_range::ha, LOG_WARNING, and OBJ_POINTER.
Referenced by set_config().
02598 { 02599 struct addr_range tmp; 02600 struct addr_range *addr_range = NULL; 02601 struct ast_ha *ha = NULL; 02602 int error = 0; 02603 02604 if (ast_strlen_zero(addr)) { 02605 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02606 return -1; 02607 } 02608 02609 ha = ast_append_ha("permit", addr, NULL, &error); 02610 02611 /* check for valid config information */ 02612 if (error) { 02613 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02614 return -1; 02615 } 02616 02617 ast_copy_ha(ha, &tmp.ha); 02618 /* find or create the addr_range */ 02619 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02620 ao2_lock(addr_range); 02621 addr_range->delme = 0; 02622 ao2_unlock(addr_range); 02623 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02624 /* copy over config data into addr_range object */ 02625 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02626 ao2_link(calltoken_ignores, addr_range); 02627 } else { 02628 ast_free_ha(ha); 02629 return -1; 02630 } 02631 02632 ast_free_ha(ha); 02633 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02634 02635 return 0; 02636 }
static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4834 of file chan_iax2.c.
References iax_ie_data::buf, IAX_IE_CALLTOKEN, and iax_ie_data::pos.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_do_register(), iax2_poke_peer(), and registry_rerequest().
04835 { 04836 /* first make sure their are two empty bytes left in ied->buf */ 04837 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04838 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04839 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04840 pvt->calltoken_ie_len = 2; 04841 } 04842 }
static int addr_range_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2248 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_cmp_addr(), CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.
Referenced by load_objects().
02249 { 02250 struct addr_range *lim1 = obj, *lim2 = arg; 02251 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) && 02252 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ? 02253 CMP_MATCH | CMP_STOP : 0; 02254 }
static int addr_range_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2233 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
02234 { 02235 struct addr_range *lim = obj; 02236 lim->delme = 1; 02237 return 0; 02238 }
static int addr_range_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2240 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, and addr_range::ha.
Referenced by load_objects().
02241 { 02242 const struct addr_range *lim = obj; 02243 struct sockaddr_in sin; 02244 ast_sockaddr_to_sin(&lim->ha.addr, &sin); 02245 return abs((int) sin.sin_addr.s_addr); 02246 }
static int addr_range_match_address_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2268 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, CMP_MATCH, CMP_STOP, addr_range::ha, and ast_ha::netmask.
Referenced by calltoken_required(), and set_peercnt_limit().
02269 { 02270 struct addr_range *addr_range = obj; 02271 struct sockaddr_in *sin = arg; 02272 struct sockaddr_in ha_netmask_sin; 02273 struct sockaddr_in ha_addr_sin; 02274 02275 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin); 02276 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin); 02277 02278 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) { 02279 return CMP_MATCH | CMP_STOP; 02280 } 02281 return 0; 02282 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 7657 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 7352 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().
07353 { 07354 int x; 07355 int numchans = 0; 07356 char first_message[10] = { 0, }; 07357 char last_message[10] = { 0, }; 07358 #define ACN_FORMAT1 "%-20.25s %4u %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" 07359 #define ACN_FORMAT2 "%s %u %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 07360 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07361 ast_mutex_lock(&iaxsl[x]); 07362 if (iaxs[x]) { 07363 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 07364 jb_info jbinfo; 07365 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07366 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07367 07368 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07369 jb_getinfo(iaxs[x]->jb, &jbinfo); 07370 localjitter = jbinfo.jitter; 07371 localdelay = jbinfo.current - jbinfo.min; 07372 locallost = jbinfo.frames_lost; 07373 locallosspct = jbinfo.losspct/1000; 07374 localdropped = jbinfo.frames_dropped; 07375 localooo = jbinfo.frames_ooo; 07376 } else { 07377 localjitter = -1; 07378 localdelay = 0; 07379 locallost = -1; 07380 locallosspct = -1; 07381 localdropped = 0; 07382 localooo = -1; 07383 } 07384 if (s) 07385 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07386 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07387 iaxs[x]->pingtime, 07388 localjitter, 07389 localdelay, 07390 locallost, 07391 locallosspct, 07392 localdropped, 07393 localooo, 07394 iaxs[x]->frames_received/1000, 07395 iaxs[x]->remote_rr.jitter, 07396 iaxs[x]->remote_rr.delay, 07397 iaxs[x]->remote_rr.losscnt, 07398 iaxs[x]->remote_rr.losspct, 07399 iaxs[x]->remote_rr.dropped, 07400 iaxs[x]->remote_rr.ooo, 07401 iaxs[x]->remote_rr.packets/1000, 07402 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07403 first_message, 07404 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07405 last_message); 07406 else 07407 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07408 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07409 iaxs[x]->pingtime, 07410 localjitter, 07411 localdelay, 07412 locallost, 07413 locallosspct, 07414 localdropped, 07415 localooo, 07416 iaxs[x]->frames_received/1000, 07417 iaxs[x]->remote_rr.jitter, 07418 iaxs[x]->remote_rr.delay, 07419 iaxs[x]->remote_rr.losscnt, 07420 iaxs[x]->remote_rr.losspct, 07421 iaxs[x]->remote_rr.dropped, 07422 iaxs[x]->remote_rr.ooo, 07423 iaxs[x]->remote_rr.packets/1000, 07424 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07425 first_message, 07426 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07427 last_message); 07428 numchans++; 07429 } 07430 ast_mutex_unlock(&iaxsl[x]); 07431 } 07432 07433 return numchans; 07434 }
AST_DATA_STRUCTURE | ( | iax2_user | , | |
DATA_EXPORT_IAX2_USER | ||||
) |
AST_DATA_STRUCTURE | ( | iax2_peer | , | |
DATA_EXPORT_IAX2_PEER | ||||
) |
static struct ast_channel* ast_iax2_new | ( | int | callno, | |
int | state, | |||
format_t | capability, | |||
const char * | linkedid, | |||
unsigned int | cachable | |||
) | [static, read] |
Create new call, interface with the PBX core.
Definition at line 5838 of file chan_iax2.c.
References chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, ast_party_caller::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_release(), ast_copy_string(), ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_FLAG_DISABLE_DEVSTATE_CACHE, ast_free, ast_hangup(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, ast_log(), ast_module_ref(), ast_mutex_lock, ast_mutex_unlock, ast_pbx_start(), AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), ast_channel::caller, chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::dialed, ast_channel::exten, ast_channel::flags, ast_party_redirecting::from, iax2_ami_channelupdate(), iax2_tech, iax2_variable_datastore_info, iaxs, iaxsl, ast_party_caller::id, ast_datastore::inheritance, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_party_id::name, ast_channel::nativeformats, ast_variable::next, ast_party_dialed::number, ast_party_id::number, chan_iax2_pvt::owner, parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_party_number::plan, ast_party_number::presentation, ast_party_name::presentation, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::redirecting, ast_party_dialed::str, ast_party_number::str, ast_channel::tech, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, ast_party_number::valid, ast_variable::value, var, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
05839 { 05840 struct ast_channel *tmp; 05841 struct chan_iax2_pvt *i; 05842 struct ast_variable *v = NULL; 05843 05844 if (!(i = iaxs[callno])) { 05845 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05846 return NULL; 05847 } 05848 05849 /* Don't hold call lock */ 05850 ast_mutex_unlock(&iaxsl[callno]); 05851 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno); 05852 ast_mutex_lock(&iaxsl[callno]); 05853 if (i != iaxs[callno]) { 05854 if (tmp) { 05855 /* unlock and relock iaxsl[callno] to preserve locking order */ 05856 ast_mutex_unlock(&iaxsl[callno]); 05857 tmp = ast_channel_release(tmp); 05858 ast_mutex_lock(&iaxsl[callno]); 05859 } 05860 return NULL; 05861 } 05862 iax2_ami_channelupdate(i); 05863 if (!tmp) 05864 return NULL; 05865 tmp->tech = &iax2_tech; 05866 /* We can support any format by default, until we get restricted */ 05867 tmp->nativeformats = capability; 05868 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05869 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05870 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05871 05872 if (!ast_strlen_zero(i->parkinglot)) 05873 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05874 /* Don't use ast_set_callerid() here because it will 05875 * generate a NewCallerID event before the NewChannel event */ 05876 if (!ast_strlen_zero(i->ani)) { 05877 tmp->caller.ani.number.valid = 1; 05878 tmp->caller.ani.number.str = ast_strdup(i->ani); 05879 } else if (!ast_strlen_zero(i->cid_num)) { 05880 tmp->caller.ani.number.valid = 1; 05881 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 05882 } 05883 tmp->dialed.number.str = ast_strdup(i->dnid); 05884 if (!ast_strlen_zero(i->rdnis)) { 05885 tmp->redirecting.from.number.valid = 1; 05886 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 05887 } 05888 tmp->caller.id.name.presentation = i->calling_pres; 05889 tmp->caller.id.number.presentation = i->calling_pres; 05890 tmp->caller.id.number.plan = i->calling_ton; 05891 tmp->dialed.transit_network_select = i->calling_tns; 05892 if (!ast_strlen_zero(i->language)) 05893 ast_string_field_set(tmp, language, i->language); 05894 if (!ast_strlen_zero(i->accountcode)) 05895 ast_string_field_set(tmp, accountcode, i->accountcode); 05896 if (i->amaflags) 05897 tmp->amaflags = i->amaflags; 05898 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05899 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05900 if (i->adsi) 05901 tmp->adsicpe = i->peeradsicpe; 05902 else 05903 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05904 i->owner = tmp; 05905 i->capability = capability; 05906 05907 if (!cachable) { 05908 tmp->flags |= AST_FLAG_DISABLE_DEVSTATE_CACHE; 05909 } 05910 05911 /* Set inherited variables */ 05912 if (i->vars) { 05913 for (v = i->vars ; v ; v = v->next) 05914 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05915 } 05916 if (i->iaxvars) { 05917 struct ast_datastore *variablestore; 05918 struct ast_variable *var, *prev = NULL; 05919 AST_LIST_HEAD(, ast_var_t) *varlist; 05920 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05921 varlist = ast_calloc(1, sizeof(*varlist)); 05922 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05923 if (variablestore && varlist) { 05924 variablestore->data = varlist; 05925 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05926 AST_LIST_HEAD_INIT(varlist); 05927 for (var = i->iaxvars; var; var = var->next) { 05928 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05929 if (prev) 05930 ast_free(prev); 05931 prev = var; 05932 if (!newvar) { 05933 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05934 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05935 } else { 05936 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05937 } 05938 } 05939 if (prev) 05940 ast_free(prev); 05941 i->iaxvars = NULL; 05942 ast_channel_datastore_add(i->owner, variablestore); 05943 } else { 05944 if (variablestore) { 05945 ast_datastore_free(variablestore); 05946 } 05947 if (varlist) { 05948 ast_free(varlist); 05949 } 05950 } 05951 } 05952 05953 if (state != AST_STATE_DOWN) { 05954 if (ast_pbx_start(tmp)) { 05955 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05956 ast_hangup(tmp); 05957 i->owner = NULL; 05958 return NULL; 05959 } 05960 } 05961 05962 ast_module_ref(ast_module_info->self); 05963 return tmp; 05964 }
static AST_LIST_HEAD_NOLOCK | ( | iax_frame | ) | [static] |
a list of frames that may need to be retransmitted
peer connection private, keeps track of all the call numbers consumed by a single ip address
ip address consuming call numbers
Number of call numbers currently used by this ip address
Max call numbers allowed for this ip address
Specifies whether limit is set by a registration or not, if so normal limit setting rules do not apply to this address.
Definition at line 865 of file chan_iax2.c.
References iax2_trunk_peer::addr.
00912 { 00913 /*! ip address consuming call numbers */ 00914 unsigned long addr; 00915 /*! Number of call numbers currently used by this ip address */ 00916 uint16_t cur; 00917 /*! Max call numbers allowed for this ip address */ 00918 uint16_t limit; 00919 /*! Specifies whether limit is set by a registration or not, if so normal 00920 * limit setting rules do not apply to this address. */ 00921 unsigned char reg; 00922 };
static AST_LIST_HEAD_STATIC | ( | dynamic_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | active_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | idle_list | , | |
iax2_thread | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | dpcache | , | |
iax2_dpcache | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | firmwares | , | |
iax_firmware | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | registrations | , | |
iax2_registry | ||||
) | [static] |
static AST_LIST_HEAD_STATIC | ( | tpeers | , | |
iax2_trunk_peer | ||||
) | [static] |
AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
AST_MODFLAG_LOAD_ORDER | , | |||
"Inter Asterisk eXchange (Ver 2)" | , | |||
. | load = load_module , |
|||
. | unload = unload_module , |
|||
. | reload = reload , |
|||
. | load_pri = AST_MODPRI_CHANNEL_DRIVER , |
|||
. | nonoptreq = "res_crypto" | |||
) |
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3651 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03652 { 03653 #ifdef SCHED_MULTITHREADED 03654 if (schedule_action(__attempt_transmit, data)) 03655 #endif 03656 __attempt_transmit(data); 03657 return 0; 03658 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 9146 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().
09147 { 09148 /* Schedule sending the authentication failure in one second, to prevent 09149 guessing */ 09150 if (iaxs[callno]) { 09151 iaxs[callno]->authfail = failcode; 09152 if (delayreject) { 09153 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 09154 sched, 1000, auth_reject, (void *)(long)callno); 09155 } else 09156 auth_reject((void *)(long)callno); 09157 } 09158 return 0; 09159 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 9132 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().
09133 { 09134 int callno = (int)(long)(data); 09135 ast_mutex_lock(&iaxsl[callno]); 09136 if (iaxs[callno]) 09137 iaxs[callno]->authid = -1; 09138 ast_mutex_unlock(&iaxsl[callno]); 09139 #ifdef SCHED_MULTITHREADED 09140 if (schedule_action(__auth_reject, data)) 09141 #endif 09142 __auth_reject(data); 09143 return 0; 09144 }
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 8230 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().
08231 { 08232 int res = -1; 08233 int x; 08234 if (!ast_strlen_zero(keyn)) { 08235 if (!(authmethods & IAX_AUTH_RSA)) { 08236 if (ast_strlen_zero(secret)) 08237 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)); 08238 } else if (ast_strlen_zero(challenge)) { 08239 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 08240 } else { 08241 char sig[256]; 08242 struct ast_key *key; 08243 key = ast_key_get(keyn, AST_KEY_PRIVATE); 08244 if (!key) { 08245 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 08246 } else { 08247 if (ast_sign(key, (char*)challenge, sig)) { 08248 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 08249 res = -1; 08250 } else { 08251 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 08252 res = 0; 08253 } 08254 } 08255 } 08256 } 08257 /* Fall back */ 08258 if (res && !ast_strlen_zero(secret)) { 08259 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 08260 struct MD5Context md5; 08261 unsigned char digest[16]; 08262 char digres[128]; 08263 MD5Init(&md5); 08264 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 08265 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 08266 MD5Final(digest, &md5); 08267 /* If they support md5, authenticate with it. */ 08268 for (x=0;x<16;x++) 08269 sprintf(digres + (x << 1), "%2.2x", (unsigned)digest[x]); /* safe */ 08270 if (pvt) { 08271 build_encryption_keys(digest, pvt); 08272 } 08273 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 08274 res = 0; 08275 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 08276 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 08277 res = 0; 08278 } else 08279 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 08280 } 08281 return res; 08282 }
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 8288 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().
08289 { 08290 struct iax2_peer *peer = NULL; 08291 /* Start pessimistic */ 08292 int res = -1; 08293 int authmethods = 0; 08294 struct iax_ie_data ied; 08295 uint16_t callno = p->callno; 08296 08297 memset(&ied, 0, sizeof(ied)); 08298 08299 if (ies->username) 08300 ast_string_field_set(p, username, ies->username); 08301 if (ies->challenge) 08302 ast_string_field_set(p, challenge, ies->challenge); 08303 if (ies->authmethods) 08304 authmethods = ies->authmethods; 08305 if (authmethods & IAX_AUTH_MD5) 08306 merge_encryption(p, ies->encmethods); 08307 else 08308 p->encmethods = 0; 08309 08310 /* Check for override RSA authentication first */ 08311 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 08312 /* Normal password authentication */ 08313 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 08314 } else { 08315 struct ao2_iterator i = ao2_iterator_init(peers, 0); 08316 while ((peer = ao2_iterator_next(&i))) { 08317 struct sockaddr_in peer_addr; 08318 08319 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 08320 08321 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 08322 /* No peer specified at our end, or this is the peer */ 08323 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 08324 /* No username specified in peer rule, or this is the right username */ 08325 && (!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))) 08326 /* No specified host, or this is our host */ 08327 ) { 08328 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 08329 if (!res) { 08330 peer_unref(peer); 08331 break; 08332 } 08333 } 08334 peer_unref(peer); 08335 } 08336 ao2_iterator_destroy(&i); 08337 if (!peer) { 08338 /* We checked our list and didn't find one. It's unlikely, but possible, 08339 that we're trying to authenticate *to* a realtime peer */ 08340 const char *peer_name = ast_strdupa(p->peer); 08341 ast_mutex_unlock(&iaxsl[callno]); 08342 if ((peer = realtime_peer(peer_name, NULL))) { 08343 ast_mutex_lock(&iaxsl[callno]); 08344 if (!(p = iaxs[callno])) { 08345 peer_unref(peer); 08346 return -1; 08347 } 08348 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 08349 peer_unref(peer); 08350 } 08351 if (!peer) { 08352 ast_mutex_lock(&iaxsl[callno]); 08353 if (!(p = iaxs[callno])) 08354 return -1; 08355 } 08356 } 08357 } 08358 08359 if (ies->encmethods) { 08360 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 08361 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 08362 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set\n"); 08363 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 08364 } 08365 if (!res) { 08366 struct ast_datastore *variablestore; 08367 struct ast_variable *var, *prev = NULL; 08368 AST_LIST_HEAD(, ast_var_t) *varlist; 08369 varlist = ast_calloc(1, sizeof(*varlist)); 08370 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 08371 if (variablestore && varlist && p->owner) { 08372 variablestore->data = varlist; 08373 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 08374 AST_LIST_HEAD_INIT(varlist); 08375 for (var = ies->vars; var; var = var->next) { 08376 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 08377 if (prev) 08378 ast_free(prev); 08379 prev = var; 08380 if (!newvar) { 08381 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 08382 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08383 } else { 08384 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 08385 } 08386 } 08387 if (prev) 08388 ast_free(prev); 08389 ies->vars = NULL; 08390 ast_channel_datastore_add(p->owner, variablestore); 08391 } else { 08392 if (p->owner) 08393 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08394 if (variablestore) 08395 ast_datastore_free(variablestore); 08396 if (varlist) 08397 ast_free(varlist); 08398 } 08399 } 08400 08401 if (!res) 08402 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08403 return res; 08404 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7936 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().
07937 { 07938 struct iax_ie_data ied; 07939 int res = -1, authreq_restrict = 0; 07940 char challenge[10]; 07941 struct chan_iax2_pvt *p = iaxs[call_num]; 07942 07943 memset(&ied, 0, sizeof(ied)); 07944 07945 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07946 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07947 struct iax2_user *user, tmp_user = { 07948 .name = p->username, 07949 }; 07950 07951 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07952 if (user) { 07953 if (user->curauthreq == user->maxauthreq) 07954 authreq_restrict = 1; 07955 else 07956 user->curauthreq++; 07957 user = user_unref(user); 07958 } 07959 } 07960 07961 /* If the AUTHREQ limit test failed, send back an error */ 07962 if (authreq_restrict) { 07963 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07964 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07965 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07966 return 0; 07967 } 07968 07969 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07970 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07971 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07972 ast_string_field_set(p, challenge, challenge); 07973 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07974 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07975 } 07976 if (p->encmethods) 07977 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07978 07979 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07980 07981 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07982 07983 if (p->encmethods) 07984 ast_set_flag64(p, IAX_ENCRYPTED); 07985 07986 return res; 07987 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7989 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().
07990 { 07991 char requeststr[256]; 07992 char md5secret[256] = ""; 07993 char secret[256] = ""; 07994 char rsasecret[256] = ""; 07995 int res = -1; 07996 int x; 07997 struct iax2_user *user, tmp_user = { 07998 .name = p->username, 07999 }; 08000 08001 if (p->authrej) { 08002 return res; 08003 } 08004 user = ao2_find(users, &tmp_user, OBJ_POINTER); 08005 if (user) { 08006 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 08007 ast_atomic_fetchadd_int(&user->curauthreq, -1); 08008 ast_clear_flag64(p, IAX_MAXAUTHREQ); 08009 } 08010 ast_string_field_set(p, host, user->name); 08011 user = user_unref(user); 08012 } 08013 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 08014 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled.\n"); 08015 return res; 08016 } 08017 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 08018 return res; 08019 if (ies->password) 08020 ast_copy_string(secret, ies->password, sizeof(secret)); 08021 if (ies->md5_result) 08022 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 08023 if (ies->rsa_result) 08024 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 08025 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 08026 struct ast_key *key; 08027 char *keyn; 08028 char tmpkey[256]; 08029 char *stringp=NULL; 08030 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 08031 stringp=tmpkey; 08032 keyn = strsep(&stringp, ":"); 08033 while(keyn) { 08034 key = ast_key_get(keyn, AST_KEY_PUBLIC); 08035 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 08036 res = 0; 08037 break; 08038 } else if (!key) 08039 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 08040 keyn = strsep(&stringp, ":"); 08041 } 08042 } else if (p->authmethods & IAX_AUTH_MD5) { 08043 struct MD5Context md5; 08044 unsigned char digest[16]; 08045 char *tmppw, *stringp; 08046 08047 tmppw = ast_strdupa(p->secret); 08048 stringp = tmppw; 08049 while((tmppw = strsep(&stringp, ";"))) { 08050 MD5Init(&md5); 08051 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 08052 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08053 MD5Final(digest, &md5); 08054 /* If they support md5, authenticate with it. */ 08055 for (x=0;x<16;x++) 08056 sprintf(requeststr + (x << 1), "%2.2x", (unsigned)digest[x]); /* safe */ 08057 if (!strcasecmp(requeststr, md5secret)) { 08058 res = 0; 08059 break; 08060 } 08061 } 08062 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 08063 if (!strcmp(secret, p->secret)) 08064 res = 0; 08065 } 08066 return res; 08067 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4771 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call().
04772 { 04773 #ifdef SCHED_MULTITHREADED 04774 if (schedule_action(__auto_congest, data)) 04775 #endif 04776 __auto_congest(data); 04777 return 0; 04778 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 9176 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().
09177 { 09178 int callno = (int)(long)(data); 09179 ast_mutex_lock(&iaxsl[callno]); 09180 if (iaxs[callno]) { 09181 iaxs[callno]->autoid = -1; 09182 } 09183 ast_mutex_unlock(&iaxsl[callno]); 09184 #ifdef SCHED_MULTITHREADED 09185 if (schedule_action(__auto_hangup, data)) 09186 #endif 09187 __auto_hangup(data); 09188 return 0; 09189 }
static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2542 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), addr_range::delme, addr_range::ha, addr_range::limit, LOG_ERROR, ast_variable::name, ast_variable::next, OBJ_POINTER, and ast_variable::value.
Referenced by set_config().
02543 { 02544 struct addr_range *addr_range = NULL; 02545 struct addr_range tmp; 02546 struct ast_ha *ha; 02547 int limit; 02548 int error; 02549 int found; 02550 02551 for (; v; v = v->next) { 02552 limit = -1; 02553 error = 0; 02554 found = 0; 02555 ha = ast_append_ha("permit", v->name, NULL, &error); 02556 02557 /* check for valid config information */ 02558 if (error) { 02559 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02560 continue; 02561 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02562 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02563 ast_free_ha(ha); 02564 continue; 02565 } 02566 02567 ast_copy_ha(ha, &tmp.ha); 02568 /* find or create the addr_range */ 02569 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02570 ao2_lock(addr_range); 02571 found = 1; 02572 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02573 ast_free_ha(ha); 02574 return; /* out of memory */ 02575 } 02576 02577 /* copy over config data into addr_range object */ 02578 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02579 ast_free_ha(ha); /* cleanup the tmp ha */ 02580 addr_range->limit = limit; 02581 addr_range->delme = 0; 02582 02583 /* cleanup */ 02584 if (found) { 02585 ao2_unlock(addr_range); 02586 } else { 02587 ao2_link(callno_limits, addr_range); 02588 } 02589 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02590 } 02591 }
static struct iax2_context* build_context | ( | const char * | context | ) | [static, read] |
Definition at line 12474 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), and iax2_context::context.
Referenced by build_user().
12475 { 12476 struct iax2_context *con; 12477 12478 if ((con = ast_calloc(1, sizeof(*con)))) 12479 ast_copy_string(con->context, context, sizeof(con->context)); 12480 12481 return con; 12482 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6305 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), ast_aes_set_encrypt_key(), build_rand_pad(), chan_iax2_pvt::ecx, chan_iax2_pvt::mydcx, and chan_iax2_pvt::semirand.
Referenced by build_encryption_keys(), and iax2_key_rotate().
06306 { 06307 /* it is required to hold the corresponding decrypt key to our encrypt key 06308 * in the pvt struct because queued frames occasionally need to be decrypted and 06309 * re-encrypted when updated for a retransmission */ 06310 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 06311 ast_aes_set_encrypt_key(digest, &pvt->ecx); 06312 ast_aes_set_decrypt_key(digest, &pvt->mydcx); 06313 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6299 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
06300 { 06301 build_ecx_key(digest, pvt); 06302 ast_aes_set_decrypt_key(digest, &pvt->dcx); 06303 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static, read] |
Create peer structure based on configuration.
Definition at line 12623 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().
12624 { 12625 struct iax2_peer *peer = NULL; 12626 struct ast_ha *oldha = NULL; 12627 int maskfound = 0; 12628 int found = 0; 12629 int firstpass = 1; 12630 struct iax2_peer tmp_peer = { 12631 .name = name, 12632 }; 12633 12634 if (!temponly) { 12635 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 12636 if (peer && !ast_test_flag64(peer, IAX_DELME)) 12637 firstpass = 0; 12638 } 12639 12640 if (peer) { 12641 found++; 12642 if (firstpass) { 12643 oldha = peer->ha; 12644 peer->ha = NULL; 12645 } 12646 unlink_peer(peer); 12647 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 12648 peer->expire = -1; 12649 peer->pokeexpire = -1; 12650 peer->sockfd = defaultsockfd; 12651 peer->addr.ss.ss_family = AF_INET; 12652 peer->addr.len = sizeof(struct sockaddr_in); 12653 if (ast_string_field_init(peer, 32)) 12654 peer = peer_unref(peer); 12655 } 12656 12657 if (peer) { 12658 if (firstpass) { 12659 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12660 peer->encmethods = iax2_encryption; 12661 peer->adsi = adsi; 12662 ast_string_field_set(peer,secret,""); 12663 if (!found) { 12664 ast_string_field_set(peer, name, name); 12665 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12666 peer->expiry = min_reg_expire; 12667 } 12668 peer->prefs = prefs; 12669 peer->capability = iax2_capability; 12670 peer->smoothing = 0; 12671 peer->pokefreqok = DEFAULT_FREQ_OK; 12672 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 12673 peer->maxcallno = 0; 12674 peercnt_modify((unsigned char) 0, 0, &peer->addr); 12675 peer->calltoken_required = CALLTOKEN_DEFAULT; 12676 ast_string_field_set(peer,context,""); 12677 ast_string_field_set(peer,peercontext,""); 12678 ast_clear_flag64(peer, IAX_HASCALLERID); 12679 ast_string_field_set(peer, cid_name, ""); 12680 ast_string_field_set(peer, cid_num, ""); 12681 ast_string_field_set(peer, mohinterpret, mohinterpret); 12682 ast_string_field_set(peer, mohsuggest, mohsuggest); 12683 } 12684 12685 if (!v) { 12686 v = alt; 12687 alt = NULL; 12688 } 12689 while(v) { 12690 if (!strcasecmp(v->name, "secret")) { 12691 ast_string_field_set(peer, secret, v->value); 12692 } else if (!strcasecmp(v->name, "mailbox")) { 12693 ast_string_field_set(peer, mailbox, v->value); 12694 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12695 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12696 ast_string_field_set(peer, mailbox, name); 12697 } 12698 } else if (!strcasecmp(v->name, "mohinterpret")) { 12699 ast_string_field_set(peer, mohinterpret, v->value); 12700 } else if (!strcasecmp(v->name, "mohsuggest")) { 12701 ast_string_field_set(peer, mohsuggest, v->value); 12702 } else if (!strcasecmp(v->name, "dbsecret")) { 12703 ast_string_field_set(peer, dbsecret, v->value); 12704 } else if (!strcasecmp(v->name, "trunk")) { 12705 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12706 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12707 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12708 ast_clear_flag64(peer, IAX_TRUNK); 12709 } 12710 } else if (!strcasecmp(v->name, "auth")) { 12711 peer->authmethods = get_auth_methods(v->value); 12712 } else if (!strcasecmp(v->name, "encryption")) { 12713 peer->encmethods |= get_encrypt_methods(v->value); 12714 if (!peer->encmethods) { 12715 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12716 } 12717 } else if (!strcasecmp(v->name, "forceencryption")) { 12718 if (ast_false(v->value)) { 12719 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12720 } else { 12721 peer->encmethods |= get_encrypt_methods(v->value); 12722 if (peer->encmethods) { 12723 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12724 } 12725 } 12726 } else if (!strcasecmp(v->name, "transfer")) { 12727 if (!strcasecmp(v->value, "mediaonly")) { 12728 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12729 } else if (ast_true(v->value)) { 12730 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12731 } else 12732 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12733 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12734 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12735 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12736 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12737 } else if (!strcasecmp(v->name, "host")) { 12738 if (!strcasecmp(v->value, "dynamic")) { 12739 /* They'll register with us */ 12740 ast_set_flag64(peer, IAX_DYNAMIC); 12741 if (!found) { 12742 /* Initialize stuff iff we're not found, otherwise 12743 we keep going with what we had */ 12744 if (ast_sockaddr_port(&peer->addr)) { 12745 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr)); 12746 } 12747 ast_sockaddr_setnull(&peer->addr); 12748 } 12749 } else { 12750 /* Non-dynamic. Make sure we become that way if we're not */ 12751 ast_sched_thread_del(sched, peer->expire); 12752 ast_clear_flag64(peer, IAX_DYNAMIC); 12753 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12754 return peer_unref(peer); 12755 if (!ast_sockaddr_port(&peer->addr)) { 12756 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12757 } 12758 } 12759 if (!maskfound) 12760 inet_aton("255.255.255.255", &peer->mask); 12761 } else if (!strcasecmp(v->name, "defaultip")) { 12762 struct ast_sockaddr peer_defaddr_tmp; 12763 12764 peer_defaddr_tmp.ss.ss_family = AF_INET; 12765 if (ast_get_ip(&peer_defaddr_tmp, v->value)) { 12766 return peer_unref(peer); 12767 } 12768 ast_sockaddr_to_sin(&peer_defaddr_tmp, 12769 &peer->defaddr); 12770 } else if (!strcasecmp(v->name, "sourceaddress")) { 12771 peer_set_srcaddr(peer, v->value); 12772 } else if (!strcasecmp(v->name, "permit") || 12773 !strcasecmp(v->name, "deny")) { 12774 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12775 } else if (!strcasecmp(v->name, "mask")) { 12776 maskfound++; 12777 inet_aton(v->value, &peer->mask); 12778 } else if (!strcasecmp(v->name, "context")) { 12779 ast_string_field_set(peer, context, v->value); 12780 } else if (!strcasecmp(v->name, "regexten")) { 12781 ast_string_field_set(peer, regexten, v->value); 12782 } else if (!strcasecmp(v->name, "peercontext")) { 12783 ast_string_field_set(peer, peercontext, v->value); 12784 } else if (!strcasecmp(v->name, "port")) { 12785 if (ast_test_flag64(peer, IAX_DYNAMIC)) { 12786 peer->defaddr.sin_port = htons(atoi(v->value)); 12787 } else { 12788 ast_sockaddr_set_port(&peer->addr, atoi(v->value)); 12789 } 12790 } else if (!strcasecmp(v->name, "username")) { 12791 ast_string_field_set(peer, username, v->value); 12792 } else if (!strcasecmp(v->name, "allow")) { 12793 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12794 } else if (!strcasecmp(v->name, "disallow")) { 12795 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12796 } else if (!strcasecmp(v->name, "callerid")) { 12797 if (!ast_strlen_zero(v->value)) { 12798 char name2[80]; 12799 char num2[80]; 12800 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12801 ast_string_field_set(peer, cid_name, name2); 12802 ast_string_field_set(peer, cid_num, num2); 12803 } else { 12804 ast_string_field_set(peer, cid_name, ""); 12805 ast_string_field_set(peer, cid_num, ""); 12806 } 12807 ast_set_flag64(peer, IAX_HASCALLERID); 12808 } else if (!strcasecmp(v->name, "fullname")) { 12809 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12810 ast_set_flag64(peer, IAX_HASCALLERID); 12811 } else if (!strcasecmp(v->name, "cid_number")) { 12812 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12813 ast_set_flag64(peer, IAX_HASCALLERID); 12814 } else if (!strcasecmp(v->name, "sendani")) { 12815 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12816 } else if (!strcasecmp(v->name, "inkeys")) { 12817 ast_string_field_set(peer, inkeys, v->value); 12818 } else if (!strcasecmp(v->name, "outkey")) { 12819 ast_string_field_set(peer, outkey, v->value); 12820 } else if (!strcasecmp(v->name, "qualify")) { 12821 if (!strcasecmp(v->value, "no")) { 12822 peer->maxms = 0; 12823 } else if (!strcasecmp(v->value, "yes")) { 12824 peer->maxms = DEFAULT_MAXMS; 12825 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12826 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); 12827 peer->maxms = 0; 12828 } 12829 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12830 peer->smoothing = ast_true(v->value); 12831 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12832 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12833 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); 12834 } 12835 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12836 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12837 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); 12838 } 12839 } else if (!strcasecmp(v->name, "timezone")) { 12840 ast_string_field_set(peer, zonetag, v->value); 12841 } else if (!strcasecmp(v->name, "adsi")) { 12842 peer->adsi = ast_true(v->value); 12843 } else if (!strcasecmp(v->name, "connectedline")) { 12844 if (ast_true(v->value)) { 12845 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12846 } else if (!strcasecmp(v->value, "send")) { 12847 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12848 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12849 } else if (!strcasecmp(v->value, "receive")) { 12850 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12851 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12852 } else { 12853 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12854 } 12855 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12856 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12857 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12858 } else { 12859 peercnt_modify((unsigned char) 1, peer->maxcallno, &peer->addr); 12860 } 12861 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12862 /* default is required unless in optional ip list */ 12863 if (ast_false(v->value)) { 12864 peer->calltoken_required = CALLTOKEN_NO; 12865 } else if (!strcasecmp(v->value, "auto")) { 12866 peer->calltoken_required = CALLTOKEN_AUTO; 12867 } else if (ast_true(v->value)) { 12868 peer->calltoken_required = CALLTOKEN_YES; 12869 } else { 12870 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12871 } 12872 } /* else if (strcasecmp(v->name,"type")) */ 12873 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12874 v = v->next; 12875 if (!v) { 12876 v = alt; 12877 alt = NULL; 12878 } 12879 } 12880 if (!peer->authmethods) 12881 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12882 ast_clear_flag64(peer, IAX_DELME); 12883 } 12884 12885 if (oldha) 12886 ast_free_ha(oldha); 12887 12888 if (!ast_strlen_zero(peer->mailbox)) { 12889 char *mailbox, *context; 12890 context = mailbox = ast_strdupa(peer->mailbox); 12891 strsep(&context, "@"); 12892 if (ast_strlen_zero(context)) 12893 context = "default"; 12894 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12895 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12896 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12897 AST_EVENT_IE_END); 12898 } 12899 12900 return peer; 12901 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 6289 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
06290 { 06291 long tmp; 06292 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 06293 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 06294 buf += sizeof(tmp); 06295 len -= sizeof(tmp); 06296 } 06297 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static, read] |
Create in-memory user structure from configuration.
Definition at line 12917 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().
12918 { 12919 struct iax2_user *user = NULL; 12920 struct iax2_context *con, *conl = NULL; 12921 struct ast_ha *oldha = NULL; 12922 struct iax2_context *oldcon = NULL; 12923 int format; 12924 int firstpass=1; 12925 int oldcurauthreq = 0; 12926 char *varname = NULL, *varval = NULL; 12927 struct ast_variable *tmpvar = NULL; 12928 struct iax2_user tmp_user = { 12929 .name = name, 12930 }; 12931 12932 if (!temponly) { 12933 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12934 if (user && !ast_test_flag64(user, IAX_DELME)) 12935 firstpass = 0; 12936 } 12937 12938 if (user) { 12939 if (firstpass) { 12940 oldcurauthreq = user->curauthreq; 12941 oldha = user->ha; 12942 oldcon = user->contexts; 12943 user->ha = NULL; 12944 user->contexts = NULL; 12945 } 12946 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12947 ao2_unlink(users, user); 12948 } else { 12949 user = ao2_alloc(sizeof(*user), user_destructor); 12950 } 12951 12952 if (user) { 12953 if (firstpass) { 12954 ast_string_field_free_memory(user); 12955 memset(user, 0, sizeof(struct iax2_user)); 12956 if (ast_string_field_init(user, 32)) { 12957 user = user_unref(user); 12958 goto cleanup; 12959 } 12960 user->maxauthreq = maxauthreq; 12961 user->curauthreq = oldcurauthreq; 12962 user->prefs = prefs; 12963 user->capability = iax2_capability; 12964 user->encmethods = iax2_encryption; 12965 user->adsi = adsi; 12966 user->calltoken_required = CALLTOKEN_DEFAULT; 12967 ast_string_field_set(user, name, name); 12968 ast_string_field_set(user, language, language); 12969 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); 12970 ast_clear_flag64(user, IAX_HASCALLERID); 12971 ast_string_field_set(user, cid_name, ""); 12972 ast_string_field_set(user, cid_num, ""); 12973 ast_string_field_set(user, accountcode, accountcode); 12974 ast_string_field_set(user, mohinterpret, mohinterpret); 12975 ast_string_field_set(user, mohsuggest, mohsuggest); 12976 } 12977 if (!v) { 12978 v = alt; 12979 alt = NULL; 12980 } 12981 while(v) { 12982 if (!strcasecmp(v->name, "context")) { 12983 con = build_context(v->value); 12984 if (con) { 12985 if (conl) 12986 conl->next = con; 12987 else 12988 user->contexts = con; 12989 conl = con; 12990 } 12991 } else if (!strcasecmp(v->name, "permit") || 12992 !strcasecmp(v->name, "deny")) { 12993 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12994 } else if (!strcasecmp(v->name, "setvar")) { 12995 varname = ast_strdupa(v->value); 12996 if ((varval = strchr(varname, '='))) { 12997 *varval = '\0'; 12998 varval++; 12999 if((tmpvar = ast_variable_new(varname, varval, ""))) { 13000 tmpvar->next = user->vars; 13001 user->vars = tmpvar; 13002 } 13003 } 13004 } else if (!strcasecmp(v->name, "allow")) { 13005 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 13006 } else if (!strcasecmp(v->name, "disallow")) { 13007 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 13008 } else if (!strcasecmp(v->name, "trunk")) { 13009 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 13010 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 13011 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 13012 ast_clear_flag64(user, IAX_TRUNK); 13013 } 13014 } else if (!strcasecmp(v->name, "auth")) { 13015 user->authmethods = get_auth_methods(v->value); 13016 } else if (!strcasecmp(v->name, "encryption")) { 13017 user->encmethods |= get_encrypt_methods(v->value); 13018 if (!user->encmethods) { 13019 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 13020 } 13021 } else if (!strcasecmp(v->name, "forceencryption")) { 13022 if (ast_false(v->value)) { 13023 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 13024 } else { 13025 user->encmethods |= get_encrypt_methods(v->value); 13026 if (user->encmethods) { 13027 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 13028 } 13029 } 13030 } else if (!strcasecmp(v->name, "transfer")) { 13031 if (!strcasecmp(v->value, "mediaonly")) { 13032 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13033 } else if (ast_true(v->value)) { 13034 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13035 } else 13036 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13037 } else if (!strcasecmp(v->name, "codecpriority")) { 13038 if(!strcasecmp(v->value, "caller")) 13039 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 13040 else if(!strcasecmp(v->value, "disabled")) 13041 ast_set_flag64(user, IAX_CODEC_NOPREFS); 13042 else if(!strcasecmp(v->value, "reqonly")) { 13043 ast_set_flag64(user, IAX_CODEC_NOCAP); 13044 ast_set_flag64(user, IAX_CODEC_NOPREFS); 13045 } 13046 } else if (!strcasecmp(v->name, "immediate")) { 13047 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 13048 } else if (!strcasecmp(v->name, "jitterbuffer")) { 13049 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 13050 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 13051 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 13052 } else if (!strcasecmp(v->name, "dbsecret")) { 13053 ast_string_field_set(user, dbsecret, v->value); 13054 } else if (!strcasecmp(v->name, "secret")) { 13055 if (!ast_strlen_zero(user->secret)) { 13056 char *old = ast_strdupa(user->secret); 13057 13058 ast_string_field_build(user, secret, "%s;%s", old, v->value); 13059 } else 13060 ast_string_field_set(user, secret, v->value); 13061 } else if (!strcasecmp(v->name, "callerid")) { 13062 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 13063 char name2[80]; 13064 char num2[80]; 13065 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 13066 ast_string_field_set(user, cid_name, name2); 13067 ast_string_field_set(user, cid_num, num2); 13068 ast_set_flag64(user, IAX_HASCALLERID); 13069 } else { 13070 ast_clear_flag64(user, IAX_HASCALLERID); 13071 ast_string_field_set(user, cid_name, ""); 13072 ast_string_field_set(user, cid_num, ""); 13073 } 13074 } else if (!strcasecmp(v->name, "fullname")) { 13075 if (!ast_strlen_zero(v->value)) { 13076 ast_string_field_set(user, cid_name, v->value); 13077 ast_set_flag64(user, IAX_HASCALLERID); 13078 } else { 13079 ast_string_field_set(user, cid_name, ""); 13080 if (ast_strlen_zero(user->cid_num)) 13081 ast_clear_flag64(user, IAX_HASCALLERID); 13082 } 13083 } else if (!strcasecmp(v->name, "cid_number")) { 13084 if (!ast_strlen_zero(v->value)) { 13085 ast_string_field_set(user, cid_num, v->value); 13086 ast_set_flag64(user, IAX_HASCALLERID); 13087 } else { 13088 ast_string_field_set(user, cid_num, ""); 13089 if (ast_strlen_zero(user->cid_name)) 13090 ast_clear_flag64(user, IAX_HASCALLERID); 13091 } 13092 } else if (!strcasecmp(v->name, "accountcode")) { 13093 ast_string_field_set(user, accountcode, v->value); 13094 } else if (!strcasecmp(v->name, "mohinterpret")) { 13095 ast_string_field_set(user, mohinterpret, v->value); 13096 } else if (!strcasecmp(v->name, "mohsuggest")) { 13097 ast_string_field_set(user, mohsuggest, v->value); 13098 } else if (!strcasecmp(v->name, "parkinglot")) { 13099 ast_string_field_set(user, parkinglot, v->value); 13100 } else if (!strcasecmp(v->name, "language")) { 13101 ast_string_field_set(user, language, v->value); 13102 } else if (!strcasecmp(v->name, "amaflags")) { 13103 format = ast_cdr_amaflags2int(v->value); 13104 if (format < 0) { 13105 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13106 } else { 13107 user->amaflags = format; 13108 } 13109 } else if (!strcasecmp(v->name, "inkeys")) { 13110 ast_string_field_set(user, inkeys, v->value); 13111 } else if (!strcasecmp(v->name, "maxauthreq")) { 13112 user->maxauthreq = atoi(v->value); 13113 if (user->maxauthreq < 0) 13114 user->maxauthreq = 0; 13115 } else if (!strcasecmp(v->name, "adsi")) { 13116 user->adsi = ast_true(v->value); 13117 } else if (!strcasecmp(v->name, "connectedline")) { 13118 if (ast_true(v->value)) { 13119 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13120 } else if (!strcasecmp(v->value, "send")) { 13121 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 13122 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 13123 } else if (!strcasecmp(v->value, "receive")) { 13124 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 13125 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 13126 } else { 13127 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13128 } 13129 } else if (!strcasecmp(v->name, "requirecalltoken")) { 13130 /* default is required unless in optional ip list */ 13131 if (ast_false(v->value)) { 13132 user->calltoken_required = CALLTOKEN_NO; 13133 } else if (!strcasecmp(v->value, "auto")) { 13134 user->calltoken_required = CALLTOKEN_AUTO; 13135 } else if (ast_true(v->value)) { 13136 user->calltoken_required = CALLTOKEN_YES; 13137 } else { 13138 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 13139 } 13140 } /* else if (strcasecmp(v->name,"type")) */ 13141 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13142 v = v->next; 13143 if (!v) { 13144 v = alt; 13145 alt = NULL; 13146 } 13147 } 13148 if (!user->authmethods) { 13149 if (!ast_strlen_zero(user->secret)) { 13150 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 13151 if (!ast_strlen_zero(user->inkeys)) 13152 user->authmethods |= IAX_AUTH_RSA; 13153 } else if (!ast_strlen_zero(user->inkeys)) { 13154 user->authmethods = IAX_AUTH_RSA; 13155 } else { 13156 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 13157 } 13158 } 13159 ast_clear_flag64(user, IAX_DELME); 13160 } 13161 cleanup: 13162 if (oldha) 13163 ast_free_ha(oldha); 13164 if (oldcon) 13165 free_context(oldcon); 13166 return user; 13167 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13814 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().
13815 { 13816 struct sockaddr_in sin; 13817 int x; 13818 int callno; 13819 struct iax_ie_data ied; 13820 struct create_addr_info cai; 13821 struct parsed_dial_string pds; 13822 char *tmpstr; 13823 13824 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13825 /* Look for an *exact match* call. Once a call is negotiated, it can only 13826 look up entries for a single context */ 13827 if (!ast_mutex_trylock(&iaxsl[x])) { 13828 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13829 return x; 13830 ast_mutex_unlock(&iaxsl[x]); 13831 } 13832 } 13833 13834 /* No match found, we need to create a new one */ 13835 13836 memset(&cai, 0, sizeof(cai)); 13837 memset(&ied, 0, sizeof(ied)); 13838 memset(&pds, 0, sizeof(pds)); 13839 13840 tmpstr = ast_strdupa(data); 13841 parse_dial_string(tmpstr, &pds); 13842 13843 if (ast_strlen_zero(pds.peer)) { 13844 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13845 return -1; 13846 } 13847 13848 /* Populate our address from the given */ 13849 if (create_addr(pds.peer, NULL, &sin, &cai)) 13850 return -1; 13851 13852 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13853 pds.peer, pds.username, pds.password, pds.context); 13854 13855 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13856 if (callno < 1) { 13857 ast_log(LOG_WARNING, "Unable to create call\n"); 13858 return -1; 13859 } 13860 13861 ast_string_field_set(iaxs[callno], dproot, data); 13862 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13863 13864 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13865 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13866 /* the string format is slightly different from a standard dial string, 13867 because the context appears in the 'exten' position 13868 */ 13869 if (pds.exten) 13870 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13871 if (pds.username) 13872 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13873 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13874 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13875 /* Keep password handy */ 13876 if (pds.password) 13877 ast_string_field_set(iaxs[callno], secret, pds.password); 13878 if (pds.key) 13879 ast_string_field_set(iaxs[callno], outkey, pds.key); 13880 /* Start the call going */ 13881 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13882 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13883 13884 return callno; 13885 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 6142 of file chan_iax2.c.
References ast_debug, ast_random(), ast_samp2tv(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, and chan_iax2_pvt::rxcore.
Referenced by schedule_delivery().
06143 { 06144 /* Returns where in "receive time" we are. That is, how many ms 06145 since we received (or would have received) the frame with timestamp 0 */ 06146 int ms; 06147 #ifdef IAXTESTS 06148 int jit; 06149 #endif /* IAXTESTS */ 06150 /* Setup rxcore if necessary */ 06151 if (ast_tvzero(p->rxcore)) { 06152 p->rxcore = ast_tvnow(); 06153 if (iaxdebug) 06154 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %ums\n", 06155 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 06156 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 06157 #if 1 06158 if (iaxdebug) 06159 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 06160 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 06161 #endif 06162 } 06163 06164 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 06165 #ifdef IAXTESTS 06166 if (test_jit) { 06167 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 06168 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 06169 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 06170 jit = -jit; 06171 ms += jit; 06172 } 06173 } 06174 if (test_late) { 06175 ms += test_late; 06176 test_late = 0; 06177 } 06178 #endif /* IAXTESTS */ 06179 return ms; 06180 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 6010 of file chan_iax2.c.
References ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, ast_frame_subclass::codec, ast_frame::delivery, ast_frame::frametype, iaxs, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, chan_iax2_pvt::peercallno, ast_frame::samples, and ast_frame::subclass.
Referenced by iax2_send(), and socket_process().
06011 { 06012 int ms; 06013 int voice = 0; 06014 int genuine = 0; 06015 int adjust; 06016 int rate = ast_format_rate(f->subclass.codec) / 1000; 06017 struct timeval *delivery = NULL; 06018 06019 06020 /* What sort of frame do we have?: voice is self-explanatory 06021 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 06022 non-genuine frames are CONTROL frames [ringing etc], DTMF 06023 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 06024 the others need a timestamp slaved to the voice frames so that they go in sequence 06025 */ 06026 if (f->frametype == AST_FRAME_VOICE) { 06027 voice = 1; 06028 delivery = &f->delivery; 06029 } else if (f->frametype == AST_FRAME_IAX) { 06030 genuine = 1; 06031 } else if (f->frametype == AST_FRAME_CNG) { 06032 p->notsilenttx = 0; 06033 } 06034 06035 if (ast_tvzero(p->offset)) { 06036 p->offset = ast_tvnow(); 06037 /* Round to nearest 20ms for nice looking traces */ 06038 p->offset.tv_usec -= p->offset.tv_usec % 20000; 06039 } 06040 /* If the timestamp is specified, just send it as is */ 06041 if (ts) 06042 return ts; 06043 /* If we have a time that the frame arrived, always use it to make our timestamp */ 06044 if (delivery && !ast_tvzero(*delivery)) { 06045 ms = ast_tvdiff_ms(*delivery, p->offset); 06046 if (ms < 0) { 06047 ms = 0; 06048 } 06049 if (iaxdebug) 06050 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 06051 } else { 06052 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 06053 if (ms < 0) 06054 ms = 0; 06055 if (voice) { 06056 /* On a voice frame, use predicted values if appropriate */ 06057 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 06058 /* Adjust our txcore, keeping voice and non-voice synchronized */ 06059 /* AN EXPLANATION: 06060 When we send voice, we usually send "calculated" timestamps worked out 06061 on the basis of the number of samples sent. When we send other frames, 06062 we usually send timestamps worked out from the real clock. 06063 The problem is that they can tend to drift out of step because the 06064 source channel's clock and our clock may not be exactly at the same rate. 06065 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 06066 for this call. Moving it adjusts timestamps for non-voice frames. 06067 We make the adjustment in the style of a moving average. Each time we 06068 adjust p->offset by 10% of the difference between our clock-derived 06069 timestamp and the predicted timestamp. That's why you see "10000" 06070 below even though IAX2 timestamps are in milliseconds. 06071 The use of a moving average avoids offset moving too radically. 06072 Generally, "adjust" roams back and forth around 0, with offset hardly 06073 changing at all. But if a consistent different starts to develop it 06074 will be eliminated over the course of 10 frames (200-300msecs) 06075 */ 06076 adjust = (ms - p->nextpred); 06077 if (adjust < 0) 06078 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 06079 else if (adjust > 0) 06080 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 06081 06082 if (!p->nextpred) { 06083 p->nextpred = ms; /*f->samples / rate;*/ 06084 if (p->nextpred <= p->lastsent) 06085 p->nextpred = p->lastsent + 3; 06086 } 06087 ms = p->nextpred; 06088 } else { 06089 /* in this case, just use the actual 06090 * time, since we're either way off 06091 * (shouldn't happen), or we're ending a 06092 * silent period -- and seed the next 06093 * predicted time. Also, round ms to the 06094 * next multiple of frame size (so our 06095 * silent periods are multiples of 06096 * frame size too) */ 06097 06098 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 06099 ast_debug(1, "predicted timestamp skew (%d) > max (%d), using real ts instead.\n", 06100 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 06101 06102 if (f->samples >= rate) /* check to make sure we don't core dump */ 06103 { 06104 int diff = ms % (f->samples / rate); 06105 if (diff) 06106 ms += f->samples/rate - diff; 06107 } 06108 06109 p->nextpred = ms; 06110 p->notsilenttx = 1; 06111 } 06112 } else if ( f->frametype == AST_FRAME_VIDEO ) { 06113 /* 06114 * IAX2 draft 03 says that timestamps MUST be in order. 06115 * It does not say anything about several frames having the same timestamp 06116 * When transporting video, we can have a frame that spans multiple iax packets 06117 * (so called slices), so it would make sense to use the same timestamp for all of 06118 * them 06119 * We do want to make sure that frames don't go backwards though 06120 */ 06121 if ( (unsigned int)ms < p->lastsent ) 06122 ms = p->lastsent; 06123 } else { 06124 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 06125 it's a genuine frame */ 06126 if (genuine) { 06127 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 06128 if (ms <= p->lastsent) 06129 ms = p->lastsent + 3; 06130 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 06131 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 06132 ms = p->lastsent + 3; 06133 } 06134 } 06135 } 06136 p->lastsent = ms; 06137 if (voice) 06138 p->nextpred = p->nextpred + f->samples / rate; 06139 return ms; 06140 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | now | |||
) | [static] |
Definition at line 5966 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvzero(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lasttxtime, MAX_TIMESTAMP_SKEW, iax2_trunk_peer::trunkact, and iax2_trunk_peer::txtrunktime.
Referenced by send_trunk().
05967 { 05968 unsigned long int mssincetx; /* unsigned to handle overflows */ 05969 long int ms, pred; 05970 05971 tpeer->trunkact = *now; 05972 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05973 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05974 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05975 tpeer->txtrunktime = *now; 05976 tpeer->lastsent = 999999; 05977 } 05978 /* Update last transmit time now */ 05979 tpeer->lasttxtime = *now; 05980 05981 /* Calculate ms offset */ 05982 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05983 /* Predict from last value */ 05984 pred = tpeer->lastsent + sampms; 05985 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05986 ms = pred; 05987 05988 /* We never send the same timestamp twice, so fudge a little if we must */ 05989 if (ms == tpeer->lastsent) 05990 ms = tpeer->lastsent + 1; 05991 tpeer->lastsent = ms; 05992 return ms; 05993 }
static int callno_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2765 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02766 { 02767 return abs(ast_random()); 02768 }
static int calltoken_required | ( | struct sockaddr_in * | sin, | |
const char * | name, | |||
int | subclass | |||
) | [static] |
Definition at line 2289 of file chan_iax2.c.
References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, iax2_user::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), realtime_peer(), realtime_user(), S_OR, and user_unref().
Referenced by handle_call_token().
02290 { 02291 struct addr_range *addr_range; 02292 struct iax2_peer *peer = NULL; 02293 struct iax2_user *user = NULL; 02294 /* if no username is given, check for guest accounts */ 02295 const char *find = S_OR(name, "guest"); 02296 int res = 1; /* required by default */ 02297 int optional = 0; 02298 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 02299 /* There are only two cases in which calltoken validation is not required. 02300 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 02301 * the peer definition has not set the requirecalltoken option. 02302 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 02303 */ 02304 02305 /* ----- Case 1 ----- */ 02306 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 02307 ao2_ref(addr_range, -1); 02308 optional = 1; 02309 } 02310 02311 /* ----- Case 2 ----- */ 02312 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 02313 calltoken_required = user->calltoken_required; 02314 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 02315 calltoken_required = user->calltoken_required; 02316 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 02317 calltoken_required = peer->calltoken_required; 02318 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 02319 calltoken_required = peer->calltoken_required; 02320 } 02321 02322 if (peer) { 02323 peer_unref(peer); 02324 } 02325 if (user) { 02326 user_unref(user); 02327 } 02328 02329 ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %u\n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required); 02330 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 02331 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 02332 res = 0; 02333 } 02334 02335 return res; 02336 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7668 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().
07669 { 07670 /* Start pessimistic */ 07671 int res = -1; 07672 int version = 2; 07673 struct iax2_user *user = NULL, *best = NULL; 07674 int bestscore = 0; 07675 int gotcapability = 0; 07676 struct ast_variable *v = NULL, *tmpvar = NULL; 07677 struct ao2_iterator i; 07678 struct ast_sockaddr addr; 07679 07680 if (!iaxs[callno]) 07681 return res; 07682 if (ies->called_number) 07683 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07684 if (ies->calling_number) { 07685 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07686 ast_shrink_phone_number(ies->calling_number); 07687 } 07688 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07689 } 07690 if (ies->calling_name) 07691 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07692 if (ies->calling_ani) 07693 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07694 if (ies->dnid) 07695 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07696 if (ies->rdnis) 07697 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07698 if (ies->called_context) 07699 ast_string_field_set(iaxs[callno], context, ies->called_context); 07700 if (ies->language) 07701 ast_string_field_set(iaxs[callno], language, ies->language); 07702 if (ies->username) 07703 ast_string_field_set(iaxs[callno], username, ies->username); 07704 if (ies->calling_ton > -1) 07705 iaxs[callno]->calling_ton = ies->calling_ton; 07706 if (ies->calling_tns > -1) 07707 iaxs[callno]->calling_tns = ies->calling_tns; 07708 if (ies->calling_pres > -1) 07709 iaxs[callno]->calling_pres = ies->calling_pres; 07710 if (ies->format) 07711 iaxs[callno]->peerformat = ies->format; 07712 if (ies->adsicpe) 07713 iaxs[callno]->peeradsicpe = ies->adsicpe; 07714 if (ies->capability) { 07715 gotcapability = 1; 07716 iaxs[callno]->peercapability = ies->capability; 07717 } 07718 if (ies->version) 07719 version = ies->version; 07720 07721 /* Use provided preferences until told otherwise for actual preferences */ 07722 if (ies->codec_prefs) { 07723 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07724 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07725 } 07726 07727 if (!gotcapability) 07728 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07729 if (version > IAX_PROTO_VERSION) { 07730 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07731 ast_inet_ntoa(sin->sin_addr), version); 07732 return res; 07733 } 07734 /* Search the userlist for a compatible entry, and fill in the rest */ 07735 ast_sockaddr_from_sin(&addr, sin); 07736 i = ao2_iterator_init(users, 0); 07737 while ((user = ao2_iterator_next(&i))) { 07738 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07739 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07740 && ast_apply_ha(user->ha, &addr) == AST_SENSE_ALLOW /* Access is permitted from this IP */ 07741 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07742 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07743 if (!ast_strlen_zero(iaxs[callno]->username)) { 07744 /* Exact match, stop right now. */ 07745 if (best) 07746 user_unref(best); 07747 best = user; 07748 break; 07749 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07750 /* No required authentication */ 07751 if (user->ha) { 07752 /* There was host authentication and we passed, bonus! */ 07753 if (bestscore < 4) { 07754 bestscore = 4; 07755 if (best) 07756 user_unref(best); 07757 best = user; 07758 continue; 07759 } 07760 } else { 07761 /* No host access, but no secret, either, not bad */ 07762 if (bestscore < 3) { 07763 bestscore = 3; 07764 if (best) 07765 user_unref(best); 07766 best = user; 07767 continue; 07768 } 07769 } 07770 } else { 07771 if (user->ha) { 07772 /* Authentication, but host access too, eh, it's something.. */ 07773 if (bestscore < 2) { 07774 bestscore = 2; 07775 if (best) 07776 user_unref(best); 07777 best = user; 07778 continue; 07779 } 07780 } else { 07781 /* Authentication and no host access... This is our baseline */ 07782 if (bestscore < 1) { 07783 bestscore = 1; 07784 if (best) 07785 user_unref(best); 07786 best = user; 07787 continue; 07788 } 07789 } 07790 } 07791 } 07792 user_unref(user); 07793 } 07794 ao2_iterator_destroy(&i); 07795 user = best; 07796 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07797 user = realtime_user(iaxs[callno]->username, sin); 07798 if (user && (ast_apply_ha(user->ha, &addr) == AST_SENSE_DENY /* Access is denied from this IP */ 07799 || (!ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07800 !apply_context(user->contexts, iaxs[callno]->context)))) { /* Context is permitted */ 07801 user = user_unref(user); 07802 } 07803 } 07804 if (user) { 07805 /* We found our match (use the first) */ 07806 /* copy vars */ 07807 for (v = user->vars ; v ; v = v->next) { 07808 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07809 tmpvar->next = iaxs[callno]->vars; 07810 iaxs[callno]->vars = tmpvar; 07811 } 07812 } 07813 /* If a max AUTHREQ restriction is in place, activate it */ 07814 if (user->maxauthreq > 0) 07815 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07816 iaxs[callno]->prefs = user->prefs; 07817 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07818 iaxs[callno]->encmethods = user->encmethods; 07819 /* Store the requested username if not specified */ 07820 if (ast_strlen_zero(iaxs[callno]->username)) 07821 ast_string_field_set(iaxs[callno], username, user->name); 07822 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07823 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07824 iaxs[callno]->capability = user->capability; 07825 /* And use the default context */ 07826 if (ast_strlen_zero(iaxs[callno]->context)) { 07827 if (user->contexts) 07828 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07829 else 07830 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07831 } 07832 /* And any input keys */ 07833 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07834 /* And the permitted authentication methods */ 07835 iaxs[callno]->authmethods = user->authmethods; 07836 iaxs[callno]->adsi = user->adsi; 07837 /* If the user has callerid, override the remote caller id. */ 07838 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07839 iaxs[callno]->calling_tns = 0; 07840 iaxs[callno]->calling_ton = 0; 07841 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07842 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07843 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07844 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07845 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07846 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07847 } /* else user is allowed to set their own CID settings */ 07848 if (!ast_strlen_zero(user->accountcode)) 07849 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07850 if (!ast_strlen_zero(user->mohinterpret)) 07851 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07852 if (!ast_strlen_zero(user->mohsuggest)) 07853 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07854 if (!ast_strlen_zero(user->parkinglot)) 07855 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07856 if (user->amaflags) 07857 iaxs[callno]->amaflags = user->amaflags; 07858 if (!ast_strlen_zero(user->language)) 07859 ast_string_field_set(iaxs[callno], language, user->language); 07860 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07861 /* Keep this check last */ 07862 if (!ast_strlen_zero(user->dbsecret)) { 07863 char *family, *key=NULL; 07864 char buf[80]; 07865 family = ast_strdupa(user->dbsecret); 07866 key = strchr(family, '/'); 07867 if (key) { 07868 *key = '\0'; 07869 key++; 07870 } 07871 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07872 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07873 else 07874 ast_string_field_set(iaxs[callno], secret, buf); 07875 } else 07876 ast_string_field_set(iaxs[callno], secret, user->secret); 07877 res = 0; 07878 user = user_unref(user); 07879 } else { 07880 /* user was not found, but we should still fake an AUTHREQ. 07881 * Set authmethods to the last known authmethod used by the system 07882 * Set a fake secret, it's not looked at, just required to attempt authentication. 07883 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07884 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07885 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07886 iaxs[callno]->authrej = 1; 07887 if (!ast_strlen_zero(iaxs[callno]->username)) { 07888 /* only send the AUTHREQ if a username was specified. */ 07889 res = 0; 07890 } 07891 } 07892 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07893 return res; 07894 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 9546 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09547 { 09548 unsigned int ourver; 09549 char rsi[80]; 09550 snprintf(rsi, sizeof(rsi), "si-%s", si); 09551 if (iax_provision_version(&ourver, rsi, 1)) 09552 return 0; 09553 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09554 if (ourver != ver) 09555 iax2_provision(sin, sockfd, NULL, rsi, 1); 09556 return 0; 09557 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 12500 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
12501 { 12502 int sd; 12503 int res; 12504 12505 sd = socket(AF_INET, SOCK_DGRAM, 0); 12506 if (sd < 0) { 12507 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 12508 return -1; 12509 } 12510 12511 res = bind(sd, sa, salen); 12512 if (res < 0) { 12513 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 12514 close(sd); 12515 return 1; 12516 } 12517 12518 close(sd); 12519 return 0; 12520 }
static void cleanup_thread_list | ( | void * | head | ) | [static] |
Definition at line 14554 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().
14555 { 14556 AST_LIST_HEAD(iax2_thread_list, iax2_thread); 14557 struct iax2_thread_list *list_head = head; 14558 struct iax2_thread *thread; 14559 14560 AST_LIST_LOCK(list_head); 14561 while ((thread = AST_LIST_REMOVE_HEAD(list_head, list))) { 14562 pthread_t thread_id = thread->threadid; 14563 14564 thread->stop = 1; 14565 signal_condition(&thread->lock, &thread->cond); 14566 14567 AST_LIST_UNLOCK(list_head); 14568 pthread_join(thread_id, NULL); 14569 AST_LIST_LOCK(list_head); 14570 } 14571 AST_LIST_UNLOCK(list_head); 14572 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8458 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().
08459 { 08460 char exten[256] = ""; 08461 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08462 struct iax2_dpcache *dp = NULL; 08463 08464 if (ies->called_number) 08465 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08466 08467 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08468 status = CACHE_FLAG_EXISTS; 08469 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08470 status = CACHE_FLAG_CANEXIST; 08471 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08472 status = CACHE_FLAG_NONEXISTENT; 08473 08474 if (ies->refresh) 08475 expiry = ies->refresh; 08476 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08477 matchmore = CACHE_FLAG_MATCHMORE; 08478 08479 AST_LIST_LOCK(&dpcache); 08480 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08481 if (strcmp(dp->exten, exten)) 08482 continue; 08483 AST_LIST_REMOVE_CURRENT(peer_list); 08484 dp->callno = 0; 08485 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08486 if (dp->flags & CACHE_FLAG_PENDING) { 08487 dp->flags &= ~CACHE_FLAG_PENDING; 08488 dp->flags |= status; 08489 dp->flags |= matchmore; 08490 } 08491 /* Wake up waiters */ 08492 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08493 if (dp->waiters[x] > -1) { 08494 if (write(dp->waiters[x], "asdf", 4) < 0) { 08495 } 08496 } 08497 } 08498 } 08499 AST_LIST_TRAVERSE_SAFE_END; 08500 AST_LIST_UNLOCK(&dpcache); 08501 08502 return 0; 08503 }
static char * complete_iax2_peers | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
uint64_t | flags | |||
) | [static] |
Definition at line 3918 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_test_flag64, and peer_unref().
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), and handle_cli_iax2_show_peer().
03919 { 03920 int which = 0; 03921 struct iax2_peer *peer; 03922 char *res = NULL; 03923 int wordlen = strlen(word); 03924 struct ao2_iterator i; 03925 03926 i = ao2_iterator_init(peers, 0); 03927 while ((peer = ao2_iterator_next(&i))) { 03928 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03929 && (!flags || ast_test_flag64(peer, flags))) { 03930 res = ast_strdup(peer->name); 03931 peer_unref(peer); 03932 break; 03933 } 03934 peer_unref(peer); 03935 } 03936 ao2_iterator_destroy(&i); 03937 03938 return res; 03939 }
static char * complete_iax2_unregister | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 7009 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::expire, and peer_unref().
Referenced by handle_cli_iax2_unregister().
07010 { 07011 int which = 0; 07012 struct iax2_peer *p = NULL; 07013 char *res = NULL; 07014 int wordlen = strlen(word); 07015 07016 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 07017 if (pos == 2) { 07018 struct ao2_iterator i = ao2_iterator_init(peers, 0); 07019 while ((p = ao2_iterator_next(&i))) { 07020 if (!strncasecmp(p->name, word, wordlen) && 07021 ++which > state && p->expire > 0) { 07022 res = ast_strdup(p->name); 07023 peer_unref(p); 07024 break; 07025 } 07026 peer_unref(p); 07027 } 07028 ao2_iterator_destroy(&i); 07029 } 07030 07031 return res; 07032 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8505 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().
08506 { 08507 int peercallno = 0; 08508 struct chan_iax2_pvt *pvt = iaxs[callno]; 08509 struct iax_frame *cur; 08510 jb_frame frame; 08511 08512 if (ies->callno) 08513 peercallno = ies->callno; 08514 08515 if (peercallno < 1) { 08516 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08517 return -1; 08518 } 08519 remove_by_transfercallno(pvt); 08520 /* since a transfer has taken place, the address will change. 08521 * This must be accounted for in the peercnts table. Remove 08522 * the old address and add the new one */ 08523 peercnt_remove_by_addr(&pvt->addr); 08524 peercnt_add(&pvt->transfer); 08525 /* now copy over the new address */ 08526 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08527 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08528 /* Reset sequence numbers */ 08529 pvt->oseqno = 0; 08530 pvt->rseqno = 0; 08531 pvt->iseqno = 0; 08532 pvt->aseqno = 0; 08533 08534 if (pvt->peercallno) { 08535 remove_by_peercallno(pvt); 08536 } 08537 pvt->peercallno = peercallno; 08538 /*this is where the transfering call swiches hash tables */ 08539 store_by_peercallno(pvt); 08540 pvt->transferring = TRANSFER_NONE; 08541 pvt->svoiceformat = -1; 08542 pvt->voiceformat = 0; 08543 pvt->svideoformat = -1; 08544 pvt->videoformat = 0; 08545 pvt->transfercallno = 0; 08546 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08547 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08548 /* reset jitterbuffer */ 08549 while(jb_getall(pvt->jb,&frame) == JB_OK) 08550 iax2_frame_free(frame.data); 08551 jb_reset(pvt->jb); 08552 pvt->lag = 0; 08553 pvt->last = 0; 08554 pvt->lastsent = 0; 08555 pvt->nextpred = 0; 08556 pvt->pingtime = DEFAULT_RETRY_TIME; 08557 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08558 /* We must cancel any packets that would have been transmitted 08559 because now we're talking to someone new. It's okay, they 08560 were transmitted to someone that didn't care anyway. */ 08561 cur->retries = -1; 08562 } 08563 return 0; 08564 }
static unsigned char compress_subclass | ( | format_t | subclass | ) | [static] |
Definition at line 1691 of file chan_iax2.c.
References ast_log(), IAX_FLAG_SC_LOG, IAX_MAX_SHIFT, and LOG_WARNING.
Referenced by iax2_send(), raw_hangup(), and send_apathetic_reply().
01692 { 01693 int x; 01694 int power=-1; 01695 /* If it's 64 or smaller, just return it */ 01696 if (subclass < IAX_FLAG_SC_LOG) 01697 return subclass; 01698 /* Otherwise find its power */ 01699 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01700 if (subclass & (1LL << x)) { 01701 if (power > -1) { 01702 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass); 01703 return 0; 01704 } else 01705 power = x; 01706 } 01707 } 01708 return power | IAX_FLAG_SC_LOG; 01709 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 9559 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().
09560 { 09561 jb_info stats; 09562 jb_getinfo(pvt->jb, &stats); 09563 09564 memset(iep, 0, sizeof(*iep)); 09565 09566 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09567 if(stats.frames_in == 0) stats.frames_in = 1; 09568 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09569 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09570 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09571 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09572 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09573 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 4657 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag64, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags64, ast_copy_string(), ast_db_get(), ast_debug, ast_get_ip_or_srv(), ast_log(), ast_sockaddr_to_sin, ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, create_addr_info::cid_name, create_addr_info::cid_num, create_addr_info::context, iax2_peer::defaddr, iax2_peer::encmethods, create_addr_info::encmethods, find_peer(), create_addr_info::found, IAX_DEFAULT_PORTNO, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, create_addr_info::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, create_addr_info::outkey, peer_unref(), create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, ast_sockaddr::ss, create_addr_info::timezone, and create_addr_info::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_provision(), and iax2_request().
04658 { 04659 struct iax2_peer *peer; 04660 int res = -1; 04661 struct ast_codec_pref ourprefs; 04662 struct sockaddr_in peer_addr; 04663 04664 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04665 cai->sockfd = defaultsockfd; 04666 cai->maxtime = 0; 04667 sin->sin_family = AF_INET; 04668 04669 if (!(peer = find_peer(peername, 1))) { 04670 struct ast_sockaddr sin_tmp; 04671 04672 cai->found = 0; 04673 sin_tmp.ss.ss_family = AF_INET; 04674 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) { 04675 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04676 return -1; 04677 } 04678 ast_sockaddr_to_sin(&sin_tmp, sin); 04679 if (sin->sin_port == 0) { 04680 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04681 } 04682 /* use global iax prefs for unknown peer/user */ 04683 /* But move the calling channel's native codec to the top of the preference list */ 04684 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04685 if (c) 04686 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04687 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04688 return 0; 04689 } 04690 04691 cai->found = 1; 04692 04693 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 04694 04695 /* if the peer has no address (current or default), return failure */ 04696 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 04697 goto return_unref; 04698 } 04699 04700 /* if the peer is being monitored and is currently unreachable, return failure */ 04701 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04702 goto return_unref; 04703 04704 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04705 cai->maxtime = peer->maxms; 04706 cai->capability = peer->capability; 04707 cai->encmethods = peer->encmethods; 04708 cai->sockfd = peer->sockfd; 04709 cai->adsi = peer->adsi; 04710 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04711 /* Move the calling channel's native codec to the top of the preference list */ 04712 if (c) { 04713 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats); 04714 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04715 } 04716 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04717 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04718 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04719 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04720 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04721 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04722 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04723 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04724 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04725 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04726 if (ast_strlen_zero(peer->dbsecret)) { 04727 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04728 } else { 04729 char *family; 04730 char *key = NULL; 04731 04732 family = ast_strdupa(peer->dbsecret); 04733 key = strchr(family, '/'); 04734 if (key) 04735 *key++ = '\0'; 04736 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04737 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04738 goto return_unref; 04739 } 04740 } 04741 04742 if (peer_addr.sin_addr.s_addr) { 04743 sin->sin_addr = peer_addr.sin_addr; 04744 sin->sin_port = peer_addr.sin_port; 04745 } else { 04746 sin->sin_addr = peer->defaddr.sin_addr; 04747 sin->sin_port = peer->defaddr.sin_port; 04748 } 04749 04750 res = 0; 04751 04752 return_unref: 04753 peer_unref(peer); 04754 04755 return res; 04756 }
static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2770 of file chan_iax2.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, callno_entry::callno, and callno_hash().
Referenced by load_objects().
02771 { 02772 uint16_t i; 02773 02774 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02775 return -1; 02776 } 02777 02778 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02779 return -1; 02780 } 02781 02782 /* start at 2, 0 and 1 are reserved */ 02783 for (i = 2; i < IAX_MAX_CALLS; i++) { 02784 struct callno_entry *callno_entry; 02785 02786 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02787 return -1; 02788 } 02789 02790 callno_entry->callno = i; 02791 02792 if (i < TRUNK_CALL_START) { 02793 ao2_link(callno_pool, callno_entry); 02794 } else { 02795 ao2_link(callno_pool_trunk, callno_entry); 02796 } 02797 02798 ao2_ref(callno_entry, -1); 02799 } 02800 02801 return 0; 02802 }
static int decode_frame | ( | ast_aes_decrypt_key * | dcx, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 6363 of file chan_iax2.c.
References ast_alloca, ast_debug, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frame_subclass::codec, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame::frametype, IAX_FLAG_FULL, ast_frame_subclass::integer, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame(), and update_packet().
06364 { 06365 int padding; 06366 unsigned char *workspace; 06367 06368 workspace = ast_alloca(*datalen); 06369 memset(f, 0, sizeof(*f)); 06370 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06371 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06372 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06373 return -1; 06374 /* Decrypt */ 06375 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06376 06377 padding = 16 + (workspace[15] & 0x0f); 06378 if (iaxdebug) 06379 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, (unsigned)workspace[15]); 06380 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06381 return -1; 06382 06383 *datalen -= padding; 06384 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06385 f->frametype = fh->type; 06386 if (f->frametype == AST_FRAME_VIDEO) { 06387 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06388 } else if (f->frametype == AST_FRAME_VOICE) { 06389 f->subclass.codec = uncompress_subclass(fh->csub); 06390 } else { 06391 f->subclass.integer = uncompress_subclass(fh->csub); 06392 } 06393 } else { 06394 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06395 if (iaxdebug) 06396 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06397 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06398 return -1; 06399 /* Decrypt */ 06400 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06401 padding = 16 + (workspace[15] & 0x0f); 06402 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06403 return -1; 06404 *datalen -= padding; 06405 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06406 } 06407 return 0; 06408 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 6449 of file chan_iax2.c.
References ast_set_flag64, ast_strdupa, ast_test_flag64, build_encryption_keys(), decode_frame(), IAX_KEYPOPULATED, iaxs, MD5Final(), MD5Init(), MD5Update(), and secret.
Referenced by socket_process().
06450 { 06451 int res=-1; 06452 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06453 /* Search for possible keys, given secrets */ 06454 struct MD5Context md5; 06455 unsigned char digest[16]; 06456 char *tmppw, *stringp; 06457 06458 tmppw = ast_strdupa(iaxs[callno]->secret); 06459 stringp = tmppw; 06460 while ((tmppw = strsep(&stringp, ";"))) { 06461 MD5Init(&md5); 06462 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06463 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06464 MD5Final(digest, &md5); 06465 build_encryption_keys(digest, iaxs[callno]); 06466 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06467 if (!res) { 06468 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06469 break; 06470 } 06471 } 06472 } else 06473 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06474 return res; 06475 }
static void defer_full_frame | ( | struct iax2_thread * | from_here, | |
struct iax2_thread * | to_here | |||
) | [static] |
Queue the last read full frame for processing by a certain thread.
If there are already any full frames queued, they are sorted by sequence number.
Definition at line 9706 of file chan_iax2.c.
References ast_calloc, ast_cond_signal, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock, ast_mutex_unlock, IAX_IOSTATE_READY, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
09707 { 09708 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09709 struct ast_iax2_full_hdr *fh, *cur_fh; 09710 09711 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09712 return; 09713 09714 pkt_buf->len = from_here->buf_len; 09715 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09716 09717 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09718 ast_mutex_lock(&to_here->lock); 09719 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09720 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09721 if (fh->oseqno < cur_fh->oseqno) { 09722 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09723 break; 09724 } 09725 } 09726 AST_LIST_TRAVERSE_SAFE_END 09727 09728 if (!cur_pkt_buf) 09729 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09730 09731 to_here->iostate = IAX_IOSTATE_READY; 09732 ast_cond_signal(&to_here->cond); 09733 09734 ast_mutex_unlock(&to_here->lock); 09735 }
static void delete_users | ( | void | ) | [static] |
Definition at line 13187 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().
13188 { 13189 struct iax2_registry *reg; 13190 13191 ao2_callback(users, 0, user_delme_cb, NULL); 13192 13193 AST_LIST_LOCK(®istrations); 13194 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 13195 if (sched) { 13196 ast_sched_thread_del(sched, reg->expire); 13197 } 13198 if (reg->callno) { 13199 int callno = reg->callno; 13200 ast_mutex_lock(&iaxsl[callno]); 13201 if (iaxs[callno]) { 13202 iaxs[callno]->reg = NULL; 13203 iax2_destroy(callno); 13204 } 13205 ast_mutex_unlock(&iaxsl[callno]); 13206 } 13207 if (reg->dnsmgr) 13208 ast_dnsmgr_release(reg->dnsmgr); 13209 ast_free(reg); 13210 } 13211 AST_LIST_UNLOCK(®istrations); 13212 13213 ao2_callback(peers, 0, peer_delme_cb, NULL); 13214 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 3100 of file chan_iax2.c.
References ast_free.
Referenced by reload_firmware().
03101 { 03102 /* Close firmware */ 03103 if (cur->fwh) { 03104 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 03105 } 03106 close(cur->fd); 03107 ast_free(cur); 03108 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 9361 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().
09362 { 09363 unsigned short dpstatus = 0; 09364 struct iax_ie_data ied1; 09365 int mm; 09366 09367 memset(&ied1, 0, sizeof(ied1)); 09368 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 09369 /* Must be started */ 09370 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 09371 dpstatus = IAX_DPSTATUS_EXISTS; 09372 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 09373 dpstatus = IAX_DPSTATUS_CANEXIST; 09374 } else { 09375 dpstatus = IAX_DPSTATUS_NONEXISTENT; 09376 } 09377 if (ast_ignore_pattern(context, callednum)) 09378 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 09379 if (mm) 09380 dpstatus |= IAX_DPSTATUS_MATCHMORE; 09381 if (!skiplock) 09382 ast_mutex_lock(&iaxsl[callno]); 09383 if (iaxs[callno]) { 09384 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 09385 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 09386 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 09387 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 09388 } 09389 if (!skiplock) 09390 ast_mutex_unlock(&iaxsl[callno]); 09391 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 9393 of file chan_iax2.c.
References ast_free, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, and dp_lookup().
Referenced by spawn_dp_lookup().
static void encmethods_to_str | ( | int | e, | |
struct ast_str ** | buf | |||
) | [static] |
Definition at line 1625 of file chan_iax2.c.
References ast_str_append(), ast_str_set(), ast_str_strlen(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by __iax2_show_peers(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().
01626 { 01627 ast_str_set(buf, 0, "("); 01628 if (e & IAX_ENCRYPT_AES128) { 01629 ast_str_append(buf, 0, "aes128"); 01630 } 01631 if (e & IAX_ENCRYPT_KEYROTATE) { 01632 ast_str_append(buf, 0, ",keyrotate"); 01633 } 01634 if (ast_str_strlen(*buf) > 1) { 01635 ast_str_append(buf, 0, ")"); 01636 } else { 01637 ast_str_set(buf, 0, "No"); 01638 } 01639 }
static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 6410 of file chan_iax2.c.
References ast_alloca, ast_debug, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, IAX_FLAG_FULL, memcpy_encrypt(), ast_iax2_full_hdr::scallno, and ast_iax2_full_hdr::type.
Referenced by iax2_send(), and update_packet().
06411 { 06412 int padding; 06413 unsigned char *workspace; 06414 workspace = ast_alloca(*datalen + 32); 06415 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06416 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06417 if (iaxdebug) 06418 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06419 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06420 padding = 16 + (padding & 0xf); 06421 memcpy(workspace, poo, padding); 06422 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06423 workspace[15] &= 0xf0; 06424 workspace[15] |= (padding & 0xf); 06425 if (iaxdebug) 06426 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, (unsigned)workspace[15]); 06427 *datalen += padding; 06428 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06429 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06430 memcpy(poo, workspace + *datalen - 32, 32); 06431 } else { 06432 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06433 if (iaxdebug) 06434 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06435 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06436 padding = 16 + (padding & 0xf); 06437 memcpy(workspace, poo, padding); 06438 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06439 workspace[15] &= 0xf0; 06440 workspace[15] |= (padding & 0x0f); 06441 *datalen += padding; 06442 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06443 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06444 memcpy(poo, workspace + *datalen - 32, 32); 06445 } 06446 return 0; 06447 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8773 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().
08774 { 08775 #ifdef SCHED_MULTITHREADED 08776 if (schedule_action(__expire_registry, data)) 08777 #endif 08778 __expire_registry(data); 08779 return 0; 08780 }
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 13887 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().
13888 { 13889 struct iax2_dpcache *dp = NULL; 13890 struct timeval now = ast_tvnow(); 13891 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13892 struct ast_channel *c = NULL; 13893 struct ast_frame *f = NULL; 13894 13895 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13896 if (ast_tvcmp(now, dp->expiry) > 0) { 13897 AST_LIST_REMOVE_CURRENT(cache_list); 13898 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13899 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13900 else 13901 ast_free(dp); 13902 continue; 13903 } 13904 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13905 break; 13906 } 13907 AST_LIST_TRAVERSE_SAFE_END; 13908 13909 if (!dp) { 13910 /* No matching entry. Create a new one. */ 13911 /* First, can we make a callno? */ 13912 if ((callno = cache_get_callno_locked(data)) < 0) { 13913 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13914 return NULL; 13915 } 13916 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13917 ast_mutex_unlock(&iaxsl[callno]); 13918 return NULL; 13919 } 13920 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13921 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13922 dp->expiry = ast_tvnow(); 13923 dp->orig = dp->expiry; 13924 /* Expires in 30 mins by default */ 13925 dp->expiry.tv_sec += iaxdefaultdpcache; 13926 dp->flags = CACHE_FLAG_PENDING; 13927 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13928 dp->waiters[x] = -1; 13929 /* Insert into the lists */ 13930 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13931 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13932 /* Send the request if we're already up */ 13933 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13934 iax2_dprequest(dp, callno); 13935 ast_mutex_unlock(&iaxsl[callno]); 13936 } 13937 13938 /* By here we must have a dp */ 13939 if (dp->flags & CACHE_FLAG_PENDING) { 13940 struct timeval start; 13941 int ms; 13942 /* Okay, here it starts to get nasty. We need a pipe now to wait 13943 for a reply to come back so long as it's pending */ 13944 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13945 /* Find an empty slot */ 13946 if (dp->waiters[x] < 0) 13947 break; 13948 } 13949 if (x >= ARRAY_LEN(dp->waiters)) { 13950 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13951 return NULL; 13952 } 13953 if (pipe(com)) { 13954 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13955 return NULL; 13956 } 13957 dp->waiters[x] = com[1]; 13958 /* Okay, now we wait */ 13959 timeout = iaxdefaulttimeout * 1000; 13960 /* Temporarily unlock */ 13961 AST_LIST_UNLOCK(&dpcache); 13962 /* Defer any dtmf */ 13963 if (chan) 13964 old = ast_channel_defer_dtmf(chan); 13965 doabort = 0; 13966 start = ast_tvnow(); 13967 while ((ms = ast_remaining_ms(start, timeout))) { 13968 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &ms); 13969 if (outfd > -1) 13970 break; 13971 if (!c) 13972 continue; 13973 if (!(f = ast_read(c))) { 13974 doabort = 1; 13975 break; 13976 } 13977 ast_frfree(f); 13978 } 13979 if (!ms) { 13980 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13981 } 13982 AST_LIST_LOCK(&dpcache); 13983 dp->waiters[x] = -1; 13984 close(com[1]); 13985 close(com[0]); 13986 if (doabort) { 13987 /* Don't interpret anything, just abort. Not sure what th epoint 13988 of undeferring dtmf on a hung up channel is but hey whatever */ 13989 if (!old && chan) 13990 ast_channel_undefer_dtmf(chan); 13991 return NULL; 13992 } 13993 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13994 /* Now to do non-independent analysis the results of our wait */ 13995 if (dp->flags & CACHE_FLAG_PENDING) { 13996 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13997 pending. Don't let it take as long to timeout. */ 13998 dp->flags &= ~CACHE_FLAG_PENDING; 13999 dp->flags |= CACHE_FLAG_TIMEOUT; 14000 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 14001 systems without leaving it unavailable once the server comes back online */ 14002 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 14003 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 14004 if (dp->waiters[x] > -1) { 14005 if (write(dp->waiters[x], "asdf", 4) < 0) { 14006 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 14007 } 14008 } 14009 } 14010 } 14011 } 14012 /* Our caller will obtain the rest */ 14013 if (!old && chan) 14014 ast_channel_undefer_dtmf(chan); 14015 } 14016 return dp; 14017 }
static int find_callno | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 3025 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
03025 { 03026 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 03027 }
static int find_callno_locked | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | new, | |||
int | sockfd, | |||
int | full_frame | |||
) | [static] |
Definition at line 3029 of file chan_iax2.c.
References __find_callno().
Referenced by cache_get_callno_locked(), iax2_do_register(), iax2_provision(), iax2_request(), and socket_process_meta().
03029 { 03030 03031 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 03032 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 1477 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, iax2_thread::ffinfo, iax2_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, and thread.
Referenced by __schedule_action(), and socket_read().
01478 { 01479 struct iax2_thread *thread = NULL; 01480 01481 /* Pop the head of the idle list off */ 01482 AST_LIST_LOCK(&idle_list); 01483 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01484 AST_LIST_UNLOCK(&idle_list); 01485 01486 /* If we popped a thread off the idle list, just return it */ 01487 if (thread) { 01488 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01489 return thread; 01490 } 01491 01492 /* Pop the head of the dynamic list off */ 01493 AST_LIST_LOCK(&dynamic_list); 01494 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01495 AST_LIST_UNLOCK(&dynamic_list); 01496 01497 /* If we popped a thread off the dynamic list, just return it */ 01498 if (thread) { 01499 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01500 return thread; 01501 } 01502 01503 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01504 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01505 return NULL; 01506 01507 /* Set default values */ 01508 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01509 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01510 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01511 01512 /* Initialize lock and condition */ 01513 ast_mutex_init(&thread->lock); 01514 ast_cond_init(&thread->cond, NULL); 01515 ast_mutex_init(&thread->init_lock); 01516 ast_cond_init(&thread->init_cond, NULL); 01517 ast_mutex_lock(&thread->init_lock); 01518 01519 /* Create thread and send it on it's way */ 01520 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01521 ast_cond_destroy(&thread->cond); 01522 ast_mutex_destroy(&thread->lock); 01523 ast_mutex_unlock(&thread->init_lock); 01524 ast_cond_destroy(&thread->init_cond); 01525 ast_mutex_destroy(&thread->init_lock); 01526 ast_free(thread); 01527 return NULL; 01528 } 01529 01530 /* this thread is not processing a full frame (since it is idle), 01531 so ensure that the field for the full frame call number is empty */ 01532 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01533 01534 /* Wait for the thread to be ready before returning it to the caller */ 01535 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01536 01537 /* Done with init_lock */ 01538 ast_mutex_unlock(&thread->init_lock); 01539 01540 return thread; 01541 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static, read] |
Definition at line 1769 of file chan_iax2.c.
References ao2_find, OBJ_POINTER, and realtime_peer().
Referenced by calltoken_required(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), and update_registry().
01770 { 01771 struct iax2_peer *peer = NULL; 01772 struct iax2_peer tmp_peer = { 01773 .name = name, 01774 }; 01775 01776 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01777 01778 /* Now go for realtime if applicable */ 01779 if(!peer && realtime) 01780 peer = realtime_peer(name, NULL); 01781 01782 return peer; 01783 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static, read] |
Definition at line 6182 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_calloc, ast_debug, ast_inet_ntoa(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_init, ast_mutex_lock, ast_tvnow(), inaddrcmp(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lock, iax2_trunk_peer::sockfd, and iax2_trunk_peer::trunkact.
Referenced by iax2_trunk_queue(), and socket_process_meta().
06183 { 06184 struct iax2_trunk_peer *tpeer = NULL; 06185 06186 /* Finds and locks trunk peer */ 06187 AST_LIST_LOCK(&tpeers); 06188 06189 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 06190 if (!inaddrcmp(&tpeer->addr, sin)) { 06191 ast_mutex_lock(&tpeer->lock); 06192 break; 06193 } 06194 } 06195 06196 if (!tpeer) { 06197 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 06198 ast_mutex_init(&tpeer->lock); 06199 tpeer->lastsent = 9999; 06200 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 06201 tpeer->trunkact = ast_tvnow(); 06202 ast_mutex_lock(&tpeer->lock); 06203 tpeer->sockfd = fd; 06204 #ifdef SO_NO_CHECK 06205 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 06206 #endif 06207 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06208 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 06209 } 06210 } 06211 06212 AST_LIST_UNLOCK(&tpeers); 06213 06214 return tpeer; 06215 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static, read] |
Definition at line 1797 of file chan_iax2.c.
References ao2_find, and OBJ_POINTER.
Referenced by calltoken_required(), handle_cli_iax2_prune_realtime(), and requirecalltoken_mark_auto().
01798 { 01799 struct iax2_user tmp_user = { 01800 .name = name, 01801 }; 01802 01803 return ao2_find(users, &tmp_user, OBJ_POINTER); 01804 }
static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 5995 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05996 { 05997 long ms; /* NOT unsigned */ 05998 if (ast_tvzero(iaxs[callno]->rxcore)) { 05999 /* Initialize rxcore time if appropriate */ 06000 iaxs[callno]->rxcore = ast_tvnow(); 06001 /* Round to nearest 20ms so traces look pretty */ 06002 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 06003 } 06004 /* Calculate difference between trunk and channel */ 06005 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 06006 /* Return as the sum of trunk time and the difference between trunk and real time */ 06007 return ms + ts; 06008 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 12319 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
12320 { 12321 struct iax2_context *conl; 12322 while(con) { 12323 conl = con; 12324 con = con->next; 12325 ast_free(conl); 12326 } 12327 }
static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1903 of file chan_iax2.c.
References ast_free, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, and ast_frame::ptr.
Referenced by pvt_destructor(), queue_signalling(), and send_signaling().
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 14140 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.
14141 { 14142 struct iax2_peer *peer; 14143 char *peername, *colname; 14144 14145 peername = ast_strdupa(data); 14146 14147 /* if our channel, return the IP address of the endpoint of current channel */ 14148 if (!strcmp(peername,"CURRENTCHANNEL")) { 14149 unsigned short callno; 14150 if (!chan || chan->tech != &iax2_tech) { 14151 return -1; 14152 } 14153 callno = PTR_TO_CALLNO(chan->tech_pvt); 14154 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 14155 return 0; 14156 } 14157 14158 if ((colname = strchr(peername, ','))) 14159 *colname++ = '\0'; 14160 else 14161 colname = "ip"; 14162 14163 if (!(peer = find_peer(peername, 1))) 14164 return -1; 14165 14166 if (!strcasecmp(colname, "ip")) { 14167 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 14168 } else if (!strcasecmp(colname, "status")) { 14169 peer_status(peer, buf, len); 14170 } else if (!strcasecmp(colname, "mailbox")) { 14171 ast_copy_string(buf, peer->mailbox, len); 14172 } else if (!strcasecmp(colname, "context")) { 14173 ast_copy_string(buf, peer->context, len); 14174 } else if (!strcasecmp(colname, "expire")) { 14175 snprintf(buf, len, "%d", peer->expire); 14176 } else if (!strcasecmp(colname, "dynamic")) { 14177 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 14178 } else if (!strcasecmp(colname, "callerid_name")) { 14179 ast_copy_string(buf, peer->cid_name, len); 14180 } else if (!strcasecmp(colname, "callerid_num")) { 14181 ast_copy_string(buf, peer->cid_num, len); 14182 } else if (!strcasecmp(colname, "codecs")) { 14183 ast_getformatname_multiple(buf, len -1, peer->capability); 14184 } else if (!strncasecmp(colname, "codec[", 6)) { 14185 char *codecnum, *ptr; 14186 int codec = 0; 14187 14188 /* skip over "codec" to the '[' */ 14189 codecnum = colname + 5; 14190 *codecnum = '\0'; 14191 codecnum++; 14192 if ((ptr = strchr(codecnum, ']'))) { 14193 *ptr = '\0'; 14194 } 14195 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 14196 ast_copy_string(buf, ast_getformatname(codec), len); 14197 } else { 14198 buf[0] = '\0'; 14199 } 14200 } else { 14201 buf[0] = '\0'; 14202 } 14203 14204 peer_unref(peer); 14205 14206 return 0; 14207 }
static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 12484 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
12485 { 12486 int methods = 0; 12487 if (strstr(value, "rsa")) 12488 methods |= IAX_AUTH_RSA; 12489 if (strstr(value, "md5")) 12490 methods |= IAX_AUTH_MD5; 12491 if (strstr(value, "plaintext")) 12492 methods |= IAX_AUTH_PLAINTEXT; 12493 return methods; 12494 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1641 of file chan_iax2.c.
References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by build_peer(), build_user(), and set_config().
01642 { 01643 int e; 01644 if (!strcasecmp(s, "aes128")) 01645 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01646 else if (ast_true(s)) 01647 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01648 else 01649 e = 0; 01650 return e; 01651 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4228 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
04229 { 04230 #ifdef SCHED_MULTITHREADED 04231 if (schedule_action(__get_from_jb, data)) 04232 #endif 04233 __get_from_jb(data); 04234 return 0; 04235 }
static struct callno_entry * get_unused_callno | ( | int | trunk, | |
int | validated | |||
) | [static, read] |
Definition at line 2703 of file chan_iax2.c.
References ao2_container_count(), ao2_find, ao2_lock, ao2_unlock, ast_log(), LOG_WARNING, OBJ_CONTINUE, OBJ_POINTER, OBJ_UNLINK, and callno_entry::validated.
Referenced by __find_callno(), and make_trunk().
02704 { 02705 struct callno_entry *callno_entry = NULL; 02706 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02707 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02708 /* Minor optimization for the extreme case. */ 02709 return NULL; 02710 } 02711 02712 /* the callno_pool container is locked here primarily to ensure thread 02713 * safety of the total_nonval_callno_used check and increment */ 02714 ao2_lock(callno_pool); 02715 02716 /* only a certain number of nonvalidated call numbers should be allocated. 02717 * If there ever is an attack, this separates the calltoken validating 02718 * users from the non calltoken validating users. */ 02719 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02720 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02721 ao2_unlock(callno_pool); 02722 return NULL; 02723 } 02724 02725 /* unlink the object from the container, taking over ownership 02726 * of the reference the container had to the object */ 02727 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02728 02729 if (callno_entry) { 02730 callno_entry->validated = validated; 02731 if (!validated) { 02732 total_nonval_callno_used++; 02733 } 02734 } 02735 02736 ao2_unlock(callno_pool); 02737 return callno_entry; 02738 }
static int handle_call_token | ( | struct ast_iax2_full_hdr * | fh, | |
struct iax_ies * | ies, | |||
struct sockaddr_in * | sin, | |||
int | fd | |||
) | [static] |
Definition at line 4966 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), ast_sha1_hash(), ast_str_alloca, ast_str_buffer(), ast_str_set(), iax_ie_data::buf, iax_ies::calltoken, CALLTOKEN_HASH_FORMAT, CALLTOKEN_IE_FORMAT, calltoken_required(), iax_ies::calltokendata, ast_iax2_full_hdr::csub, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, iax_ie_append_str(), IAX_IE_CALLTOKEN, ast_iax2_full_hdr::iseqno, LOG_ERROR, LOG_WARNING, requirecalltoken_mark_auto(), S_OR, ast_iax2_full_hdr::scallno, send_apathetic_reply(), ast_iax2_full_hdr::ts, uncompress_subclass(), and iax_ies::username.
Referenced by socket_process().
04968 { 04969 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04970 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04971 struct ast_str *buf = ast_str_alloca(256); 04972 time_t t = time(NULL); 04973 char hash[41]; /* 40 char sha1 hash */ 04974 int subclass = uncompress_subclass(fh->csub); 04975 04976 /* ----- Case 1 ----- */ 04977 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04978 struct iax_ie_data ied = { 04979 .buf = { 0 }, 04980 .pos = 0, 04981 }; 04982 04983 /* create the hash with their address data and our timestamp */ 04984 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04985 ast_sha1_hash(hash, ast_str_buffer(buf)); 04986 04987 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04988 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04989 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04990 04991 return 1; 04992 04993 /* ----- Case 2 ----- */ 04994 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04995 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04996 char *rec_ts = NULL; /* received timestamp */ 04997 unsigned int rec_time; /* received time_t */ 04998 04999 /* split the timestamp from the hash data */ 05000 rec_hash = strchr((char *) ies->calltokendata, '?'); 05001 if (rec_hash) { 05002 *rec_hash++ = '\0'; 05003 rec_ts = (char *) ies->calltokendata; 05004 } 05005 05006 /* check that we have valid data before we do any comparisons */ 05007 if (!rec_hash || !rec_ts) { 05008 goto reject; 05009 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 05010 goto reject; 05011 } 05012 05013 /* create a hash with their address and the _TOKEN'S_ timestamp */ 05014 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 05015 ast_sha1_hash(hash, ast_str_buffer(buf)); 05016 05017 /* compare hashes and then check timestamp delay */ 05018 if (strcmp(hash, rec_hash)) { 05019 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 05020 goto reject; /* received hash does not match ours, reject */ 05021 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 05022 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 05023 goto reject; /* too much delay, reject */ 05024 } 05025 05026 /* at this point the call token is valid, returning 0 05027 * will allow socket_process to continue as usual */ 05028 requirecalltoken_mark_auto(ies->username, subclass); 05029 return 0; 05030 05031 /* ----- Case 3 ----- */ 05032 } else { /* calltokens are not supported for this client, how do we respond? */ 05033 if (calltoken_required(sin, ies->username, subclass)) { 05034 ast_log(LOG_ERROR, "Call rejected, CallToken Support required. If unexpected, resolve by placing address %s in the calltokenoptional list or setting user %s requirecalltoken=no\n", ast_inet_ntoa(sin->sin_addr), S_OR(ies->username, "guest")); 05035 goto reject; 05036 } 05037 return 0; /* calltoken is not required for this addr, so permit it. */ 05038 } 05039 05040 reject: 05041 /* received frame has failed calltoken inspection, send apathetic reject messages */ 05042 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 05043 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 05044 } else { 05045 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 05046 } 05047 05048 return 1; 05049 }
static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 12166 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.
12167 { 12168 int force = 0; 12169 int res; 12170 12171 switch (cmd) { 12172 case CLI_INIT: 12173 e->command = "iax2 provision"; 12174 e->usage = 12175 "Usage: iax2 provision <host> <template> [forced]\n" 12176 " Provisions the given peer or IP address using a template\n" 12177 " matching either 'template' or '*' if the template is not\n" 12178 " found. If 'forced' is specified, even empty provisioning\n" 12179 " fields will be provisioned as empty fields.\n"; 12180 return NULL; 12181 case CLI_GENERATE: 12182 if (a->pos == 3) 12183 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 12184 return NULL; 12185 } 12186 12187 if (a->argc < 4) 12188 return CLI_SHOWUSAGE; 12189 if (a->argc > 4) { 12190 if (!strcasecmp(a->argv[4], "forced")) 12191 force = 1; 12192 else 12193 return CLI_SHOWUSAGE; 12194 } 12195 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 12196 if (res < 0) 12197 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 12198 else if (res < 1) 12199 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 12200 else 12201 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 12202 return CLI_SUCCESS; 12203 }
static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3660 of file chan_iax2.c.
References ao2_unlink, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), ast_set_flag64, ast_test_flag64, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), expire_registry(), ast_cli_args::fd, find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, ast_cli_args::line, ast_cli_args::n, peer_ref(), peer_unref(), ast_cli_args::pos, prune_peers(), prune_users(), ast_cli_entry::usage, user_unref(), and ast_cli_args::word.
03661 { 03662 struct iax2_peer *peer = NULL; 03663 struct iax2_user *user = NULL; 03664 static const char * const choices[] = { "all", NULL }; 03665 char *cmplt; 03666 03667 switch (cmd) { 03668 case CLI_INIT: 03669 e->command = "iax2 prune realtime"; 03670 e->usage = 03671 "Usage: iax2 prune realtime [<peername>|all]\n" 03672 " Prunes object(s) from the cache\n"; 03673 return NULL; 03674 case CLI_GENERATE: 03675 if (a->pos == 3) { 03676 cmplt = ast_cli_complete(a->word, choices, a->n); 03677 if (!cmplt) 03678 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03679 return cmplt; 03680 } 03681 return NULL; 03682 } 03683 if (a->argc != 4) 03684 return CLI_SHOWUSAGE; 03685 if (!strcmp(a->argv[3], "all")) { 03686 prune_users(); 03687 prune_peers(); 03688 ast_cli(a->fd, "Cache flushed successfully.\n"); 03689 return CLI_SUCCESS; 03690 } 03691 peer = find_peer(a->argv[3], 0); 03692 user = find_user(a->argv[3]); 03693 if (peer || user) { 03694 if (peer) { 03695 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 03696 ast_set_flag64(peer, IAX_RTAUTOCLEAR); 03697 expire_registry(peer_ref(peer)); 03698 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03699 } else { 03700 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03701 } 03702 peer_unref(peer); 03703 } 03704 if (user) { 03705 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 03706 ast_set_flag64(user, IAX_RTAUTOCLEAR); 03707 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03708 } else { 03709 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03710 } 03711 ao2_unlink(users,user); 03712 user_unref(user); 03713 } 03714 } else { 03715 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03716 } 03717 03718 return CLI_SUCCESS; 03719 }
static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 13791 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
13792 { 13793 switch (cmd) { 13794 case CLI_INIT: 13795 e->command = "iax2 reload"; 13796 e->usage = 13797 "Usage: iax2 reload\n" 13798 " Reloads IAX configuration from iax.conf\n"; 13799 return NULL; 13800 case CLI_GENERATE: 13801 return NULL; 13802 } 13803 13804 reload_config(); 13805 13806 return CLI_SUCCESS; 13807 }
static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7459 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.
07460 { 07461 switch (cmd) { 07462 case CLI_INIT: 07463 e->command = "iax2 set debug {on|off|peer}"; 07464 e->usage = 07465 "Usage: iax2 set debug {on|off|peer peername}\n" 07466 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07467 return NULL; 07468 case CLI_GENERATE: 07469 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07470 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07471 return NULL; 07472 } 07473 07474 if (a->argc < e->args || a->argc > e->args + 1) 07475 return CLI_SHOWUSAGE; 07476 07477 if (!strcasecmp(a->argv[3], "peer")) { 07478 struct iax2_peer *peer; 07479 struct sockaddr_in peer_addr; 07480 07481 07482 if (a->argc != e->args + 1) 07483 return CLI_SHOWUSAGE; 07484 07485 peer = find_peer(a->argv[4], 1); 07486 07487 if (!peer) { 07488 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07489 return CLI_FAILURE; 07490 } 07491 07492 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 07493 07494 debugaddr.sin_addr = peer_addr.sin_addr; 07495 debugaddr.sin_port = peer_addr.sin_port; 07496 07497 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07498 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07499 07500 ao2_ref(peer, -1); 07501 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07502 iaxdebug = 1; 07503 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07504 } else { 07505 iaxdebug = 0; 07506 memset(&debugaddr, 0, sizeof(debugaddr)); 07507 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07508 } 07509 return CLI_SUCCESS; 07510 }
static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7538 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.
07539 { 07540 switch (cmd) { 07541 case CLI_INIT: 07542 e->command = "iax2 set debug jb {on|off}"; 07543 e->usage = 07544 "Usage: iax2 set debug jb {on|off}\n" 07545 " Enables/Disables jitterbuffer debugging information\n"; 07546 return NULL; 07547 case CLI_GENERATE: 07548 return NULL; 07549 } 07550 07551 if (a->argc != e->args) 07552 return CLI_SHOWUSAGE; 07553 07554 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07555 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07556 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07557 } else { 07558 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07559 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07560 } 07561 return CLI_SUCCESS; 07562 }
static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7512 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.
07513 { 07514 switch (cmd) { 07515 case CLI_INIT: 07516 e->command = "iax2 set debug trunk {on|off}"; 07517 e->usage = 07518 "Usage: iax2 set debug trunk {on|off}\n" 07519 " Enables/Disables debugging of IAX trunking\n"; 07520 return NULL; 07521 case CLI_GENERATE: 07522 return NULL; 07523 } 07524 07525 if (a->argc != e->args) 07526 return CLI_SHOWUSAGE; 07527 07528 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07529 iaxtrunkdebug = 1; 07530 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07531 } else { 07532 iaxtrunkdebug = 0; 07533 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07534 } 07535 return CLI_SUCCESS; 07536 }
static char* handle_cli_iax2_set_mtu | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Set trunk MTU from CLI.
Definition at line 3987 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, MAX_TRUNK_MTU, and ast_cli_entry::usage.
03988 { 03989 int mtuv; 03990 03991 switch (cmd) { 03992 case CLI_INIT: 03993 e->command = "iax2 set mtu"; 03994 e->usage = 03995 "Usage: iax2 set mtu <value>\n" 03996 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03997 " zero to disable. Disabling means that the operating system\n" 03998 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03999 " packet exceeds the UDP payload size. This is substantially\n" 04000 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 04001 " greater for G.711 samples.\n"; 04002 return NULL; 04003 case CLI_GENERATE: 04004 return NULL; 04005 } 04006 04007 if (a->argc != 4) 04008 return CLI_SHOWUSAGE; 04009 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 04010 mtuv = MAX_TRUNK_MTU; 04011 else 04012 mtuv = atoi(a->argv[3]); 04013 04014 if (mtuv == 0) { 04015 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 04016 global_max_trunk_mtu = 0; 04017 return CLI_SUCCESS; 04018 } 04019 if (mtuv < 172 || mtuv > 4000) { 04020 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 04021 return CLI_SHOWUSAGE; 04022 } 04023 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 04024 global_max_trunk_mtu = mtuv; 04025 return CLI_SUCCESS; 04026 }
static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 4028 of file chan_iax2.c.
References ARRAY_LEN, ast_cli(), ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_tvnow(), CACHE_FLAG_CANEXIST, CACHE_FLAG_EXISTS, CACHE_FLAG_MATCHMORE, CACHE_FLAG_NONEXISTENT, CACHE_FLAG_PENDING, CACHE_FLAG_TIMEOUT, CACHE_FLAG_TRANSMITTED, CACHE_FLAG_UNKNOWN, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, iax2_dpcache::expiry, iax2_dpcache::exten, ast_cli_args::fd, iax2_dpcache::flags, iax2_dpcache::peercontext, ast_cli_entry::usage, and iax2_dpcache::waiters.
04029 { 04030 struct iax2_dpcache *dp = NULL; 04031 char tmp[1024], *pc = NULL; 04032 int s, x, y; 04033 struct timeval now = ast_tvnow(); 04034 04035 switch (cmd) { 04036 case CLI_INIT: 04037 e->command = "iax2 show cache"; 04038 e->usage = 04039 "Usage: iax2 show cache\n" 04040 " Display currently cached IAX Dialplan results.\n"; 04041 return NULL; 04042 case CLI_GENERATE: 04043 return NULL; 04044 } 04045 04046 AST_LIST_LOCK(&dpcache); 04047 04048 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 04049 04050 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 04051 s = dp->expiry.tv_sec - now.tv_sec; 04052 tmp[0] = '\0'; 04053 if (dp->flags & CACHE_FLAG_EXISTS) 04054 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 04055 if (dp->flags & CACHE_FLAG_NONEXISTENT) 04056 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 04057 if (dp->flags & CACHE_FLAG_CANEXIST) 04058 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 04059 if (dp->flags & CACHE_FLAG_PENDING) 04060 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 04061 if (dp->flags & CACHE_FLAG_TIMEOUT) 04062 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 04063 if (dp->flags & CACHE_FLAG_TRANSMITTED) 04064 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 04065 if (dp->flags & CACHE_FLAG_MATCHMORE) 04066 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 04067 if (dp->flags & CACHE_FLAG_UNKNOWN) 04068 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 04069 /* Trim trailing pipe */ 04070 if (!ast_strlen_zero(tmp)) { 04071 tmp[strlen(tmp) - 1] = '\0'; 04072 } else { 04073 ast_copy_string(tmp, "(none)", sizeof(tmp)); 04074 } 04075 y = 0; 04076 pc = strchr(dp->peercontext, '@'); 04077 if (!pc) { 04078 pc = dp->peercontext; 04079 } else { 04080 pc++; 04081 } 04082 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 04083 if (dp->waiters[x] > -1) 04084 y++; 04085 } 04086 if (s > 0) { 04087 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 04088 } else { 04089 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 04090 } 04091 } 04092 04093 AST_LIST_UNLOCK(&dpcache); 04094 04095 return CLI_SUCCESS; 04096 }
static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2638 of file chan_iax2.c.
References ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_inet_ntoa(), CLI_GENERATE, CLI_HANDLER, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
02639 { 02640 struct ao2_iterator i; 02641 struct peercnt *peercnt; 02642 struct sockaddr_in sin; 02643 int found = 0; 02644 02645 switch (cmd) { 02646 case CLI_INIT: 02647 e->command = "iax2 show callnumber usage"; 02648 e->usage = 02649 "Usage: iax2 show callnumber usage [IP address]\n" 02650 " Shows current IP addresses which are consuming iax2 call numbers\n"; 02651 return NULL; 02652 case CLI_GENERATE: 02653 return NULL; 02654 case CLI_HANDLER: 02655 if (a->argc < 4 || a->argc > 5) 02656 return CLI_SHOWUSAGE; 02657 02658 if (a->argc == 4) { 02659 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02660 } 02661 02662 i = ao2_iterator_init(peercnts, 0); 02663 while ((peercnt = ao2_iterator_next(&i))) { 02664 sin.sin_addr.s_addr = peercnt->addr; 02665 if (a->argc == 5) { 02666 if (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr))) { 02667 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02668 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02669 ao2_ref(peercnt, -1); 02670 found = 1; 02671 break; 02672 } 02673 } else { 02674 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02675 } 02676 ao2_ref(peercnt, -1); 02677 } 02678 ao2_iterator_destroy(&i); 02679 02680 if (a->argc == 4) { 02681 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n" 02682 "Non-CallToken Validated Callno Used: %d\n", 02683 global_maxcallno_nonval, 02684 total_nonval_callno_used); 02685 02686 ast_cli(a->fd, "Total Available Callno: %d\n" 02687 "Regular Callno Available: %d\n" 02688 "Trunk Callno Available: %d\n", 02689 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk), 02690 ao2_container_count(callno_pool), 02691 ao2_container_count(callno_pool_trunk)); 02692 } else if (a->argc == 5 && !found) { 02693 ast_cli(a->fd, "No call number table entries for %s found\n", a->argv[4] ); 02694 } 02695 02696 02697 return CLI_SUCCESS; 02698 default: 02699 return NULL; 02700 } 02701 }
static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7280 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_cli_args::argc, ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, iax2_registry::callno, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, jb_info::current, ast_cli_args::fd, FORMAT, FORMAT2, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, chan_iax2_pvt::owner, S_OR, and ast_cli_entry::usage.
07281 { 07282 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 07283 #define FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" 07284 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 07285 int x; 07286 int numchans = 0; 07287 int usedchans = 0; 07288 char first_message[10] = { 0, }; 07289 char last_message[10] = { 0, }; 07290 07291 switch (cmd) { 07292 case CLI_INIT: 07293 e->command = "iax2 show channels"; 07294 e->usage = 07295 "Usage: iax2 show channels\n" 07296 " Lists all currently active IAX channels.\n"; 07297 return NULL; 07298 case CLI_GENERATE: 07299 return NULL; 07300 } 07301 07302 if (a->argc != 3) 07303 return CLI_SHOWUSAGE; 07304 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 07305 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07306 ast_mutex_lock(&iaxsl[x]); 07307 if (iaxs[x]) { 07308 int lag, jitter, localdelay; 07309 jb_info jbinfo; 07310 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07311 jb_getinfo(iaxs[x]->jb, &jbinfo); 07312 jitter = jbinfo.jitter; 07313 localdelay = jbinfo.current - jbinfo.min; 07314 } else { 07315 jitter = -1; 07316 localdelay = 0; 07317 } 07318 07319 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07320 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07321 lag = iaxs[x]->remote_rr.delay; 07322 ast_cli(a->fd, FORMAT, 07323 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07324 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 07325 S_OR(iaxs[x]->username, "(None)"), 07326 iaxs[x]->callno, iaxs[x]->peercallno, 07327 iaxs[x]->oseqno, iaxs[x]->iseqno, 07328 lag, 07329 jitter, 07330 localdelay, 07331 ast_getformatname(iaxs[x]->voiceformat), 07332 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07333 first_message, 07334 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07335 last_message); 07336 numchans++; 07337 if (iaxs[x]->owner) { /* Count IAX dialog owned by a real channel */ 07338 usedchans++; 07339 } 07340 } 07341 ast_mutex_unlock(&iaxsl[x]); 07342 } 07343 ast_cli(a->fd, "%d active IAX dialog%s\n", numchans, (numchans != 1) ? "s" : ""); 07344 ast_cli(a->fd, "%d used IAX channel%s\n", usedchans, (usedchans != 1) ? "s" : ""); 07345 07346 return CLI_SUCCESS; 07347 #undef FORMAT 07348 #undef FORMAT2 07349 #undef FORMATB 07350 }
static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7066 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.
07067 { 07068 struct iax_firmware *cur = NULL; 07069 07070 switch (cmd) { 07071 case CLI_INIT: 07072 e->command = "iax2 show firmware"; 07073 e->usage = 07074 "Usage: iax2 show firmware\n" 07075 " Lists all known IAX firmware images.\n"; 07076 return NULL; 07077 case CLI_GENERATE: 07078 return NULL; 07079 } 07080 07081 if (a->argc != 3 && a->argc != 4) 07082 return CLI_SHOWUSAGE; 07083 07084 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 07085 AST_LIST_LOCK(&firmwares); 07086 AST_LIST_TRAVERSE(&firmwares, cur, list) { 07087 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 07088 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 07089 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 07090 } 07091 } 07092 AST_LIST_UNLOCK(&firmwares); 07093 07094 return CLI_SUCCESS; 07095 }
static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7436 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.
07437 { 07438 int numchans = 0; 07439 07440 switch (cmd) { 07441 case CLI_INIT: 07442 e->command = "iax2 show netstats"; 07443 e->usage = 07444 "Usage: iax2 show netstats\n" 07445 " Lists network status for all currently active IAX channels.\n"; 07446 return NULL; 07447 case CLI_GENERATE: 07448 return NULL; 07449 } 07450 if (a->argc != 3) 07451 return CLI_SHOWUSAGE; 07452 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 07453 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 07454 numchans = ast_cli_netstats(NULL, a->fd, 1); 07455 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07456 return CLI_SUCCESS; 07457 }
static char* handle_cli_iax2_show_peer | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Show one peer in detail.
Definition at line 3835 of file chan_iax2.c.
References iax2_peer::addr, ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cli(), ast_codec_pref_index(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_sockaddr_to_sin, ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), iax2_peer::defaddr, iax2_peer::encmethods, encmethods_to_str(), iax2_peer::expire, ast_cli_args::fd, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, ast_cli_args::line, iax2_peer::maxcallno, ast_cli_args::n, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::smoothing, status, ast_cli_entry::usage, and ast_cli_args::word.
03836 { 03837 char status[30]; 03838 char cbuf[256]; 03839 struct iax2_peer *peer; 03840 char codec_buf[512]; 03841 struct ast_str *encmethods = ast_str_alloca(256); 03842 int x = 0, codec = 0, load_realtime = 0; 03843 03844 switch (cmd) { 03845 case CLI_INIT: 03846 e->command = "iax2 show peer"; 03847 e->usage = 03848 "Usage: iax2 show peer <name>\n" 03849 " Display details on specific IAX peer\n"; 03850 return NULL; 03851 case CLI_GENERATE: 03852 if (a->pos == 3) 03853 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03854 return NULL; 03855 } 03856 03857 if (a->argc < 4) 03858 return CLI_SHOWUSAGE; 03859 03860 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03861 03862 peer = find_peer(a->argv[3], load_realtime); 03863 if (peer) { 03864 struct sockaddr_in peer_addr; 03865 03866 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 03867 03868 encmethods_to_str(peer->encmethods, &encmethods); 03869 ast_cli(a->fd, "\n\n"); 03870 ast_cli(a->fd, " * Name : %s\n", peer->name); 03871 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03872 ast_cli(a->fd, " Context : %s\n", peer->context); 03873 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03874 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03875 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03876 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03877 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03878 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 03879 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03880 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03881 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03882 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03883 ast_cli(a->fd, " Addr->IP : %s Port %d\n", peer_addr.sin_addr.s_addr ? ast_inet_ntoa(peer_addr.sin_addr) : "(Unspecified)", ntohs(peer_addr.sin_port)); 03884 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03885 ast_cli(a->fd, " Username : %s\n", peer->username); 03886 ast_cli(a->fd, " Codecs : "); 03887 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03888 ast_cli(a->fd, "%s\n", codec_buf); 03889 03890 ast_cli(a->fd, " Codec Order : ("); 03891 for(x = 0; x < 32 ; x++) { 03892 codec = ast_codec_pref_index(&peer->prefs,x); 03893 if(!codec) 03894 break; 03895 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03896 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03897 ast_cli(a->fd, "|"); 03898 } 03899 03900 if (!x) 03901 ast_cli(a->fd, "none"); 03902 ast_cli(a->fd, ")\n"); 03903 03904 ast_cli(a->fd, " Status : "); 03905 peer_status(peer, status, sizeof(status)); 03906 ast_cli(a->fd, "%s\n",status); 03907 ast_cli(a->fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 03908 ast_cli(a->fd, "\n"); 03909 peer_unref(peer); 03910 } else { 03911 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03912 ast_cli(a->fd, "\n"); 03913 } 03914 03915 return CLI_SUCCESS; 03916 }
static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7034 of file chan_iax2.c.
References __iax2_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, RESULT_FAILURE, RESULT_SHOWUSAGE, and ast_cli_entry::usage.
07035 { 07036 switch (cmd) { 07037 case CLI_INIT: 07038 e->command = "iax2 show peers"; 07039 e->usage = 07040 "Usage: iax2 show peers [registered] [like <pattern>]\n" 07041 " Lists all known IAX2 peers.\n" 07042 " Optional 'registered' argument lists only peers with known addresses.\n" 07043 " Optional regular expression pattern is used to filter the peer list.\n"; 07044 return NULL; 07045 case CLI_GENERATE: 07046 return NULL; 07047 } 07048 07049 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) { 07050 case RESULT_SHOWUSAGE: 07051 return CLI_SHOWUSAGE; 07052 case RESULT_FAILURE: 07053 return CLI_FAILURE; 07054 default: 07055 return CLI_SUCCESS; 07056 } 07057 }
static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7189 of file chan_iax2.c.
References iax2_registry::addr, ast_cli_args::argc, ast_cli(), ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.
07190 { 07191 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 07192 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 07193 struct iax2_registry *reg = NULL; 07194 char host[80]; 07195 char perceived[80]; 07196 int counter = 0; 07197 07198 switch (cmd) { 07199 case CLI_INIT: 07200 e->command = "iax2 show registry"; 07201 e->usage = 07202 "Usage: iax2 show registry\n" 07203 " Lists all registration requests and status.\n"; 07204 return NULL; 07205 case CLI_GENERATE: 07206 return NULL; 07207 } 07208 if (a->argc != 3) 07209 return CLI_SHOWUSAGE; 07210 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 07211 AST_LIST_LOCK(®istrations); 07212 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07213 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07214 if (reg->us.sin_addr.s_addr) 07215 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07216 else 07217 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07218 ast_cli(a->fd, FORMAT, host, 07219 (reg->dnsmgr) ? "Y" : "N", 07220 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 07221 counter++; 07222 } 07223 AST_LIST_UNLOCK(®istrations); 07224 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 07225 return CLI_SUCCESS; 07226 #undef FORMAT 07227 #undef FORMAT2 07228 }
static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3941 of file chan_iax2.c.
References ast_cli_args::argc, ARRAY_LEN, ast_cli(), AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, iax_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxsl, iax_frame::retries, and ast_cli_entry::usage.
03942 { 03943 struct iax_frame *cur; 03944 int cnt = 0, dead = 0, final = 0, i = 0; 03945 03946 switch (cmd) { 03947 case CLI_INIT: 03948 e->command = "iax2 show stats"; 03949 e->usage = 03950 "Usage: iax2 show stats\n" 03951 " Display statistics on IAX channel driver.\n"; 03952 return NULL; 03953 case CLI_GENERATE: 03954 return NULL; 03955 } 03956 03957 if (a->argc != 3) 03958 return CLI_SHOWUSAGE; 03959 03960 for (i = 0; i < ARRAY_LEN(frame_queue); i++) { 03961 ast_mutex_lock(&iaxsl[i]); 03962 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) { 03963 if (cur->retries < 0) 03964 dead++; 03965 if (cur->final) 03966 final++; 03967 cnt++; 03968 } 03969 ast_mutex_unlock(&iaxsl[i]); 03970 } 03971 03972 ast_cli(a->fd, " IAX Statistics\n"); 03973 ast_cli(a->fd, "---------------------\n"); 03974 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03975 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03976 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03977 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03978 03979 trunk_timed = trunk_untimed = 0; 03980 if (trunk_maxmtu > trunk_nmaxmtu) 03981 trunk_nmaxmtu = trunk_maxmtu; 03982 03983 return CLI_SUCCESS; 03984 }
static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6896 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, thread, and ast_cli_entry::usage.
06897 { 06898 struct iax2_thread *thread = NULL; 06899 time_t t; 06900 int threadcount = 0, dynamiccount = 0; 06901 char type; 06902 06903 switch (cmd) { 06904 case CLI_INIT: 06905 e->command = "iax2 show threads"; 06906 e->usage = 06907 "Usage: iax2 show threads\n" 06908 " Lists status of IAX helper threads\n"; 06909 return NULL; 06910 case CLI_GENERATE: 06911 return NULL; 06912 } 06913 if (a->argc != 3) 06914 return CLI_SHOWUSAGE; 06915 06916 ast_cli(a->fd, "IAX2 Thread Information\n"); 06917 time(&t); 06918 ast_cli(a->fd, "Idle Threads:\n"); 06919 AST_LIST_LOCK(&idle_list); 06920 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06921 #ifdef DEBUG_SCHED_MULTITHREAD 06922 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n", 06923 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06924 #else 06925 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n", 06926 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06927 #endif 06928 threadcount++; 06929 } 06930 AST_LIST_UNLOCK(&idle_list); 06931 ast_cli(a->fd, "Active Threads:\n"); 06932 AST_LIST_LOCK(&active_list); 06933 AST_LIST_TRAVERSE(&active_list, thread, list) { 06934 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06935 type = 'D'; 06936 else 06937 type = 'P'; 06938 #ifdef DEBUG_SCHED_MULTITHREAD 06939 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d, func='%s'\n", 06940 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06941 #else 06942 ast_cli(a->fd, "Thread %c%d: state=%u, update=%d, actions=%d\n", 06943 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06944 #endif 06945 threadcount++; 06946 } 06947 AST_LIST_UNLOCK(&active_list); 06948 ast_cli(a->fd, "Dynamic Threads:\n"); 06949 AST_LIST_LOCK(&dynamic_list); 06950 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06951 #ifdef DEBUG_SCHED_MULTITHREAD 06952 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d, func='%s'\n", 06953 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06954 #else 06955 ast_cli(a->fd, "Thread %d: state=%u, update=%d, actions=%d\n", 06956 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06957 #endif 06958 dynamiccount++; 06959 } 06960 AST_LIST_UNLOCK(&dynamic_list); 06961 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06962 return CLI_SUCCESS; 06963 }
static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6687 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_strlen_zero(), ast_test_flag64, iax2_user::authmethods, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, ast_cli_entry::usage, and user_unref().
06688 { 06689 regex_t regexbuf; 06690 int havepattern = 0; 06691 06692 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06693 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06694 06695 struct iax2_user *user = NULL; 06696 char auth[90]; 06697 char *pstr = ""; 06698 struct ao2_iterator i; 06699 06700 switch (cmd) { 06701 case CLI_INIT: 06702 e->command = "iax2 show users [like]"; 06703 e->usage = 06704 "Usage: iax2 show users [like <pattern>]\n" 06705 " Lists all known IAX2 users.\n" 06706 " Optional regular expression pattern is used to filter the user list.\n"; 06707 return NULL; 06708 case CLI_GENERATE: 06709 return NULL; 06710 } 06711 06712 switch (a->argc) { 06713 case 5: 06714 if (!strcasecmp(a->argv[3], "like")) { 06715 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06716 return CLI_SHOWUSAGE; 06717 havepattern = 1; 06718 } else 06719 return CLI_SHOWUSAGE; 06720 case 3: 06721 break; 06722 default: 06723 return CLI_SHOWUSAGE; 06724 } 06725 06726 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06727 i = ao2_iterator_init(users, 0); 06728 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 06729 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06730 continue; 06731 06732 if (!ast_strlen_zero(user->secret)) { 06733 ast_copy_string(auth,user->secret, sizeof(auth)); 06734 } else if (!ast_strlen_zero(user->inkeys)) { 06735 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06736 } else 06737 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06738 06739 if(ast_test_flag64(user, IAX_CODEC_NOCAP)) 06740 pstr = "REQ Only"; 06741 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS)) 06742 pstr = "Disabled"; 06743 else 06744 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06745 06746 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06747 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06748 user->ha ? "Yes" : "No", pstr); 06749 } 06750 ao2_iterator_destroy(&i); 06751 06752 if (havepattern) 06753 regfree(®exbuf); 06754 06755 return CLI_SUCCESS; 06756 #undef FORMAT 06757 #undef FORMAT2 06758 }
static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3721 of file chan_iax2.c.
References ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, and ast_cli_entry::usage.
03722 { 03723 switch (cmd) { 03724 case CLI_INIT: 03725 e->command = "iax2 test losspct"; 03726 e->usage = 03727 "Usage: iax2 test losspct <percentage>\n" 03728 " For testing, throws away <percentage> percent of incoming packets\n"; 03729 return NULL; 03730 case CLI_GENERATE: 03731 return NULL; 03732 } 03733 if (a->argc != 4) 03734 return CLI_SHOWUSAGE; 03735 03736 test_losspct = atoi(a->argv[3]); 03737 03738 return CLI_SUCCESS; 03739 }
static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6965 of file chan_iax2.c.
References ao2_find, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_unregister(), iax2_peer::expire, expire_registry(), ast_cli_args::fd, find_peer(), ast_cli_args::line, ast_cli_args::n, OBJ_POINTER, peer_ref(), peer_unref(), ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
06966 { 06967 struct iax2_peer *p; 06968 06969 switch (cmd) { 06970 case CLI_INIT: 06971 e->command = "iax2 unregister"; 06972 e->usage = 06973 "Usage: iax2 unregister <peername>\n" 06974 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06975 return NULL; 06976 case CLI_GENERATE: 06977 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06978 } 06979 06980 if (a->argc != 3) 06981 return CLI_SHOWUSAGE; 06982 06983 p = find_peer(a->argv[2], 1); 06984 if (p) { 06985 if (p->expire > 0) { 06986 struct iax2_peer tmp_peer = { 06987 .name = a->argv[2], 06988 }; 06989 struct iax2_peer *peer; 06990 06991 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06992 if (peer) { 06993 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06994 peer_unref(peer); /* ref from ao2_find() */ 06995 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06996 } else { 06997 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06998 } 06999 } else { 07000 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 07001 } 07002 peer_unref(p); 07003 } else { 07004 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 07005 } 07006 return CLI_SUCCESS; 07007 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9676 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().
09677 { 09678 struct iax2_pkt_buf *pkt_buf; 09679 09680 ast_mutex_lock(&thread->lock); 09681 09682 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09683 ast_mutex_unlock(&thread->lock); 09684 09685 thread->buf = pkt_buf->buf; 09686 thread->buf_len = pkt_buf->len; 09687 thread->buf_size = pkt_buf->len + 1; 09688 09689 socket_process(thread); 09690 09691 thread->buf = NULL; 09692 ast_free(pkt_buf); 09693 09694 ast_mutex_lock(&thread->lock); 09695 } 09696 09697 ast_mutex_unlock(&thread->lock); 09698 }
static int handle_error | ( | void | ) | [static] |
Definition at line 3371 of file chan_iax2.c.
References ast_inet_ntoa(), ast_log(), errno, LOG_WARNING, and netsocket.
Referenced by send_packet(), socket_read(), and transmit_trunk().
03372 { 03373 /* XXX Ideally we should figure out why an error occurred and then abort those 03374 rather than continuing to try. Unfortunately, the published interface does 03375 not seem to work XXX */ 03376 #if 0 03377 struct sockaddr_in *sin; 03378 int res; 03379 struct msghdr m; 03380 struct sock_extended_err e; 03381 m.msg_name = NULL; 03382 m.msg_namelen = 0; 03383 m.msg_iov = NULL; 03384 m.msg_control = &e; 03385 m.msg_controllen = sizeof(e); 03386 m.msg_flags = 0; 03387 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03388 if (res < 0) 03389 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03390 else { 03391 if (m.msg_controllen) { 03392 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03393 if (sin) 03394 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03395 else 03396 ast_log(LOG_WARNING, "No address detected??\n"); 03397 } else { 03398 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03399 } 03400 } 03401 #endif 03402 return 0; 03403 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 8567 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().
08568 { 08569 struct iax2_registry *reg; 08570 /* Start pessimistic */ 08571 char peer[256] = ""; 08572 char msgstatus[60]; 08573 int refresh = 60; 08574 char ourip[256] = "<Unspecified>"; 08575 struct sockaddr_in oldus; 08576 struct sockaddr_in us; 08577 int oldmsgs; 08578 struct sockaddr_in reg_addr; 08579 08580 memset(&us, 0, sizeof(us)); 08581 if (ies->apparent_addr) { 08582 memmove(&us, ies->apparent_addr, sizeof(us)); 08583 } 08584 if (ies->username) { 08585 ast_copy_string(peer, ies->username, sizeof(peer)); 08586 } 08587 if (ies->refresh) { 08588 refresh = ies->refresh; 08589 } 08590 if (ies->calling_number) { 08591 /* We don't do anything with it really, but maybe we should */ 08592 } 08593 reg = iaxs[callno]->reg; 08594 if (!reg) { 08595 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08596 return -1; 08597 } 08598 memcpy(&oldus, ®->us, sizeof(oldus)); 08599 oldmsgs = reg->messages; 08600 ast_sockaddr_to_sin(®->addr, ®_addr); 08601 if (inaddrcmp(®_addr, sin)) { 08602 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08603 return -1; 08604 } 08605 memcpy(®->us, &us, sizeof(reg->us)); 08606 if (ies->msgcount >= 0) { 08607 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08608 } 08609 /* always refresh the registration at the interval requested by the server 08610 we are registering to 08611 */ 08612 reg->refresh = refresh; 08613 reg->expire = iax2_sched_replace(reg->expire, sched, 08614 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08615 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08616 if (reg->messages > 255) { 08617 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08618 } else if (reg->messages > 1) { 08619 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages); 08620 } else if (reg->messages > 0) { 08621 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus)); 08622 } else { 08623 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus)); 08624 } 08625 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08626 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08627 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08628 } 08629 reg->regstate = REG_STATE_REGISTERED; 08630 return 0; 08631 }
static int attribute_pure iax2_allow_new | ( | int | frametype, | |
int | subclass, | |||
int | inbound | |||
) | [inline, static] |
Definition at line 2839 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_FWDOWNL, IAX_COMMAND_NEW, IAX_COMMAND_POKE, IAX_COMMAND_REGREL, and IAX_COMMAND_REGREQ.
Referenced by resend_with_token(), and socket_process().
02840 { 02841 if (frametype != AST_FRAME_IAX) { 02842 return 0; 02843 } 02844 switch (subclass) { 02845 case IAX_COMMAND_NEW: 02846 case IAX_COMMAND_REGREQ: 02847 case IAX_COMMAND_FWDOWNL: 02848 case IAX_COMMAND_REGREL: 02849 return 1; 02850 case IAX_COMMAND_POKE: 02851 if (!inbound) { 02852 return 1; 02853 } 02854 break; 02855 } 02856 return 0; 02857 }
static void iax2_ami_channelupdate | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers.
Definition at line 1406 of file chan_iax2.c.
References chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, chan_iax2_pvt::owner, and chan_iax2_pvt::peercallno.
Referenced by ast_iax2_new(), and iax2_answer().
01407 { 01408 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01409 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01410 pvt->owner ? pvt->owner->name : "", 01411 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01412 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5732 of file chan_iax2.c.
References AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, ast_mutex_lock, ast_mutex_unlock, iax2_ami_channelupdate(), iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05733 { 05734 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05735 ast_debug(1, "Answering IAX2 call\n"); 05736 ast_mutex_lock(&iaxsl[callno]); 05737 if (iaxs[callno]) 05738 iax2_ami_channelupdate(iaxs[callno]); 05739 ast_mutex_unlock(&iaxsl[callno]); 05740 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05741 }
static int iax2_append_register | ( | const char * | hostname, | |
const char * | username, | |||
const char * | secret, | |||
const char * | porta | |||
) | [static] |
Definition at line 8633 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().
08635 { 08636 struct iax2_registry *reg; 08637 08638 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08639 return -1; 08640 08641 reg->addr.ss.ss_family = AF_INET; 08642 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08643 ast_free(reg); 08644 return -1; 08645 } 08646 08647 ast_copy_string(reg->username, username, sizeof(reg->username)); 08648 08649 if (secret) 08650 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08651 08652 reg->expire = -1; 08653 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08654 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); 08655 08656 AST_LIST_LOCK(®istrations); 08657 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08658 AST_LIST_UNLOCK(®istrations); 08659 08660 return 0; 08661 }
static enum ast_bridge_result iax2_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
int | timeoutms | |||
) | [static] |
Definition at line 5561 of file chan_iax2.c.
References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname_multiple(), ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag64, ast_tvnow(), ast_tvzero(), ast_verb, ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, f, ast_frame::frametype, iax2_start_transfer(), iax2_tech, IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, iaxs, iaxsl, ast_frame_subclass::integer, lock_both(), LOG_WARNING, ast_channel::nativeformats, PTR_TO_CALLNO, ast_frame::subclass, ast_channel::tech, ast_channel::tech_pvt, TRANSFER_RELEASED, and unlock_both().
05562 { 05563 struct ast_channel *cs[3]; 05564 struct ast_channel *who, *other; 05565 int to = -1; 05566 int res = -1; 05567 int transferstarted=0; 05568 struct ast_frame *f; 05569 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05570 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05571 struct timeval waittimer = {0, 0}; 05572 05573 /* We currently do not support native bridging if a timeoutms value has been provided */ 05574 if (timeoutms > 0) { 05575 return AST_BRIDGE_FAILED; 05576 } 05577 05578 timeoutms = -1; 05579 05580 lock_both(callno0, callno1); 05581 if (!iaxs[callno0] || !iaxs[callno1]) { 05582 unlock_both(callno0, callno1); 05583 return AST_BRIDGE_FAILED; 05584 } 05585 /* Put them in native bridge mode */ 05586 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05587 iaxs[callno0]->bridgecallno = callno1; 05588 iaxs[callno1]->bridgecallno = callno0; 05589 } 05590 unlock_both(callno0, callno1); 05591 05592 /* If not, try to bridge until we can execute a transfer, if we can */ 05593 cs[0] = c0; 05594 cs[1] = c1; 05595 for (/* ever */;;) { 05596 /* Check in case we got masqueraded into */ 05597 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05598 ast_verb(3, "Can't masquerade, we're different...\n"); 05599 /* Remove from native mode */ 05600 if (c0->tech == &iax2_tech) { 05601 ast_mutex_lock(&iaxsl[callno0]); 05602 iaxs[callno0]->bridgecallno = 0; 05603 ast_mutex_unlock(&iaxsl[callno0]); 05604 } 05605 if (c1->tech == &iax2_tech) { 05606 ast_mutex_lock(&iaxsl[callno1]); 05607 iaxs[callno1]->bridgecallno = 0; 05608 ast_mutex_unlock(&iaxsl[callno1]); 05609 } 05610 return AST_BRIDGE_FAILED_NOWARN; 05611 } 05612 if (c0->nativeformats != c1->nativeformats) { 05613 char buf0[256]; 05614 char buf1[256]; 05615 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats); 05616 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats); 05617 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1); 05618 /* Remove from native mode */ 05619 lock_both(callno0, callno1); 05620 if (iaxs[callno0]) 05621 iaxs[callno0]->bridgecallno = 0; 05622 if (iaxs[callno1]) 05623 iaxs[callno1]->bridgecallno = 0; 05624 unlock_both(callno0, callno1); 05625 return AST_BRIDGE_FAILED_NOWARN; 05626 } 05627 /* check if transferred and if we really want native bridging */ 05628 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) { 05629 /* Try the transfer */ 05630 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05631 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA))) 05632 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05633 transferstarted = 1; 05634 } 05635 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05636 /* Call has been transferred. We're no longer involved */ 05637 struct timeval now = ast_tvnow(); 05638 if (ast_tvzero(waittimer)) { 05639 waittimer = now; 05640 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05641 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05642 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05643 *fo = NULL; 05644 *rc = c0; 05645 res = AST_BRIDGE_COMPLETE; 05646 break; 05647 } 05648 } 05649 to = 1000; 05650 who = ast_waitfor_n(cs, 2, &to); 05651 /* XXX This will need to be updated to calculate 05652 * timeout correctly once timeoutms is allowed to be 05653 * > 0. Right now, this can go badly if the waitfor 05654 * times out in less than a millisecond 05655 */ 05656 if (timeoutms > -1) { 05657 timeoutms -= (1000 - to); 05658 if (timeoutms < 0) 05659 timeoutms = 0; 05660 } 05661 if (!who) { 05662 if (!timeoutms) { 05663 res = AST_BRIDGE_RETRY; 05664 break; 05665 } 05666 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05667 res = AST_BRIDGE_FAILED; 05668 break; 05669 } 05670 continue; 05671 } 05672 f = ast_read(who); 05673 if (!f) { 05674 *fo = NULL; 05675 *rc = who; 05676 res = AST_BRIDGE_COMPLETE; 05677 break; 05678 } 05679 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05680 if (f->frametype == AST_FRAME_CONTROL && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 05681 switch (f->subclass.integer) { 05682 case AST_CONTROL_VIDUPDATE: 05683 case AST_CONTROL_SRCUPDATE: 05684 case AST_CONTROL_SRCCHANGE: 05685 case AST_CONTROL_T38_PARAMETERS: 05686 ast_write(other, f); 05687 break; 05688 default: 05689 *fo = f; 05690 *rc = who; 05691 res = AST_BRIDGE_COMPLETE; 05692 break; 05693 } 05694 if (res == AST_BRIDGE_COMPLETE) { 05695 break; 05696 } 05697 } else if (f->frametype == AST_FRAME_VOICE 05698 || f->frametype == AST_FRAME_TEXT 05699 || f->frametype == AST_FRAME_VIDEO 05700 || f->frametype == AST_FRAME_IMAGE) { 05701 ast_write(other, f); 05702 } else if (f->frametype == AST_FRAME_DTMF) { 05703 /* monitored dtmf take out of the bridge. 05704 * check if we monitor the specific source. 05705 */ 05706 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05707 05708 if (flags & monitored_source) { 05709 *rc = who; 05710 *fo = f; 05711 res = AST_BRIDGE_COMPLETE; 05712 /* Remove from native mode */ 05713 break; 05714 } 05715 ast_write(other, f); 05716 } 05717 ast_frfree(f); 05718 /* Swap who gets priority */ 05719 cs[2] = cs[0]; 05720 cs[0] = cs[1]; 05721 cs[1] = cs[2]; 05722 } 05723 lock_both(callno0, callno1); 05724 if(iaxs[callno0]) 05725 iaxs[callno0]->bridgecallno = 0; 05726 if(iaxs[callno1]) 05727 iaxs[callno1]->bridgecallno = 0; 05728 unlock_both(callno0, callno1); 05729 return res; 05730 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 5109 of file chan_iax2.c.
References ast_channel::_state, add_empty_calltoken_ie(), create_addr_info::adsi, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_party_connected_line::ani, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, ast_channel_datastore_find(), ast_copy_string(), ast_debug, AST_FRAME_IAX, AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_party_id_presentation(), AST_PRES_NUMBER_NOT_AVAILABLE, ast_setstate(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag64, ast_var_name(), ast_var_value(), auto_congest(), iax_ie_data::buf, CALLNO_TO_PTR, capability, ast_channel::connected, context, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), ast_datastore::data, ast_channel::dialed, chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, ast_party_redirecting::from, ast_channel::hangupcause, iax2_datetime(), iax2_sched_add(), iax2_variable_datastore_info, IAX_COMMAND_NEW, IAX_FORCE_ENCRYPT, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_raw(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_AUTOANSWER, IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CALLING_ANI, IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_CALLINGPRES, IAX_IE_CALLINGTNS, IAX_IE_CALLINGTON, IAX_IE_CAPABILITY, IAX_IE_CAPABILITY2, IAX_IE_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_LANGUAGE, IAX_IE_OSPTOKEN, IAX_IE_RDNIS, IAX_IE_USERNAME, IAX_IE_VARIABLE, IAX_IE_VERSION, IAX_MAX_OSPBLOCK_SIZE, IAX_MAX_OSPTOKEN_SIZE, IAX_PROTO_VERSION, IAX_SENDANI, iaxs, iaxsl, ast_party_connected_line::id, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_party_id::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, pbx_builtin_getvar_helper(), parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, ast_party_number::plan, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, ast_channel::redirecting, secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, create_addr_info::timezone, ast_party_dialed::transit_network_select, create_addr_info::username, parsed_dial_string::username, ast_party_name::valid, ast_party_number::valid, and var.
05110 { 05111 struct sockaddr_in sin; 05112 char *l=NULL, *n=NULL, *tmpstr; 05113 struct iax_ie_data ied; 05114 char *defaultrdest = "s"; 05115 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05116 struct parsed_dial_string pds; 05117 struct create_addr_info cai; 05118 struct ast_var_t *var; 05119 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 05120 const char* osp_token_ptr; 05121 unsigned int osp_token_length; 05122 unsigned char osp_block_index; 05123 unsigned int osp_block_length; 05124 unsigned char osp_buffer[256]; 05125 05126 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 05127 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 05128 return -1; 05129 } 05130 05131 memset(&cai, 0, sizeof(cai)); 05132 cai.encmethods = iax2_encryption; 05133 05134 memset(&pds, 0, sizeof(pds)); 05135 tmpstr = ast_strdupa(dest); 05136 parse_dial_string(tmpstr, &pds); 05137 05138 if (ast_strlen_zero(pds.peer)) { 05139 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 05140 return -1; 05141 } 05142 if (!pds.exten) { 05143 pds.exten = defaultrdest; 05144 } 05145 if (create_addr(pds.peer, c, &sin, &cai)) { 05146 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 05147 return -1; 05148 } 05149 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) { 05150 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n"); 05151 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05152 return -1; 05153 } 05154 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 05155 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 05156 return -1; 05157 } 05158 if (!pds.username && !ast_strlen_zero(cai.username)) 05159 pds.username = cai.username; 05160 if (!pds.password && !ast_strlen_zero(cai.secret)) 05161 pds.password = cai.secret; 05162 if (!pds.key && !ast_strlen_zero(cai.outkey)) 05163 pds.key = cai.outkey; 05164 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 05165 pds.context = cai.peercontext; 05166 05167 /* Keep track of the context for outgoing calls too */ 05168 ast_copy_string(c->context, cai.context, sizeof(c->context)); 05169 05170 if (pds.port) 05171 sin.sin_port = htons(atoi(pds.port)); 05172 05173 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL; 05174 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL; 05175 05176 /* Now build request */ 05177 memset(&ied, 0, sizeof(ied)); 05178 05179 /* On new call, first IE MUST be IAX version of caller */ 05180 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 05181 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 05182 if (pds.options && strchr(pds.options, 'a')) { 05183 /* Request auto answer */ 05184 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 05185 } 05186 05187 /* WARNING: this breaks down at 190 bits! */ 05188 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 05189 05190 if (l) { 05191 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 05192 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05193 ast_party_id_presentation(&c->connected.id)); 05194 } else if (n) { 05195 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05196 ast_party_id_presentation(&c->connected.id)); 05197 } else { 05198 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 05199 } 05200 05201 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan); 05202 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select); 05203 05204 if (n) 05205 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 05206 if (ast_test_flag64(iaxs[callno], IAX_SENDANI) 05207 && c->connected.ani.number.valid 05208 && c->connected.ani.number.str) { 05209 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str); 05210 } 05211 05212 if (!ast_strlen_zero(c->language)) 05213 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 05214 if (!ast_strlen_zero(c->dialed.number.str)) { 05215 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str); 05216 } 05217 if (c->redirecting.from.number.valid 05218 && !ast_strlen_zero(c->redirecting.from.number.str)) { 05219 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str); 05220 } 05221 05222 if (pds.context) 05223 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 05224 05225 if (pds.username) 05226 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 05227 05228 if (cai.encmethods) 05229 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 05230 05231 ast_mutex_lock(&iaxsl[callno]); 05232 05233 if (!ast_strlen_zero(c->context)) 05234 ast_string_field_set(iaxs[callno], context, c->context); 05235 05236 if (pds.username) 05237 ast_string_field_set(iaxs[callno], username, pds.username); 05238 05239 iaxs[callno]->encmethods = cai.encmethods; 05240 05241 iaxs[callno]->adsi = cai.adsi; 05242 05243 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 05244 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 05245 05246 if (pds.key) 05247 ast_string_field_set(iaxs[callno], outkey, pds.key); 05248 if (pds.password) 05249 ast_string_field_set(iaxs[callno], secret, pds.password); 05250 05251 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats); 05252 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats); 05253 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability); 05254 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability); 05255 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 05256 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 05257 05258 if (iaxs[callno]->maxtime) { 05259 /* Initialize pingtime and auto-congest time */ 05260 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 05261 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 05262 } else if (autokill) { 05263 iaxs[callno]->pingtime = autokill / 2; 05264 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 05265 } 05266 05267 /* Check if there is an OSP token */ 05268 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 05269 if (!ast_strlen_zero(osp_token_ptr)) { 05270 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 05271 osp_block_index = 0; 05272 while (osp_token_length > 0) { 05273 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 05274 osp_buffer[0] = osp_block_index; 05275 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 05276 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 05277 osp_block_index++; 05278 osp_token_ptr += osp_block_length; 05279 osp_token_length -= osp_block_length; 05280 } 05281 } else 05282 ast_log(LOG_WARNING, "OSP token is too long\n"); 05283 } else if (iaxdebug) 05284 ast_debug(1, "OSP token is undefined\n"); 05285 05286 /* send the command using the appropriate socket for this peer */ 05287 iaxs[callno]->sockfd = cai.sockfd; 05288 05289 /* Add remote vars */ 05290 if (variablestore) { 05291 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 05292 ast_debug(1, "Found an IAX variable store on this channel\n"); 05293 AST_LIST_LOCK(variablelist); 05294 AST_LIST_TRAVERSE(variablelist, var, entries) { 05295 char tmp[256]; 05296 int i; 05297 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 05298 /* Automatically divide the value up into sized chunks */ 05299 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 05300 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 05301 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 05302 } 05303 } 05304 AST_LIST_UNLOCK(variablelist); 05305 } 05306 05307 /* Transmit the string in a "NEW" request */ 05308 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 05309 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 05310 05311 ast_mutex_unlock(&iaxsl[callno]); 05312 ast_setstate(c, AST_STATE_RINGING); 05313 05314 return 0; 05315 }
static int iax2_canmatch | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
part of the IAX2 dial plan switch interface
Definition at line 14043 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.
14044 { 14045 int res = 0; 14046 struct iax2_dpcache *dp = NULL; 14047 #if 0 14048 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 14049 #endif 14050 if ((priority != 1) && (priority != 2)) 14051 return 0; 14052 14053 AST_LIST_LOCK(&dpcache); 14054 if ((dp = find_cache(chan, data, context, exten, priority))) { 14055 if (dp->flags & CACHE_FLAG_CANEXIST) 14056 res = 1; 14057 } else { 14058 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 14059 } 14060 AST_LIST_UNLOCK(&dpcache); 14061 14062 return res; 14063 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4780 of file chan_iax2.c.
References ast_localtime(), ast_strlen_zero(), ast_tvnow(), ast_tm::tm_hour, ast_tm::tm_mday, ast_tm::tm_min, ast_tm::tm_mon, ast_tm::tm_sec, and ast_tm::tm_year.
Referenced by iax2_call(), and update_registry().
04781 { 04782 struct timeval t = ast_tvnow(); 04783 struct ast_tm tm; 04784 unsigned int tmp; 04785 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04786 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04787 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04788 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04789 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04790 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04791 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04792 return tmp; 04793 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3475 of file chan_iax2.c.
References ao2_ref, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iax2_destroy_helper(), iaxs, iaxsl, chan_iax2_pvt::owner, chan_iax2_pvt::peercallno, remove_by_peercallno(), remove_by_transfercallno(), chan_iax2_pvt::transfercallno, and update_max_trunk.
Referenced by __attempt_transmit(), __iax2_poke_noanswer(), __unload_module(), delete_users(), iax2_do_register(), iax2_hangup(), iax2_poke_peer(), peer_destructor(), scheduled_destroy(), and socket_process().
03476 { 03477 struct chan_iax2_pvt *pvt = NULL; 03478 struct ast_channel *owner = NULL; 03479 03480 retry: 03481 if ((pvt = iaxs[callno])) { 03482 #if 0 03483 /* iax2_destroy_helper gets called from this function later on. When 03484 * called twice, we get the (previously) familiar FRACK! errors in 03485 * devmode, from the scheduler. An alternative to this approach is to 03486 * reset the scheduler entries to -1 when they're deleted in 03487 * iax2_destroy_helper(). That approach was previously decided to be 03488 * "wrong" because "the memory is going to be deallocated anyway. Why 03489 * should we be resetting those values?" */ 03490 iax2_destroy_helper(pvt); 03491 #endif 03492 } 03493 03494 owner = pvt ? pvt->owner : NULL; 03495 03496 if (owner) { 03497 if (ast_channel_trylock(owner)) { 03498 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03499 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03500 goto retry; 03501 } 03502 } 03503 03504 if (!owner) { 03505 iaxs[callno] = NULL; 03506 } 03507 03508 if (pvt) { 03509 if (!owner) { 03510 pvt->owner = NULL; 03511 } else { 03512 /* If there's an owner, prod it to give up */ 03513 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03514 * because we already hold the owner channel lock. */ 03515 ast_queue_hangup(owner); 03516 } 03517 03518 if (pvt->peercallno) { 03519 remove_by_peercallno(pvt); 03520 } 03521 03522 if (pvt->transfercallno) { 03523 remove_by_transfercallno(pvt); 03524 } 03525 03526 if (!owner) { 03527 ao2_ref(pvt, -1); 03528 pvt = NULL; 03529 } 03530 } 03531 03532 if (owner) { 03533 ast_channel_unlock(owner); 03534 } 03535 03536 if (callno & TRUNK_CALL_START) { 03537 update_max_trunk(); 03538 } 03539 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1854 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag64, AST_SCHED_DEL_SPINLOCK, ast_sched_thread_del, ast_sched_thread_get_context(), ast_test_flag64, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, iax2_user::curauthreq, DONT_RESCHEDULE, IAX_MAXAUTHREQ, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, OBJ_POINTER, chan_iax2_pvt::pingid, and user_unref().
Referenced by iax2_destroy(), iax2_predestroy(), pvt_destructor(), and stop_stuff().
01855 { 01856 /* Decrement AUTHREQ count if needed */ 01857 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) { 01858 struct iax2_user *user; 01859 struct iax2_user tmp_user = { 01860 .name = pvt->username, 01861 }; 01862 01863 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01864 if (user) { 01865 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01866 user_unref(user); 01867 } 01868 01869 ast_clear_flag64(pvt, IAX_MAXAUTHREQ); 01870 } 01871 /* No more pings or lagrq's */ 01872 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]); 01873 pvt->pingid = DONT_RESCHEDULE; 01874 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]); 01875 pvt->lagid = DONT_RESCHEDULE; 01876 ast_sched_thread_del(sched, pvt->autoid); 01877 ast_sched_thread_del(sched, pvt->authid); 01878 ast_sched_thread_del(sched, pvt->initid); 01879 ast_sched_thread_del(sched, pvt->jbid); 01880 ast_sched_thread_del(sched, pvt->keyrotateid); 01881 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 14250 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().
14251 { 14252 struct parsed_dial_string pds; 14253 char *tmp = ast_strdupa(data); 14254 struct iax2_peer *p; 14255 int res = AST_DEVICE_INVALID; 14256 14257 memset(&pds, 0, sizeof(pds)); 14258 parse_dial_string(tmp, &pds); 14259 14260 if (ast_strlen_zero(pds.peer)) { 14261 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 14262 return res; 14263 } 14264 14265 ast_debug(3, "Checking device state for device %s\n", pds.peer); 14266 14267 /* SLD: FIXME: second call to find_peer during registration */ 14268 if (!(p = find_peer(pds.peer, 1))) 14269 return res; 14270 14271 res = AST_DEVICE_UNAVAILABLE; 14272 ast_debug(3, "Found peer. What's device state of %s? addr=%u, defaddr=%u maxms=%d, lastms=%d\n", 14273 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 14274 14275 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) && 14276 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 14277 /* Peer is registered, or have default IP address 14278 and a valid registration */ 14279 if (p->historicms == 0 || p->historicms <= p->maxms) 14280 /* let the core figure out whether it is in use or not */ 14281 res = AST_DEVICE_UNKNOWN; 14282 } 14283 14284 peer_unref(p); 14285 14286 return res; 14287 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 4381 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04382 { 04383 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04384 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 4386 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04387 { 04388 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04389 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 12024 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().
12025 { 12026 struct iax_ie_data ied; 12027 if (iaxdebug) 12028 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 12029 12030 if (reg->dnsmgr && 12031 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) { 12032 /* Maybe the IP has changed, force DNS refresh */ 12033 ast_dnsmgr_refresh(reg->dnsmgr); 12034 } 12035 12036 /* 12037 * if IP has Changed, free allocated call to create a new one with new IP 12038 * call has the pointer to IP and must be updated to the new one 12039 */ 12040 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 12041 int callno = reg->callno; 12042 ast_mutex_lock(&iaxsl[callno]); 12043 iax2_destroy(callno); 12044 ast_mutex_unlock(&iaxsl[callno]); 12045 reg->callno = 0; 12046 } 12047 if (!ast_sockaddr_ipv4(®->addr)) { 12048 if (iaxdebug) 12049 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 12050 /* Setup the next registration attempt */ 12051 reg->expire = iax2_sched_replace(reg->expire, sched, 12052 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 12053 return -1; 12054 } 12055 12056 if (!reg->callno) { 12057 struct sockaddr_in reg_addr; 12058 12059 ast_debug(3, "Allocate call number\n"); 12060 12061 ast_sockaddr_to_sin(®->addr, ®_addr); 12062 12063 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0); 12064 if (reg->callno < 1) { 12065 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 12066 return -1; 12067 } else 12068 ast_debug(3, "Registration created on call %d\n", reg->callno); 12069 iaxs[reg->callno]->reg = reg; 12070 ast_mutex_unlock(&iaxsl[reg->callno]); 12071 } 12072 /* Setup the next registration a little early */ 12073 reg->expire = iax2_sched_replace(reg->expire, sched, 12074 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 12075 /* Send the request */ 12076 memset(&ied, 0, sizeof(ied)); 12077 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 12078 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 12079 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 12080 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 12081 reg->regstate = REG_STATE_REGSENT; 12082 return 0; 12083 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8415 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
08416 { 08417 #ifdef SCHED_MULTITHREADED 08418 if (schedule_action(__iax2_do_register_s, data)) 08419 #endif 08420 __iax2_do_register_s(data); 08421 return 0; 08422 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 9191 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().
09192 { 09193 struct iax_ie_data ied; 09194 /* Auto-hangup with 30 seconds of inactivity */ 09195 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 09196 sched, 30000, auto_hangup, (void *)(long)callno); 09197 memset(&ied, 0, sizeof(ied)); 09198 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 09199 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 09200 dp->flags |= CACHE_FLAG_TRANSMITTED; 09201 }
static void * iax2_dup_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1420 of file chan_iax2.c.
References ast_calloc, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_name(), ast_var_value(), and LOG_ERROR.
01421 { 01422 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01423 struct ast_var_t *oldvar, *newvar; 01424 01425 newlist = ast_calloc(sizeof(*newlist), 1); 01426 if (!newlist) { 01427 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01428 return NULL; 01429 } 01430 01431 AST_LIST_HEAD_INIT(newlist); 01432 AST_LIST_LOCK(oldlist); 01433 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01434 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01435 if (newvar) 01436 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01437 else 01438 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01439 } 01440 AST_LIST_UNLOCK(oldlist); 01441 return newlist; 01442 }
static int iax2_exec | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Execute IAX2 dialplan switch.
Definition at line 14089 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().
14090 { 14091 char odata[256]; 14092 char req[256]; 14093 char *ncontext; 14094 struct iax2_dpcache *dp = NULL; 14095 struct ast_app *dial = NULL; 14096 #if 0 14097 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); 14098 #endif 14099 if (priority == 2) { 14100 /* Indicate status, can be overridden in dialplan */ 14101 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 14102 if (dialstatus) { 14103 dial = pbx_findapp(dialstatus); 14104 if (dial) 14105 pbx_exec(chan, dial, ""); 14106 } 14107 return -1; 14108 } else if (priority != 1) 14109 return -1; 14110 14111 AST_LIST_LOCK(&dpcache); 14112 if ((dp = find_cache(chan, data, context, exten, priority))) { 14113 if (dp->flags & CACHE_FLAG_EXISTS) { 14114 ast_copy_string(odata, data, sizeof(odata)); 14115 ncontext = strchr(odata, '/'); 14116 if (ncontext) { 14117 *ncontext = '\0'; 14118 ncontext++; 14119 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 14120 } else { 14121 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 14122 } 14123 ast_verb(3, "Executing Dial('%s')\n", req); 14124 } else { 14125 AST_LIST_UNLOCK(&dpcache); 14126 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 14127 return -1; 14128 } 14129 } 14130 AST_LIST_UNLOCK(&dpcache); 14131 14132 if ((dial = pbx_findapp("Dial"))) 14133 return pbx_exec(chan, dial, req); 14134 else 14135 ast_log(LOG_WARNING, "No dial application registered\n"); 14136 14137 return -1; 14138 }
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 14020 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.
14021 { 14022 int res = 0; 14023 struct iax2_dpcache *dp = NULL; 14024 #if 0 14025 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 14026 #endif 14027 if ((priority != 1) && (priority != 2)) 14028 return 0; 14029 14030 AST_LIST_LOCK(&dpcache); 14031 if ((dp = find_cache(chan, data, context, exten, priority))) { 14032 if (dp->flags & CACHE_FLAG_EXISTS) 14033 res = 1; 14034 } else { 14035 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 14036 } 14037 AST_LIST_UNLOCK(&dpcache); 14038 14039 return res; 14040 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 4408 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax_frame::callno, iaxs, iaxsl, LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
04409 { 04410 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04411 ast_mutex_lock(&iaxsl[callno]); 04412 if (iaxs[callno]) 04413 iaxs[callno]->owner = newchan; 04414 else 04415 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04416 ast_mutex_unlock(&iaxsl[callno]); 04417 return 0; 04418 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1883 of file chan_iax2.c.
References ast_sched_thread_del, iax_frame_free(), and iax_frame::retrans.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), resend_with_token(), and schedule_delivery().
01884 { 01885 ast_sched_thread_del(sched, fr->retrans); 01886 iax_frame_free(fr); 01887 }
static void iax2_free_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1444 of file chan_iax2.c.
References ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
01445 { 01446 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01447 struct ast_var_t *oldvar; 01448 01449 AST_LIST_LOCK(oldlist); 01450 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01451 ast_free(oldvar); 01452 } 01453 AST_LIST_UNLOCK(oldlist); 01454 AST_LIST_HEAD_DESTROY(oldlist); 01455 ast_free(oldlist); 01456 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1817 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_sockaddr_to_sin, peer_unref(), and realtime_peer().
Referenced by __find_callno().
01818 { 01819 struct iax2_peer *peer = NULL; 01820 int res = 0; 01821 struct ao2_iterator i; 01822 01823 i = ao2_iterator_init(peers, 0); 01824 while ((peer = ao2_iterator_next(&i))) { 01825 struct sockaddr_in peer_addr; 01826 01827 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 01828 01829 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01830 (peer_addr.sin_port == sin.sin_port)) { 01831 ast_copy_string(host, peer->name, len); 01832 peer_unref(peer); 01833 res = 1; 01834 break; 01835 } 01836 peer_unref(peer); 01837 } 01838 ao2_iterator_destroy(&i); 01839 01840 if (!peer) { 01841 peer = realtime_peer(NULL, &sin); 01842 if (peer) { 01843 ast_copy_string(host, peer->name, len); 01844 peer_unref(peer); 01845 res = 1; 01846 } 01847 } 01848 01849 return res; 01850 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5812 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_sockaddr_to_sin, ast_test_flag64, IAX_TRUNK, and peer_unref().
Referenced by check_access().
05813 { 05814 struct iax2_peer *peer; 05815 int res = 0; 05816 struct ao2_iterator i; 05817 05818 i = ao2_iterator_init(peers, 0); 05819 while ((peer = ao2_iterator_next(&i))) { 05820 struct sockaddr_in peer_addr; 05821 05822 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 05823 05824 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05825 (peer_addr.sin_port == sin.sin_port)) { 05826 res = ast_test_flag64(peer, IAX_TRUNK); 05827 peer_unref(peer); 05828 break; 05829 } 05830 peer_unref(peer); 05831 } 05832 ao2_iterator_destroy(&i); 05833 05834 return res; 05835 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5317 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_add(), ast_test_flag64, ast_verb, iax_ie_data::buf, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, iaxs, iaxsl, LOG_ERROR, LOG_WARNING, iax_ie_data::pos, PTR_TO_CALLNO, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.
05318 { 05319 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05320 struct iax_ie_data ied; 05321 int alreadygone; 05322 memset(&ied, 0, sizeof(ied)); 05323 ast_mutex_lock(&iaxsl[callno]); 05324 if (callno && iaxs[callno]) { 05325 ast_debug(1, "We're hanging up %s now...\n", c->name); 05326 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE); 05327 /* Send the hangup unless we have had a transmission error or are already gone */ 05328 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 05329 if (!iaxs[callno]->error && !alreadygone) { 05330 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 05331 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 05332 } 05333 if (!iaxs[callno]) { 05334 ast_mutex_unlock(&iaxsl[callno]); 05335 return 0; 05336 } 05337 } 05338 /* Explicitly predestroy it */ 05339 iax2_predestroy(callno); 05340 /* If we were already gone to begin with, destroy us now */ 05341 if (iaxs[callno] && alreadygone) { 05342 ast_debug(1, "Really destroying %s now...\n", c->name); 05343 iax2_destroy(callno); 05344 } else if (iaxs[callno]) { 05345 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 05346 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05347 iax2_destroy(callno); 05348 } 05349 } 05350 } else if (c->tech_pvt) { 05351 /* If this call no longer exists, but the channel still 05352 * references it we need to set the channel's tech_pvt to null 05353 * to avoid ast_channel_free() trying to free it. 05354 */ 05355 c->tech_pvt = NULL; 05356 } 05357 ast_mutex_unlock(&iaxsl[callno]); 05358 ast_verb(3, "Hungup '%s'\n", c->name); 05359 return 0; 05360 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5743 of file chan_iax2.c.
References AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, IAX_SENDCONNECTEDLINE, iaxs, iaxsl, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
05744 { 05745 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05746 struct chan_iax2_pvt *pvt; 05747 int res = 0; 05748 05749 if (iaxdebug) 05750 ast_debug(1, "Indicating condition %d\n", condition); 05751 05752 ast_mutex_lock(&iaxsl[callno]); 05753 pvt = iaxs[callno]; 05754 05755 if (wait_for_peercallno(pvt)) { 05756 res = -1; 05757 goto done; 05758 } 05759 05760 switch (condition) { 05761 case AST_CONTROL_HOLD: 05762 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05763 ast_moh_start(c, data, pvt->mohinterpret); 05764 goto done; 05765 } 05766 break; 05767 case AST_CONTROL_UNHOLD: 05768 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05769 ast_moh_stop(c); 05770 goto done; 05771 } 05772 break; 05773 case AST_CONTROL_CONNECTED_LINE: 05774 case AST_CONTROL_REDIRECTING: 05775 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) { 05776 /* We are not configured to allow sending these updates. */ 05777 ast_debug(2, "Callno %d: Config blocked sending control frame %d.\n", 05778 callno, condition); 05779 goto done; 05780 } 05781 break; 05782 } 05783 05784 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05785 05786 done: 05787 ast_mutex_unlock(&iaxsl[callno]); 05788 05789 return res; 05790 }
static int iax2_is_control_frame_allowed | ( | int | subtype | ) | [static] |
Definition at line 1284 of file chan_iax2.c.
References _XXX_AST_CONTROL_T38, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CC, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_INCOMPLETE, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_READ_ACTION, AST_CONTROL_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, and AST_CONTROL_WINK.
Referenced by send_command(), and socket_process().
01285 { 01286 enum ast_control_frame_type control = subtype; 01287 int is_allowed; 01288 01289 /* 01290 * Note: If we compare the enumeration type, which does not have any 01291 * negative constants, the compiler may optimize this code away. 01292 * Therefore, we must perform an integer comparison here. 01293 */ 01294 if (subtype == -1) { 01295 return -1; 01296 } 01297 01298 /* Default to not allowing control frames to pass. */ 01299 is_allowed = 0; 01300 01301 /* 01302 * The switch default is not present in order to take advantage 01303 * of the compiler complaining of a missing enum case. 01304 */ 01305 switch (control) { 01306 /* 01307 * These control frames make sense to send/receive across the link. 01308 */ 01309 case AST_CONTROL_HANGUP: 01310 case AST_CONTROL_RING: 01311 case AST_CONTROL_RINGING: 01312 case AST_CONTROL_ANSWER: 01313 case AST_CONTROL_BUSY: 01314 case AST_CONTROL_TAKEOFFHOOK: 01315 case AST_CONTROL_OFFHOOK: 01316 case AST_CONTROL_CONGESTION: 01317 case AST_CONTROL_FLASH: 01318 case AST_CONTROL_WINK: 01319 case AST_CONTROL_OPTION: 01320 case AST_CONTROL_RADIO_KEY: 01321 case AST_CONTROL_RADIO_UNKEY: 01322 case AST_CONTROL_PROGRESS: 01323 case AST_CONTROL_PROCEEDING: 01324 case AST_CONTROL_HOLD: 01325 case AST_CONTROL_UNHOLD: 01326 case AST_CONTROL_VIDUPDATE: 01327 case AST_CONTROL_CONNECTED_LINE: 01328 case AST_CONTROL_REDIRECTING: 01329 case AST_CONTROL_T38_PARAMETERS: 01330 case AST_CONTROL_AOC: 01331 case AST_CONTROL_INCOMPLETE: 01332 is_allowed = -1; 01333 break; 01334 01335 /* 01336 * These control frames do not make sense to send/receive across the link. 01337 */ 01338 case _XXX_AST_CONTROL_T38: 01339 /* The control value is deprecated in favor of AST_CONTROL_T38_PARAMETERS. */ 01340 case AST_CONTROL_SRCUPDATE: 01341 /* Across an IAX link the source is still the same. */ 01342 case AST_CONTROL_TRANSFER: 01343 /* A success/fail status report from calling ast_transfer() on this machine. */ 01344 case AST_CONTROL_CC: 01345 /* The payload contains pointers that are valid for the sending machine only. */ 01346 case AST_CONTROL_SRCCHANGE: 01347 /* Across an IAX link the source is still the same. */ 01348 case AST_CONTROL_READ_ACTION: 01349 /* The action can only be done by the sending machine. */ 01350 case AST_CONTROL_END_OF_Q: 01351 /* This frame would cause the call to unexpectedly hangup. */ 01352 case AST_CONTROL_UPDATE_RTP_PEER: 01353 /* Only meaningful across a bridge on this machine for direct-media exchange. */ 01354 break; 01355 } 01356 return is_allowed; 01357 }
static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5479 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, ast_random(), ast_sched_thread_add(), iax_ie_data::buf, build_ecx_key(), chan_iax2_pvt::callno, IAX_COMMAND_RTKEY, IAX_DEBUGDIGEST, iax_ie_append_raw(), IAX_IE_CHALLENGE, iaxsl, chan_iax2_pvt::keyrotateid, MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, and send_command().
Referenced by iax2_send().
05480 { 05481 int res = 0; 05482 struct chan_iax2_pvt *pvt = (void *) vpvt; 05483 struct MD5Context md5; 05484 char key[17] = ""; 05485 struct iax_ie_data ied = { 05486 .pos = 0, 05487 }; 05488 05489 ast_mutex_lock(&iaxsl[pvt->callno]); 05490 pvt->keyrotateid = 05491 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05492 05493 snprintf(key, sizeof(key), "%lX", (unsigned long)ast_random()); 05494 05495 MD5Init(&md5); 05496 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05497 MD5Final((unsigned char *) key, &md5); 05498 05499 IAX_DEBUGDIGEST("Sending", key); 05500 05501 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05502 05503 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05504 05505 build_ecx_key((unsigned char *) key, pvt); 05506 05507 ast_mutex_unlock(&iaxsl[pvt->callno]); 05508 05509 return res; 05510 }
static void iax2_lock_owner | ( | int | callno | ) | [static] |
Definition at line 1260 of file chan_iax2.c.
References ast_channel_trylock, DEADLOCK_AVOIDANCE, iaxs, and iaxsl.
Referenced by iax2_queue_control_data(), iax2_queue_frame(), iax2_queue_hangup(), schedule_delivery(), set_hangup_source_and_cause(), and socket_process().
01261 { 01262 for (;;) { 01263 if (!iaxs[callno] || !iaxs[callno]->owner) { 01264 /* There is no owner lock to get. */ 01265 break; 01266 } 01267 if (!ast_channel_trylock(iaxs[callno]->owner)) { 01268 /* We got the lock */ 01269 break; 01270 } 01271 /* Avoid deadlock by pausing and trying again */ 01272 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01273 } 01274 }
static int iax2_matchmore | ( | struct ast_channel * | chan, | |
const char * | context, | |||
const char * | exten, | |||
int | priority, | |||
const char * | callerid, | |||
const char * | data | |||
) | [static] |
Part of the IAX2 Switch interface.
Definition at line 14066 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.
14067 { 14068 int res = 0; 14069 struct iax2_dpcache *dp = NULL; 14070 #if 0 14071 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 14072 #endif 14073 if ((priority != 1) && (priority != 2)) 14074 return 0; 14075 14076 AST_LIST_LOCK(&dpcache); 14077 if ((dp = find_cache(chan, data, context, exten, priority))) { 14078 if (dp->flags & CACHE_FLAG_MATCHMORE) 14079 res = 1; 14080 } else { 14081 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 14082 } 14083 AST_LIST_UNLOCK(&dpcache); 14084 14085 return res; 14086 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 12228 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
12229 { 12230 struct iax2_peer *peer = (struct iax2_peer *)data; 12231 peer->pokeexpire = -1; 12232 #ifdef SCHED_MULTITHREADED 12233 if (schedule_action(__iax2_poke_noanswer, data)) 12234 #endif 12235 __iax2_poke_noanswer(data); 12236 peer_unref(peer); 12237 return 0; 12238 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 12249 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().
12250 { 12251 int callno; 12252 struct sockaddr_in peer_addr; 12253 12254 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) { 12255 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 12256 immediately after clearing things out */ 12257 peer->lastms = 0; 12258 peer->historicms = 0; 12259 peer->pokeexpire = -1; 12260 peer->callno = 0; 12261 return 0; 12262 } 12263 12264 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 12265 12266 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 12267 if ((callno = peer->callno) > 0) { 12268 ast_log(LOG_NOTICE, "Still have a callno...\n"); 12269 ast_mutex_lock(&iaxsl[callno]); 12270 iax2_destroy(callno); 12271 ast_mutex_unlock(&iaxsl[callno]); 12272 } 12273 if (heldcall) 12274 ast_mutex_unlock(&iaxsl[heldcall]); 12275 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0); 12276 if (heldcall) 12277 ast_mutex_lock(&iaxsl[heldcall]); 12278 if (peer->callno < 1) { 12279 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 12280 return -1; 12281 } 12282 12283 /* Speed up retransmission times for this qualify call */ 12284 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 12285 iaxs[peer->callno]->peerpoke = peer; 12286 12287 if (peer->pokeexpire > -1) { 12288 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 12289 peer->pokeexpire = -1; 12290 peer_unref(peer); 12291 } 12292 } 12293 12294 /* Queue up a new task to handle no reply */ 12295 /* If the host is already unreachable then use the unreachable interval instead */ 12296 if (peer->lastms < 0) 12297 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 12298 else 12299 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 12300 12301 if (peer->pokeexpire == -1) 12302 peer_unref(peer); 12303 12304 /* And send the poke */ 12305 ast_mutex_lock(&iaxsl[callno]); 12306 if (iaxs[callno]) { 12307 struct iax_ie_data ied = { 12308 .buf = { 0 }, 12309 .pos = 0, 12310 }; 12311 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 12312 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 12313 } 12314 ast_mutex_unlock(&iaxsl[callno]); 12315 12316 return 0; 12317 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12240 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
12241 { 12242 struct iax2_peer *peer = obj; 12243 12244 iax2_poke_peer(peer, 0); 12245 12246 return 0; 12247 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9228 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
09229 { 09230 struct iax2_peer *peer = (struct iax2_peer *)data; 09231 peer->pokeexpire = -1; 09232 #ifdef SCHED_MULTITHREADED 09233 if (schedule_action(__iax2_poke_peer_s, data)) 09234 #endif 09235 __iax2_poke_peer_s(data); 09236 return 0; 09237 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3452 of file chan_iax2.c.
References ast_module_unref(), ast_set_flag64, ast_test_flag64, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, iaxs, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
03453 { 03454 struct ast_channel *c = NULL; 03455 struct chan_iax2_pvt *pvt = iaxs[callno]; 03456 03457 if (!pvt) 03458 return -1; 03459 03460 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) { 03461 iax2_destroy_helper(pvt); 03462 ast_set_flag64(pvt, IAX_ALREADYGONE); 03463 } 03464 03465 if ((c = pvt->owner)) { 03466 c->tech_pvt = NULL; 03467 iax2_queue_hangup(callno); 03468 pvt->owner = NULL; 03469 ast_module_unref(ast_module_info->self); 03470 } 03471 03472 return 0; 03473 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 11878 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().
11879 { 11880 struct iax2_thread *thread = data; 11881 struct timeval wait; 11882 struct timespec ts; 11883 int put_into_idle = 0; 11884 int first_time = 1; 11885 int old_state; 11886 11887 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1); 11888 11889 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); 11890 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11891 11892 for (;;) { 11893 /* Wait for something to signal us to be awake */ 11894 ast_mutex_lock(&thread->lock); 11895 11896 if (thread->stop) { 11897 ast_mutex_unlock(&thread->lock); 11898 break; 11899 } 11900 11901 /* Flag that we're ready to accept signals */ 11902 if (first_time) { 11903 signal_condition(&thread->init_lock, &thread->init_cond); 11904 first_time = 0; 11905 } 11906 11907 /* Put into idle list if applicable */ 11908 if (put_into_idle) { 11909 insert_idle_thread(thread); 11910 } 11911 11912 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11913 struct iax2_thread *t = NULL; 11914 /* Wait to be signalled or time out */ 11915 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11916 ts.tv_sec = wait.tv_sec; 11917 ts.tv_nsec = wait.tv_usec * 1000; 11918 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11919 /* This thread was never put back into the available dynamic 11920 * thread list, so just go away. */ 11921 if (!put_into_idle || thread->stop) { 11922 ast_mutex_unlock(&thread->lock); 11923 break; 11924 } 11925 AST_LIST_LOCK(&dynamic_list); 11926 /* Account for the case where this thread is acquired *right* after a timeout */ 11927 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11928 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11929 AST_LIST_UNLOCK(&dynamic_list); 11930 if (t) { 11931 /* This dynamic thread timed out waiting for a task and was 11932 * not acquired immediately after the timeout, 11933 * so it's time to go away. */ 11934 ast_mutex_unlock(&thread->lock); 11935 break; 11936 } 11937 /* Someone grabbed our thread *right* after we timed out. 11938 * Wait for them to set us up with something to do and signal 11939 * us to continue. */ 11940 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11941 ts.tv_sec = wait.tv_sec; 11942 ts.tv_nsec = wait.tv_usec * 1000; 11943 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11944 ast_mutex_unlock(&thread->lock); 11945 break; 11946 } 11947 } 11948 } else { 11949 ast_cond_wait(&thread->cond, &thread->lock); 11950 } 11951 11952 /* Go back into our respective list */ 11953 put_into_idle = 1; 11954 11955 ast_mutex_unlock(&thread->lock); 11956 11957 if (thread->stop) { 11958 break; 11959 } 11960 11961 /* See what we need to do */ 11962 switch (thread->iostate) { 11963 case IAX_IOSTATE_IDLE: 11964 continue; 11965 case IAX_IOSTATE_READY: 11966 thread->actions++; 11967 thread->iostate = IAX_IOSTATE_PROCESSING; 11968 socket_process(thread); 11969 handle_deferred_full_frames(thread); 11970 break; 11971 case IAX_IOSTATE_SCHEDREADY: 11972 thread->actions++; 11973 thread->iostate = IAX_IOSTATE_PROCESSING; 11974 #ifdef SCHED_MULTITHREADED 11975 thread->schedfunc(thread->scheddata); 11976 #endif 11977 break; 11978 default: 11979 break; 11980 } 11981 11982 /* The network thread added us to the active_thread list when we were given 11983 * frames to process, Now that we are done, we must remove ourselves from 11984 * the active list, and return to the idle list */ 11985 AST_LIST_LOCK(&active_list); 11986 AST_LIST_REMOVE(&active_list, thread, list); 11987 AST_LIST_UNLOCK(&active_list); 11988 11989 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11990 handle_deferred_full_frames(thread); 11991 11992 time(&thread->checktime); 11993 thread->iostate = IAX_IOSTATE_IDLE; 11994 #ifdef DEBUG_SCHED_MULTITHREAD 11995 thread->curfunc[0]='\0'; 11996 #endif 11997 } 11998 11999 /*! 12000 * \note For some reason, idle threads are exiting without being 12001 * removed from an idle list, which is causing memory 12002 * corruption. Forcibly remove it from the list, if it's there. 12003 */ 12004 AST_LIST_LOCK(&idle_list); 12005 AST_LIST_REMOVE(&idle_list, thread, list); 12006 AST_LIST_UNLOCK(&idle_list); 12007 12008 AST_LIST_LOCK(&dynamic_list); 12009 AST_LIST_REMOVE(&dynamic_list, thread, list); 12010 AST_LIST_UNLOCK(&dynamic_list); 12011 12012 if (!thread->stop) { 12013 /* Nobody asked me to stop so nobody is waiting to join me. */ 12014 pthread_detach(pthread_self()); 12015 } 12016 12017 /* I am exiting here on my own volition, I need to clean up my own data structures 12018 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 12019 */ 12020 pthread_cleanup_pop(1); 12021 return NULL; 12022 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11866 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().
11867 { 11868 struct iax2_thread *thread = data; 11869 ast_mutex_destroy(&thread->lock); 11870 ast_cond_destroy(&thread->cond); 11871 ast_mutex_destroy(&thread->init_lock); 11872 ast_cond_destroy(&thread->init_cond); 11873 ast_free(thread); 11874 /* Ignore check_return warning from Coverity for ast_atomic_dec_and_test below */ 11875 ast_atomic_dec_and_test(&iaxactivethreadcount); 11876 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
const char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 12085 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().
12086 { 12087 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 12088 is found for template */ 12089 struct iax_ie_data provdata; 12090 struct iax_ie_data ied; 12091 unsigned int sig; 12092 struct sockaddr_in sin; 12093 int callno; 12094 struct create_addr_info cai; 12095 12096 memset(&cai, 0, sizeof(cai)); 12097 12098 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 12099 12100 if (iax_provision_build(&provdata, &sig, template, force)) { 12101 ast_debug(1, "No provisioning found for template '%s'\n", template); 12102 return 0; 12103 } 12104 12105 if (end) { 12106 memcpy(&sin, end, sizeof(sin)); 12107 cai.sockfd = sockfd; 12108 } else if (create_addr(dest, NULL, &sin, &cai)) 12109 return -1; 12110 12111 /* Build the rest of the message */ 12112 memset(&ied, 0, sizeof(ied)); 12113 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 12114 12115 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12116 if (!callno) 12117 return -1; 12118 12119 if (iaxs[callno]) { 12120 /* Schedule autodestruct in case they don't ever give us anything back */ 12121 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 12122 sched, 15000, auto_hangup, (void *)(long)callno); 12123 ast_set_flag64(iaxs[callno], IAX_PROVISION); 12124 /* Got a call number now, so go ahead and send the provisioning information */ 12125 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 12126 } 12127 ast_mutex_unlock(&iaxsl[callno]); 12128 12129 return 1; 12130 }
static int iax2_queryoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int * | datalen | |||
) | [static] |
Definition at line 5456 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_unlock, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, ast_test_flag64, chan_iax2_pvt::callno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, and ast_channel::tech_pvt.
05457 { 05458 switch (option) { 05459 case AST_OPTION_SECURE_SIGNALING: 05460 case AST_OPTION_SECURE_MEDIA: 05461 { 05462 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05463 ast_mutex_lock(&iaxsl[callno]); 05464 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0; 05465 ast_mutex_unlock(&iaxsl[callno]); 05466 return 0; 05467 } 05468 default: 05469 return -1; 05470 } 05471 }
static int iax2_queue_control_data | ( | int | callno, | |
enum ast_control_frame_type | control, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Queue a control frame on the ast_channel owner.
This function queues a control frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 3090 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_control_data(), iax2_lock_owner(), and iaxs.
Referenced by socket_process().
03092 { 03093 iax2_lock_owner(callno); 03094 if (iaxs[callno] && iaxs[callno]->owner) { 03095 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 03096 ast_channel_unlock(iaxs[callno]->owner); 03097 } 03098 return 0; 03099 }
static int iax2_queue_frame | ( | int | callno, | |
struct ast_frame * | f | |||
) | [static] |
Queue a frame to a call's owning asterisk channel.
Definition at line 3044 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_frame(), iax2_lock_owner(), and iaxs.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
03045 { 03046 iax2_lock_owner(callno); 03047 if (iaxs[callno] && iaxs[callno]->owner) { 03048 ast_queue_frame(iaxs[callno]->owner, f); 03049 ast_channel_unlock(iaxs[callno]->owner); 03050 } 03051 return 0; 03052 }
static int iax2_queue_hangup | ( | int | callno | ) | [static] |
Queue a hangup frame on the ast_channel owner.
This function queues a hangup frame on the owner of the IAX2 pvt struct that is active for the given call number.
Definition at line 3067 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_hangup(), iax2_lock_owner(), and iaxs.
Referenced by iax2_predestroy().
03068 { 03069 iax2_lock_owner(callno); 03070 if (iaxs[callno] && iaxs[callno]->owner) { 03071 ast_queue_hangup(iaxs[callno]->owner); 03072 ast_channel_unlock(iaxs[callno]->owner); 03073 } 03074 return 0; 03075 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 5473 of file chan_iax2.c.
References ast_debug, and ast_null_frame.
05474 { 05475 ast_debug(1, "I should never be called!\n"); 05476 return &ast_null_frame; 05477 }
static int iax2_register | ( | const char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 8663 of file chan_iax2.c.
References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, and secret.
Referenced by set_config().
08664 { 08665 char copy[256]; 08666 char *username, *hostname, *secret; 08667 char *porta; 08668 char *stringp=NULL; 08669 08670 if (!value) 08671 return -1; 08672 08673 ast_copy_string(copy, value, sizeof(copy)); 08674 stringp = copy; 08675 username = strsep(&stringp, "@"); 08676 hostname = strsep(&stringp, "@"); 08677 08678 if (!hostname) { 08679 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08680 return -1; 08681 } 08682 08683 stringp = username; 08684 username = strsep(&stringp, ":"); 08685 secret = strsep(&stringp, ":"); 08686 stringp = hostname; 08687 hostname = strsep(&stringp, ":"); 08688 porta = strsep(&stringp, ":"); 08689 08690 if (porta && !atoi(porta)) { 08691 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08692 return -1; 08693 } 08694 08695 return iax2_append_register(hostname, username, secret, porta); 08696 }
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 12329 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.
12330 { 12331 int callno; 12332 int res; 12333 format_t fmt, native; 12334 struct sockaddr_in sin; 12335 struct ast_channel *c; 12336 struct parsed_dial_string pds; 12337 struct create_addr_info cai; 12338 char *tmpstr; 12339 12340 memset(&pds, 0, sizeof(pds)); 12341 tmpstr = ast_strdupa(data); 12342 parse_dial_string(tmpstr, &pds); 12343 12344 if (ast_strlen_zero(pds.peer)) { 12345 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12346 return NULL; 12347 } 12348 12349 memset(&cai, 0, sizeof(cai)); 12350 cai.capability = iax2_capability; 12351 12352 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12353 12354 /* Populate our address from the given */ 12355 if (create_addr(pds.peer, NULL, &sin, &cai)) { 12356 *cause = AST_CAUSE_UNREGISTERED; 12357 return NULL; 12358 } 12359 12360 if (pds.port) 12361 sin.sin_port = htons(atoi(pds.port)); 12362 12363 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12364 if (callno < 1) { 12365 ast_log(LOG_WARNING, "Unable to create call\n"); 12366 *cause = AST_CAUSE_CONGESTION; 12367 return NULL; 12368 } 12369 12370 /* If this is a trunk, update it now */ 12371 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12372 if (ast_test_flag64(&cai, IAX_TRUNK)) { 12373 int new_callno; 12374 if ((new_callno = make_trunk(callno, 1)) != -1) 12375 callno = new_callno; 12376 } 12377 iaxs[callno]->maxtime = cai.maxtime; 12378 if (cai.found) 12379 ast_string_field_set(iaxs[callno], host, pds.peer); 12380 12381 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL, cai.found); 12382 12383 ast_mutex_unlock(&iaxsl[callno]); 12384 12385 if (c) { 12386 /* Choose a format we can live with */ 12387 if (c->nativeformats & format) 12388 c->nativeformats &= format; 12389 else { 12390 native = c->nativeformats; 12391 fmt = format; 12392 res = ast_translator_best_choice(&fmt, &native); 12393 if (res < 0) { 12394 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 12395 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 12396 ast_hangup(c); 12397 return NULL; 12398 } 12399 c->nativeformats = native; 12400 } 12401 c->readformat = ast_best_codec(c->nativeformats); 12402 c->writeformat = c->readformat; 12403 } 12404 12405 return c; 12406 }
static int iax2_sched_add | ( | struct ast_sched_thread * | st, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1580 of file chan_iax2.c.
References ast_sched_thread_add().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_poke_peer(), make_trunk(), network_change_event_cb(), realtime_peer(), reg_source_db(), sched_delay_remove(), socket_process(), transmit_frame(), and update_registry().
01582 { 01583 return ast_sched_thread_add(st, when, callback, data); 01584 }
static int iax2_sched_replace | ( | int | id, | |
struct ast_sched_thread * | st, | |||
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1572 of file chan_iax2.c.
References ast_sched_thread_add(), and ast_sched_thread_del.
Referenced by auth_fail(), iax2_ack_registry(), iax2_do_register(), iax2_dprequest(), iax2_provision(), and update_jbsched().
01574 { 01575 ast_sched_thread_del(st, id); 01576 01577 return ast_sched_thread_add(st, when, callback, data); 01578 }
static int iax2_send | ( | struct chan_iax2_pvt * | pvt, | |
struct ast_frame * | f, | |||
unsigned int | ts, | |||
int | seqno, | |||
int | now, | |||
int | transfer, | |||
int | final | |||
) | [static] |
Definition at line 6477 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag64, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, ast_frame_subclass::codec, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::ecx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_frame::encmethods, encrypt_frame(), iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_frame_subclass::integer, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, chan_iax2_pvt::mydcx, iax_frame::mydcx, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_frame::ptr, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, iax_frame::semirand, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), send_signaling(), and socket_process().
06478 { 06479 /* Queue a packet for delivery on a given private structure. Use "ts" for 06480 timestamp, or calculate if ts is 0. Send immediately without retransmission 06481 or delayed, with retransmission */ 06482 struct ast_iax2_full_hdr *fh; 06483 struct ast_iax2_mini_hdr *mh; 06484 struct ast_iax2_video_hdr *vh; 06485 struct { 06486 struct iax_frame fr2; 06487 unsigned char buffer[4096]; 06488 } frb; 06489 struct iax_frame *fr; 06490 int res; 06491 int sendmini=0; 06492 unsigned int lastsent; 06493 unsigned int fts; 06494 06495 frb.fr2.afdatalen = sizeof(frb.buffer); 06496 06497 if (!pvt) { 06498 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06499 return -1; 06500 } 06501 06502 lastsent = pvt->lastsent; 06503 06504 /* Calculate actual timestamp */ 06505 fts = calc_timestamp(pvt, ts, f); 06506 06507 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06508 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06509 * increment the "predicted timestamps" for voice, if we're predicting */ 06510 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06511 return 0; 06512 #if 0 06513 ast_log(LOG_NOTICE, 06514 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06515 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06516 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06517 pvt->keyrotateid != -1 ? "" : "no " 06518 ); 06519 #endif 06520 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06521 iax2_key_rotate(pvt); 06522 } 06523 06524 if ((ast_test_flag64(pvt, IAX_TRUNK) || 06525 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06526 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06527 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06528 (f->frametype == AST_FRAME_VOICE) 06529 /* is a voice frame */ && 06530 (f->subclass.codec == pvt->svoiceformat) 06531 /* is the same type */ ) { 06532 /* Force immediate rather than delayed transmission */ 06533 now = 1; 06534 /* Mark that mini-style frame is appropriate */ 06535 sendmini = 1; 06536 } 06537 if ( f->frametype == AST_FRAME_VIDEO ) { 06538 /* 06539 * If the lower 15 bits of the timestamp roll over, or if 06540 * the video format changed then send a full frame. 06541 * Otherwise send a mini video frame 06542 */ 06543 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06544 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat) 06545 ) { 06546 now = 1; 06547 sendmini = 1; 06548 } else { 06549 now = 0; 06550 sendmini = 0; 06551 } 06552 pvt->lastvsent = fts; 06553 } 06554 if (f->frametype == AST_FRAME_IAX) { 06555 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06556 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX; 06557 if (!pvt->first_iax_message) { 06558 pvt->first_iax_message = pvt->last_iax_message; 06559 } 06560 } 06561 /* Allocate an iax_frame */ 06562 if (now) { 06563 fr = &frb.fr2; 06564 } else 06565 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag64(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO)); 06566 if (!fr) { 06567 ast_log(LOG_WARNING, "Out of memory\n"); 06568 return -1; 06569 } 06570 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06571 iax_frame_wrap(fr, f); 06572 06573 fr->ts = fts; 06574 fr->callno = pvt->callno; 06575 fr->transfer = transfer; 06576 fr->final = final; 06577 fr->encmethods = 0; 06578 if (!sendmini) { 06579 /* We need a full frame */ 06580 if (seqno > -1) 06581 fr->oseqno = seqno; 06582 else 06583 fr->oseqno = pvt->oseqno++; 06584 fr->iseqno = pvt->iseqno; 06585 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06586 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06587 fh->ts = htonl(fr->ts); 06588 fh->oseqno = fr->oseqno; 06589 if (transfer) { 06590 fh->iseqno = 0; 06591 } else 06592 fh->iseqno = fr->iseqno; 06593 /* Keep track of the last thing we've acknowledged */ 06594 if (!transfer) 06595 pvt->aseqno = fr->iseqno; 06596 fh->type = fr->af.frametype & 0xFF; 06597 06598 if (fr->af.frametype == AST_FRAME_VIDEO) { 06599 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6); 06600 } else if (fr->af.frametype == AST_FRAME_VOICE) { 06601 fh->csub = compress_subclass(fr->af.subclass.codec); 06602 } else { 06603 fh->csub = compress_subclass(fr->af.subclass.integer); 06604 } 06605 06606 if (transfer) { 06607 fr->dcallno = pvt->transfercallno; 06608 } else 06609 fr->dcallno = pvt->peercallno; 06610 fh->dcallno = htons(fr->dcallno); 06611 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06612 fr->data = fh; 06613 fr->retries = 0; 06614 /* Retry after 2x the ping time has passed */ 06615 fr->retrytime = pvt->pingtime * 2; 06616 if (fr->retrytime < MIN_RETRY_TIME) 06617 fr->retrytime = MIN_RETRY_TIME; 06618 if (fr->retrytime > MAX_RETRY_TIME) 06619 fr->retrytime = MAX_RETRY_TIME; 06620 /* Acks' don't get retried */ 06621 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK)) 06622 fr->retries = -1; 06623 else if (f->frametype == AST_FRAME_VOICE) 06624 pvt->svoiceformat = f->subclass.codec; 06625 else if (f->frametype == AST_FRAME_VIDEO) 06626 pvt->svideoformat = f->subclass.codec & ~0x1LL; 06627 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06628 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06629 if (fr->transfer) 06630 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06631 else 06632 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06633 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06634 fr->encmethods = pvt->encmethods; 06635 fr->ecx = pvt->ecx; 06636 fr->mydcx = pvt->mydcx; 06637 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06638 } else 06639 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06640 } 06641 06642 if (now) { 06643 res = send_packet(fr); 06644 } else 06645 res = iax2_transmit(fr); 06646 } else { 06647 if (ast_test_flag64(pvt, IAX_TRUNK)) { 06648 iax2_trunk_queue(pvt, fr); 06649 res = 0; 06650 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06651 /* Video frame have no sequence number */ 06652 fr->oseqno = -1; 06653 fr->iseqno = -1; 06654 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06655 vh->zeros = 0; 06656 vh->callno = htons(0x8000 | fr->callno); 06657 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0)); 06658 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06659 fr->data = vh; 06660 fr->retries = -1; 06661 res = send_packet(fr); 06662 } else { 06663 /* Mini-frames have no sequence number */ 06664 fr->oseqno = -1; 06665 fr->iseqno = -1; 06666 /* Mini frame will do */ 06667 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06668 mh->callno = htons(fr->callno); 06669 mh->ts = htons(fr->ts & 0xFFFF); 06670 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06671 fr->data = mh; 06672 fr->retries = -1; 06673 if (pvt->transferring == TRANSFER_MEDIAPASS) 06674 fr->transfer = 1; 06675 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06676 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06677 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06678 } else 06679 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06680 } 06681 res = send_packet(fr); 06682 } 06683 } 06684 return res; 06685 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4403 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04404 { 04405 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04406 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 4398 of file chan_iax2.c.
References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, ast_frame_subclass::integer, ast_frame::ptr, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.
04399 { 04400 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1); 04401 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 4391 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04392 { 04393 04394 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04395 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04396 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 5384 of file chan_iax2.c.
References ast_clear_flag64, AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, AST_OPTION_FLAG_REQUEST, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_set_flag64, ast_option_header::data, errno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
05385 { 05386 struct ast_option_header *h; 05387 int res; 05388 05389 switch (option) { 05390 case AST_OPTION_TXGAIN: 05391 case AST_OPTION_RXGAIN: 05392 /* these two cannot be sent, because they require a result */ 05393 errno = ENOSYS; 05394 return -1; 05395 case AST_OPTION_OPRMODE: 05396 errno = EINVAL; 05397 return -1; 05398 case AST_OPTION_SECURE_SIGNALING: 05399 case AST_OPTION_SECURE_MEDIA: 05400 { 05401 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05402 ast_mutex_lock(&iaxsl[callno]); 05403 if ((*(int *) data)) { 05404 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05405 } else { 05406 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05407 } 05408 ast_mutex_unlock(&iaxsl[callno]); 05409 return 0; 05410 } 05411 /* These options are sent to the other side across the network where 05412 * they will be passed to whatever channel is bridged there. Don't 05413 * do anything silly like pass an option that transmits pointers to 05414 * memory on this machine to a remote machine to use */ 05415 case AST_OPTION_TONE_VERIFY: 05416 case AST_OPTION_TDD: 05417 case AST_OPTION_RELAXDTMF: 05418 case AST_OPTION_AUDIO_MODE: 05419 case AST_OPTION_DIGIT_DETECT: 05420 case AST_OPTION_FAX_DETECT: 05421 { 05422 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05423 struct chan_iax2_pvt *pvt; 05424 05425 ast_mutex_lock(&iaxsl[callno]); 05426 pvt = iaxs[callno]; 05427 05428 if (wait_for_peercallno(pvt)) { 05429 ast_mutex_unlock(&iaxsl[callno]); 05430 return -1; 05431 } 05432 05433 ast_mutex_unlock(&iaxsl[callno]); 05434 05435 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05436 return -1; 05437 } 05438 05439 h->flag = AST_OPTION_FLAG_REQUEST; 05440 h->option = htons(option); 05441 memcpy(h->data, data, datalen); 05442 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05443 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05444 datalen + sizeof(*h), -1); 05445 ast_free(h); 05446 return res; 05447 } 05448 default: 05449 return -1; 05450 } 05451 05452 /* Just in case someone does a break instead of a return */ 05453 return -1; 05454 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 5512 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag64, iax_ie_data::buf, IAX_CALLENCRYPTED, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, IAX_NOTRANSFER, iaxs, iax_ie_data::pos, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
Referenced by iax2_bridge().
05513 { 05514 int res; 05515 struct iax_ie_data ied0; 05516 struct iax_ie_data ied1; 05517 unsigned int transferid = (unsigned int)ast_random(); 05518 05519 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05520 ast_debug(1, "transfers are not supported for encrypted calls at this time\n"); 05521 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER); 05522 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER); 05523 return 0; 05524 } 05525 05526 memset(&ied0, 0, sizeof(ied0)); 05527 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05528 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05529 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05530 05531 memset(&ied1, 0, sizeof(ied1)); 05532 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05533 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05534 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05535 05536 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05537 if (res) 05538 return -1; 05539 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05540 if (res) 05541 return -1; 05542 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05543 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05544 return 0; 05545 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 5792 of file chan_iax2.c.
References AST_CONTROL_TRANSFER, ast_copy_string(), ast_debug, AST_FRAME_IAX, ast_queue_control_data(), AST_TRANSFER_SUCCESS, iax_ie_data::buf, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05793 { 05794 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05795 struct iax_ie_data ied = { "", }; 05796 char tmp[256], *context; 05797 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 05798 ast_copy_string(tmp, dest, sizeof(tmp)); 05799 context = strchr(tmp, '@'); 05800 if (context) { 05801 *context = '\0'; 05802 context++; 05803 } 05804 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05805 if (context) 05806 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05807 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05808 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message)); 05809 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05810 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4374 of file chan_iax2.c.
References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().
Referenced by iax2_send().
04375 { 04376 fr->sentyet = 0; 04377 04378 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr); 04379 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 9282 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
09283 { 09284 /* Drop when trunk is about 5 seconds idle */ 09285 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 09286 return 1; 09287 return 0; 09288 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 6217 of file chan_iax2.c.
References iax2_trunk_peer::addr, chan_iax2_pvt::addr, iax_frame::af, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_unlock, ast_realloc, ast_test_flag64, ast_tvnow(), ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, f, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, ast_frame::ptr, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
06218 { 06219 struct ast_frame *f; 06220 struct iax2_trunk_peer *tpeer; 06221 void *tmp, *ptr; 06222 struct timeval now; 06223 struct ast_iax2_meta_trunk_entry *met; 06224 struct ast_iax2_meta_trunk_mini *mtm; 06225 06226 f = &fr->af; 06227 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 06228 if (tpeer) { 06229 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 06230 /* Need to reallocate space */ 06231 if (tpeer->trunkdataalloc < trunkmaxsize) { 06232 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 06233 ast_mutex_unlock(&tpeer->lock); 06234 return -1; 06235 } 06236 06237 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 06238 tpeer->trunkdata = tmp; 06239 ast_debug(1, "Expanded trunk '%s:%d' to %u bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 06240 } else { 06241 ast_log(LOG_WARNING, "Maximum trunk data space exceeded to %s:%d\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06242 ast_mutex_unlock(&tpeer->lock); 06243 return -1; 06244 } 06245 } 06246 06247 /* Append to meta frame */ 06248 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 06249 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) { 06250 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06251 mtm->len = htons(f->datalen); 06252 mtm->mini.callno = htons(pvt->callno); 06253 mtm->mini.ts = htons(0xffff & fr->ts); 06254 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06255 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 06256 } else { 06257 met = (struct ast_iax2_meta_trunk_entry *)ptr; 06258 /* Store call number and length in meta header */ 06259 met->callno = htons(pvt->callno); 06260 met->len = htons(f->datalen); 06261 /* Advance pointers/decrease length past trunk entry header */ 06262 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06263 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 06264 } 06265 /* Copy actual trunk data */ 06266 memcpy(ptr, f->data.ptr, f->datalen); 06267 tpeer->trunkdatalen += f->datalen; 06268 06269 tpeer->calls++; 06270 06271 /* track the largest mtu we actually have sent */ 06272 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 06273 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 06274 06275 /* if we have enough for a full MTU, ship it now without waiting */ 06276 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 06277 now = ast_tvnow(); 06278 send_trunk(tpeer, &now); 06279 trunk_untimed ++; 06280 } 06281 06282 ast_mutex_unlock(&tpeer->lock); 06283 } 06284 return 0; 06285 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 9203 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().
09204 { 09205 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 09206 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 7564 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.
07565 { 07566 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07567 int res = -1; 07568 ast_mutex_lock(&iaxsl[callno]); 07569 if (iaxs[callno]) { 07570 /* If there's an outstanding error, return failure now */ 07571 if (!iaxs[callno]->error) { 07572 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) 07573 res = 0; 07574 /* Don't waste bandwidth sending null frames */ 07575 else if (f->frametype == AST_FRAME_NULL) 07576 res = 0; 07577 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH)) 07578 res = 0; 07579 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07580 res = 0; 07581 else 07582 /* Simple, just queue for transmission */ 07583 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07584 } else { 07585 ast_debug(1, "Write error: %s\n", strerror(errno)); 07586 } 07587 } 07588 /* If it's already gone, just return */ 07589 ast_mutex_unlock(&iaxsl[callno]); 07590 return res; 07591 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 3246 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and ast_strlen_zero().
Referenced by update_registry().
03247 { 03248 int res = 0; 03249 struct iax_firmware *cur = NULL; 03250 03251 if (ast_strlen_zero(dev)) 03252 return 0; 03253 03254 AST_LIST_LOCK(&firmwares); 03255 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03256 if (!strcmp(dev, (char *)cur->fwh->devname)) { 03257 res = ntohs(cur->fwh->version); 03258 break; 03259 } 03260 } 03261 AST_LIST_UNLOCK(&firmwares); 03262 03263 return res; 03264 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 1120 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
01121 { 01122 if (iaxdebug) 01123 ast_verbose("%s", data); 01124 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 1126 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
01127 { 01128 ast_log(LOG_WARNING, "%s", data); 01129 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 3266 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, and IAX_IE_FWBLOCKDESC.
Referenced by socket_process().
03267 { 03268 int res = -1; 03269 unsigned int bs = desc & 0xff; 03270 unsigned int start = (desc >> 8) & 0xffffff; 03271 unsigned int bytes; 03272 struct iax_firmware *cur; 03273 03274 if (ast_strlen_zero((char *)dev) || !bs) 03275 return -1; 03276 03277 start *= bs; 03278 03279 AST_LIST_LOCK(&firmwares); 03280 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03281 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 03282 continue; 03283 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 03284 if (start < ntohl(cur->fwh->datalen)) { 03285 bytes = ntohl(cur->fwh->datalen) - start; 03286 if (bytes > bs) 03287 bytes = bs; 03288 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 03289 } else { 03290 bytes = 0; 03291 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 03292 } 03293 if (bytes == bs) 03294 res = 0; 03295 else 03296 res = 1; 03297 break; 03298 } 03299 AST_LIST_UNLOCK(&firmwares); 03300 03301 return res; 03302 }
static void iax_outputframe | ( | struct iax_frame * | f, | |
struct ast_iax2_full_hdr * | fhi, | |||
int | rx, | |||
struct sockaddr_in * | sin, | |||
int | datalen | |||
) | [static] |
Definition at line 1103 of file chan_iax2.c.
References debugaddr, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), send_apathetic_reply(), send_packet(), and socket_process().
01104 { 01105 if (iaxdebug || 01106 (sin && debugaddr.sin_addr.s_addr && 01107 (!ntohs(debugaddr.sin_port) || 01108 debugaddr.sin_port == sin->sin_port) && 01109 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 01110 if (iaxdebug) { 01111 iax_showframe(f, fhi, rx, sin, datalen); 01112 } else { 01113 iaxdebug = 1; 01114 iax_showframe(f, fhi, rx, sin, datalen); 01115 iaxdebug = 0; 01116 } 01117 } 01118 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2, | |||
const char * | park_exten, | |||
const char * | park_context | |||
) | [static] |
DO NOT hold any locks while calling iax_park
Definition at line 9456 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().
09457 { 09458 struct iax_dual *d; 09459 struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */ 09460 pthread_t th; 09461 09462 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 09463 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name); 09464 d = ast_calloc(1, sizeof(*d)); 09465 if (!chan1m || !chan2m || !d) { 09466 if (chan1m) { 09467 ast_hangup(chan1m); 09468 } 09469 if (chan2m) { 09470 ast_hangup(chan2m); 09471 } 09472 ast_free(d); 09473 return -1; 09474 } 09475 d->park_exten = ast_strdup(park_exten); 09476 d->park_context = ast_strdup(park_context); 09477 if (!d->park_exten || !d->park_context) { 09478 ast_hangup(chan1m); 09479 ast_hangup(chan2m); 09480 ast_free(d->park_exten); 09481 ast_free(d->park_context); 09482 ast_free(d); 09483 return -1; 09484 } 09485 09486 /* Make formats okay */ 09487 chan1m->readformat = chan1->readformat; 09488 chan1m->writeformat = chan1->writeformat; 09489 09490 /* Prepare for taking over the channel */ 09491 if (ast_channel_masquerade(chan1m, chan1)) { 09492 ast_hangup(chan1m); 09493 ast_hangup(chan2m); 09494 ast_free(d->park_exten); 09495 ast_free(d->park_context); 09496 ast_free(d); 09497 return -1; 09498 } 09499 09500 /* Setup the extensions and such */ 09501 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 09502 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 09503 chan1m->priority = chan1->priority; 09504 09505 ast_do_masquerade(chan1m); 09506 09507 /* We make a clone of the peer channel too, so we can play 09508 back the announcement */ 09509 09510 /* Make formats okay */ 09511 chan2m->readformat = chan2->readformat; 09512 chan2m->writeformat = chan2->writeformat; 09513 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot); 09514 09515 /* Prepare for taking over the channel */ 09516 if (ast_channel_masquerade(chan2m, chan2)) { 09517 ast_hangup(chan1m); 09518 ast_hangup(chan2m); 09519 ast_free(d->park_exten); 09520 ast_free(d->park_context); 09521 ast_free(d); 09522 return -1; 09523 } 09524 09525 /* Setup the extensions and such */ 09526 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 09527 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 09528 chan2m->priority = chan2->priority; 09529 09530 ast_do_masquerade(chan2m); 09531 09532 d->chan1 = chan1m; /* Transferee */ 09533 d->chan2 = chan2m; /* Transferer */ 09534 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) { 09535 /* Could not start thread */ 09536 ast_hangup(chan1m); 09537 ast_hangup(chan2m); 09538 ast_free(d->park_exten); 09539 ast_free(d->park_context); 09540 ast_free(d); 09541 return -1; 09542 } 09543 return 0; 09544 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 9429 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().
09430 { 09431 struct iax_dual *d; 09432 int res; 09433 int ext = 0; 09434 09435 d = stuff; 09436 09437 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n", 09438 d->chan2->name, d->chan1->name); 09439 09440 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext); 09441 if (res) { 09442 /* Parking failed. */ 09443 ast_hangup(d->chan1); 09444 } else { 09445 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 09446 } 09447 ast_hangup(d->chan2); 09448 09449 ast_free(d->park_exten); 09450 ast_free(d->park_context); 09451 ast_free(d); 09452 return NULL; 09453 }
Definition at line 2040 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, iax_frame::cacheable, ast_frame::datalen, DIRECTION_INGRESS, iax_frame_new(), and iax_frame_wrap().
Referenced by socket_process(), and socket_process_meta().
02041 { 02042 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 02043 if (new) { 02044 size_t afdatalen = new->afdatalen; 02045 memcpy(new, fr, sizeof(*new)); 02046 iax_frame_wrap(new, &fr->af); 02047 new->afdatalen = afdatalen; 02048 new->data = NULL; 02049 new->datalen = 0; 02050 new->direction = DIRECTION_INGRESS; 02051 new->retrans = -1; 02052 } 02053 return new; 02054 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1462 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, and IAX_THREAD_TYPE_DYNAMIC.
Referenced by iax2_process_thread().
01463 { 01464 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01465 AST_LIST_LOCK(&dynamic_list); 01466 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01467 AST_LIST_UNLOCK(&dynamic_list); 01468 } else { 01469 AST_LIST_LOCK(&idle_list); 01470 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01471 AST_LIST_UNLOCK(&idle_list); 01472 } 01473 01474 return; 01475 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1155 of file chan_iax2.c.
References args, and ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01156 { 01157 va_list args; 01158 char buf[1024]; 01159 01160 va_start(args, fmt); 01161 vsnprintf(buf, sizeof(buf), fmt, args); 01162 va_end(args); 01163 01164 ast_verbose("%s", buf); 01165 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1131 of file chan_iax2.c.
References args, ast_log(), and LOG_ERROR.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1143 of file chan_iax2.c.
References args, ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01144 { 01145 va_list args; 01146 char buf[1024]; 01147 01148 va_start(args, fmt); 01149 vsnprintf(buf, sizeof(buf), fmt, args); 01150 va_end(args); 01151 01152 ast_log(LOG_WARNING, "%s", buf); 01153 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 14949 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().
14950 { 14951 static const char config[] = "iax.conf"; 14952 int x = 0; 14953 struct iax2_registry *reg = NULL; 14954 14955 if (load_objects()) { 14956 return AST_MODULE_LOAD_FAILURE; 14957 } 14958 14959 memset(iaxs, 0, sizeof(iaxs)); 14960 14961 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14962 ast_mutex_init(&iaxsl[x]); 14963 } 14964 14965 if (!(sched = ast_sched_thread_create())) { 14966 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 14967 return AST_MODULE_LOAD_FAILURE; 14968 } 14969 14970 if (!(io = io_context_create())) { 14971 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 14972 sched = ast_sched_thread_destroy(sched); 14973 return AST_MODULE_LOAD_FAILURE; 14974 } 14975 14976 if (!(netsock = ast_netsock_list_alloc())) { 14977 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 14978 io_context_destroy(io); 14979 sched = ast_sched_thread_destroy(sched); 14980 return AST_MODULE_LOAD_FAILURE; 14981 } 14982 ast_netsock_init(netsock); 14983 14984 outsock = ast_netsock_list_alloc(); 14985 if (!outsock) { 14986 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 14987 io_context_destroy(io); 14988 sched = ast_sched_thread_destroy(sched); 14989 return AST_MODULE_LOAD_FAILURE; 14990 } 14991 ast_netsock_init(outsock); 14992 14993 randomcalltokendata = ast_random(); 14994 14995 iax_set_output(iax_debug_output); 14996 iax_set_error(iax_error_output); 14997 jb_setoutput(jb_error_output, jb_warning_output, NULL); 14998 14999 if ((timer = ast_timer_open())) { 15000 ast_timer_set_rate(timer, 1000 / trunkfreq); 15001 } 15002 15003 if (set_config(config, 0) == -1) { 15004 if (timer) { 15005 ast_timer_close(timer); 15006 timer = NULL; 15007 } 15008 return AST_MODULE_LOAD_DECLINE; 15009 } 15010 15011 #ifdef TEST_FRAMEWORK 15012 AST_TEST_REGISTER(test_iax2_peers_get); 15013 AST_TEST_REGISTER(test_iax2_users_get); 15014 #endif 15015 15016 /* Register AstData providers */ 15017 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers)); 15018 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 15019 15020 ast_register_application_xml(papp, iax2_prov_app); 15021 15022 ast_custom_function_register(&iaxpeer_function); 15023 ast_custom_function_register(&iaxvar_function); 15024 15025 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers); 15026 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list); 15027 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats); 15028 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry); 15029 15030 if (ast_channel_register(&iax2_tech)) { 15031 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 15032 __unload_module(); 15033 return AST_MODULE_LOAD_FAILURE; 15034 } 15035 15036 if (ast_register_switch(&iax2_switch)) { 15037 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 15038 } 15039 15040 if (start_network_thread()) { 15041 ast_log(LOG_ERROR, "Unable to start network thread\n"); 15042 __unload_module(); 15043 return AST_MODULE_LOAD_FAILURE; 15044 } else { 15045 ast_verb(2, "IAX Ready and Listening\n"); 15046 } 15047 15048 AST_LIST_LOCK(®istrations); 15049 AST_LIST_TRAVERSE(®istrations, reg, entry) 15050 iax2_do_register(reg); 15051 AST_LIST_UNLOCK(®istrations); 15052 15053 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 15054 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 15055 15056 15057 reload_firmware(0); 15058 iax_provision_reload(0); 15059 15060 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 15061 15062 network_change_event_subscribe(); 15063 15064 return AST_MODULE_LOAD_SUCCESS; 15065 }
static int load_objects | ( | void | ) | [static] |
Definition at line 14711 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().
14712 { 14713 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 14714 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 14715 14716 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 14717 goto container_fail; 14718 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 14719 goto container_fail; 14720 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 14721 goto container_fail; 14722 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 14723 goto container_fail; 14724 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 14725 goto container_fail; 14726 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14727 goto container_fail; 14728 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14729 goto container_fail; 14730 } else if (create_callno_pools()) { 14731 goto container_fail; 14732 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) { 14733 goto container_fail; 14734 } 14735 14736 return 0; 14737 14738 container_fail: 14739 if (peers) { 14740 ao2_ref(peers, -1); 14741 } 14742 if (users) { 14743 ao2_ref(users, -1); 14744 } 14745 if (iax_peercallno_pvts) { 14746 ao2_ref(iax_peercallno_pvts, -1); 14747 } 14748 if (iax_transfercallno_pvts) { 14749 ao2_ref(iax_transfercallno_pvts, -1); 14750 } 14751 if (peercnts) { 14752 ao2_ref(peercnts, -1); 14753 } 14754 if (callno_limits) { 14755 ao2_ref(callno_limits, -1); 14756 } 14757 if (calltoken_ignores) { 14758 ao2_ref(calltoken_ignores, -1); 14759 } 14760 if (callno_pool) { 14761 ao2_ref(callno_pool, -1); 14762 } 14763 if (callno_pool_trunk) { 14764 ao2_ref(callno_pool_trunk, -1); 14765 } 14766 return AST_MODULE_LOAD_FAILURE; 14767 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5547 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
05548 { 05549 ast_mutex_lock(&iaxsl[callno0]); 05550 while (ast_mutex_trylock(&iaxsl[callno1])) { 05551 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05552 } 05553 }
static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9616 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().
09617 { 09618 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09619 jb_info jbinfo; 09620 09621 ast_mutex_lock(&iaxsl[callno]); 09622 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 09623 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) { 09624 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09625 localjitter = jbinfo.jitter; 09626 localdelay = jbinfo.current - jbinfo.min; 09627 locallost = jbinfo.frames_lost; 09628 locallosspct = jbinfo.losspct/1000; 09629 localdropped = jbinfo.frames_dropped; 09630 localooo = jbinfo.frames_ooo; 09631 localpackets = jbinfo.frames_in; 09632 } 09633 ast_debug(3, "JB STATS:%s ping=%u ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n", 09634 iaxs[callno]->owner->name, 09635 iaxs[callno]->pingtime, 09636 localjitter, 09637 localdelay, 09638 locallost, 09639 locallosspct, 09640 localdropped, 09641 localooo, 09642 localpackets, 09643 iaxs[callno]->remote_rr.jitter, 09644 iaxs[callno]->remote_rr.delay, 09645 iaxs[callno]->remote_rr.losscnt, 09646 iaxs[callno]->remote_rr.losspct/1000, 09647 iaxs[callno]->remote_rr.dropped, 09648 iaxs[callno]->remote_rr.ooo, 09649 iaxs[callno]->remote_rr.packets); 09650 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %u\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n", 09651 iaxs[callno]->owner->name, 09652 iaxs[callno]->pingtime, 09653 localjitter, 09654 localdelay, 09655 locallost, 09656 locallosspct, 09657 localdropped, 09658 localooo, 09659 localpackets, 09660 iaxs[callno]->remote_rr.jitter, 09661 iaxs[callno]->remote_rr.delay, 09662 iaxs[callno]->remote_rr.losscnt, 09663 iaxs[callno]->remote_rr.losspct/1000, 09664 iaxs[callno]->remote_rr.dropped, 09665 iaxs[callno]->remote_rr.ooo, 09666 iaxs[callno]->remote_rr.packets); 09667 } 09668 ast_mutex_unlock(&iaxsl[callno]); 09669 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 2135 of file chan_iax2.c.
References ast_debug, ast_log(), ast_mutex_lock, ast_mutex_unlock, ast_sched_thread_del, chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), iax2_sched_add(), iaxs, iaxsl, chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, replace_callno(), send_lagrq(), send_ping(), update_max_nontrunk, update_max_trunk, and callno_entry::validated.
Referenced by iax2_request(), and socket_process().
02136 { 02137 int x; 02138 int res= 0; 02139 struct callno_entry *callno_entry; 02140 if (iaxs[callno]->oseqno) { 02141 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 02142 return -1; 02143 } 02144 if (callno >= TRUNK_CALL_START) { 02145 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 02146 return -1; 02147 } 02148 02149 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 02150 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 02151 return -1; 02152 } 02153 02154 x = callno_entry->callno; 02155 ast_mutex_lock(&iaxsl[x]); 02156 02157 /*! 02158 * \note We delete these before switching the slot, because if 02159 * they fire in the meantime, they will generate a warning. 02160 */ 02161 ast_sched_thread_del(sched, iaxs[callno]->pingid); 02162 ast_sched_thread_del(sched, iaxs[callno]->lagid); 02163 iaxs[callno]->lagid = iaxs[callno]->pingid = -1; 02164 iaxs[x] = iaxs[callno]; 02165 iaxs[x]->callno = x; 02166 02167 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 02168 * before assigning the new one */ 02169 if (iaxs[x]->callno_entry) { 02170 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 02171 } 02172 iaxs[x]->callno_entry = callno_entry; 02173 02174 iaxs[callno] = NULL; 02175 /* Update the two timers that should have been started */ 02176 iaxs[x]->pingid = iax2_sched_add(sched, 02177 ping_time * 1000, send_ping, (void *)(long)x); 02178 iaxs[x]->lagid = iax2_sched_add(sched, 02179 lagrq_time * 1000, send_lagrq, (void *)(long)x); 02180 02181 if (locked) 02182 ast_mutex_unlock(&iaxsl[callno]); 02183 res = x; 02184 if (!locked) 02185 ast_mutex_unlock(&iaxsl[x]); 02186 02187 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 02188 /* We move this call from a non-trunked to a trunked call */ 02189 update_max_trunk(); 02190 update_max_nontrunk(); 02191 return res; 02192 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 7059 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
07060 { 07061 ast_cli_netstats(s, -1, 0); 07062 astman_append(s, "\r\n"); 07063 return RESULT_SUCCESS; 07064 }
static int manager_iax2_show_peer_list | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
callback to display iax peers in manager format
Definition at line 7122 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), ast_inet_ntoa(), ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag64, astman_append(), astman_get_header(), iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, peer_status(), peer_unref(), RESULT_SUCCESS, and status.
Referenced by load_module().
07123 { 07124 struct iax2_peer *peer = NULL; 07125 int peer_count = 0; 07126 char nm[20]; 07127 char status[20]; 07128 const char *id = astman_get_header(m,"ActionID"); 07129 char idtext[256] = ""; 07130 struct ast_str *encmethods = ast_str_alloca(256); 07131 struct ao2_iterator i; 07132 07133 if (!ast_strlen_zero(id)) 07134 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07135 07136 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 07137 07138 07139 i = ao2_iterator_init(peers, 0); 07140 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 07141 encmethods_to_str(peer->encmethods, &encmethods); 07142 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 07143 if (!ast_strlen_zero(peer->username)) { 07144 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 07145 } else { 07146 astman_append(s, "ObjectName: %s\r\n", peer->name); 07147 } 07148 astman_append(s, "ChanObjectType: peer\r\n"); 07149 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr)); 07150 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 07151 astman_append(s, "Mask: %s\r\n", nm); 07152 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr)); 07153 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 07154 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 07155 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 07156 peer_status(peer, status, sizeof(status)); 07157 astman_append(s, "Status: %s\r\n\r\n", status); 07158 peer_count++; 07159 } 07160 ao2_iterator_destroy(&i); 07161 07162 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 07163 return RESULT_SUCCESS; 07164 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
callback to display iax peers in manager
Definition at line 7098 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), and total.
Referenced by load_module().
07099 { 07100 static const char * const a[] = { "iax2", "show", "peers" }; 07101 const char *id = astman_get_header(m,"ActionID"); 07102 char idtext[256] = ""; 07103 int total = 0; 07104 07105 if (!ast_strlen_zero(id)) 07106 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07107 07108 astman_send_listack(s, m, "Peer status list will follow", "start"); 07109 /* List the peers in separate manager events */ 07110 __iax2_show_peers(-1, &total, s, 3, a); 07111 /* Send final confirmation */ 07112 astman_append(s, 07113 "Event: PeerlistComplete\r\n" 07114 "EventList: Complete\r\n" 07115 "ListItems: %d\r\n" 07116 "%s" 07117 "\r\n", total, idtext); 07118 return 0; 07119 }
static int manager_iax2_show_registry | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 7230 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_sockaddr_stringify(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), iax2_registry::dnsmgr, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.
Referenced by load_module().
07231 { 07232 const char *id = astman_get_header(m, "ActionID"); 07233 struct iax2_registry *reg = NULL; 07234 char idtext[256] = ""; 07235 char host[80] = ""; 07236 char perceived[80] = ""; 07237 int total = 0; 07238 07239 if (!ast_strlen_zero(id)) 07240 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07241 07242 astman_send_listack(s, m, "Registrations will follow", "start"); 07243 07244 AST_LIST_LOCK(®istrations); 07245 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07246 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07247 07248 if (reg->us.sin_addr.s_addr) { 07249 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07250 } else { 07251 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07252 } 07253 07254 astman_append(s, 07255 "Event: RegistryEntry\r\n" 07256 "%s" 07257 "Host: %s\r\n" 07258 "DNSmanager: %s\r\n" 07259 "Username: %s\r\n" 07260 "Perceived: %s\r\n" 07261 "Refresh: %d\r\n" 07262 "State: %s\r\n" 07263 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 07264 reg->refresh, regstate2str(reg->regstate)); 07265 07266 total++; 07267 } 07268 AST_LIST_UNLOCK(®istrations); 07269 07270 astman_append(s, 07271 "Event: RegistrationsComplete\r\n" 07272 "EventList: Complete\r\n" 07273 "ListItems: %d\r\n" 07274 "%s" 07275 "\r\n", total, idtext); 07276 07277 return 0; 07278 }
static int match | ( | struct sockaddr_in * | sin, | |
unsigned short | callno, | |||
unsigned short | dcallno, | |||
const struct chan_iax2_pvt * | cur, | |||
int | check_dcallno | |||
) | [static] |
Definition at line 2069 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), __get_header(), ast_parse_device_state(), ast_srtp_add_stream(), ast_srtp_change_source(), check_blacklist(), find_by_name(), find_command(), handle_updates(), internal_ao2_callback(), lua_find_extension(), misdn_update_redirecting(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), transfercallno_pvt_cmp_cb(), and xmldoc_attribute_match().
02070 { 02071 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 02072 (cur->addr.sin_port == sin->sin_port)) { 02073 /* This is the main host */ 02074 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 02075 (check_dcallno ? dcallno == cur->callno : 1) ) { 02076 /* That's us. Be sure we keep track of the peer call number */ 02077 return 1; 02078 } 02079 } 02080 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 02081 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 02082 /* We're transferring */ 02083 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 02084 return 1; 02085 } 02086 return 0; 02087 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_decrypt_key * | dcx | |||
) | [static] |
Definition at line 6315 of file chan_iax2.c.
References ast_aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
06316 { 06317 #if 0 06318 /* Debug with "fake encryption" */ 06319 int x; 06320 if (len % 16) 06321 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06322 for (x=0;x<len;x++) 06323 dst[x] = src[x] ^ 0xff; 06324 #else 06325 unsigned char lastblock[16] = { 0 }; 06326 int x; 06327 while(len > 0) { 06328 ast_aes_decrypt(src, dst, dcx); 06329 for (x=0;x<16;x++) 06330 dst[x] ^= lastblock[x]; 06331 memcpy(lastblock, src, sizeof(lastblock)); 06332 dst += 16; 06333 src += 16; 06334 len -= 16; 06335 } 06336 #endif 06337 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_encrypt_key * | ecx | |||
) | [static] |
Definition at line 6339 of file chan_iax2.c.
References ast_aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
06340 { 06341 #if 0 06342 /* Debug with "fake encryption" */ 06343 int x; 06344 if (len % 16) 06345 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06346 for (x=0;x<len;x++) 06347 dst[x] = src[x] ^ 0xff; 06348 #else 06349 unsigned char curblock[16] = { 0 }; 06350 int x; 06351 while(len > 0) { 06352 for (x=0;x<16;x++) 06353 curblock[x] ^= src[x]; 06354 ast_aes_encrypt(curblock, dst, ecx); 06355 memcpy(curblock, dst, sizeof(curblock)); 06356 dst += 16; 06357 src += 16; 06358 len -= 16; 06359 } 06360 #endif 06361 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 7915 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().
07916 { 07917 /* Select exactly one common encryption if there are any */ 07918 p->encmethods &= enc; 07919 if (p->encmethods) { 07920 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07921 p->keyrotateid = -2; 07922 } 07923 if (p->encmethods & IAX_ENCRYPT_AES128) 07924 p->encmethods = IAX_ENCRYPT_AES128; 07925 else 07926 p->encmethods = 0; 07927 } 07928 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 1359 of file chan_iax2.c.
Referenced by build_peer().
static void network_change_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 1394 of file chan_iax2.c.
References ast_debug, iax2_sched_add(), and network_change_event_sched_cb().
Referenced by network_change_event_subscribe().
01395 { 01396 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n"); 01397 if (network_change_event_sched_id == -1) { 01398 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 01399 } 01400 01401 }
static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 1381 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and iax2_do_register().
Referenced by network_change_event_cb().
01382 { 01383 struct iax2_registry *reg; 01384 network_change_event_sched_id = -1; 01385 AST_LIST_LOCK(®istrations); 01386 AST_LIST_TRAVERSE(®istrations, reg, entry) { 01387 iax2_do_register(reg); 01388 } 01389 AST_LIST_UNLOCK(®istrations); 01390 01391 return 0; 01392 }
static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 1366 of file chan_iax2.c.
References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), and network_change_event_cb().
Referenced by load_module(), and set_config().
01367 { 01368 if (!network_change_event_subscription) { 01369 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 01370 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END); 01371 } 01372 }
static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 1374 of file chan_iax2.c.
References ast_event_unsubscribe().
Referenced by __unload_module(), and set_config().
01375 { 01376 if (network_change_event_subscription) { 01377 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 01378 } 01379 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 12408 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().
12409 { 12410 if (timer) { 12411 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 12412 } 12413 12414 for (;;) { 12415 pthread_testcancel(); 12416 /* Wake up once a second just in case SIGURG was sent while 12417 * we weren't in poll(), to make sure we don't hang when trying 12418 * to unload. */ 12419 if (ast_io_wait(io, 1000) <= 0) { 12420 break; 12421 } 12422 } 12423 12424 return NULL; 12425 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static, read] |
Definition at line 1998 of file chan_iax2.c.
References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, exten, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, pvt_destructor(), jb_conf::resync_threshold, and jb_conf::target_extra.
Referenced by __find_callno().
01999 { 02000 struct chan_iax2_pvt *tmp; 02001 jb_conf jbconf; 02002 02003 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 02004 return NULL; 02005 } 02006 02007 if (ast_string_field_init(tmp, 32)) { 02008 ao2_ref(tmp, -1); 02009 tmp = NULL; 02010 return NULL; 02011 } 02012 02013 tmp->prefs = prefs; 02014 tmp->pingid = -1; 02015 tmp->lagid = -1; 02016 tmp->autoid = -1; 02017 tmp->authid = -1; 02018 tmp->initid = -1; 02019 tmp->keyrotateid = -1; 02020 02021 ast_string_field_set(tmp,exten, "s"); 02022 ast_string_field_set(tmp,host, host); 02023 02024 tmp->jb = jb_new(); 02025 tmp->jbid = -1; 02026 jbconf.max_jitterbuf = maxjitterbuffer; 02027 jbconf.resync_threshold = resyncthreshold; 02028 jbconf.max_contig_interp = maxjitterinterps; 02029 jbconf.target_extra = jittertargetextra; 02030 jb_setconf(tmp->jb,&jbconf); 02031 02032 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 02033 02034 tmp->hold_signaling = 1; 02035 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 02036 02037 return tmp; 02038 }
static void parse_dial_string | ( | char * | data, | |
struct parsed_dial_string * | pds | |||
) | [static] |
Parses an IAX dial string into its component parts.
data | the string to be parsed | |
pds | pointer to a struct parsed_dial_string to be filled in |
This function parses the string and fills the structure with pointers to its component parts. The input string will be modified.
Definition at line 5069 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
05070 { 05071 if (ast_strlen_zero(data)) 05072 return; 05073 05074 pds->peer = strsep(&data, "/"); 05075 pds->exten = strsep(&data, "/"); 05076 pds->options = data; 05077 05078 if (pds->exten) { 05079 data = pds->exten; 05080 pds->exten = strsep(&data, "@"); 05081 pds->context = data; 05082 } 05083 05084 if (strchr(pds->peer, '@')) { 05085 data = pds->peer; 05086 pds->username = strsep(&data, "@"); 05087 pds->peer = data; 05088 } 05089 05090 if (pds->username) { 05091 data = pds->username; 05092 pds->username = strsep(&data, ":"); 05093 pds->password = data; 05094 } 05095 05096 data = pds->peer; 05097 pds->peer = strsep(&data, ":"); 05098 pds->port = data; 05099 05100 /* check for a key name wrapped in [] in the secret position, if found, 05101 move it to the key field instead 05102 */ 05103 if (pds->password && (pds->password[0] == '[')) { 05104 pds->key = ast_strip_quoted(pds->password, "[", "]"); 05105 pds->password = NULL; 05106 } 05107 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1738 of file chan_iax2.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 13169 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
13170 { 13171 struct iax2_peer *peer = obj; 13172 13173 ast_set_flag64(peer, IAX_DELME); 13174 13175 return 0; 13176 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 12598 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().
12599 { 12600 struct iax2_peer *peer = obj; 12601 int callno = peer->callno; 12602 12603 ast_free_ha(peer->ha); 12604 12605 if (callno > 0) { 12606 ast_mutex_lock(&iaxsl[callno]); 12607 iax2_destroy(callno); 12608 ast_mutex_unlock(&iaxsl[callno]); 12609 } 12610 12611 register_peer_exten(peer, 0); 12612 12613 if (peer->dnsmgr) 12614 ast_dnsmgr_release(peer->dnsmgr); 12615 12616 if (peer->mwi_event_sub) 12617 ast_event_unsubscribe(peer->mwi_event_sub); 12618 12619 ast_string_field_free_memory(peer); 12620 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1728 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_objects().
01729 { 01730 const struct iax2_peer *peer = obj; 01731 01732 return ast_str_hash(peer->name); 01733 }
Definition at line 1785 of file chan_iax2.c.
References ao2_ref.
Referenced by __iax2_poke_noanswer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), iax2_poke_peer(), realtime_peer(), reg_source_db(), socket_process(), and update_registry().
01786 { 01787 ao2_ref(peer, +1); 01788 return peer; 01789 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14665 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
14666 { 14667 struct iax2_peer *peer = obj; 14668 14669 if (peer->sockfd < 0) 14670 peer->sockfd = defaultsockfd; 14671 14672 return 0; 14673 }
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 12525 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().
12526 { 12527 struct sockaddr_in sin; 12528 struct ast_sockaddr sin_tmp; 12529 int nonlocal = 1; 12530 int port = IAX_DEFAULT_PORTNO; 12531 int sockfd = defaultsockfd; 12532 char *tmp; 12533 char *addr; 12534 char *portstr; 12535 12536 tmp = ast_strdupa(srcaddr); 12537 addr = strsep(&tmp, ":"); 12538 portstr = tmp; 12539 12540 if (portstr) { 12541 port = atoi(portstr); 12542 if (port < 1) 12543 port = IAX_DEFAULT_PORTNO; 12544 } 12545 12546 sin_tmp.ss.ss_family = AF_INET; 12547 if (!ast_get_ip(&sin_tmp, addr)) { 12548 struct ast_netsock *sock; 12549 int res; 12550 12551 ast_sockaddr_to_sin(&sin_tmp, &sin); 12552 sin.sin_port = 0; 12553 sin.sin_family = AF_INET; 12554 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 12555 if (res == 0) { 12556 /* ip address valid. */ 12557 sin.sin_port = htons(port); 12558 if (!(sock = ast_netsock_find(netsock, &sin))) 12559 sock = ast_netsock_find(outsock, &sin); 12560 if (sock) { 12561 sockfd = ast_netsock_sockfd(sock); 12562 nonlocal = 0; 12563 } else { 12564 unsigned int orig_saddr = sin.sin_addr.s_addr; 12565 /* INADDR_ANY matches anyway! */ 12566 sin.sin_addr.s_addr = INADDR_ANY; 12567 if (ast_netsock_find(netsock, &sin)) { 12568 sin.sin_addr.s_addr = orig_saddr; 12569 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 12570 if (sock) { 12571 sockfd = ast_netsock_sockfd(sock); 12572 ast_netsock_unref(sock); 12573 nonlocal = 0; 12574 } else { 12575 nonlocal = 2; 12576 } 12577 } 12578 } 12579 } 12580 } 12581 12582 peer->sockfd = sockfd; 12583 12584 if (nonlocal == 1) { 12585 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 12586 srcaddr, peer->name); 12587 return -1; 12588 } else if (nonlocal == 2) { 12589 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 12590 srcaddr, peer->name); 12591 return -1; 12592 } else { 12593 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 12594 return 0; 12595 } 12596 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3812 of file chan_iax2.c.
References ast_copy_string(), iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), function_iaxpeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().
03813 { 03814 int res = 0; 03815 if (peer->maxms) { 03816 if (peer->lastms < 0) { 03817 ast_copy_string(status, "UNREACHABLE", statuslen); 03818 } else if (peer->lastms > peer->maxms) { 03819 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03820 res = 1; 03821 } else if (peer->lastms) { 03822 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03823 res = 1; 03824 } else { 03825 ast_copy_string(status, "UNKNOWN", statuslen); 03826 } 03827 } else { 03828 ast_copy_string(status, "Unmonitored", statuslen); 03829 res = -1; 03830 } 03831 return res; 03832 }
Definition at line 1791 of file chan_iax2.c.
References ao2_ref.
Referenced by __expire_registry(), __iax2_poke_noanswer(), __iax2_poke_peer_s(), __iax2_show_peers(), authenticate_reply(), build_peer(), calltoken_required(), complete_iax2_peers(), complete_iax2_unregister(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), iax2_getpeername(), iax2_getpeertrunk(), iax2_poke_noanswer(), iax2_poke_peer(), manager_iax2_show_peer_list(), peers_data_provider_get(), poke_all_peers(), prune_peers(), realtime_peer(), reg_source_db(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().
01792 { 01793 ao2_ref(peer, -1); 01794 return NULL; 01795 }
static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2432 of file chan_iax2.c.
References iax2_trunk_peer::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_inet_ntoa(), ast_log(), LOG_ERROR, OBJ_POINTER, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
02433 { 02434 struct peercnt *peercnt; 02435 unsigned long addr = sin->sin_addr.s_addr; 02436 int res = 0; 02437 struct peercnt tmp = { 02438 .addr = addr, 02439 }; 02440 02441 /* Reasoning for peercnts container lock: Two identical ip addresses 02442 * could be added by different threads at the "same time". Without the container 02443 * lock, both threads could alloc space for the same object and attempt 02444 * to link to table. With the lock, one would create the object and link 02445 * to table while the other would find the already created peercnt object 02446 * rather than creating a new one. */ 02447 ao2_lock(peercnts); 02448 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02449 ao2_lock(peercnt); 02450 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02451 ao2_lock(peercnt); 02452 /* create and set defaults */ 02453 peercnt->addr = addr; 02454 set_peercnt_limit(peercnt); 02455 /* guarantees it does not go away after unlocking table 02456 * ao2_find automatically adds this */ 02457 ao2_link(peercnts, peercnt); 02458 } else { 02459 ao2_unlock(peercnts); 02460 return -1; 02461 } 02462 02463 /* check to see if the address has hit its callno limit. If not increment cur. */ 02464 if (peercnt->limit > peercnt->cur) { 02465 peercnt->cur++; 02466 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02467 } else { /* max num call numbers for this peer has been reached! */ 02468 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02469 res = -1; 02470 } 02471 02472 /* clean up locks and ref count */ 02473 ao2_unlock(peercnt); 02474 ao2_unlock(peercnts); 02475 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02476 02477 return res; 02478 }
static int peercnt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2262 of file chan_iax2.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
static int peercnt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2256 of file chan_iax2.c.
Referenced by load_objects().
static void peercnt_modify | ( | unsigned char | reg, | |
uint16_t | limit, | |||
struct ast_sockaddr * | sockaddr | |||
) | [static] |
Definition at line 2399 of file chan_iax2.c.
References ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), ast_sockaddr_to_sin, OBJ_POINTER, and set_peercnt_limit().
Referenced by __expire_registry(), build_peer(), and update_registry().
02400 { 02401 /* this function turns off and on custom callno limits set by peer registration */ 02402 struct peercnt *peercnt; 02403 struct peercnt tmp = { 02404 .addr = 0, 02405 }; 02406 struct sockaddr_in sin; 02407 02408 ast_sockaddr_to_sin(sockaddr, &sin); 02409 02410 tmp.addr = sin.sin_addr.s_addr; 02411 02412 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02413 peercnt->reg = reg; 02414 if (limit) { 02415 peercnt->limit = limit; 02416 } else { 02417 set_peercnt_limit(peercnt); 02418 } 02419 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg); 02420 ao2_ref(peercnt, -1); /* decrement ref from find */ 02421 } 02422 }
static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2484 of file chan_iax2.c.
References ao2_lock, ao2_unlink, ao2_unlock, ast_debug, and ast_inet_ntoa().
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
02485 { 02486 struct sockaddr_in sin = { 02487 .sin_addr.s_addr = peercnt->addr, 02488 }; 02489 02490 /* 02491 * Container locked here since peercnt may be unlinked from 02492 * list. If left unlocked, peercnt_add could try and grab this 02493 * entry from the table and modify it at the "same time" this 02494 * thread attemps to unlink it. 02495 */ 02496 ao2_lock(peercnts); 02497 peercnt->cur--; 02498 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02499 /* if this was the last connection from the peer remove it from table */ 02500 if (peercnt->cur == 0) { 02501 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02502 } 02503 ao2_unlock(peercnts); 02504 }
static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2524 of file chan_iax2.c.
References ao2_find, ao2_ref, OBJ_POINTER, and peercnt_remove().
Referenced by __find_callno(), and complete_transfer().
02525 { 02526 struct peercnt *peercnt; 02527 struct peercnt tmp = { 02528 .addr = sin->sin_addr.s_addr, 02529 }; 02530 02531 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02532 peercnt_remove(peercnt); 02533 ao2_ref(peercnt, -1); /* decrement ref from find */ 02534 } 02535 return 0; 02536 }
static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2510 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02511 { 02512 struct peercnt *peercnt = (struct peercnt *) obj; 02513 02514 peercnt_remove(peercnt); 02515 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02516 02517 return 0; 02518 }
static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 14799 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.
14801 { 14802 struct ast_data *data_peer; 14803 struct iax2_peer *peer; 14804 struct ao2_iterator i; 14805 char status[20]; 14806 struct ast_str *encmethods = ast_str_alloca(256); 14807 14808 i = ao2_iterator_init(peers, 0); 14809 while ((peer = ao2_iterator_next(&i))) { 14810 data_peer = ast_data_add_node(data_root, "peer"); 14811 if (!data_peer) { 14812 peer_unref(peer); 14813 continue; 14814 } 14815 14816 ast_data_add_structure(iax2_peer, data_peer, peer); 14817 14818 ast_data_add_codecs(data_peer, "codecs", peer->capability); 14819 14820 peer_status(peer, status, sizeof(status)); 14821 ast_data_add_str(data_peer, "status", status); 14822 14823 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr)); 14824 14825 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask)); 14826 14827 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr)); 14828 14829 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK)); 14830 14831 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC)); 14832 14833 encmethods_to_str(peer->encmethods, &encmethods); 14834 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no"); 14835 14836 peer_unref(peer); 14837 14838 if (!ast_data_search_match(search, data_peer)) { 14839 ast_data_remove_node(data_root, data_peer); 14840 } 14841 } 14842 ao2_iterator_destroy(&i); 14843 14844 return 0; 14845 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 13748 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().
13749 { 13750 struct ao2_iterator i; 13751 struct iax2_peer *peer; 13752 13753 i = ao2_iterator_init(peers, 0); 13754 while ((peer = ao2_iterator_next(&i))) { 13755 iax2_poke_peer(peer, 0); 13756 peer_unref(peer); 13757 } 13758 ao2_iterator_destroy(&i); 13759 }
static int prune_addr_range_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2388 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02389 { 02390 struct addr_range *addr_range = obj; 02391 02392 return addr_range->delme ? CMP_MATCH : 0; 02393 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 13232 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().
13233 { 13234 struct iax2_peer *peer; 13235 struct ao2_iterator i; 13236 13237 i = ao2_iterator_init(peers, 0); 13238 while ((peer = ao2_iterator_next(&i))) { 13239 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 13240 unlink_peer(peer); 13241 } 13242 peer_unref(peer); 13243 } 13244 ao2_iterator_destroy(&i); 13245 }
static void prune_users | ( | void | ) | [static] |
Definition at line 13216 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().
13217 { 13218 struct iax2_user *user; 13219 struct ao2_iterator i; 13220 13221 i = ao2_iterator_init(users, 0); 13222 while ((user = ao2_iterator_next(&i))) { 13223 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 13224 ao2_unlink(users, user); 13225 } 13226 user_unref(user); 13227 } 13228 ao2_iterator_destroy(&i); 13229 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14682 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by load_objects().
14683 { 14684 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14685 14686 /* The frames_received field is used to hold whether we're matching 14687 * against a full frame or not ... */ 14688 14689 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 14690 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14691 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1951 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_mutex_lock, ast_mutex_unlock, ast_set_flag64, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, jb_frame::data, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, and sched_delay_remove().
Referenced by new_iax().
01952 { 01953 struct chan_iax2_pvt *pvt = obj; 01954 struct iax_frame *cur = NULL; 01955 struct signaling_queue_entry *s = NULL; 01956 01957 ast_mutex_lock(&iaxsl[pvt->callno]); 01958 01959 iax2_destroy_helper(pvt); 01960 01961 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01962 pvt->callno_entry = NULL; 01963 01964 /* Already gone */ 01965 ast_set_flag64(pvt, IAX_ALREADYGONE); 01966 01967 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) { 01968 /* Cancel any pending transmissions */ 01969 cur->retries = -1; 01970 } 01971 01972 ast_mutex_unlock(&iaxsl[pvt->callno]); 01973 01974 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01975 free_signaling_queue_entry(s); 01976 } 01977 01978 if (pvt->reg) { 01979 pvt->reg->callno = 0; 01980 } 01981 01982 if (!pvt->owner) { 01983 jb_frame frame; 01984 if (pvt->vars) { 01985 ast_variables_destroy(pvt->vars); 01986 pvt->vars = NULL; 01987 } 01988 01989 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01990 iax2_frame_free(frame.data); 01991 } 01992 01993 jb_destroy(pvt->jb); 01994 ast_string_field_free_memory(pvt); 01995 } 01996 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14675 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_objects().
14676 { 14677 const struct chan_iax2_pvt *pvt = obj; 14678 14679 return pvt->peercallno; 14680 }
static int queue_signalling | ( | struct chan_iax2_pvt * | pvt, | |
struct ast_frame * | f | |||
) | [static] |
All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number.
Definition at line 1926 of file chan_iax2.c.
References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, ast_malloc, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, ast_frame::frametype, free_signaling_queue_entry(), and ast_frame::ptr.
Referenced by __send_command().
01927 { 01928 struct signaling_queue_entry *qe; 01929 01930 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01931 return 1; /* do not queue this frame */ 01932 } else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01933 return -1; /* out of memory */ 01934 } 01935 01936 /* copy ast_frame into our queue entry */ 01937 qe->f = *f; 01938 if (qe->f.datalen) { 01939 /* if there is data in this frame copy it over as well */ 01940 if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) { 01941 free_signaling_queue_entry(qe); 01942 return -1; 01943 } 01944 memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen); 01945 } 01946 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, qe, next); 01947 01948 return 0; 01949 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 7896 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().
07897 { 07898 struct ast_iax2_full_hdr fh; 07899 fh.scallno = htons(src | IAX_FLAG_FULL); 07900 fh.dcallno = htons(dst); 07901 fh.ts = 0; 07902 fh.oseqno = 0; 07903 fh.iseqno = 0; 07904 fh.type = AST_FRAME_IAX; 07905 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07906 iax_outputframe(NULL, &fh, 0, sin, 0); 07907 #if 0 07908 if (option_debug) 07909 #endif 07910 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07911 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07912 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07913 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 4424 of file chan_iax2.c.
References iax2_peer::addr, ao2_link, ast_copy_flags64, ast_debug, ast_get_time_t(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_log(), ast_sched_thread_del, ast_set_flag64, ast_sockaddr_parse(), ast_sockaddr_set_port, ast_test_flag64, ast_variables_destroy(), build_peer(), iax2_peer::expire, expire_registry(), hp, iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, LOG_WARNING, ast_variable::name, ast_variable::next, PARSE_PORT_IGNORE, peer_ref(), peer_unref(), realtime_update_peer(), reg_source_db(), SENTINEL, ast_variable::value, and var.
Referenced by authenticate_reply(), calltoken_required(), find_peer(), and iax2_getpeername().
04425 { 04426 struct ast_variable *var = NULL; 04427 struct ast_variable *tmp; 04428 struct iax2_peer *peer=NULL; 04429 time_t regseconds = 0, nowtime; 04430 int dynamic=0; 04431 04432 if (peername) { 04433 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04434 if (!var && sin) 04435 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04436 } else if (sin) { 04437 char porta[25]; 04438 sprintf(porta, "%d", ntohs(sin->sin_port)); 04439 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04440 if (var) { 04441 /* We'll need the peer name in order to build the structure! */ 04442 for (tmp = var; tmp; tmp = tmp->next) { 04443 if (!strcasecmp(tmp->name, "name")) 04444 peername = tmp->value; 04445 } 04446 } 04447 } 04448 if (!var && peername) { /* Last ditch effort */ 04449 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04450 /*!\note 04451 * If this one loaded something, then we need to ensure that the host 04452 * field matched. The only reason why we can't have this as a criteria 04453 * is because we only have the IP address and the host field might be 04454 * set as a name (and the reverse PTR might not match). 04455 */ 04456 if (var && sin) { 04457 for (tmp = var; tmp; tmp = tmp->next) { 04458 if (!strcasecmp(tmp->name, "host")) { 04459 struct ast_hostent ahp; 04460 struct hostent *hp; 04461 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04462 /* No match */ 04463 ast_variables_destroy(var); 04464 var = NULL; 04465 } 04466 break; 04467 } 04468 } 04469 } 04470 } 04471 if (!var) 04472 return NULL; 04473 04474 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04475 04476 if (!peer) { 04477 ast_variables_destroy(var); 04478 return NULL; 04479 } 04480 04481 for (tmp = var; tmp; tmp = tmp->next) { 04482 /* Make sure it's not a user only... */ 04483 if (!strcasecmp(tmp->name, "type")) { 04484 if (strcasecmp(tmp->value, "friend") && 04485 strcasecmp(tmp->value, "peer")) { 04486 /* Whoops, we weren't supposed to exist! */ 04487 peer = peer_unref(peer); 04488 break; 04489 } 04490 } else if (!strcasecmp(tmp->name, "regseconds")) { 04491 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04492 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04493 if (!ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE)) { 04494 ast_log(LOG_WARNING, "Failed to parse sockaddr '%s' for ipaddr of realtime peer '%s'\n", tmp->value, tmp->name); 04495 } 04496 } else if (!strcasecmp(tmp->name, "port")) { 04497 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value)); 04498 } else if (!strcasecmp(tmp->name, "host")) { 04499 if (!strcasecmp(tmp->value, "dynamic")) 04500 dynamic = 1; 04501 } 04502 } 04503 04504 ast_variables_destroy(var); 04505 04506 if (!peer) 04507 return NULL; 04508 04509 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04510 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04511 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) { 04512 if (peer->expire > -1) { 04513 if (!ast_sched_thread_del(sched, peer->expire)) { 04514 peer->expire = -1; 04515 peer_unref(peer); 04516 } 04517 } 04518 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04519 if (peer->expire == -1) 04520 peer_unref(peer); 04521 } 04522 ao2_link(peers, peer); 04523 if (ast_test_flag64(peer, IAX_DYNAMIC)) 04524 reg_source_db(peer); 04525 } else { 04526 ast_set_flag64(peer, IAX_TEMPONLY); 04527 } 04528 04529 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04530 time(&nowtime); 04531 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04532 memset(&peer->addr, 0, sizeof(peer->addr)); 04533 realtime_update_peer(peer->name, &peer->addr, 0); 04534 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04535 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04536 } 04537 else { 04538 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04539 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04540 } 04541 } 04542 04543 return peer; 04544 }
static void realtime_update_peer | ( | const char * | peername, | |
struct ast_sockaddr * | sockaddr, | |||
time_t | regtime | |||
) | [static] |
Definition at line 4617 of file chan_iax2.c.
References ast_config_AST_SYSTEM_NAME, ast_sockaddr_port, ast_sockaddr_stringify_addr(), ast_strlen_zero(), ast_test_flag64, ast_update_realtime(), IAX_RTSAVE_SYSNAME, and SENTINEL.
Referenced by __expire_registry(), realtime_peer(), and update_registry().
04618 { 04619 char port[10]; 04620 char regseconds[20]; 04621 const char *sysname = ast_config_AST_SYSTEM_NAME; 04622 char *syslabel = NULL; 04623 04624 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04625 sysname = NULL; 04626 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME)) 04627 syslabel = "regserver"; 04628 04629 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04630 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr)); 04631 ast_update_realtime("iaxpeers", "name", peername, 04632 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 04633 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */ 04634 }
static struct iax2_user * realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static, read] |
Definition at line 4546 of file chan_iax2.c.
References ao2_link, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_set_flag64, ast_test_flag64, ast_variables_destroy(), build_user(), hp, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
Referenced by calltoken_required(), and check_access().
04547 { 04548 struct ast_variable *var; 04549 struct ast_variable *tmp; 04550 struct iax2_user *user=NULL; 04551 04552 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04553 if (!var) 04554 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04555 if (!var && sin) { 04556 char porta[6]; 04557 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04558 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04559 if (!var) 04560 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04561 } 04562 if (!var) { /* Last ditch effort */ 04563 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04564 /*!\note 04565 * If this one loaded something, then we need to ensure that the host 04566 * field matched. The only reason why we can't have this as a criteria 04567 * is because we only have the IP address and the host field might be 04568 * set as a name (and the reverse PTR might not match). 04569 */ 04570 if (var) { 04571 for (tmp = var; tmp; tmp = tmp->next) { 04572 if (!strcasecmp(tmp->name, "host")) { 04573 struct ast_hostent ahp; 04574 struct hostent *hp; 04575 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || memcmp(hp->h_addr, &sin->sin_addr, hp->h_length)) { 04576 /* No match */ 04577 ast_variables_destroy(var); 04578 var = NULL; 04579 } 04580 break; 04581 } 04582 } 04583 } 04584 } 04585 if (!var) 04586 return NULL; 04587 04588 tmp = var; 04589 while(tmp) { 04590 /* Make sure it's not a peer only... */ 04591 if (!strcasecmp(tmp->name, "type")) { 04592 if (strcasecmp(tmp->value, "friend") && 04593 strcasecmp(tmp->value, "user")) { 04594 return NULL; 04595 } 04596 } 04597 tmp = tmp->next; 04598 } 04599 04600 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)); 04601 04602 ast_variables_destroy(var); 04603 04604 if (!user) 04605 return NULL; 04606 04607 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04608 ast_set_flag64(user, IAX_RTCACHEFRIENDS); 04609 ao2_link(users, user); 04610 } else { 04611 ast_set_flag64(user, IAX_TEMPONLY); 04612 } 04613 04614 return user; 04615 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8782 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().
08783 { 08784 char data[80]; 08785 char *expiry; 08786 08787 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) { 08788 return; 08789 } 08790 08791 expiry = strrchr(data, ':'); 08792 if (!expiry) { 08793 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data); 08794 return; 08795 } 08796 *expiry++ = '\0'; 08797 08798 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) { 08799 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data); 08800 return; 08801 } 08802 08803 p->expiry = atoi(expiry); 08804 08805 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name, 08806 ast_sockaddr_stringify(&p->addr), p->expiry); 08807 08808 iax2_poke_peer(p, 0); 08809 if (p->expire > -1) { 08810 if (!ast_sched_thread_del(sched, p->expire)) { 08811 p->expire = -1; 08812 peer_unref(p); 08813 } 08814 } 08815 08816 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08817 08818 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08819 if (p->expire == -1) { 08820 peer_unref(p); 08821 } 08822 08823 if (iax2_regfunk) { 08824 iax2_regfunk(p->name, 1); 08825 } 08826 08827 register_peer_exten(p, 1); 08828 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 8699 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().
08700 { 08701 char multi[256]; 08702 char *stringp, *ext; 08703 if (!ast_strlen_zero(regcontext)) { 08704 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08705 stringp = multi; 08706 while((ext = strsep(&stringp, "&"))) { 08707 if (onoff) { 08708 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08709 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08710 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08711 } else 08712 ast_context_remove_extension(regcontext, ext, 1, NULL); 08713 } 08714 } 08715 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 8070 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().
08071 { 08072 char requeststr[256] = ""; 08073 char peer[256] = ""; 08074 char md5secret[256] = ""; 08075 char rsasecret[256] = ""; 08076 char secret[256] = ""; 08077 struct iax2_peer *p = NULL; 08078 struct ast_key *key; 08079 char *keyn; 08080 int x; 08081 int expire = 0; 08082 int res = -1; 08083 struct ast_sockaddr addr; 08084 08085 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08086 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 08087 if (ies->username) 08088 ast_copy_string(peer, ies->username, sizeof(peer)); 08089 if (ies->password) 08090 ast_copy_string(secret, ies->password, sizeof(secret)); 08091 if (ies->md5_result) 08092 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 08093 if (ies->rsa_result) 08094 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 08095 if (ies->refresh) 08096 expire = ies->refresh; 08097 08098 if (ast_strlen_zero(peer)) { 08099 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 08100 return -1; 08101 } 08102 08103 /* SLD: first call to lookup peer during registration */ 08104 ast_mutex_unlock(&iaxsl[callno]); 08105 p = find_peer(peer, 1); 08106 ast_mutex_lock(&iaxsl[callno]); 08107 if (!p || !iaxs[callno]) { 08108 if (iaxs[callno]) { 08109 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 08110 /* Anything, as long as it's non-blank */ 08111 ast_string_field_set(iaxs[callno], secret, "badsecret"); 08112 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 08113 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 08114 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 08115 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 08116 * to be plaintext, indicating it is an authmethod used by other peers on the system. 08117 * 08118 * If none of these cases exist, res will be returned as 0 without authentication indicating 08119 * an AUTHREQ needs to be sent out. */ 08120 08121 if (ast_strlen_zero(iaxs[callno]->challenge) && 08122 !(!ast_strlen_zero(secret) && plaintext)) { 08123 /* by setting res to 0, an REGAUTH will be sent */ 08124 res = 0; 08125 } 08126 } 08127 if (authdebug && !p) 08128 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08129 goto return_unref; 08130 } 08131 08132 if (!ast_test_flag64(p, IAX_DYNAMIC)) { 08133 if (authdebug) 08134 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 08135 goto return_unref; 08136 } 08137 08138 ast_sockaddr_from_sin(&addr, sin); 08139 if (!ast_apply_ha(p->ha, &addr)) { 08140 if (authdebug) 08141 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08142 goto return_unref; 08143 } 08144 ast_string_field_set(iaxs[callno], secret, p->secret); 08145 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 08146 /* Check secret against what we have on file */ 08147 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08148 if (!ast_strlen_zero(p->inkeys)) { 08149 char tmpkeys[256]; 08150 char *stringp=NULL; 08151 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 08152 stringp=tmpkeys; 08153 keyn = strsep(&stringp, ":"); 08154 while(keyn) { 08155 key = ast_key_get(keyn, AST_KEY_PUBLIC); 08156 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 08157 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08158 break; 08159 } else if (!key) 08160 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 08161 keyn = strsep(&stringp, ":"); 08162 } 08163 if (!keyn) { 08164 if (authdebug) 08165 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 08166 goto return_unref; 08167 } 08168 } else { 08169 if (authdebug) 08170 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 08171 goto return_unref; 08172 } 08173 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08174 struct MD5Context md5; 08175 unsigned char digest[16]; 08176 char *tmppw, *stringp; 08177 08178 tmppw = ast_strdupa(p->secret); 08179 stringp = tmppw; 08180 while((tmppw = strsep(&stringp, ";"))) { 08181 MD5Init(&md5); 08182 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 08183 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08184 MD5Final(digest, &md5); 08185 for (x=0;x<16;x++) 08186 sprintf(requeststr + (x << 1), "%2.2x", (unsigned)digest[x]); /* safe */ 08187 if (!strcasecmp(requeststr, md5secret)) 08188 break; 08189 } 08190 if (tmppw) { 08191 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08192 } else { 08193 if (authdebug) 08194 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 08195 goto return_unref; 08196 } 08197 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 08198 /* They've provided a plain text password and we support that */ 08199 if (strcmp(secret, p->secret)) { 08200 if (authdebug) 08201 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08202 goto return_unref; 08203 } else 08204 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08205 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 08206 /* if challenge has been sent, but no challenge response if given, reject. */ 08207 goto return_unref; 08208 } 08209 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08210 08211 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 08212 res = 0; 08213 08214 return_unref: 08215 if (iaxs[callno]) { 08216 ast_string_field_set(iaxs[callno], peer, peer); 08217 08218 /* Choose lowest expiry number */ 08219 if (expire && (expire < iaxs[callno]->expiry)) { 08220 iaxs[callno]->expiry = expire; 08221 } 08222 } 08223 08224 if (p) { 08225 peer_unref(p); 08226 } 08227 return res; 08228 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 9007 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().
09008 { 09009 struct iax_ie_data ied; 09010 struct iax2_peer *p; 09011 char challenge[10]; 09012 const char *peer_name; 09013 int sentauthmethod; 09014 09015 peer_name = ast_strdupa(iaxs[callno]->peer); 09016 09017 /* SLD: third call to find_peer in registration */ 09018 ast_mutex_unlock(&iaxsl[callno]); 09019 if ((p = find_peer(peer_name, 1))) { 09020 last_authmethod = p->authmethods; 09021 } 09022 09023 ast_mutex_lock(&iaxsl[callno]); 09024 if (!iaxs[callno]) 09025 goto return_unref; 09026 09027 memset(&ied, 0, sizeof(ied)); 09028 /* The selection of which delayed reject is sent may leak information, 09029 * if it sets a static response. For example, if a host is known to only 09030 * use MD5 authentication, then an RSA response would indicate that the 09031 * peer does not exist, and vice-versa. 09032 * Therefore, we use whatever the last peer used (which may vary over the 09033 * course of a server, which should leak minimal information). */ 09034 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 09035 if (!p) { 09036 iaxs[callno]->authmethods = sentauthmethod; 09037 } 09038 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 09039 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 09040 /* Build the challenge */ 09041 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 09042 ast_string_field_set(iaxs[callno], challenge, challenge); 09043 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 09044 } 09045 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 09046 09047 return_unref: 09048 if (p) { 09049 peer_unref(p); 09050 } 09051 09052 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 09053 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 9055 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().
09056 { 09057 struct iax2_registry *reg; 09058 /* Start pessimistic */ 09059 struct iax_ie_data ied; 09060 char peer[256] = ""; 09061 char challenge[256] = ""; 09062 int res; 09063 int authmethods = 0; 09064 if (ies->authmethods) 09065 authmethods = ies->authmethods; 09066 if (ies->username) 09067 ast_copy_string(peer, ies->username, sizeof(peer)); 09068 if (ies->challenge) 09069 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 09070 memset(&ied, 0, sizeof(ied)); 09071 reg = iaxs[callno]->reg; 09072 if (reg) { 09073 struct sockaddr_in reg_addr; 09074 09075 ast_sockaddr_to_sin(®->addr, ®_addr); 09076 09077 if (inaddrcmp(®_addr, sin)) { 09078 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 09079 return -1; 09080 } 09081 if (ast_strlen_zero(reg->secret)) { 09082 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 09083 reg->regstate = REG_STATE_NOAUTH; 09084 return -1; 09085 } 09086 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 09087 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 09088 if (reg->secret[0] == '[') { 09089 char tmpkey[256]; 09090 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 09091 tmpkey[strlen(tmpkey) - 1] = '\0'; 09092 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 09093 } else 09094 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 09095 if (!res) { 09096 reg->regstate = REG_STATE_AUTHSENT; 09097 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 09098 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 09099 } else 09100 return -1; 09101 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 09102 } else 09103 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 09104 return -1; 09105 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 7167 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_cli_iax2_show_registry(), and manager_iax2_show_registry().
07168 { 07169 switch(regstate) { 07170 case REG_STATE_UNREGISTERED: 07171 return "Unregistered"; 07172 case REG_STATE_REGSENT: 07173 return "Request Sent"; 07174 case REG_STATE_AUTHSENT: 07175 return "Auth. Sent"; 07176 case REG_STATE_REGISTERED: 07177 return "Registered"; 07178 case REG_STATE_REJECTED: 07179 return "Rejected"; 07180 case REG_STATE_TIMEOUT: 07181 return "Timeout"; 07182 case REG_STATE_NOAUTH: 07183 return "No Authentication"; 07184 default: 07185 return "Unknown"; 07186 } 07187 }
static int reload | ( | void | ) | [static] |
Definition at line 13809 of file chan_iax2.c.
References reload_config().
13810 { 13811 return reload_config(); 13812 }
static int reload_config | ( | void | ) | [static] |
Definition at line 13760 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().
13761 { 13762 static const char config[] = "iax.conf"; 13763 struct iax2_registry *reg; 13764 13765 if (set_config(config, 1) > 0) { 13766 prune_peers(); 13767 prune_users(); 13768 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13769 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13770 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 13771 trunk_timed = trunk_untimed = 0; 13772 trunk_nmaxmtu = trunk_maxmtu = 0; 13773 memset(&debugaddr, '\0', sizeof(debugaddr)); 13774 13775 AST_LIST_LOCK(®istrations); 13776 AST_LIST_TRAVERSE(®istrations, reg, entry) 13777 iax2_do_register(reg); 13778 AST_LIST_UNLOCK(®istrations); 13779 13780 /* Qualify hosts, too */ 13781 poke_all_peers(); 13782 } 13783 13784 reload_firmware(0); 13785 iax_provision_reload(1); 13786 ast_unload_realtime("iaxpeers"); 13787 13788 return 0; 13789 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 3305 of file chan_iax2.c.
References ast_config_AST_DATA_DIR, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verb, destroy_firmware(), errno, LOG_WARNING, and try_firmware().
Referenced by __unload_module(), load_module(), and reload_config().
03306 { 03307 struct iax_firmware *cur = NULL; 03308 DIR *fwd; 03309 struct dirent *de; 03310 char dir[256], fn[256]; 03311 03312 AST_LIST_LOCK(&firmwares); 03313 03314 /* Mark all as dead */ 03315 AST_LIST_TRAVERSE(&firmwares, cur, list) 03316 cur->dead = 1; 03317 03318 /* Now that we have marked them dead... load new ones */ 03319 if (!unload) { 03320 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 03321 fwd = opendir(dir); 03322 if (fwd) { 03323 while((de = readdir(fwd))) { 03324 if (de->d_name[0] != '.') { 03325 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 03326 if (!try_firmware(fn)) { 03327 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 03328 } 03329 } 03330 } 03331 closedir(fwd); 03332 } else 03333 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 03334 } 03335 03336 /* Clean up leftovers */ 03337 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 03338 if (!cur->dead) 03339 continue; 03340 AST_LIST_REMOVE_CURRENT(list); 03341 destroy_firmware(cur); 03342 } 03343 AST_LIST_TRAVERSE_SAFE_END; 03344 03345 AST_LIST_UNLOCK(&firmwares); 03346 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2223 of file chan_iax2.c.
References ao2_unlink, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), resend_with_token(), and socket_process().
02224 { 02225 if (!pvt->peercallno) { 02226 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02227 return; 02228 } 02229 02230 ao2_unlink(iax_peercallno_pvts, pvt); 02231 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2204 of file chan_iax2.c.
References ao2_unlink, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by complete_transfer(), and iax2_destroy().
02205 { 02206 if (!pvt->transfercallno) { 02207 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02208 return; 02209 } 02210 02211 ao2_unlink(iax_transfercallno_pvts, pvt); 02212 }
static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2740 of file chan_iax2.c.
References ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_log(), callno_entry::callno, LOG_ERROR, and callno_entry::validated.
Referenced by __find_callno(), make_trunk(), and sched_delay_remove().
02741 { 02742 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02743 02744 /* the callno_pool container is locked here primarily to ensure thread 02745 * safety of the total_nonval_callno_used check and decrement */ 02746 ao2_lock(callno_pool); 02747 02748 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02749 total_nonval_callno_used--; 02750 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02751 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02752 } 02753 02754 if (callno_entry->callno < TRUNK_CALL_START) { 02755 ao2_link(callno_pool, callno_entry); 02756 } else { 02757 ao2_link(callno_pool_trunk, callno_entry); 02758 } 02759 ao2_ref(callno_entry, -1); /* only container ref remains */ 02760 02761 ao2_unlock(callno_pool); 02762 return 0; 02763 }
static void requirecalltoken_mark_auto | ( | const char * | name, | |
int | subclass | |||
) | [static] |
Definition at line 4926 of file chan_iax2.c.
References ast_strlen_zero(), CALLTOKEN_AUTO, iax2_peer::calltoken_required, iax2_user::calltoken_required, CALLTOKEN_YES, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), and user_unref().
Referenced by handle_call_token().
04927 { 04928 struct iax2_user *user = NULL; 04929 struct iax2_peer *peer = NULL; 04930 04931 if (ast_strlen_zero(name)) { 04932 return; /* no username given */ 04933 } 04934 04935 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04936 user->calltoken_required = CALLTOKEN_YES; 04937 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04938 peer->calltoken_required = CALLTOKEN_YES; 04939 } 04940 04941 if (peer) { 04942 peer_unref(peer); 04943 } 04944 if (user) { 04945 user_unref(user); 04946 } 04947 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4844 of file chan_iax2.c.
References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, iax_frame::encmethods, ast_frame::frametype, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, send_command(), and ast_frame::subclass.
Referenced by socket_process().
04845 { 04846 struct chan_iax2_pvt *pvt = iaxs[callno]; 04847 int frametype = f->af.frametype; 04848 int subclass = f->af.subclass.integer; 04849 struct { 04850 struct ast_iax2_full_hdr fh; 04851 struct iax_ie_data ied; 04852 } data = { 04853 .ied.buf = { 0 }, 04854 .ied.pos = 0, 04855 }; 04856 /* total len - header len gives us the frame's IE len */ 04857 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04858 04859 if (!pvt) { 04860 return; /* this should not be possible if called from socket_process() */ 04861 } 04862 04863 /* 04864 * Check to make sure last frame sent is valid for call token resend 04865 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04866 * 2. Frame should _NOT_ already have a destination callno 04867 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04868 * 4. Pvt must have a calltoken_ie_len which represents the number of 04869 * bytes at the end of the frame used for the previous calltoken ie. 04870 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04871 * 6. Total length of f->data must be _LESS_ than size of our data struct 04872 * because f->data must be able to fit within data. 04873 */ 04874 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04875 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04876 (f->datalen > sizeof(data))) { 04877 04878 return; /* ignore resend, token was not valid for the dialog */ 04879 } 04880 04881 /* token is valid 04882 * 1. Copy frame data over 04883 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04884 * NOTE: Having the ie always be last is not protocol specified, 04885 * it is only an implementation choice. Since we only expect the ie to 04886 * be last for frames we have sent, this can no way be affected by 04887 * another end point. 04888 * 3. Remove frame from queue 04889 * 4. Free old frame 04890 * 5. Clear previous seqnos 04891 * 6. Resend with CALLTOKEN ie. 04892 */ 04893 04894 /* ---1.--- */ 04895 memcpy(&data, f->data, f->datalen); 04896 data.ied.pos = ie_data_pos; 04897 04898 /* ---2.--- */ 04899 /* move to the beginning of the calltoken ie so we can write over it */ 04900 data.ied.pos -= pvt->calltoken_ie_len; 04901 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04902 04903 /* make sure to update token length incase it ever has to be stripped off again */ 04904 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04905 04906 /* ---3.--- */ 04907 AST_LIST_REMOVE(&frame_queue[callno], f, list); 04908 04909 /* ---4.--- */ 04910 iax2_frame_free(f); 04911 04912 /* ---5.--- */ 04913 pvt->oseqno = 0; 04914 pvt->rseqno = 0; 04915 pvt->iseqno = 0; 04916 pvt->aseqno = 0; 04917 if (pvt->peercallno) { 04918 remove_by_peercallno(pvt); 04919 pvt->peercallno = 0; 04920 } 04921 04922 /* ---6.--- */ 04923 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04924 }
Definition at line 9586 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().
09587 { 09588 int i; 09589 unsigned int length, offset = 0; 09590 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09591 09592 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09593 length = ies->ospblocklength[i]; 09594 if (length != 0) { 09595 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09596 /* OSP token block length wrong, clear buffer */ 09597 offset = 0; 09598 break; 09599 } else { 09600 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09601 offset += length; 09602 } 09603 } else { 09604 break; 09605 } 09606 } 09607 *(full_osptoken + offset) = '\0'; 09608 if (strlen(full_osptoken) != offset) { 09609 /* OSP token length wrong, clear buffer */ 09610 *full_osptoken = '\0'; 09611 } 09612 09613 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09614 }
Definition at line 9575 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().
09576 { 09577 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09578 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09579 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09580 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09581 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09582 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09583 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09584 }
static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
struct callno_entry * | callno_entry | |||
) | [static] |
Definition at line 2812 of file chan_iax2.c.
References ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), and replace_callno().
Referenced by pvt_destructor().
02813 { 02814 int i; 02815 struct peercnt *peercnt; 02816 struct peercnt tmp = { 02817 .addr = sin->sin_addr.s_addr, 02818 }; 02819 02820 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02821 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02822 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02823 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02824 if (i == -1) { 02825 ao2_ref(peercnt, -1); 02826 } 02827 } 02828 02829 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02830 }
static int schedule_delivery | ( | struct iax_frame * | fr, | |
int | updatehistory, | |||
int | fromtrunk, | |||
unsigned int * | tsout | |||
) | [static] |
Definition at line 4243 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_channel_unlock, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), ast_sched_thread_del, ast_test_flag64, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, calc_rxstamp(), iax_frame::callno, ast_frame_subclass::codec, jb_frame::data, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, len(), chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process(), and socket_process_meta().
04244 { 04245 int type, len; 04246 int ret; 04247 int needfree = 0; 04248 struct ast_channel *owner = NULL; 04249 struct ast_channel *bridge = NULL; 04250 04251 /* 04252 * Clear fr->af.data if there is no data in the buffer. Things 04253 * like AST_CONTROL_HOLD without a suggested music class must 04254 * have a NULL pointer. 04255 */ 04256 if (!fr->af.datalen) { 04257 memset(&fr->af.data, 0, sizeof(fr->af.data)); 04258 } 04259 04260 /* Attempt to recover wrapped timestamps */ 04261 unwrap_timestamp(fr); 04262 04263 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 04264 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 04265 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 04266 else { 04267 #if 0 04268 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 04269 #endif 04270 fr->af.delivery = ast_tv(0,0); 04271 } 04272 04273 type = JB_TYPE_CONTROL; 04274 len = 0; 04275 04276 if(fr->af.frametype == AST_FRAME_VOICE) { 04277 type = JB_TYPE_VOICE; 04278 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000); 04279 } else if(fr->af.frametype == AST_FRAME_CNG) { 04280 type = JB_TYPE_SILENCE; 04281 } 04282 04283 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04284 if (tsout) 04285 *tsout = fr->ts; 04286 __do_deliver(fr); 04287 return -1; 04288 } 04289 04290 iax2_lock_owner(fr->callno); 04291 if (!iaxs[fr->callno]) { 04292 /* The call dissappeared so discard this frame that we could not send. */ 04293 iax2_frame_free(fr); 04294 return -1; 04295 } 04296 if ((owner = iaxs[fr->callno]->owner)) 04297 bridge = ast_bridged_channel(owner); 04298 04299 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04300 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04301 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04302 jb_frame frame; 04303 04304 ast_channel_unlock(owner); 04305 04306 /* deliver any frames in the jb */ 04307 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04308 __do_deliver(frame.data); 04309 /* __do_deliver() can make the call disappear */ 04310 if (!iaxs[fr->callno]) 04311 return -1; 04312 } 04313 04314 jb_reset(iaxs[fr->callno]->jb); 04315 04316 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid); 04317 04318 /* deliver this frame now */ 04319 if (tsout) 04320 *tsout = fr->ts; 04321 __do_deliver(fr); 04322 return -1; 04323 } 04324 if (owner) { 04325 ast_channel_unlock(owner); 04326 } 04327 04328 /* insert into jitterbuffer */ 04329 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04330 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04331 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04332 if (ret == JB_DROP) { 04333 needfree++; 04334 } else if (ret == JB_SCHED) { 04335 update_jbsched(iaxs[fr->callno]); 04336 } 04337 if (tsout) 04338 *tsout = fr->ts; 04339 if (needfree) { 04340 /* Free our iax frame */ 04341 iax2_frame_free(fr); 04342 return -1; 04343 } 04344 return 0; 04345 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1889 of file chan_iax2.c.
References ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_destroy(), iaxs, iaxsl, LOG_DEBUG, option_debug, and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01890 { 01891 unsigned short callno = PTR_TO_CALLNO(vid); 01892 ast_mutex_lock(&iaxsl[callno]); 01893 if (iaxs[callno]) { 01894 if (option_debug) { 01895 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01896 } 01897 iax2_destroy(callno); 01898 } 01899 ast_mutex_unlock(&iaxsl[callno]); 01900 return 0; 01901 }
static int send_apathetic_reply | ( | unsigned short | callno, | |
unsigned short | dcallno, | |||
struct sockaddr_in * | sin, | |||
int | command, | |||
int | ts, | |||
unsigned char | seqno, | |||
int | sockfd, | |||
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4806 of file chan_iax2.c.
References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), IAX_FLAG_RETRANS, iax_outputframe(), and iax_ie_data::pos.
Referenced by handle_call_token(), and socket_process().
04809 { 04810 struct { 04811 struct ast_iax2_full_hdr f; 04812 struct iax_ie_data ied; 04813 } data; 04814 size_t size = sizeof(struct ast_iax2_full_hdr); 04815 04816 if (ied) { 04817 size += ied->pos; 04818 memcpy(&data.ied, ied->buf, ied->pos); 04819 } 04820 04821 data.f.scallno = htons(0x8000 | callno); 04822 data.f.dcallno = htons(dcallno & ~IAX_FLAG_RETRANS); 04823 data.f.ts = htonl(ts); 04824 data.f.iseqno = seqno; 04825 data.f.oseqno = 0; 04826 data.f.type = AST_FRAME_IAX; 04827 data.f.csub = compress_subclass(command); 04828 04829 iax_outputframe(NULL, &data.f, 0, sin, size - sizeof(struct ast_iax2_full_hdr)); 04830 04831 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04832 }
static int send_command | ( | struct chan_iax2_pvt * | i, | |
char | type, | |||
int | command, | |||
unsigned int | ts, | |||
const unsigned char * | data, | |||
int | datalen, | |||
int | seqno | |||
) | [static] |
Definition at line 7612 of file chan_iax2.c.
References __send_command(), ast_debug, AST_FRAME_CONTROL, chan_iax2_pvt::callno, and iax2_is_control_frame_allowed().
Referenced by __attempt_transmit(), __send_lagrq(), __send_ping(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_key_rotate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), resend_with_token(), send_command_locked(), and socket_process().
07613 { 07614 if (type == AST_FRAME_CONTROL && !iax2_is_control_frame_allowed(command)) { 07615 /* Control frame should not go out on the wire. */ 07616 ast_debug(2, "Callno %d: Blocked sending control frame %d.\n", 07617 i->callno, command); 07618 return 0; 07619 } 07620 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07621 }
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 7637 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().
07638 { 07639 int call_num = i->callno; 07640 /* It is assumed that the callno has already been locked */ 07641 iax2_predestroy(i->callno); 07642 if (!iaxs[call_num]) 07643 return -1; 07644 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07645 }
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 7647 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07648 { 07649 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07650 }
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 7623 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().
07624 { 07625 int res; 07626 ast_mutex_lock(&iaxsl[callno]); 07627 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07628 ast_mutex_unlock(&iaxsl[callno]); 07629 return res; 07630 }
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 7652 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07653 { 07654 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07655 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1675 of file chan_iax2.c.
References __send_lagrq(), ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::lagid, and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01676 { 01677 int callno = (long) data; 01678 ast_mutex_lock(&iaxsl[callno]); 01679 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) { 01680 iaxs[callno]->lagid = -1; 01681 } 01682 ast_mutex_unlock(&iaxsl[callno]); 01683 01684 #ifdef SCHED_MULTITHREADED 01685 if (schedule_action(__send_lagrq, data)) 01686 #endif 01687 __send_lagrq(data); 01688 return 0; 01689 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3418 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax2_trunk_peer::addr, ast_debug, ast_inet_ntoa(), iax_frame::callno, iax_frame::data, iax_frame::datalen, errno, handle_error(), iax_outputframe(), iaxs, chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.
Referenced by __attempt_transmit(), iax2_send(), transmit_frame(), and vnak_retransmit().
03419 { 03420 int res; 03421 int callno = f->callno; 03422 03423 /* Don't send if there was an error, but return error instead */ 03424 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03425 return -1; 03426 03427 /* Called with iaxsl held */ 03428 if (iaxdebug) 03429 ast_debug(3, "Sending %u on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port)); 03430 03431 if (f->transfer) { 03432 iax_outputframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03433 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03434 } else { 03435 iax_outputframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03436 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03437 } 03438 if (res < 0) { 03439 if (iaxdebug) 03440 ast_debug(1, "Received error: %s\n", strerror(errno)); 03441 handle_error(); 03442 } else 03443 res = 0; 03444 03445 return res; 03446 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1608 of file chan_iax2.c.
References __send_ping(), ast_mutex_lock, ast_mutex_unlock, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::pingid, and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01609 { 01610 int callno = (long) data; 01611 ast_mutex_lock(&iaxsl[callno]); 01612 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) { 01613 iaxs[callno]->pingid = -1; 01614 } 01615 ast_mutex_unlock(&iaxsl[callno]); 01616 01617 #ifdef SCHED_MULTITHREADED 01618 if (schedule_action(__send_ping, data)) 01619 #endif 01620 __send_ping(data); 01621 01622 return 0; 01623 }
static void send_signaling | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point.
Definition at line 1913 of file chan_iax2.c.
References AST_LIST_REMOVE_HEAD, signaling_queue_entry::f, free_signaling_queue_entry(), and iax2_send().
Referenced by socket_process().
01914 { 01915 struct signaling_queue_entry *s = NULL; 01916 01917 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01918 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01919 free_signaling_queue_entry(s); 01920 } 01921 pvt->hold_signaling = 0; 01922 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 9239 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().
09240 { 09241 int res = 0; 09242 struct iax_frame *fr; 09243 struct ast_iax2_meta_hdr *meta; 09244 struct ast_iax2_meta_trunk_hdr *mth; 09245 int calls = 0; 09246 09247 /* Point to frame */ 09248 fr = (struct iax_frame *)tpeer->trunkdata; 09249 /* Point to meta data */ 09250 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 09251 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 09252 if (tpeer->trunkdatalen) { 09253 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 09254 meta->zeros = 0; 09255 meta->metacmd = IAX_META_TRUNK; 09256 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) 09257 meta->cmddata = IAX_META_TRUNK_MINI; 09258 else 09259 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 09260 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 09261 /* And the rest of the ast_iax2 header */ 09262 fr->direction = DIRECTION_OUTGRESS; 09263 fr->retrans = -1; 09264 fr->transfer = 0; 09265 /* Any appropriate call will do */ 09266 fr->data = fr->afdata; 09267 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 09268 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 09269 calls = tpeer->calls; 09270 #if 0 09271 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)); 09272 #endif 09273 /* Reset transmit trunk side data */ 09274 tpeer->trunkdatalen = 0; 09275 tpeer->calls = 0; 09276 } 09277 if (res < 0) 09278 return res; 09279 return calls; 09280 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 13264 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().
13265 { 13266 struct ast_config *cfg, *ucfg; 13267 format_t capability = iax2_capability; 13268 struct ast_variable *v; 13269 char *cat; 13270 const char *utype; 13271 const char *tosval; 13272 int format; 13273 int portno = IAX_DEFAULT_PORTNO; 13274 int x; 13275 int mtuv; 13276 int subscribe_network_change = 1; 13277 struct iax2_user *user; 13278 struct iax2_peer *peer; 13279 struct ast_netsock *ns; 13280 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 13281 #if 0 13282 static unsigned short int last_port=0; 13283 #endif 13284 13285 cfg = ast_config_load(config_file, config_flags); 13286 13287 if (!cfg) { 13288 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 13289 return -1; 13290 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 13291 ucfg = ast_config_load("users.conf", config_flags); 13292 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 13293 return 0; 13294 /* Otherwise we need to reread both files */ 13295 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13296 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 13297 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13298 ast_config_destroy(ucfg); 13299 return 0; 13300 } 13301 if (!cfg) { 13302 /* should have been able to load the config here */ 13303 ast_log(LOG_ERROR, "Unable to load config %s again\n", config_file); 13304 return -1; 13305 } 13306 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 13307 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13308 return 0; 13309 } else { /* iax.conf changed, gotta reread users.conf, too */ 13310 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13311 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 13312 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 13313 ast_config_destroy(cfg); 13314 return 0; 13315 } 13316 } 13317 13318 if (reload) { 13319 set_config_destroy(); 13320 } 13321 13322 /* Reset global codec prefs */ 13323 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 13324 13325 /* Reset Global Flags */ 13326 memset(&globalflags, 0, sizeof(globalflags)); 13327 ast_set_flag64(&globalflags, IAX_RTUPDATE); 13328 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13329 13330 #ifdef SO_NO_CHECK 13331 nochecksums = 0; 13332 #endif 13333 /* Reset default parking lot */ 13334 default_parkinglot[0] = '\0'; 13335 13336 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13337 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13338 global_max_trunk_mtu = MAX_TRUNK_MTU; 13339 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 13340 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 13341 13342 maxauthreq = 3; 13343 13344 srvlookup = 0; 13345 13346 v = ast_variable_browse(cfg, "general"); 13347 13348 /* Seed initial tos value */ 13349 tosval = ast_variable_retrieve(cfg, "general", "tos"); 13350 if (tosval) { 13351 if (ast_str2tos(tosval, &qos.tos)) 13352 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 13353 } 13354 /* Seed initial cos value */ 13355 tosval = ast_variable_retrieve(cfg, "general", "cos"); 13356 if (tosval) { 13357 if (ast_str2cos(tosval, &qos.cos)) 13358 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 13359 } 13360 while(v) { 13361 if (!strcasecmp(v->name, "bindport")){ 13362 if (reload) 13363 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 13364 else 13365 portno = atoi(v->value); 13366 } else if (!strcasecmp(v->name, "pingtime")) 13367 ping_time = atoi(v->value); 13368 else if (!strcasecmp(v->name, "iaxthreadcount")) { 13369 if (reload) { 13370 if (atoi(v->value) != iaxthreadcount) 13371 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 13372 } else { 13373 iaxthreadcount = atoi(v->value); 13374 if (iaxthreadcount < 1) { 13375 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 13376 iaxthreadcount = 1; 13377 } else if (iaxthreadcount > 256) { 13378 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 13379 iaxthreadcount = 256; 13380 } 13381 } 13382 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 13383 if (reload) { 13384 AST_LIST_LOCK(&dynamic_list); 13385 iaxmaxthreadcount = atoi(v->value); 13386 AST_LIST_UNLOCK(&dynamic_list); 13387 } else { 13388 iaxmaxthreadcount = atoi(v->value); 13389 if (iaxmaxthreadcount < 0) { 13390 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 13391 iaxmaxthreadcount = 0; 13392 } else if (iaxmaxthreadcount > 256) { 13393 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 13394 iaxmaxthreadcount = 256; 13395 } 13396 } 13397 } else if (!strcasecmp(v->name, "nochecksums")) { 13398 #ifdef SO_NO_CHECK 13399 if (ast_true(v->value)) 13400 nochecksums = 1; 13401 else 13402 nochecksums = 0; 13403 #else 13404 if (ast_true(v->value)) 13405 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 13406 #endif 13407 } 13408 else if (!strcasecmp(v->name, "maxjitterbuffer")) 13409 maxjitterbuffer = atoi(v->value); 13410 else if (!strcasecmp(v->name, "resyncthreshold")) 13411 resyncthreshold = atoi(v->value); 13412 else if (!strcasecmp(v->name, "maxjitterinterps")) 13413 maxjitterinterps = atoi(v->value); 13414 else if (!strcasecmp(v->name, "jittertargetextra")) 13415 jittertargetextra = atoi(v->value); 13416 else if (!strcasecmp(v->name, "lagrqtime")) 13417 lagrq_time = atoi(v->value); 13418 else if (!strcasecmp(v->name, "maxregexpire")) 13419 max_reg_expire = atoi(v->value); 13420 else if (!strcasecmp(v->name, "minregexpire")) 13421 min_reg_expire = atoi(v->value); 13422 else if (!strcasecmp(v->name, "bindaddr")) { 13423 if (reload) { 13424 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 13425 } else { 13426 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 13427 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 13428 } else { 13429 if (strchr(v->value, ':')) 13430 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 13431 else 13432 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 13433 if (defaultsockfd < 0) 13434 defaultsockfd = ast_netsock_sockfd(ns); 13435 ast_netsock_unref(ns); 13436 } 13437 } 13438 } else if (!strcasecmp(v->name, "authdebug")) { 13439 authdebug = ast_true(v->value); 13440 } else if (!strcasecmp(v->name, "encryption")) { 13441 iax2_encryption |= get_encrypt_methods(v->value); 13442 if (!iax2_encryption) { 13443 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13444 } 13445 } else if (!strcasecmp(v->name, "forceencryption")) { 13446 if (ast_false(v->value)) { 13447 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13448 } else { 13449 iax2_encryption |= get_encrypt_methods(v->value); 13450 if (iax2_encryption) { 13451 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13452 } 13453 } 13454 } else if (!strcasecmp(v->name, "transfer")) { 13455 if (!strcasecmp(v->value, "mediaonly")) { 13456 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13457 } else if (ast_true(v->value)) { 13458 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13459 } else 13460 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13461 } else if (!strcasecmp(v->name, "codecpriority")) { 13462 if(!strcasecmp(v->value, "caller")) 13463 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST); 13464 else if(!strcasecmp(v->value, "disabled")) 13465 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13466 else if(!strcasecmp(v->value, "reqonly")) { 13467 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP); 13468 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13469 } 13470 } else if (!strcasecmp(v->name, "jitterbuffer")) 13471 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 13472 else if (!strcasecmp(v->name, "forcejitterbuffer")) 13473 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 13474 else if (!strcasecmp(v->name, "delayreject")) 13475 delayreject = ast_true(v->value); 13476 else if (!strcasecmp(v->name, "allowfwdownload")) 13477 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 13478 else if (!strcasecmp(v->name, "rtcachefriends")) 13479 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 13480 else if (!strcasecmp(v->name, "rtignoreregexpire")) 13481 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 13482 else if (!strcasecmp(v->name, "rtupdate")) 13483 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE); 13484 else if (!strcasecmp(v->name, "rtsavesysname")) 13485 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME); 13486 else if (!strcasecmp(v->name, "trunktimestamps")) 13487 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 13488 else if (!strcasecmp(v->name, "rtautoclear")) { 13489 int i = atoi(v->value); 13490 if(i > 0) 13491 global_rtautoclear = i; 13492 else 13493 i = 0; 13494 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 13495 } else if (!strcasecmp(v->name, "trunkfreq")) { 13496 trunkfreq = atoi(v->value); 13497 if (trunkfreq < 10) { 13498 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 10ms instead.\n"); 13499 trunkfreq = 10; 13500 } else if (trunkfreq > 1000) { 13501 ast_log(LOG_NOTICE, "trunkfreq must be between 10ms and 1000ms, using 1000ms instead.\n"); 13502 trunkfreq = 1000; 13503 } 13504 if (timer) { 13505 ast_timer_set_rate(timer, 1000 / trunkfreq); 13506 } 13507 } else if (!strcasecmp(v->name, "trunkmtu")) { 13508 mtuv = atoi(v->value); 13509 if (mtuv == 0 ) 13510 global_max_trunk_mtu = 0; 13511 else if (mtuv >= 172 && mtuv < 4000) 13512 global_max_trunk_mtu = mtuv; 13513 else 13514 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 13515 mtuv, v->lineno); 13516 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 13517 trunkmaxsize = atoi(v->value); 13518 if (trunkmaxsize == 0) 13519 trunkmaxsize = MAX_TRUNKDATA; 13520 } else if (!strcasecmp(v->name, "autokill")) { 13521 if (sscanf(v->value, "%30d", &x) == 1) { 13522 if (x >= 0) 13523 autokill = x; 13524 else 13525 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 13526 } else if (ast_true(v->value)) { 13527 autokill = DEFAULT_MAXMS; 13528 } else { 13529 autokill = 0; 13530 } 13531 } else if (!strcasecmp(v->name, "bandwidth")) { 13532 if (!strcasecmp(v->value, "low")) { 13533 capability = IAX_CAPABILITY_LOWBANDWIDTH; 13534 } else if (!strcasecmp(v->value, "medium")) { 13535 capability = IAX_CAPABILITY_MEDBANDWIDTH; 13536 } else if (!strcasecmp(v->value, "high")) { 13537 capability = IAX_CAPABILITY_FULLBANDWIDTH; 13538 } else 13539 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 13540 } else if (!strcasecmp(v->name, "allow")) { 13541 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 13542 } else if (!strcasecmp(v->name, "disallow")) { 13543 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 13544 } else if (!strcasecmp(v->name, "register")) { 13545 iax2_register(v->value, v->lineno); 13546 } else if (!strcasecmp(v->name, "iaxcompat")) { 13547 iaxcompat = ast_true(v->value); 13548 } else if (!strcasecmp(v->name, "regcontext")) { 13549 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 13550 /* Create context if it doesn't exist already */ 13551 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 13552 } else if (!strcasecmp(v->name, "tos")) { 13553 if (ast_str2tos(v->value, &qos.tos)) 13554 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 13555 } else if (!strcasecmp(v->name, "cos")) { 13556 if (ast_str2cos(v->value, &qos.cos)) 13557 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 13558 } else if (!strcasecmp(v->name, "parkinglot")) { 13559 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 13560 } else if (!strcasecmp(v->name, "accountcode")) { 13561 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 13562 } else if (!strcasecmp(v->name, "mohinterpret")) { 13563 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 13564 } else if (!strcasecmp(v->name, "mohsuggest")) { 13565 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 13566 } else if (!strcasecmp(v->name, "amaflags")) { 13567 format = ast_cdr_amaflags2int(v->value); 13568 if (format < 0) { 13569 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13570 } else { 13571 amaflags = format; 13572 } 13573 } else if (!strcasecmp(v->name, "language")) { 13574 ast_copy_string(language, v->value, sizeof(language)); 13575 } else if (!strcasecmp(v->name, "maxauthreq")) { 13576 maxauthreq = atoi(v->value); 13577 if (maxauthreq < 0) 13578 maxauthreq = 0; 13579 } else if (!strcasecmp(v->name, "adsi")) { 13580 adsi = ast_true(v->value); 13581 } else if (!strcasecmp(v->name, "srvlookup")) { 13582 srvlookup = ast_true(v->value); 13583 } else if (!strcasecmp(v->name, "connectedline")) { 13584 if (ast_true(v->value)) { 13585 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13586 } else if (!strcasecmp(v->value, "send")) { 13587 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13588 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13589 } else if (!strcasecmp(v->value, "receive")) { 13590 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13591 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13592 } else { 13593 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13594 } 13595 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 13596 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 13597 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 13598 } 13599 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 13600 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 13601 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); 13602 } 13603 } else if (!strcasecmp(v->name, "calltokenoptional")) { 13604 if (add_calltoken_ignore(v->value)) { 13605 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 13606 } 13607 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 13608 if (ast_true(v->value)) { 13609 subscribe_network_change = 1; 13610 } else if (ast_false(v->value)) { 13611 subscribe_network_change = 0; 13612 } else { 13613 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 13614 } 13615 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 13616 if (ast_true(v->value)) { 13617 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13618 } else if (ast_false(v->value)) { 13619 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID); 13620 } else { 13621 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 13622 } 13623 }/*else if (strcasecmp(v->name,"type")) */ 13624 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13625 v = v->next; 13626 } 13627 13628 if (subscribe_network_change) { 13629 network_change_event_subscribe(); 13630 } else { 13631 network_change_event_unsubscribe(); 13632 } 13633 13634 if (defaultsockfd < 0) { 13635 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 13636 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 13637 } else { 13638 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 13639 defaultsockfd = ast_netsock_sockfd(ns); 13640 ast_netsock_unref(ns); 13641 } 13642 } 13643 if (reload) { 13644 ast_netsock_release(outsock); 13645 outsock = ast_netsock_list_alloc(); 13646 if (!outsock) { 13647 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13648 return -1; 13649 } 13650 ast_netsock_init(outsock); 13651 } 13652 13653 if (min_reg_expire > max_reg_expire) { 13654 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 13655 min_reg_expire, max_reg_expire, max_reg_expire); 13656 min_reg_expire = max_reg_expire; 13657 } 13658 iax2_capability = capability; 13659 13660 if (ucfg) { 13661 struct ast_variable *gen; 13662 int genhasiax; 13663 int genregisteriax; 13664 const char *hasiax, *registeriax; 13665 13666 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 13667 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 13668 gen = ast_variable_browse(ucfg, "general"); 13669 cat = ast_category_browse(ucfg, NULL); 13670 while (cat) { 13671 if (strcasecmp(cat, "general")) { 13672 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 13673 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 13674 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 13675 /* Start with general parameters, then specific parameters, user and peer */ 13676 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 13677 if (user) { 13678 ao2_link(users, user); 13679 user = user_unref(user); 13680 } 13681 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 13682 if (peer) { 13683 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13684 reg_source_db(peer); 13685 ao2_link(peers, peer); 13686 peer = peer_unref(peer); 13687 } 13688 } 13689 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 13690 char tmp[256]; 13691 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 13692 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 13693 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 13694 if (!host) 13695 host = ast_variable_retrieve(ucfg, "general", "host"); 13696 if (!username) 13697 username = ast_variable_retrieve(ucfg, "general", "username"); 13698 if (!secret) 13699 secret = ast_variable_retrieve(ucfg, "general", "secret"); 13700 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 13701 if (!ast_strlen_zero(secret)) 13702 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 13703 else 13704 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 13705 iax2_register(tmp, 0); 13706 } 13707 } 13708 } 13709 cat = ast_category_browse(ucfg, cat); 13710 } 13711 ast_config_destroy(ucfg); 13712 } 13713 13714 cat = ast_category_browse(cfg, NULL); 13715 while(cat) { 13716 if (strcasecmp(cat, "general")) { 13717 utype = ast_variable_retrieve(cfg, cat, "type"); 13718 if (!strcasecmp(cat, "callnumberlimits")) { 13719 build_callno_limits(ast_variable_browse(cfg, cat)); 13720 } else if (utype) { 13721 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 13722 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 13723 if (user) { 13724 ao2_link(users, user); 13725 user = user_unref(user); 13726 } 13727 } 13728 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 13729 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 13730 if (peer) { 13731 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13732 reg_source_db(peer); 13733 ao2_link(peers, peer); 13734 peer = peer_unref(peer); 13735 } 13736 } else if (strcasecmp(utype, "user")) { 13737 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 13738 } 13739 } else 13740 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 13741 } 13742 cat = ast_category_browse(cfg, cat); 13743 } 13744 ast_config_destroy(cfg); 13745 return 1; 13746 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 13247 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().
13248 { 13249 strcpy(accountcode, ""); 13250 strcpy(language, ""); 13251 strcpy(mohinterpret, ""); 13252 strcpy(mohsuggest, ""); 13253 trunkmaxsize = MAX_TRUNKDATA; 13254 amaflags = 0; 13255 delayreject = 0; 13256 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | 13257 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13258 delete_users(); 13259 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 13260 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 13261 }
static void set_hangup_source_and_cause | ( | int | callno, | |
unsigned char | causecode | |||
) | [static] |
Definition at line 10030 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().
10031 { 10032 iax2_lock_owner(callno); 10033 if (iaxs[callno] && iaxs[callno]->owner) { 10034 struct ast_channel *owner; 10035 const char *name; 10036 10037 owner = iaxs[callno]->owner; 10038 if (causecode) { 10039 owner->hangupcause = causecode; 10040 } 10041 name = ast_strdupa(owner->name); 10042 ast_channel_ref(owner); 10043 ast_channel_unlock(owner); 10044 ast_mutex_unlock(&iaxsl[callno]); 10045 ast_set_hangupsource(owner, name, 0); 10046 ast_channel_unref(owner); 10047 ast_mutex_lock(&iaxsl[callno]); 10048 } 10049 }
static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2348 of file chan_iax2.c.
References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), and addr_range::limit.
Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().
02349 { 02350 uint16_t limit = global_maxcallno; 02351 struct addr_range *addr_range; 02352 struct sockaddr_in sin = { 02353 .sin_addr.s_addr = peercnt->addr, 02354 }; 02355 02356 02357 if (peercnt->reg && peercnt->limit) { 02358 return; /* this peercnt has a custom limit set by a registration */ 02359 } 02360 02361 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02362 limit = addr_range->limit; 02363 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02364 ao2_ref(addr_range, -1); 02365 } 02366 02367 peercnt->limit = limit; 02368 }
static int set_peercnt_limit_all_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2374 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02375 { 02376 struct peercnt *peercnt = obj; 02377 02378 set_peercnt_limit(peercnt); 02379 ast_debug(1, "Reset limits for peercnts table\n"); 02380 02381 return 0; 02382 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 1052 of file chan_iax2.c.
References ast_cond_signal, ast_mutex_lock, and ast_mutex_unlock.
Referenced by __schedule_action(), cleanup_thread_list(), iax2_process_thread(), and socket_read().
01053 { 01054 ast_mutex_lock(lock); 01055 ast_cond_signal(cond); 01056 ast_mutex_unlock(lock); 01057 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 10051 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_aes_set_decrypt_key(), ast_alloca, ast_async_goto(), ast_best_codec(), ast_bridged_channel(), ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_NO_ROUTE_DESTINATION, ast_channel_datastore_add(), ast_channel_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_clear_flag64, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, ast_devstate_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_getformatname_multiple(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_event, ast_mutex_lock, ast_mutex_trylock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_sched_thread_del, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax_frame::cacheable, calc_timestamp(), iax_ies::called_number, ast_channel::caller, chan_iax2_pvt::calling_pres, iax2_peer::callno, chan_iax2_pvt::callno, iax_frame::callno, iax_ies::calltoken, iax_ies::calltokendata, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, cid_name, cid_num, ast_frame_subclass::codec, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), context, ast_iax2_full_hdr::csub, ast_datastore::data, ast_frame::data, ast_frame::datalen, DATASTORE_INHERIT_FOREVER, ast_iax2_full_hdr::dcallno, DEADLOCK_AVOIDANCE, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, ast_frame::frametype, iax_ies::fwdesc, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_is_control_frame_allowed(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, IAX_FORCE_ENCRYPT, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_IAX_UNKNOWN, IAX_IMMEDIATE, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxs, iaxsl, ast_party_caller::id, ast_party_connected_line::id, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::initid, ast_frame_subclass::integer, chan_iax2_pvt::iseqno, iax_frame::iseqno, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_frame::len, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, iax_ies::musiconhold, ast_party_id::name, ast_variable::name, ast_channel::nativeformats, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, ast_variable::next, ast_party_id::number, ast_frame::offset, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, ast_party_name::presentation, ast_party_number::presentation, iax_ies::provver, iax_ies::provverpres, ast_frame::ptr, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, S_COR, S_OR, ast_frame::samples, save_osptoken(), save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, set_hangup_source_and_cause(), iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_party_name::str, ast_party_number::str, ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_NONE, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, ast_iax2_full_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, ast_party_name::valid, ast_party_number::valid, ast_variable::value, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames(), and iax2_process_thread().
10052 { 10053 struct sockaddr_in sin; 10054 int res; 10055 int updatehistory=1; 10056 int new = NEW_PREVENT; 10057 int dcallno = 0; 10058 char decrypted = 0; 10059 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 10060 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 10061 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 10062 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 10063 struct iax_frame *fr; 10064 struct iax_frame *cur; 10065 struct ast_frame f = { 0, }; 10066 struct ast_channel *c = NULL; 10067 struct iax2_dpcache *dp; 10068 struct iax2_peer *peer; 10069 struct iax_ies ies; 10070 struct iax_ie_data ied0, ied1; 10071 format_t format; 10072 int fd; 10073 int exists; 10074 int minivid = 0; 10075 char empty[32]=""; /* Safety measure */ 10076 struct iax_frame *duped_fr; 10077 char host_pref_buf[128]; 10078 char caller_pref_buf[128]; 10079 struct ast_codec_pref pref; 10080 char *using_prefs = "mine"; 10081 10082 /* allocate an iax_frame with 4096 bytes of data buffer */ 10083 fr = ast_alloca(sizeof(*fr) + 4096); 10084 memset(fr, 0, sizeof(*fr)); 10085 fr->afdatalen = 4096; /* From ast_alloca() above */ 10086 10087 /* Copy frequently used parameters to the stack */ 10088 res = thread->buf_len; 10089 fd = thread->iofd; 10090 memcpy(&sin, &thread->iosin, sizeof(sin)); 10091 10092 if (res < sizeof(*mh)) { 10093 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 10094 return 1; 10095 } 10096 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 10097 if (res < sizeof(*vh)) { 10098 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)); 10099 return 1; 10100 } 10101 10102 /* This is a video frame, get call number */ 10103 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 10104 minivid = 1; 10105 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 10106 return socket_process_meta(res, meta, &sin, fd, fr); 10107 10108 #ifdef DEBUG_SUPPORT 10109 if (res >= sizeof(*fh)) 10110 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 10111 #endif 10112 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10113 if (res < sizeof(*fh)) { 10114 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)); 10115 return 1; 10116 } 10117 10118 /* Get the destination call number */ 10119 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 10120 10121 10122 /* check to make sure this full frame isn't encrypted before we attempt 10123 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 10124 * callno is not found here, that just means one hasn't been allocated for 10125 * this connection yet. */ 10126 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 10127 ast_mutex_lock(&iaxsl[fr->callno]); 10128 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { 10129 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10130 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10131 ast_mutex_unlock(&iaxsl[fr->callno]); 10132 return 1; 10133 } 10134 decrypted = 1; 10135 } 10136 ast_mutex_unlock(&iaxsl[fr->callno]); 10137 } 10138 10139 /* Retrieve the type and subclass */ 10140 f.frametype = fh->type; 10141 if (f.frametype == AST_FRAME_VIDEO) { 10142 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 10143 } else if (f.frametype == AST_FRAME_VOICE) { 10144 f.subclass.codec = uncompress_subclass(fh->csub); 10145 } else { 10146 f.subclass.integer = uncompress_subclass(fh->csub); 10147 } 10148 10149 /* Deal with POKE/PONG without allocating a callno */ 10150 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) { 10151 /* Reply back with a PONG, but don't care about the result. */ 10152 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10153 return 1; 10154 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) { 10155 /* Ignore */ 10156 return 1; 10157 } 10158 10159 f.datalen = res - sizeof(*fh); 10160 if (f.datalen) { 10161 if (f.frametype == AST_FRAME_IAX) { 10162 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 10163 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 10164 ast_variables_destroy(ies.vars); 10165 return 1; 10166 } 10167 f.data.ptr = NULL; 10168 f.datalen = 0; 10169 } else { 10170 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 10171 memset(&ies, 0, sizeof(ies)); 10172 } 10173 } else { 10174 if (f.frametype == AST_FRAME_IAX) 10175 f.data.ptr = NULL; 10176 else 10177 f.data.ptr = empty; 10178 memset(&ies, 0, sizeof(ies)); 10179 } 10180 10181 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) { 10182 /* only set NEW_ALLOW if calltoken checks out */ 10183 if (handle_call_token(fh, &ies, &sin, fd)) { 10184 ast_variables_destroy(ies.vars); 10185 return 1; 10186 } 10187 10188 if (ies.calltoken && ies.calltokendata) { 10189 /* if we've gotten this far, and the calltoken ie data exists, 10190 * then calltoken validation _MUST_ have taken place. If calltoken 10191 * data is provided, it is always validated reguardless of any 10192 * calltokenoptional or requirecalltoken options */ 10193 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 10194 } else { 10195 new = NEW_ALLOW; 10196 } 10197 } 10198 } else { 10199 /* Don't know anything about it yet */ 10200 f.frametype = AST_FRAME_NULL; 10201 f.subclass.integer = 0; 10202 memset(&ies, 0, sizeof(ies)); 10203 } 10204 10205 if (!fr->callno) { 10206 int check_dcallno = 0; 10207 10208 /* 10209 * We enforce accurate destination call numbers for ACKs. This forces the other 10210 * end to know the destination call number before call setup can complete. 10211 * 10212 * Discussed in the following thread: 10213 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 10214 */ 10215 10216 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) { 10217 check_dcallno = 1; 10218 } 10219 10220 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 10221 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) { 10222 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10223 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) { 10224 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10225 } 10226 ast_variables_destroy(ies.vars); 10227 return 1; 10228 } 10229 } 10230 10231 if (fr->callno > 0) 10232 ast_mutex_lock(&iaxsl[fr->callno]); 10233 10234 if (!fr->callno || !iaxs[fr->callno]) { 10235 /* A call arrived for a nonexistent destination. Unless it's an "inval" 10236 frame, reply with an inval */ 10237 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10238 /* We can only raw hangup control frames */ 10239 if (((f.subclass.integer != IAX_COMMAND_INVAL) && 10240 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10241 (f.subclass.integer != IAX_COMMAND_TXACC) && 10242 (f.subclass.integer != IAX_COMMAND_FWDOWNL))|| 10243 (f.frametype != AST_FRAME_IAX)) 10244 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 10245 fd); 10246 } 10247 if (fr->callno > 0) 10248 ast_mutex_unlock(&iaxsl[fr->callno]); 10249 ast_variables_destroy(ies.vars); 10250 return 1; 10251 } 10252 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 10253 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10254 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10255 ast_variables_destroy(ies.vars); 10256 ast_mutex_unlock(&iaxsl[fr->callno]); 10257 return 1; 10258 } 10259 decrypted = 1; 10260 } 10261 10262 #ifdef DEBUG_SUPPORT 10263 if (decrypted) { 10264 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 10265 } 10266 #endif 10267 10268 10269 /* count this frame */ 10270 iaxs[fr->callno]->frames_received++; 10271 10272 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 10273 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */ 10274 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */ 10275 unsigned short new_peercallno; 10276 10277 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 10278 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 10279 if (iaxs[fr->callno]->peercallno) { 10280 remove_by_peercallno(iaxs[fr->callno]); 10281 } 10282 iaxs[fr->callno]->peercallno = new_peercallno; 10283 store_by_peercallno(iaxs[fr->callno]); 10284 } 10285 } 10286 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10287 if (iaxdebug) 10288 ast_debug(1, "Received packet %d, (%u, %d)\n", fh->oseqno, f.frametype, f.subclass.integer); 10289 /* Check if it's out of order (and not an ACK or INVAL) */ 10290 fr->oseqno = fh->oseqno; 10291 fr->iseqno = fh->iseqno; 10292 fr->ts = ntohl(fh->ts); 10293 #ifdef IAXTESTS 10294 if (test_resync) { 10295 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 10296 fr->ts += test_resync; 10297 } 10298 #endif /* IAXTESTS */ 10299 #if 0 10300 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 10301 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 10302 (f.subclass == IAX_COMMAND_NEW || 10303 f.subclass == IAX_COMMAND_AUTHREQ || 10304 f.subclass == IAX_COMMAND_ACCEPT || 10305 f.subclass == IAX_COMMAND_REJECT)) ) ) 10306 #endif 10307 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 10308 updatehistory = 0; 10309 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 10310 (iaxs[fr->callno]->iseqno || 10311 ((f.subclass.integer != IAX_COMMAND_TXCNT) && 10312 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10313 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10314 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10315 (f.subclass.integer != IAX_COMMAND_TXACC)) || 10316 (f.frametype != AST_FRAME_IAX))) { 10317 if ( 10318 ((f.subclass.integer != IAX_COMMAND_ACK) && 10319 (f.subclass.integer != IAX_COMMAND_INVAL) && 10320 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10321 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10322 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10323 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10324 (f.subclass.integer != IAX_COMMAND_TXACC) && 10325 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10326 (f.frametype != AST_FRAME_IAX)) { 10327 /* If it's not an ACK packet, it's out of order. */ 10328 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %u, subclass = %d)\n", 10329 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer); 10330 /* Check to see if we need to request retransmission, 10331 * and take sequence number wraparound into account */ 10332 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 10333 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 10334 if ((f.frametype != AST_FRAME_IAX) || 10335 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) { 10336 ast_debug(1, "Acking anyway\n"); 10337 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 10338 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 10339 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10340 } 10341 } else { 10342 /* Send a VNAK requesting retransmission */ 10343 iax2_vnak(fr->callno); 10344 } 10345 ast_variables_destroy(ies.vars); 10346 ast_mutex_unlock(&iaxsl[fr->callno]); 10347 return 1; 10348 } 10349 } else { 10350 /* Increment unless it's an ACK or VNAK */ 10351 if (((f.subclass.integer != IAX_COMMAND_ACK) && 10352 (f.subclass.integer != IAX_COMMAND_INVAL) && 10353 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10354 (f.subclass.integer != IAX_COMMAND_TXACC) && 10355 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10356 (f.frametype != AST_FRAME_IAX)) 10357 iaxs[fr->callno]->iseqno++; 10358 } 10359 /* Ensure text frames are NULL-terminated */ 10360 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 10361 if (res < thread->buf_size) 10362 thread->buf[res++] = '\0'; 10363 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 10364 thread->buf[res - 1] = '\0'; 10365 } 10366 10367 /* Handle implicit ACKing unless this is an INVAL, and only if this is 10368 from the real peer, not the transfer peer */ 10369 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10370 ((f.subclass.integer != IAX_COMMAND_INVAL) || 10371 (f.frametype != AST_FRAME_IAX))) { 10372 unsigned char x; 10373 int call_to_destroy; 10374 /* First we have to qualify that the ACKed value is within our window */ 10375 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 10376 x = fr->iseqno; 10377 else 10378 x = iaxs[fr->callno]->oseqno; 10379 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 10380 /* The acknowledgement is within our window. Time to acknowledge everything 10381 that it says to */ 10382 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 10383 /* Ack the packet with the given timestamp */ 10384 if (iaxdebug) 10385 ast_debug(1, "Cancelling transmission of packet %d\n", x); 10386 call_to_destroy = 0; 10387 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10388 /* If it's our call, and our timestamp, mark -1 retries */ 10389 if (x == cur->oseqno) { 10390 cur->retries = -1; 10391 /* Destroy call if this is the end */ 10392 if (cur->final) 10393 call_to_destroy = fr->callno; 10394 } 10395 } 10396 if (call_to_destroy) { 10397 if (iaxdebug) 10398 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 10399 ast_mutex_lock(&iaxsl[call_to_destroy]); 10400 iax2_destroy(call_to_destroy); 10401 ast_mutex_unlock(&iaxsl[call_to_destroy]); 10402 } 10403 } 10404 /* Note how much we've received acknowledgement for */ 10405 if (iaxs[fr->callno]) 10406 iaxs[fr->callno]->rseqno = fr->iseqno; 10407 else { 10408 /* Stop processing now */ 10409 ast_variables_destroy(ies.vars); 10410 ast_mutex_unlock(&iaxsl[fr->callno]); 10411 return 1; 10412 } 10413 } else { 10414 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 10415 } 10416 } 10417 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10418 ((f.frametype != AST_FRAME_IAX) || 10419 ((f.subclass.integer != IAX_COMMAND_TXACC) && 10420 (f.subclass.integer != IAX_COMMAND_TXCNT)))) { 10421 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 10422 ast_variables_destroy(ies.vars); 10423 ast_mutex_unlock(&iaxsl[fr->callno]); 10424 return 1; 10425 } 10426 10427 /* when we receive the first full frame for a new incoming channel, 10428 it is safe to start the PBX on the channel because we have now 10429 completed a 3-way handshake with the peer */ 10430 if ((f.frametype == AST_FRAME_VOICE) || 10431 (f.frametype == AST_FRAME_VIDEO) || 10432 (f.frametype == AST_FRAME_IAX)) { 10433 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 10434 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10435 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL, 10436 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) { 10437 ast_variables_destroy(ies.vars); 10438 ast_mutex_unlock(&iaxsl[fr->callno]); 10439 return 1; 10440 } 10441 } 10442 10443 if (ies.vars) { 10444 struct ast_datastore *variablestore = NULL; 10445 struct ast_variable *var, *prev = NULL; 10446 AST_LIST_HEAD(, ast_var_t) *varlist; 10447 10448 iax2_lock_owner(fr->callno); 10449 if (!iaxs[fr->callno]) { 10450 ast_variables_destroy(ies.vars); 10451 ast_mutex_unlock(&iaxsl[fr->callno]); 10452 return 1; 10453 } 10454 if ((c = iaxs[fr->callno]->owner)) { 10455 varlist = ast_calloc(1, sizeof(*varlist)); 10456 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10457 10458 if (variablestore && varlist) { 10459 variablestore->data = varlist; 10460 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10461 AST_LIST_HEAD_INIT(varlist); 10462 ast_debug(1, "I can haz IAX vars?\n"); 10463 for (var = ies.vars; var; var = var->next) { 10464 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10465 if (prev) { 10466 ast_free(prev); 10467 } 10468 prev = var; 10469 if (!newvar) { 10470 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10471 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10472 } else { 10473 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10474 } 10475 } 10476 if (prev) { 10477 ast_free(prev); 10478 } 10479 ies.vars = NULL; 10480 ast_channel_datastore_add(c, variablestore); 10481 } else { 10482 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10483 if (variablestore) { 10484 ast_datastore_free(variablestore); 10485 } 10486 if (varlist) { 10487 ast_free(varlist); 10488 } 10489 } 10490 ast_channel_unlock(c); 10491 } else { 10492 /* No channel yet, so transfer the variables directly over to the pvt, 10493 * for later inheritance. */ 10494 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 10495 for (var = ies.vars; var && var->next; var = var->next); 10496 if (var) { 10497 var->next = iaxs[fr->callno]->iaxvars; 10498 iaxs[fr->callno]->iaxvars = ies.vars; 10499 ies.vars = NULL; 10500 } 10501 } 10502 } 10503 10504 if (ies.vars) { 10505 ast_debug(1, "I have IAX variables, but they were not processed\n"); 10506 } 10507 } 10508 10509 /* once we receive our first IAX Full Frame that is not CallToken related, send all 10510 * queued signaling frames that were being held. */ 10511 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 10512 send_signaling(iaxs[fr->callno]); 10513 } 10514 10515 if (f.frametype == AST_FRAME_VOICE) { 10516 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) { 10517 iaxs[fr->callno]->voiceformat = f.subclass.codec; 10518 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec)); 10519 if (iaxs[fr->callno]->owner) { 10520 iax2_lock_owner(fr->callno); 10521 if (iaxs[fr->callno]) { 10522 if (iaxs[fr->callno]->owner) { 10523 format_t orignative; 10524 10525 orignative = iaxs[fr->callno]->owner->nativeformats; 10526 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec; 10527 if (iaxs[fr->callno]->owner->readformat) 10528 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10529 iaxs[fr->callno]->owner->nativeformats = orignative; 10530 ast_channel_unlock(iaxs[fr->callno]->owner); 10531 } 10532 } else { 10533 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 10534 /* Free remote variables (if any) */ 10535 if (ies.vars) { 10536 ast_variables_destroy(ies.vars); 10537 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 10538 ies.vars = NULL; 10539 } 10540 ast_mutex_unlock(&iaxsl[fr->callno]); 10541 return 1; 10542 } 10543 } 10544 } 10545 } 10546 if (f.frametype == AST_FRAME_VIDEO) { 10547 if (f.subclass.codec != iaxs[fr->callno]->videoformat) { 10548 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL)); 10549 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL; 10550 } 10551 } 10552 if (f.frametype == AST_FRAME_IAX) { 10553 ast_sched_thread_del(sched, iaxs[fr->callno]->initid); 10554 /* Handle the IAX pseudo frame itself */ 10555 if (iaxdebug) 10556 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer); 10557 10558 /* Update last ts unless the frame's timestamp originated with us. */ 10559 if (iaxs[fr->callno]->last < fr->ts && 10560 f.subclass.integer != IAX_COMMAND_ACK && 10561 f.subclass.integer != IAX_COMMAND_PONG && 10562 f.subclass.integer != IAX_COMMAND_LAGRP) { 10563 iaxs[fr->callno]->last = fr->ts; 10564 if (iaxdebug) 10565 ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts); 10566 } 10567 iaxs[fr->callno]->last_iax_message = f.subclass.integer; 10568 if (!iaxs[fr->callno]->first_iax_message) { 10569 iaxs[fr->callno]->first_iax_message = f.subclass.integer; 10570 } 10571 switch(f.subclass.integer) { 10572 case IAX_COMMAND_ACK: 10573 /* Do nothing */ 10574 break; 10575 case IAX_COMMAND_QUELCH: 10576 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10577 /* Generate Manager Hold event, if necessary*/ 10578 if (iaxs[fr->callno]->owner) { 10579 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10580 "Status: On\r\n" 10581 "Channel: %s\r\n" 10582 "Uniqueid: %s\r\n", 10583 iaxs[fr->callno]->owner->name, 10584 iaxs[fr->callno]->owner->uniqueid); 10585 } 10586 10587 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH); 10588 if (ies.musiconhold) { 10589 iax2_lock_owner(fr->callno); 10590 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 10591 break; 10592 } 10593 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10594 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 10595 10596 /* 10597 * We already hold the owner lock so we do not 10598 * need to check iaxs[fr->callno] after it returns. 10599 */ 10600 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 10601 S_OR(moh_suggest, NULL), 10602 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 10603 } 10604 ast_channel_unlock(iaxs[fr->callno]->owner); 10605 } 10606 } 10607 break; 10608 case IAX_COMMAND_UNQUELCH: 10609 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10610 iax2_lock_owner(fr->callno); 10611 if (!iaxs[fr->callno]) { 10612 break; 10613 } 10614 /* Generate Manager Unhold event, if necessary */ 10615 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { 10616 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10617 "Status: Off\r\n" 10618 "Channel: %s\r\n" 10619 "Uniqueid: %s\r\n", 10620 iaxs[fr->callno]->owner->name, 10621 iaxs[fr->callno]->owner->uniqueid); 10622 } 10623 10624 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH); 10625 if (!iaxs[fr->callno]->owner) { 10626 break; 10627 } 10628 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10629 /* 10630 * We already hold the owner lock so we do not 10631 * need to check iaxs[fr->callno] after it returns. 10632 */ 10633 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10634 } 10635 ast_channel_unlock(iaxs[fr->callno]->owner); 10636 } 10637 break; 10638 case IAX_COMMAND_TXACC: 10639 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10640 /* Ack the packet with the given timestamp */ 10641 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10642 /* Cancel any outstanding txcnt's */ 10643 if (cur->transfer) { 10644 cur->retries = -1; 10645 } 10646 } 10647 memset(&ied1, 0, sizeof(ied1)); 10648 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10649 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10650 iaxs[fr->callno]->transferring = TRANSFER_READY; 10651 } 10652 break; 10653 case IAX_COMMAND_NEW: 10654 /* Ignore if it's already up */ 10655 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10656 break; 10657 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10658 ast_mutex_unlock(&iaxsl[fr->callno]); 10659 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10660 ast_mutex_lock(&iaxsl[fr->callno]); 10661 if (!iaxs[fr->callno]) { 10662 break; 10663 } 10664 } 10665 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10666 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) { 10667 int new_callno; 10668 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10669 fr->callno = new_callno; 10670 } 10671 /* For security, always ack immediately */ 10672 if (delayreject) 10673 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10674 if (check_access(fr->callno, &sin, &ies)) { 10675 /* They're not allowed on */ 10676 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10677 if (authdebug) 10678 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); 10679 break; 10680 } 10681 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10682 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10683 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10684 break; 10685 } 10686 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10687 const char *context, *exten, *cid_num; 10688 10689 context = ast_strdupa(iaxs[fr->callno]->context); 10690 exten = ast_strdupa(iaxs[fr->callno]->exten); 10691 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10692 10693 /* This might re-enter the IAX code and need the lock */ 10694 ast_mutex_unlock(&iaxsl[fr->callno]); 10695 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10696 ast_mutex_lock(&iaxsl[fr->callno]); 10697 10698 if (!iaxs[fr->callno]) { 10699 break; 10700 } 10701 } else 10702 exists = 0; 10703 /* Get OSP token if it does exist */ 10704 save_osptoken(fr, &ies); 10705 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10706 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10707 memset(&ied0, 0, sizeof(ied0)); 10708 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10709 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10710 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10711 if (!iaxs[fr->callno]) { 10712 break; 10713 } 10714 if (authdebug) 10715 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); 10716 } else { 10717 /* Select an appropriate format */ 10718 10719 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10720 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10721 using_prefs = "reqonly"; 10722 } else { 10723 using_prefs = "disabled"; 10724 } 10725 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10726 memset(&pref, 0, sizeof(pref)); 10727 strcpy(caller_pref_buf, "disabled"); 10728 strcpy(host_pref_buf, "disabled"); 10729 } else { 10730 using_prefs = "mine"; 10731 /* If the information elements are in here... use them */ 10732 if (ies.codec_prefs) 10733 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10734 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10735 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10736 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10737 pref = iaxs[fr->callno]->rprefs; 10738 using_prefs = "caller"; 10739 } else { 10740 pref = iaxs[fr->callno]->prefs; 10741 } 10742 } else 10743 pref = iaxs[fr->callno]->prefs; 10744 10745 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10746 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10747 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10748 } 10749 if (!format) { 10750 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10751 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10752 if (!format) { 10753 memset(&ied0, 0, sizeof(ied0)); 10754 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10755 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10756 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10757 if (!iaxs[fr->callno]) { 10758 break; 10759 } 10760 if (authdebug) { 10761 char tmp[256], tmp2[256], tmp3[256]; 10762 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10763 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 10764 ast_inet_ntoa(sin.sin_addr), 10765 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10766 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10767 } else { 10768 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10769 ast_inet_ntoa(sin.sin_addr), 10770 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10771 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10772 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10773 } 10774 } 10775 } else { 10776 /* Pick one... */ 10777 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10778 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10779 format = 0; 10780 } else { 10781 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10782 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10783 memset(&pref, 0, sizeof(pref)); 10784 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10785 strcpy(caller_pref_buf,"disabled"); 10786 strcpy(host_pref_buf,"disabled"); 10787 } else { 10788 using_prefs = "mine"; 10789 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10790 /* Do the opposite of what we tried above. */ 10791 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10792 pref = iaxs[fr->callno]->prefs; 10793 } else { 10794 pref = iaxs[fr->callno]->rprefs; 10795 using_prefs = "caller"; 10796 } 10797 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10798 } else /* if no codec_prefs IE do it the old way */ 10799 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10800 } 10801 } 10802 10803 if (!format) { 10804 char tmp[256], tmp2[256], tmp3[256]; 10805 memset(&ied0, 0, sizeof(ied0)); 10806 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10807 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10808 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 10809 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10810 if (!iaxs[fr->callno]) { 10811 break; 10812 } 10813 if (authdebug) { 10814 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10815 ast_inet_ntoa(sin.sin_addr), 10816 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10817 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10818 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10819 } 10820 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10821 break; 10822 } 10823 } 10824 } 10825 if (format) { 10826 /* No authentication required, let them in */ 10827 memset(&ied1, 0, sizeof(ied1)); 10828 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10829 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 10830 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10831 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10832 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10833 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10834 "%srequested format = %s,\n" 10835 "%srequested prefs = %s,\n" 10836 "%sactual format = %s,\n" 10837 "%shost prefs = %s,\n" 10838 "%spriority = %s\n", 10839 ast_inet_ntoa(sin.sin_addr), 10840 VERBOSE_PREFIX_4, 10841 ast_getformatname(iaxs[fr->callno]->peerformat), 10842 VERBOSE_PREFIX_4, 10843 caller_pref_buf, 10844 VERBOSE_PREFIX_4, 10845 ast_getformatname(format), 10846 VERBOSE_PREFIX_4, 10847 host_pref_buf, 10848 VERBOSE_PREFIX_4, 10849 using_prefs); 10850 10851 iaxs[fr->callno]->chosenformat = format; 10852 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10853 } else { 10854 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10855 /* If this is a TBD call, we're ready but now what... */ 10856 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10857 } 10858 } 10859 } 10860 break; 10861 } 10862 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10863 merge_encryption(iaxs[fr->callno],ies.encmethods); 10864 else 10865 iaxs[fr->callno]->encmethods = 0; 10866 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10867 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10868 break; 10869 case IAX_COMMAND_DPREQ: 10870 /* Request status in the dialplan */ 10871 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10872 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10873 if (iaxcompat) { 10874 /* Spawn a thread for the lookup */ 10875 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10876 } else { 10877 /* Just look it up */ 10878 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10879 } 10880 } 10881 break; 10882 case IAX_COMMAND_HANGUP: 10883 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10884 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10885 /* Set hangup cause according to remote and hangupsource */ 10886 if (iaxs[fr->callno]->owner) { 10887 set_hangup_source_and_cause(fr->callno, ies.causecode); 10888 if (!iaxs[fr->callno]) { 10889 break; 10890 } 10891 } 10892 10893 /* Send ack immediately, before we destroy */ 10894 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10895 iax2_destroy(fr->callno); 10896 break; 10897 case IAX_COMMAND_REJECT: 10898 /* Set hangup cause according to remote and hangup source */ 10899 if (iaxs[fr->callno]->owner) { 10900 set_hangup_source_and_cause(fr->callno, ies.causecode); 10901 if (!iaxs[fr->callno]) { 10902 break; 10903 } 10904 } 10905 10906 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10907 if (iaxs[fr->callno]->owner && authdebug) 10908 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10909 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10910 ies.cause ? ies.cause : "<Unknown>"); 10911 ast_debug(1, "Immediately destroying %d, having received reject\n", 10912 fr->callno); 10913 } 10914 /* Send ack immediately, before we destroy */ 10915 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10916 fr->ts, NULL, 0, fr->iseqno); 10917 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) 10918 iaxs[fr->callno]->error = EPERM; 10919 iax2_destroy(fr->callno); 10920 break; 10921 case IAX_COMMAND_TRANSFER: 10922 { 10923 struct ast_channel *bridged_chan; 10924 struct ast_channel *owner; 10925 10926 iax2_lock_owner(fr->callno); 10927 if (!iaxs[fr->callno]) { 10928 /* Initiating call went away before we could transfer. */ 10929 break; 10930 } 10931 owner = iaxs[fr->callno]->owner; 10932 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 10933 if (bridged_chan && ies.called_number) { 10934 const char *context; 10935 10936 context = ast_strdupa(iaxs[fr->callno]->context); 10937 10938 ast_channel_ref(owner); 10939 ast_channel_ref(bridged_chan); 10940 ast_channel_unlock(owner); 10941 ast_mutex_unlock(&iaxsl[fr->callno]); 10942 10943 /* Set BLINDTRANSFER channel variables */ 10944 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name); 10945 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name); 10946 10947 /* DO NOT hold any locks while calling ast_parking_ext_valid() */ 10948 if (ast_parking_ext_valid(ies.called_number, owner, context)) { 10949 ast_debug(1, "Parking call '%s'\n", bridged_chan->name); 10950 if (iax_park(bridged_chan, owner, ies.called_number, context)) { 10951 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 10952 bridged_chan->name); 10953 } 10954 } else { 10955 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) { 10956 ast_log(LOG_WARNING, 10957 "Async goto of '%s' to '%s@%s' failed\n", 10958 bridged_chan->name, ies.called_number, context); 10959 } else { 10960 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", 10961 bridged_chan->name, ies.called_number, context); 10962 } 10963 } 10964 ast_channel_unref(owner); 10965 ast_channel_unref(bridged_chan); 10966 10967 ast_mutex_lock(&iaxsl[fr->callno]); 10968 } else { 10969 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10970 if (owner) { 10971 ast_channel_unlock(owner); 10972 } 10973 } 10974 10975 break; 10976 } 10977 case IAX_COMMAND_ACCEPT: 10978 /* Ignore if call is already up or needs authentication or is a TBD */ 10979 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10980 break; 10981 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10982 /* Send ack immediately, before we destroy */ 10983 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10984 iax2_destroy(fr->callno); 10985 break; 10986 } 10987 if (ies.format) { 10988 iaxs[fr->callno]->peerformat = ies.format; 10989 } else { 10990 if (iaxs[fr->callno]->owner) 10991 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10992 else 10993 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10994 } 10995 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)); 10996 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10997 memset(&ied0, 0, sizeof(ied0)); 10998 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10999 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11000 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11001 if (!iaxs[fr->callno]) { 11002 break; 11003 } 11004 if (authdebug) { 11005 char tmp1[256], tmp2[256]; 11006 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n", 11007 ast_inet_ntoa(sin.sin_addr), 11008 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11009 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11010 } 11011 } else { 11012 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11013 iax2_lock_owner(fr->callno); 11014 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 11015 /* Switch us to use a compatible format */ 11016 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 11017 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 11018 11019 /* Setup read/write formats properly. */ 11020 if (iaxs[fr->callno]->owner->writeformat) 11021 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 11022 if (iaxs[fr->callno]->owner->readformat) 11023 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 11024 ast_channel_unlock(iaxs[fr->callno]->owner); 11025 } 11026 } 11027 if (iaxs[fr->callno]) { 11028 AST_LIST_LOCK(&dpcache); 11029 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 11030 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 11031 iax2_dprequest(dp, fr->callno); 11032 AST_LIST_UNLOCK(&dpcache); 11033 } 11034 break; 11035 case IAX_COMMAND_POKE: 11036 /* Send back a pong packet with the original timestamp */ 11037 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 11038 break; 11039 case IAX_COMMAND_PING: 11040 { 11041 struct iax_ie_data pingied; 11042 construct_rr(iaxs[fr->callno], &pingied); 11043 /* Send back a pong packet with the original timestamp */ 11044 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 11045 } 11046 break; 11047 case IAX_COMMAND_PONG: 11048 /* Calculate ping time */ 11049 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 11050 /* save RR info */ 11051 save_rr(fr, &ies); 11052 11053 /* Good time to write jb stats for this call */ 11054 log_jitterstats(fr->callno); 11055 11056 if (iaxs[fr->callno]->peerpoke) { 11057 peer = iaxs[fr->callno]->peerpoke; 11058 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 11059 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 11060 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %u\n", peer->name, iaxs[fr->callno]->pingtime); 11061 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %u\r\n", peer->name, iaxs[fr->callno]->pingtime); 11062 ast_devstate_changed(AST_DEVICE_NOT_INUSE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 11063 } 11064 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 11065 if (iaxs[fr->callno]->pingtime > peer->maxms) { 11066 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%u ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 11067 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %u\r\n", peer->name, iaxs[fr->callno]->pingtime); 11068 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", peer->name); /* Activate notification */ 11069 } 11070 } 11071 peer->lastms = iaxs[fr->callno]->pingtime; 11072 if (peer->smoothing && (peer->lastms > -1)) 11073 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 11074 else if (peer->smoothing && peer->lastms < 0) 11075 peer->historicms = (0 + peer->historicms) / 2; 11076 else 11077 peer->historicms = iaxs[fr->callno]->pingtime; 11078 11079 /* Remove scheduled iax2_poke_noanswer */ 11080 if (peer->pokeexpire > -1) { 11081 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 11082 peer_unref(peer); 11083 peer->pokeexpire = -1; 11084 } 11085 } 11086 /* Schedule the next cycle */ 11087 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 11088 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11089 else 11090 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 11091 if (peer->pokeexpire == -1) 11092 peer_unref(peer); 11093 /* and finally send the ack */ 11094 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11095 /* And wrap up the qualify call */ 11096 iax2_destroy(fr->callno); 11097 peer->callno = 0; 11098 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 11099 } 11100 break; 11101 case IAX_COMMAND_LAGRQ: 11102 case IAX_COMMAND_LAGRP: 11103 f.src = "LAGRQ"; 11104 f.mallocd = 0; 11105 f.offset = 0; 11106 f.samples = 0; 11107 iax_frame_wrap(fr, &f); 11108 if (f.subclass.integer == IAX_COMMAND_LAGRQ) { 11109 /* Received a LAGRQ - echo back a LAGRP */ 11110 fr->af.subclass.integer = IAX_COMMAND_LAGRP; 11111 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 11112 } else { 11113 /* Received LAGRP in response to our LAGRQ */ 11114 unsigned int ts; 11115 /* This is a reply we've been given, actually measure the difference */ 11116 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 11117 iaxs[fr->callno]->lag = ts - fr->ts; 11118 if (iaxdebug) 11119 ast_debug(1, "Peer %s lag measured as %dms\n", 11120 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 11121 } 11122 break; 11123 case IAX_COMMAND_AUTHREQ: 11124 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11125 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>"); 11126 break; 11127 } 11128 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 11129 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 11130 .subclass.integer = AST_CONTROL_HANGUP, 11131 }; 11132 ast_log(LOG_WARNING, 11133 "I don't know how to authenticate %s to %s\n", 11134 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 11135 iax2_queue_frame(fr->callno, &hangup_fr); 11136 } 11137 break; 11138 case IAX_COMMAND_AUTHREP: 11139 /* For security, always ack immediately */ 11140 if (delayreject) 11141 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11142 /* Ignore once we've started */ 11143 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 11144 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>"); 11145 break; 11146 } 11147 if (authenticate_verify(iaxs[fr->callno], &ies)) { 11148 if (authdebug) 11149 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); 11150 memset(&ied0, 0, sizeof(ied0)); 11151 auth_fail(fr->callno, IAX_COMMAND_REJECT); 11152 break; 11153 } 11154 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 11155 /* This might re-enter the IAX code and need the lock */ 11156 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 11157 } else 11158 exists = 0; 11159 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 11160 if (authdebug) 11161 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); 11162 memset(&ied0, 0, sizeof(ied0)); 11163 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11164 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11165 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11166 if (!iaxs[fr->callno]) { 11167 break; 11168 } 11169 } else { 11170 /* Select an appropriate format */ 11171 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11172 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11173 using_prefs = "reqonly"; 11174 } else { 11175 using_prefs = "disabled"; 11176 } 11177 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 11178 memset(&pref, 0, sizeof(pref)); 11179 strcpy(caller_pref_buf, "disabled"); 11180 strcpy(host_pref_buf, "disabled"); 11181 } else { 11182 using_prefs = "mine"; 11183 if (ies.codec_prefs) 11184 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 11185 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11186 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11187 pref = iaxs[fr->callno]->rprefs; 11188 using_prefs = "caller"; 11189 } else { 11190 pref = iaxs[fr->callno]->prefs; 11191 } 11192 } else /* if no codec_prefs IE do it the old way */ 11193 pref = iaxs[fr->callno]->prefs; 11194 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 11195 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 11196 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 11197 } 11198 if (!format) { 11199 char tmp1[256], tmp2[256], tmp3[256]; 11200 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11201 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n", 11202 ast_getformatname(iaxs[fr->callno]->peerformat), 11203 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability)); 11204 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 11205 } 11206 if (!format) { 11207 if (authdebug) { 11208 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11209 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr), 11210 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11211 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11212 } else { 11213 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11214 ast_inet_ntoa(sin.sin_addr), 11215 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11216 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11217 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11218 } 11219 } 11220 memset(&ied0, 0, sizeof(ied0)); 11221 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11222 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11223 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11224 if (!iaxs[fr->callno]) { 11225 break; 11226 } 11227 } else { 11228 /* Pick one... */ 11229 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11230 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 11231 format = 0; 11232 } else { 11233 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11234 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 11235 memset(&pref, 0, sizeof(pref)); 11236 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 11237 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11238 strcpy(caller_pref_buf,"disabled"); 11239 strcpy(host_pref_buf,"disabled"); 11240 } else { 11241 using_prefs = "mine"; 11242 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11243 /* Do the opposite of what we tried above. */ 11244 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11245 pref = iaxs[fr->callno]->prefs; 11246 } else { 11247 pref = iaxs[fr->callno]->rprefs; 11248 using_prefs = "caller"; 11249 } 11250 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 11251 } else /* if no codec_prefs IE do it the old way */ 11252 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11253 } 11254 } 11255 if (!format) { 11256 char tmp1[256], tmp2[256], tmp3[256]; 11257 ast_log(LOG_ERROR, "No best format in %s???\n", 11258 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 11259 if (authdebug) { 11260 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11261 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 11262 ast_inet_ntoa(sin.sin_addr), 11263 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11264 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11265 } else { 11266 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11267 ast_inet_ntoa(sin.sin_addr), 11268 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11269 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11270 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11271 } 11272 } 11273 memset(&ied0, 0, sizeof(ied0)); 11274 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11275 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11276 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11277 if (!iaxs[fr->callno]) { 11278 break; 11279 } 11280 } 11281 } 11282 } 11283 if (format) { 11284 /* Authentication received */ 11285 memset(&ied1, 0, sizeof(ied1)); 11286 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 11287 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 11288 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 11289 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 11290 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11291 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 11292 "%srequested format = %s,\n" 11293 "%srequested prefs = %s,\n" 11294 "%sactual format = %s,\n" 11295 "%shost prefs = %s,\n" 11296 "%spriority = %s\n", 11297 ast_inet_ntoa(sin.sin_addr), 11298 VERBOSE_PREFIX_4, 11299 ast_getformatname(iaxs[fr->callno]->peerformat), 11300 VERBOSE_PREFIX_4, 11301 caller_pref_buf, 11302 VERBOSE_PREFIX_4, 11303 ast_getformatname(format), 11304 VERBOSE_PREFIX_4, 11305 host_pref_buf, 11306 VERBOSE_PREFIX_4, 11307 using_prefs); 11308 11309 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11310 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1))) 11311 iax2_destroy(fr->callno); 11312 else if (ies.vars) { 11313 struct ast_datastore *variablestore; 11314 struct ast_variable *var, *prev = NULL; 11315 AST_LIST_HEAD(, ast_var_t) *varlist; 11316 varlist = ast_calloc(1, sizeof(*varlist)); 11317 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11318 if (variablestore && varlist) { 11319 variablestore->data = varlist; 11320 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11321 AST_LIST_HEAD_INIT(varlist); 11322 ast_debug(1, "I can haz IAX vars? w00t\n"); 11323 for (var = ies.vars; var; var = var->next) { 11324 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11325 if (prev) 11326 ast_free(prev); 11327 prev = var; 11328 if (!newvar) { 11329 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11330 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11331 } else { 11332 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11333 } 11334 } 11335 if (prev) 11336 ast_free(prev); 11337 ies.vars = NULL; 11338 ast_channel_datastore_add(c, variablestore); 11339 } else { 11340 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11341 if (variablestore) 11342 ast_datastore_free(variablestore); 11343 if (varlist) 11344 ast_free(varlist); 11345 } 11346 } 11347 } else { 11348 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11349 /* If this is a TBD call, we're ready but now what... */ 11350 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 11351 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) { 11352 goto immediatedial; 11353 } 11354 } 11355 } 11356 } 11357 break; 11358 case IAX_COMMAND_DIAL: 11359 immediatedial: 11360 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 11361 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11362 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 11363 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 11364 if (authdebug) 11365 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); 11366 memset(&ied0, 0, sizeof(ied0)); 11367 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11368 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11369 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11370 if (!iaxs[fr->callno]) { 11371 break; 11372 } 11373 } else { 11374 char tmp[256]; 11375 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11376 ast_verb(3, "Accepting DIAL from %s, formats = %s\n", 11377 ast_inet_ntoa(sin.sin_addr), 11378 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat)); 11379 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11380 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 11381 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1))) 11382 iax2_destroy(fr->callno); 11383 else if (ies.vars) { 11384 struct ast_datastore *variablestore; 11385 struct ast_variable *var, *prev = NULL; 11386 AST_LIST_HEAD(, ast_var_t) *varlist; 11387 varlist = ast_calloc(1, sizeof(*varlist)); 11388 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11389 ast_debug(1, "I can haz IAX vars? w00t\n"); 11390 if (variablestore && varlist) { 11391 variablestore->data = varlist; 11392 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11393 AST_LIST_HEAD_INIT(varlist); 11394 for (var = ies.vars; var; var = var->next) { 11395 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11396 if (prev) 11397 ast_free(prev); 11398 prev = var; 11399 if (!newvar) { 11400 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11401 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11402 } else { 11403 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11404 } 11405 } 11406 if (prev) 11407 ast_free(prev); 11408 ies.vars = NULL; 11409 ast_channel_datastore_add(c, variablestore); 11410 } else { 11411 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11412 if (variablestore) 11413 ast_datastore_free(variablestore); 11414 if (varlist) 11415 ast_free(varlist); 11416 } 11417 } 11418 } 11419 } 11420 break; 11421 case IAX_COMMAND_INVAL: 11422 iaxs[fr->callno]->error = ENOTCONN; 11423 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 11424 iax2_destroy(fr->callno); 11425 ast_debug(1, "Destroying call %d\n", fr->callno); 11426 break; 11427 case IAX_COMMAND_VNAK: 11428 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 11429 /* Force retransmission */ 11430 vnak_retransmit(fr->callno, fr->iseqno); 11431 break; 11432 case IAX_COMMAND_REGREQ: 11433 case IAX_COMMAND_REGREL: 11434 /* For security, always ack immediately */ 11435 if (delayreject) 11436 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11437 if (register_verify(fr->callno, &sin, &ies)) { 11438 if (!iaxs[fr->callno]) { 11439 break; 11440 } 11441 /* Send delayed failure */ 11442 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 11443 break; 11444 } 11445 if (!iaxs[fr->callno]) { 11446 break; 11447 } 11448 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 11449 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 11450 11451 if (f.subclass.integer == IAX_COMMAND_REGREL) { 11452 memset(&sin, 0, sizeof(sin)); 11453 sin.sin_family = AF_INET; 11454 } 11455 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) { 11456 ast_log(LOG_WARNING, "Registry error\n"); 11457 } 11458 if (!iaxs[fr->callno]) { 11459 break; 11460 } 11461 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 11462 ast_mutex_unlock(&iaxsl[fr->callno]); 11463 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 11464 ast_mutex_lock(&iaxsl[fr->callno]); 11465 } 11466 break; 11467 } 11468 registry_authrequest(fr->callno); 11469 break; 11470 case IAX_COMMAND_REGACK: 11471 if (iax2_ack_registry(&ies, &sin, fr->callno)) 11472 ast_log(LOG_WARNING, "Registration failure\n"); 11473 /* Send ack immediately, before we destroy */ 11474 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11475 iax2_destroy(fr->callno); 11476 break; 11477 case IAX_COMMAND_REGREJ: 11478 if (iaxs[fr->callno]->reg) { 11479 if (authdebug) { 11480 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)); 11481 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>"); 11482 } 11483 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 11484 } 11485 /* Send ack immediately, before we destroy */ 11486 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11487 iax2_destroy(fr->callno); 11488 break; 11489 case IAX_COMMAND_REGAUTH: 11490 /* Authentication request */ 11491 if (registry_rerequest(&ies, fr->callno, &sin)) { 11492 memset(&ied0, 0, sizeof(ied0)); 11493 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 11494 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 11495 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11496 } 11497 break; 11498 case IAX_COMMAND_TXREJ: 11499 while (iaxs[fr->callno] 11500 && iaxs[fr->callno]->bridgecallno 11501 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) { 11502 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 11503 } 11504 if (!iaxs[fr->callno]) { 11505 break; 11506 } 11507 11508 iaxs[fr->callno]->transferring = TRANSFER_NONE; 11509 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11510 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 11511 11512 if (!iaxs[fr->callno]->bridgecallno) { 11513 break; 11514 } 11515 11516 if (iaxs[iaxs[fr->callno]->bridgecallno] 11517 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 11518 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE; 11519 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 11520 } 11521 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11522 break; 11523 case IAX_COMMAND_TXREADY: 11524 while (iaxs[fr->callno] 11525 && iaxs[fr->callno]->bridgecallno 11526 && ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) { 11527 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 11528 } 11529 if (!iaxs[fr->callno]) { 11530 break; 11531 } 11532 11533 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 11534 iaxs[fr->callno]->transferring = TRANSFER_READY; 11535 } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) { 11536 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 11537 } else { 11538 if (iaxs[fr->callno]->bridgecallno) { 11539 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11540 } 11541 break; 11542 } 11543 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11544 11545 if (!iaxs[fr->callno]->bridgecallno) { 11546 break; 11547 } 11548 11549 if (!iaxs[iaxs[fr->callno]->bridgecallno] 11550 || (iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_READY 11551 && iaxs[iaxs[fr->callno]->bridgecallno]->transferring != TRANSFER_MREADY)) { 11552 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11553 break; 11554 } 11555 11556 /* Both sides are ready */ 11557 11558 /* XXX what isn't checked here is that both sides match transfer types. */ 11559 11560 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 11561 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11562 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11563 11564 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 11565 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 11566 11567 memset(&ied0, 0, sizeof(ied0)); 11568 memset(&ied1, 0, sizeof(ied1)); 11569 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11570 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11571 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 11572 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 11573 } else { 11574 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11575 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11576 11577 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 11578 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 11579 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 11580 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 11581 11582 /* Stop doing lag & ping requests */ 11583 stop_stuff(fr->callno); 11584 stop_stuff(iaxs[fr->callno]->bridgecallno); 11585 11586 memset(&ied0, 0, sizeof(ied0)); 11587 memset(&ied1, 0, sizeof(ied1)); 11588 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11589 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11590 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 11591 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 11592 } 11593 ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]); 11594 break; 11595 case IAX_COMMAND_TXREQ: 11596 try_transfer(iaxs[fr->callno], &ies); 11597 break; 11598 case IAX_COMMAND_TXCNT: 11599 if (iaxs[fr->callno]->transferring) 11600 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 11601 break; 11602 case IAX_COMMAND_TXREL: 11603 /* Send ack immediately, rather than waiting until we've changed addresses */ 11604 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11605 complete_transfer(fr->callno, &ies); 11606 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 11607 break; 11608 case IAX_COMMAND_TXMEDIA: 11609 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 11610 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 11611 /* Cancel any outstanding frames and start anew */ 11612 if (cur->transfer) { 11613 cur->retries = -1; 11614 } 11615 } 11616 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 11617 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 11618 } 11619 break; 11620 case IAX_COMMAND_RTKEY: 11621 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 11622 ast_log(LOG_WARNING, 11623 "we've been told to rotate our encryption key, " 11624 "but this isn't an encrypted call. bad things will happen.\n" 11625 ); 11626 break; 11627 } 11628 11629 IAX_DEBUGDIGEST("Receiving", ies.challenge); 11630 11631 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 11632 break; 11633 case IAX_COMMAND_DPREP: 11634 complete_dpreply(iaxs[fr->callno], &ies); 11635 break; 11636 case IAX_COMMAND_UNSUPPORT: 11637 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 11638 break; 11639 case IAX_COMMAND_FWDOWNL: 11640 /* Firmware download */ 11641 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 11642 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 11643 break; 11644 } 11645 memset(&ied0, 0, sizeof(ied0)); 11646 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 11647 if (res < 0) 11648 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11649 else if (res > 0) 11650 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11651 else 11652 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11653 break; 11654 case IAX_COMMAND_CALLTOKEN: 11655 { 11656 struct iax_frame *cur; 11657 /* find last sent frame */ 11658 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) { 11659 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 11660 } 11661 break; 11662 } 11663 default: 11664 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno); 11665 memset(&ied0, 0, sizeof(ied0)); 11666 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer); 11667 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11668 } 11669 /* Free remote variables (if any) */ 11670 if (ies.vars) { 11671 ast_variables_destroy(ies.vars); 11672 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11673 ies.vars = NULL; 11674 } 11675 11676 /* Don't actually pass these frames along */ 11677 if ((f.subclass.integer != IAX_COMMAND_ACK) && 11678 (f.subclass.integer != IAX_COMMAND_TXCNT) && 11679 (f.subclass.integer != IAX_COMMAND_TXACC) && 11680 (f.subclass.integer != IAX_COMMAND_INVAL) && 11681 (f.subclass.integer != IAX_COMMAND_VNAK)) { 11682 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) { 11683 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11684 } 11685 } 11686 ast_mutex_unlock(&iaxsl[fr->callno]); 11687 return 1; 11688 } 11689 /* Unless this is an ACK or INVAL frame, ack it */ 11690 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11691 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11692 } else if (minivid) { 11693 f.frametype = AST_FRAME_VIDEO; 11694 if (iaxs[fr->callno]->videoformat > 0) 11695 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0); 11696 else { 11697 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11698 iax2_vnak(fr->callno); 11699 ast_variables_destroy(ies.vars); 11700 ast_mutex_unlock(&iaxsl[fr->callno]); 11701 return 1; 11702 } 11703 f.datalen = res - sizeof(*vh); 11704 if (f.datalen) 11705 f.data.ptr = thread->buf + sizeof(*vh); 11706 else 11707 f.data.ptr = NULL; 11708 #ifdef IAXTESTS 11709 if (test_resync) { 11710 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11711 } else 11712 #endif /* IAXTESTS */ 11713 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11714 } else { 11715 /* A mini frame */ 11716 f.frametype = AST_FRAME_VOICE; 11717 if (iaxs[fr->callno]->voiceformat > 0) 11718 f.subclass.codec = iaxs[fr->callno]->voiceformat; 11719 else { 11720 ast_debug(1, "Received mini frame before first full voice frame\n"); 11721 iax2_vnak(fr->callno); 11722 ast_variables_destroy(ies.vars); 11723 ast_mutex_unlock(&iaxsl[fr->callno]); 11724 return 1; 11725 } 11726 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11727 if (f.datalen < 0) { 11728 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11729 ast_variables_destroy(ies.vars); 11730 ast_mutex_unlock(&iaxsl[fr->callno]); 11731 return 1; 11732 } 11733 if (f.datalen) 11734 f.data.ptr = thread->buf + sizeof(*mh); 11735 else 11736 f.data.ptr = NULL; 11737 #ifdef IAXTESTS 11738 if (test_resync) { 11739 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11740 } else 11741 #endif /* IAXTESTS */ 11742 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11743 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11744 } 11745 11746 /* Don't pass any packets until we're started */ 11747 if (!iaxs[fr->callno] 11748 || !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11749 ast_variables_destroy(ies.vars); 11750 ast_mutex_unlock(&iaxsl[fr->callno]); 11751 return 1; 11752 } 11753 11754 if (f.frametype == AST_FRAME_CONTROL) { 11755 if (!iax2_is_control_frame_allowed(f.subclass.integer)) { 11756 /* Control frame not allowed to come from the wire. */ 11757 ast_debug(2, "Callno %d: Blocked receiving control frame %d.\n", 11758 fr->callno, f.subclass.integer); 11759 ast_variables_destroy(ies.vars); 11760 ast_mutex_unlock(&iaxsl[fr->callno]); 11761 return 1; 11762 } 11763 if (f.subclass.integer == AST_CONTROL_CONNECTED_LINE 11764 || f.subclass.integer == AST_CONTROL_REDIRECTING) { 11765 if (iaxs[fr->callno] 11766 && !ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) { 11767 /* We are not configured to allow receiving these updates. */ 11768 ast_debug(2, "Callno %d: Config blocked receiving control frame %d.\n", 11769 fr->callno, f.subclass.integer); 11770 ast_variables_destroy(ies.vars); 11771 ast_mutex_unlock(&iaxsl[fr->callno]); 11772 return 1; 11773 } 11774 } 11775 11776 iax2_lock_owner(fr->callno); 11777 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 11778 if (f.subclass.integer == AST_CONTROL_BUSY) { 11779 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 11780 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) { 11781 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 11782 } 11783 ast_channel_unlock(iaxs[fr->callno]->owner); 11784 } 11785 } 11786 11787 if (f.frametype == AST_FRAME_CONTROL 11788 && f.subclass.integer == AST_CONTROL_CONNECTED_LINE 11789 && iaxs[fr->callno]) { 11790 struct ast_party_connected_line connected; 11791 11792 /* 11793 * Process a received connected line update. 11794 * 11795 * Initialize defaults. 11796 */ 11797 ast_party_connected_line_init(&connected); 11798 connected.id.number.presentation = iaxs[fr->callno]->calling_pres; 11799 connected.id.name.presentation = iaxs[fr->callno]->calling_pres; 11800 11801 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) { 11802 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str); 11803 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str); 11804 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id); 11805 11806 iax2_lock_owner(fr->callno); 11807 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 11808 ast_set_callerid(iaxs[fr->callno]->owner, 11809 S_COR(connected.id.number.valid, connected.id.number.str, ""), 11810 S_COR(connected.id.name.valid, connected.id.name.str, ""), 11811 NULL); 11812 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation; 11813 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation; 11814 ast_channel_unlock(iaxs[fr->callno]->owner); 11815 } 11816 } 11817 ast_party_connected_line_free(&connected); 11818 } 11819 11820 /* Common things */ 11821 f.src = "IAX2"; 11822 f.mallocd = 0; 11823 f.offset = 0; 11824 f.len = 0; 11825 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11826 f.samples = ast_codec_get_samples(&f); 11827 /* We need to byteswap incoming slinear samples from network byte order */ 11828 if (f.subclass.codec == AST_FORMAT_SLINEAR) 11829 ast_frame_byteswap_be(&f); 11830 } else 11831 f.samples = 0; 11832 iax_frame_wrap(fr, &f); 11833 11834 /* If this is our most recent packet, use it as our basis for timestamping */ 11835 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11836 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11837 fr->outoforder = 0; 11838 } else { 11839 if (iaxdebug && iaxs[fr->callno]) { 11840 ast_debug(1, "Received out of order packet... (type=%u, subclass %d, ts = %u, last = %u)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last); 11841 } 11842 fr->outoforder = -1; 11843 } 11844 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11845 if (iaxs[fr->callno]) { 11846 duped_fr = iaxfrdup2(fr); 11847 if (duped_fr) { 11848 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11849 } 11850 } 11851 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11852 iaxs[fr->callno]->last = fr->ts; 11853 #if 1 11854 if (iaxdebug) 11855 ast_debug(1, "For call=%d, set last=%u\n", fr->callno, fr->ts); 11856 #endif 11857 } 11858 11859 /* Always run again */ 11860 ast_variables_destroy(ies.vars); 11861 ast_mutex_unlock(&iaxsl[fr->callno]); 11862 return 1; 11863 }
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 9817 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().
09819 { 09820 unsigned char metatype; 09821 struct ast_iax2_meta_trunk_mini *mtm; 09822 struct ast_iax2_meta_trunk_hdr *mth; 09823 struct ast_iax2_meta_trunk_entry *mte; 09824 struct iax2_trunk_peer *tpeer; 09825 unsigned int ts; 09826 void *ptr; 09827 struct timeval rxtrunktime; 09828 struct ast_frame f = { 0, }; 09829 09830 if (packet_len < sizeof(*meta)) { 09831 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09832 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09833 return 1; 09834 } 09835 09836 if (meta->metacmd != IAX_META_TRUNK) 09837 return 1; 09838 09839 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09840 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09841 (int) (sizeof(*meta) + sizeof(*mth))); 09842 return 1; 09843 } 09844 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09845 ts = ntohl(mth->ts); 09846 metatype = meta->cmddata; 09847 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09848 ptr = mth->data; 09849 tpeer = find_tpeer(sin, sockfd); 09850 if (!tpeer) { 09851 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09852 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09853 return 1; 09854 } 09855 tpeer->trunkact = ast_tvnow(); 09856 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09857 tpeer->rxtrunktime = tpeer->trunkact; 09858 rxtrunktime = tpeer->rxtrunktime; 09859 ast_mutex_unlock(&tpeer->lock); 09860 while (packet_len >= sizeof(*mte)) { 09861 /* Process channels */ 09862 unsigned short callno, trunked_ts, len; 09863 09864 if (metatype == IAX_META_TRUNK_MINI) { 09865 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09866 ptr += sizeof(*mtm); 09867 packet_len -= sizeof(*mtm); 09868 len = ntohs(mtm->len); 09869 callno = ntohs(mtm->mini.callno); 09870 trunked_ts = ntohs(mtm->mini.ts); 09871 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09872 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09873 ptr += sizeof(*mte); 09874 packet_len -= sizeof(*mte); 09875 len = ntohs(mte->len); 09876 callno = ntohs(mte->callno); 09877 trunked_ts = 0; 09878 } else { 09879 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09880 break; 09881 } 09882 /* Stop if we don't have enough data */ 09883 if (len > packet_len) 09884 break; 09885 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09886 if (!fr->callno) 09887 continue; 09888 09889 /* If it's a valid call, deliver the contents. If not, we 09890 drop it, since we don't have a scallno to use for an INVAL */ 09891 /* Process as a mini frame */ 09892 memset(&f, 0, sizeof(f)); 09893 f.frametype = AST_FRAME_VOICE; 09894 if (!iaxs[fr->callno]) { 09895 /* drop it */ 09896 } else if (iaxs[fr->callno]->voiceformat == 0) { 09897 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09898 iax2_vnak(fr->callno); 09899 } else { 09900 f.subclass.codec = iaxs[fr->callno]->voiceformat; 09901 f.datalen = len; 09902 if (f.datalen >= 0) { 09903 if (f.datalen) 09904 f.data.ptr = ptr; 09905 else 09906 f.data.ptr = NULL; 09907 if (trunked_ts) 09908 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09909 else 09910 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09911 /* Don't pass any packets until we're started */ 09912 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09913 struct iax_frame *duped_fr; 09914 09915 /* Common things */ 09916 f.src = "IAX2"; 09917 f.mallocd = 0; 09918 f.offset = 0; 09919 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09920 f.samples = ast_codec_get_samples(&f); 09921 else 09922 f.samples = 0; 09923 fr->outoforder = 0; 09924 iax_frame_wrap(fr, &f); 09925 duped_fr = iaxfrdup2(fr); 09926 if (duped_fr) 09927 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09928 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09929 iaxs[fr->callno]->last = fr->ts; 09930 } 09931 } else { 09932 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09933 } 09934 } 09935 ast_mutex_unlock(&iaxsl[fr->callno]); 09936 ptr += len; 09937 packet_len -= len; 09938 } 09939 09940 return 1; 09941 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9737 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().
09738 { 09739 struct iax2_thread *thread; 09740 socklen_t len; 09741 time_t t; 09742 static time_t last_errtime = 0; 09743 struct ast_iax2_full_hdr *fh; 09744 09745 if (!(thread = find_idle_thread())) { 09746 time(&t); 09747 if (t != last_errtime) { 09748 last_errtime = t; 09749 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09750 } 09751 usleep(1); 09752 return 1; 09753 } 09754 09755 len = sizeof(thread->iosin); 09756 thread->iofd = fd; 09757 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09758 thread->buf_size = sizeof(thread->readbuf); 09759 thread->buf = thread->readbuf; 09760 if (thread->buf_len < 0) { 09761 if (errno != ECONNREFUSED && errno != EAGAIN) 09762 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09763 handle_error(); 09764 thread->iostate = IAX_IOSTATE_IDLE; 09765 signal_condition(&thread->lock, &thread->cond); 09766 return 1; 09767 } 09768 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09769 thread->iostate = IAX_IOSTATE_IDLE; 09770 signal_condition(&thread->lock, &thread->cond); 09771 return 1; 09772 } 09773 09774 /* Determine if this frame is a full frame; if so, and any thread is currently 09775 processing a full frame for the same callno from this peer, then drop this 09776 frame (and the peer will retransmit it) */ 09777 fh = (struct ast_iax2_full_hdr *) thread->buf; 09778 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09779 struct iax2_thread *cur = NULL; 09780 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09781 09782 AST_LIST_LOCK(&active_list); 09783 AST_LIST_TRAVERSE(&active_list, cur, list) { 09784 if ((cur->ffinfo.callno == callno) && 09785 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09786 break; 09787 } 09788 if (cur) { 09789 /* we found another thread processing a full frame for this call, 09790 so queue it up for processing later. */ 09791 defer_full_frame(thread, cur); 09792 AST_LIST_UNLOCK(&active_list); 09793 thread->iostate = IAX_IOSTATE_IDLE; 09794 signal_condition(&thread->lock, &thread->cond); 09795 return 1; 09796 } else { 09797 /* this thread is going to process this frame, so mark it */ 09798 thread->ffinfo.callno = callno; 09799 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09800 thread->ffinfo.type = fh->type; 09801 thread->ffinfo.csub = fh->csub; 09802 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09803 } 09804 AST_LIST_UNLOCK(&active_list); 09805 } 09806 09807 /* Mark as ready and send on its way */ 09808 thread->iostate = IAX_IOSTATE_READY; 09809 #ifdef DEBUG_SCHED_MULTITHREAD 09810 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09811 #endif 09812 signal_condition(&thread->lock, &thread->cond); 09813 09814 return 1; 09815 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 9404 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().
09405 { 09406 pthread_t newthread; 09407 struct dpreq_data *dpr; 09408 09409 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 09410 return; 09411 09412 dpr->callno = callno; 09413 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 09414 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 09415 if (callerid) 09416 dpr->callerid = ast_strdup(callerid); 09417 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 09418 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 09419 } 09420 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 12427 of file chan_iax2.c.
References ast_calloc, ast_cond_destroy, ast_cond_init, ast_cond_wait, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_mutex_lock, ast_mutex_unlock, ast_pthread_create_background, ast_verb, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, LOG_ERROR, LOG_WARNING, network_thread(), and thread.
Referenced by load_module().
12428 { 12429 struct iax2_thread *thread; 12430 int threadcount = 0; 12431 int x; 12432 for (x = 0; x < iaxthreadcount; x++) { 12433 thread = ast_calloc(1, sizeof(*thread)); 12434 if (thread) { 12435 thread->type = IAX_THREAD_TYPE_POOL; 12436 thread->threadnum = ++threadcount; 12437 ast_mutex_init(&thread->lock); 12438 ast_cond_init(&thread->cond, NULL); 12439 ast_mutex_init(&thread->init_lock); 12440 ast_cond_init(&thread->init_cond, NULL); 12441 12442 ast_mutex_lock(&thread->init_lock); 12443 12444 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 12445 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 12446 ast_mutex_destroy(&thread->lock); 12447 ast_cond_destroy(&thread->cond); 12448 ast_mutex_unlock(&thread->init_lock); 12449 ast_mutex_destroy(&thread->init_lock); 12450 ast_cond_destroy(&thread->init_cond); 12451 ast_free(thread); 12452 thread = NULL; 12453 continue; 12454 } 12455 /* Wait for the thread to be ready */ 12456 ast_cond_wait(&thread->init_cond, &thread->init_lock); 12457 12458 /* Done with init_lock */ 12459 ast_mutex_unlock(&thread->init_lock); 12460 12461 AST_LIST_LOCK(&idle_list); 12462 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 12463 AST_LIST_UNLOCK(&idle_list); 12464 } 12465 } 12466 if (ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL)) { 12467 ast_log(LOG_ERROR, "Failed to create new thread!\n"); 12468 return -1; 12469 } 12470 ast_verb(2, "%d helper threads started\n", threadcount); 12471 return 0; 12472 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 9107 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
09108 { 09109 iax2_destroy_helper(iaxs[callno]); 09110 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2213 of file chan_iax2.c.
References ao2_link, ast_log(), iax_peercallno_pvts, LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
02214 { 02215 if (!pvt->peercallno) { 02216 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02217 return; 02218 } 02219 02220 ao2_link(iax_peercallno_pvts, pvt); 02221 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2194 of file chan_iax2.c.
References ao2_link, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
02195 { 02196 if (!pvt->transfercallno) { 02197 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02198 return; 02199 } 02200 02201 ao2_link(iax_transfercallno_pvts, pvt); 02202 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9290 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().
09291 { 09292 int res, processed = 0, totalcalls = 0; 09293 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 09294 struct timeval now = ast_tvnow(); 09295 09296 if (iaxtrunkdebug) 09297 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 09298 09299 if (timer) { 09300 if (ast_timer_ack(timer, 1) < 0) { 09301 ast_log(LOG_ERROR, "Timer failed acknowledge\n"); 09302 return 0; 09303 } 09304 } 09305 09306 /* For each peer that supports trunking... */ 09307 AST_LIST_LOCK(&tpeers); 09308 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 09309 processed++; 09310 res = 0; 09311 ast_mutex_lock(&tpeer->lock); 09312 /* We can drop a single tpeer per pass. That makes all this logic 09313 substantially easier */ 09314 if (!drop && iax2_trunk_expired(tpeer, &now)) { 09315 /* Take it out of the list, but don't free it yet, because it 09316 could be in use */ 09317 AST_LIST_REMOVE_CURRENT(list); 09318 drop = tpeer; 09319 } else { 09320 res = send_trunk(tpeer, &now); 09321 trunk_timed++; 09322 if (iaxtrunkdebug) 09323 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %u bytes backloged and has hit a high water mark of %u bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc); 09324 } 09325 totalcalls += res; 09326 res = 0; 09327 ast_mutex_unlock(&tpeer->lock); 09328 } 09329 AST_LIST_TRAVERSE_SAFE_END; 09330 AST_LIST_UNLOCK(&tpeers); 09331 09332 if (drop) { 09333 ast_mutex_lock(&drop->lock); 09334 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 09335 because by the time they could get tpeerlock, we've already grabbed it */ 09336 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 09337 if (drop->trunkdata) { 09338 ast_free(drop->trunkdata); 09339 drop->trunkdata = NULL; 09340 } 09341 ast_mutex_unlock(&drop->lock); 09342 ast_mutex_destroy(&drop->lock); 09343 ast_free(drop); 09344 09345 } 09346 09347 if (iaxtrunkdebug) 09348 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 09349 iaxtrunkdebug = 0; 09350 09351 return 1; 09352 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14700 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and match().
Referenced by load_objects().
14701 { 14702 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14703 14704 /* The frames_received field is used to hold whether we're matching 14705 * against a full frame or not ... */ 14706 14707 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 14708 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14709 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14693 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
14694 { 14695 const struct chan_iax2_pvt *pvt = obj; 14696 14697 return pvt->transfercallno; 14698 }
static int transmit_frame | ( | void * | data | ) | [static] |
Definition at line 4347 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, iax2_sched_add(), iax_frame_free(), iaxs, iaxsl, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), and iax_frame::sentyet.
Referenced by iax2_transmit().
04348 { 04349 struct iax_frame *fr = data; 04350 04351 ast_mutex_lock(&iaxsl[fr->callno]); 04352 04353 fr->sentyet = 1; 04354 04355 if (iaxs[fr->callno]) { 04356 send_packet(fr); 04357 } 04358 04359 if (fr->retries < 0) { 04360 ast_mutex_unlock(&iaxsl[fr->callno]); 04361 /* No retransmit requested */ 04362 iax_frame_free(fr); 04363 } else { 04364 /* We need reliable delivery. Schedule a retransmission */ 04365 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list); 04366 fr->retries++; 04367 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr); 04368 ast_mutex_unlock(&iaxsl[fr->callno]); 04369 } 04370 04371 return 0; 04372 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 3405 of file chan_iax2.c.
References ast_debug, iax_frame::data, iax_frame::datalen, errno, and handle_error().
Referenced by send_trunk().
03406 { 03407 int res; 03408 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03409 sizeof(*sin)); 03410 if (res < 0) { 03411 ast_debug(1, "Received error: %s\n", strerror(errno)); 03412 handle_error(); 03413 } else 03414 res = 0; 03415 return res; 03416 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 3110 of file chan_iax2.c.
References ast_alloca, ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), MD5Context::buf, ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, errno, IAX_FIRMWARE_MAGIC, last, len(), LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), and ast_iax2_firmware_header::version.
Referenced by reload_firmware().
03111 { 03112 struct stat stbuf; 03113 struct iax_firmware *cur = NULL; 03114 int ifd, fd, res, len, chunk; 03115 struct ast_iax2_firmware_header *fwh, fwh2; 03116 struct MD5Context md5; 03117 unsigned char sum[16], buf[1024]; 03118 char *s2, *last; 03119 03120 s2 = ast_alloca(strlen(s) + 100); 03121 03122 last = strrchr(s, '/'); 03123 if (last) 03124 last++; 03125 else 03126 last = s; 03127 03128 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, ast_random()); 03129 03130 if ((res = stat(s, &stbuf) < 0)) { 03131 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 03132 return -1; 03133 } 03134 03135 /* Make sure it's not a directory */ 03136 if (S_ISDIR(stbuf.st_mode)) 03137 return -1; 03138 ifd = open(s, O_RDONLY); 03139 if (ifd < 0) { 03140 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 03141 return -1; 03142 } 03143 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 03144 if (fd < 0) { 03145 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 03146 close(ifd); 03147 return -1; 03148 } 03149 /* Unlink our newly created file */ 03150 unlink(s2); 03151 03152 /* Now copy the firmware into it */ 03153 len = stbuf.st_size; 03154 while(len) { 03155 chunk = len; 03156 if (chunk > sizeof(buf)) 03157 chunk = sizeof(buf); 03158 res = read(ifd, buf, chunk); 03159 if (res != chunk) { 03160 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03161 close(ifd); 03162 close(fd); 03163 return -1; 03164 } 03165 res = write(fd, buf, chunk); 03166 if (res != chunk) { 03167 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03168 close(ifd); 03169 close(fd); 03170 return -1; 03171 } 03172 len -= chunk; 03173 } 03174 close(ifd); 03175 /* Return to the beginning */ 03176 lseek(fd, 0, SEEK_SET); 03177 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 03178 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 03179 close(fd); 03180 return -1; 03181 } 03182 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 03183 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 03184 close(fd); 03185 return -1; 03186 } 03187 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 03188 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 03189 close(fd); 03190 return -1; 03191 } 03192 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 03193 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 03194 close(fd); 03195 return -1; 03196 } 03197 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 03198 if (fwh == MAP_FAILED) { 03199 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 03200 close(fd); 03201 return -1; 03202 } 03203 MD5Init(&md5); 03204 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 03205 MD5Final(sum, &md5); 03206 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 03207 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 03208 munmap((void*)fwh, stbuf.st_size); 03209 close(fd); 03210 return -1; 03211 } 03212 03213 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03214 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 03215 /* Found a candidate */ 03216 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 03217 /* The version we have on loaded is older, load this one instead */ 03218 break; 03219 /* This version is no newer than what we have. Don't worry about it. 03220 We'll consider it a proper load anyhow though */ 03221 munmap((void*)fwh, stbuf.st_size); 03222 close(fd); 03223 return 0; 03224 } 03225 } 03226 03227 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 03228 cur->fd = -1; 03229 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 03230 } 03231 03232 if (cur) { 03233 if (cur->fwh) 03234 munmap((void*)cur->fwh, cur->mmaplen); 03235 if (cur->fd > -1) 03236 close(cur->fd); 03237 cur->fwh = fwh; 03238 cur->fd = fd; 03239 cur->mmaplen = stbuf.st_size; 03240 cur->dead = 0; 03241 } 03242 03243 return 0; 03244 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8424 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().
08425 { 08426 int newcall = 0; 08427 char newip[256]; 08428 struct iax_ie_data ied; 08429 struct sockaddr_in new = { 0, }; 08430 08431 memset(&ied, 0, sizeof(ied)); 08432 if (ies->apparent_addr) 08433 memmove(&new, ies->apparent_addr, sizeof(new)); 08434 if (ies->callno) 08435 newcall = ies->callno; 08436 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 08437 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08438 return -1; 08439 } 08440 pvt->transfercallno = newcall; 08441 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 08442 inet_aton(newip, &pvt->transfer.sin_addr); 08443 pvt->transfer.sin_family = AF_INET; 08444 pvt->transferid = ies->transferid; 08445 /* only store by transfercallno if this is a new transfer, 08446 * just in case we get a duplicate TXREQ */ 08447 if (pvt->transferring == TRANSFER_NONE) { 08448 store_by_transfercallno(pvt); 08449 } 08450 pvt->transferring = TRANSFER_BEGIN; 08451 08452 if (ies->transferid) 08453 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 08454 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 08455 return 0; 08456 }
static format_t uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1711 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01712 { 01713 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01714 if (csub & IAX_FLAG_SC_LOG) { 01715 /* special case for 'compressed' -1 */ 01716 if (csub == 0xff) 01717 return -1; 01718 else 01719 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01720 } 01721 else 01722 return csub; 01723 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8718 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().
08719 { 08720 if (peer->expire > -1) { 08721 if (!ast_sched_thread_del(sched, peer->expire)) { 08722 peer->expire = -1; 08723 peer_unref(peer); 08724 } 08725 } 08726 08727 if (peer->pokeexpire > -1) { 08728 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 08729 peer->pokeexpire = -1; 08730 peer_unref(peer); 08731 } 08732 } 08733 08734 ao2_unlink(peers, peer); 08735 }
static int unload_module | ( | void | ) | [static] |
Definition at line 14658 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
14659 { 14660 ast_custom_function_unregister(&iaxpeer_function); 14661 ast_custom_function_unregister(&iaxvar_function); 14662 return __unload_module(); 14663 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5555 of file chan_iax2.c.
References ast_mutex_unlock, and iaxsl.
Referenced by iax2_bridge().
05556 { 05557 ast_mutex_unlock(&iaxsl[callno1]); 05558 ast_mutex_unlock(&iaxsl[callno0]); 05559 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4100 of file chan_iax2.c.
References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, iaxs, chan_iax2_pvt::last, and iax_frame::ts.
Referenced by schedule_delivery().
04101 { 04102 /* Video mini frames only encode the lower 15 bits of the session 04103 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 04104 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 04105 const int lower_mask = (1 << ts_shift) - 1; 04106 const int upper_mask = ~lower_mask; 04107 const int last_upper = iaxs[fr->callno]->last & upper_mask; 04108 04109 if ( (fr->ts & upper_mask) == last_upper ) { 04110 const int x = fr->ts - iaxs[fr->callno]->last; 04111 const int threshold = (ts_shift == 15) ? 25000 : 50000; 04112 04113 if (x < -threshold) { 04114 /* Sudden big jump backwards in timestamp: 04115 What likely happened here is that miniframe timestamp has circled but we haven't 04116 gotten the update from the main packet. We'll just pretend that we did, and 04117 update the timestamp appropriately. */ 04118 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 04119 if (iaxdebug) 04120 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 04121 } else if (x > threshold) { 04122 /* Sudden apparent big jump forwards in timestamp: 04123 What's likely happened is this is an old miniframe belonging to the previous 04124 top 15 or 16-bit timestamp that has turned up out of order. 04125 Adjust the timestamp appropriately. */ 04126 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 04127 if (iaxdebug) 04128 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 04129 } 04130 } 04131 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4135 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_replace(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.
Referenced by __get_from_jb(), and schedule_delivery().
04136 { 04137 int when; 04138 04139 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 04140 04141 when = jb_next(pvt->jb) - when; 04142 04143 if (when <= 0) { 04144 /* XXX should really just empty until when > 0.. */ 04145 when = 1; 04146 } 04147 04148 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 04149 CALLNO_TO_PTR(pvt->callno)); 04150 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3541 of file chan_iax2.c.
References build_rand_pad(), iax_frame::callno, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, decode_frame(), iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, iax_frame::mydcx, and iax_frame::semirand.
Referenced by __attempt_transmit().
03542 { 03543 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03544 struct ast_iax2_full_hdr *fh = f->data; 03545 struct ast_frame af; 03546 03547 /* if frame is encrypted. decrypt before updating it. */ 03548 if (f->encmethods) { 03549 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03550 } 03551 /* Mark this as a retransmission */ 03552 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03553 /* Update iseqno */ 03554 f->iseqno = iaxs[f->callno]->iseqno; 03555 fh->iseqno = f->iseqno; 03556 03557 /* Now re-encrypt the frame */ 03558 if (f->encmethods) { 03559 /* since this is a retransmit frame, create a new random padding 03560 * before re-encrypting. */ 03561 build_rand_pad(f->semirand, sizeof(f->semirand)); 03562 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03563 } 03564 return 0; 03565 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 8836 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().
08837 { 08838 /* Called from IAX thread only, with proper iaxsl lock */ 08839 struct iax_ie_data ied = { 08840 .pos = 0, 08841 }; 08842 struct iax2_peer *p; 08843 int msgcount; 08844 char data[80]; 08845 int version; 08846 const char *peer_name; 08847 int res = -1; 08848 struct ast_sockaddr sockaddr; 08849 08850 ast_sockaddr_from_sin(&sockaddr, sin); 08851 08852 peer_name = ast_strdupa(iaxs[callno]->peer); 08853 08854 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08855 ast_mutex_unlock(&iaxsl[callno]); 08856 if (!(p = find_peer(peer_name, 1))) { 08857 ast_mutex_lock(&iaxsl[callno]); 08858 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08859 return -1; 08860 } 08861 ast_mutex_lock(&iaxsl[callno]); 08862 if (!iaxs[callno]) 08863 goto return_unref; 08864 08865 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08866 if (sin->sin_addr.s_addr) { 08867 time_t nowtime; 08868 time(&nowtime); 08869 realtime_update_peer(peer_name, &sockaddr, nowtime); 08870 } else { 08871 realtime_update_peer(peer_name, &sockaddr, 0); 08872 } 08873 } 08874 08875 /* treat an unspecified refresh interval as the minimum */ 08876 if (!refresh) { 08877 refresh = min_reg_expire; 08878 } 08879 if (refresh > max_reg_expire) { 08880 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08881 p->name, max_reg_expire, refresh); 08882 p->expiry = max_reg_expire; 08883 } else if (refresh < min_reg_expire) { 08884 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08885 p->name, min_reg_expire, refresh); 08886 p->expiry = min_reg_expire; 08887 } else { 08888 p->expiry = refresh; 08889 } 08890 08891 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) { 08892 if (iax2_regfunk) { 08893 iax2_regfunk(p->name, 1); 08894 } 08895 08896 /* modify entry in peercnts table as _not_ registered */ 08897 peercnt_modify((unsigned char) 0, 0, &p->addr); 08898 08899 /* Stash the IP address from which they registered */ 08900 ast_sockaddr_from_sin(&p->addr, sin); 08901 08902 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08903 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08904 ast_db_put("IAX/Registry", p->name, data); 08905 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08906 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08907 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08908 register_peer_exten(p, 1); 08909 ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08910 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) { 08911 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08912 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08913 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08914 register_peer_exten(p, 0); 08915 ast_db_del("IAX/Registry", p->name); 08916 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, AST_DEVSTATE_CACHABLE, "IAX2/%s", p->name); /* Activate notification */ 08917 } 08918 /* Update the host */ 08919 /* Verify that the host is really there */ 08920 iax2_poke_peer(p, callno); 08921 } 08922 08923 /* modify entry in peercnts table as registered */ 08924 if (p->maxcallno) { 08925 peercnt_modify((unsigned char) 1, p->maxcallno, &p->addr); 08926 } 08927 08928 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08929 if (!iaxs[callno]) { 08930 res = -1; 08931 goto return_unref; 08932 } 08933 08934 /* Store socket fd */ 08935 p->sockfd = fd; 08936 /* Setup the expiry */ 08937 if (p->expire > -1) { 08938 if (!ast_sched_thread_del(sched, p->expire)) { 08939 p->expire = -1; 08940 peer_unref(p); 08941 } 08942 } 08943 08944 if (p->expiry && sin->sin_addr.s_addr) { 08945 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08946 if (p->expire == -1) 08947 peer_unref(p); 08948 } 08949 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08950 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08951 if (sin->sin_addr.s_addr) { 08952 struct sockaddr_in peer_addr; 08953 08954 ast_sockaddr_to_sin(&p->addr, &peer_addr); 08955 08956 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08957 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr); 08958 if (!ast_strlen_zero(p->mailbox)) { 08959 struct ast_event *event; 08960 int new, old; 08961 char *mailbox, *context; 08962 08963 context = mailbox = ast_strdupa(p->mailbox); 08964 strsep(&context, "@"); 08965 if (ast_strlen_zero(context)) 08966 context = "default"; 08967 08968 event = ast_event_get_cached(AST_EVENT_MWI, 08969 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08970 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08971 AST_EVENT_IE_END); 08972 if (event) { 08973 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08974 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08975 ast_event_destroy(event); 08976 } else { /* Fall back on checking the mailbox directly */ 08977 ast_app_inboxcount(p->mailbox, &new, &old); 08978 } 08979 08980 if (new > 255) { 08981 new = 255; 08982 } 08983 if (old > 255) { 08984 old = 255; 08985 } 08986 msgcount = (old << 8) | new; 08987 08988 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08989 } 08990 if (ast_test_flag64(p, IAX_HASCALLERID)) { 08991 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08992 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08993 } 08994 } 08995 version = iax_check_version(devtype); 08996 if (version) 08997 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08998 08999 res = 0; 09000 09001 return_unref: 09002 peer_unref(p); 09003 09004 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 09005 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1758 of file chan_iax2.c.
References CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 13178 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
13179 { 13180 struct iax2_user *user = obj; 13181 13182 ast_set_flag64(user, IAX_DELME); 13183 13184 return 0; 13185 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12903 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().
12904 { 12905 struct iax2_user *user = obj; 12906 12907 ast_free_ha(user->ha); 12908 free_context(user->contexts); 12909 if(user->vars) { 12910 ast_variables_destroy(user->vars); 12911 user->vars = NULL; 12912 } 12913 ast_string_field_free_memory(user); 12914 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1748 of file chan_iax2.c.
References ast_str_hash().
Referenced by load_objects().
01749 { 01750 const struct iax2_user *user = obj; 01751 01752 return ast_str_hash(user->name); 01753 }
Definition at line 1805 of file chan_iax2.c.
References ao2_ref.
01806 { 01807 ao2_ref(user, +1); 01808 return user; 01809 }
Definition at line 1811 of file chan_iax2.c.
References ao2_ref.
Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), prune_users(), requirecalltoken_mark_auto(), set_config(), and users_data_provider_get().
01812 { 01813 ao2_ref(user, -1); 01814 return NULL; 01815 }
static int users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 14863 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().
14865 { 14866 struct ast_data *data_user, *data_authmethods, *data_enum_node; 14867 struct iax2_user *user; 14868 struct ao2_iterator i; 14869 char auth[90]; 14870 char *pstr = ""; 14871 14872 i = ao2_iterator_init(users, 0); 14873 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 14874 data_user = ast_data_add_node(data_root, "user"); 14875 if (!data_user) { 14876 continue; 14877 } 14878 14879 ast_data_add_structure(iax2_user, data_user, user); 14880 14881 ast_data_add_codecs(data_user, "codecs", user->capability); 14882 14883 if (!ast_strlen_zero(user->secret)) { 14884 ast_copy_string(auth, user->secret, sizeof(auth)); 14885 } else if (!ast_strlen_zero(user->inkeys)) { 14886 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys); 14887 } else { 14888 ast_copy_string(auth, "no secret", sizeof(auth)); 14889 } 14890 ast_data_add_password(data_user, "secret", auth); 14891 14892 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT); 14893 14894 /* authmethods */ 14895 data_authmethods = ast_data_add_node(data_user, "authmethods"); 14896 if (!data_authmethods) { 14897 ast_data_remove_node(data_root, data_user); 14898 continue; 14899 } 14900 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA); 14901 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5); 14902 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT); 14903 14904 /* amaflags */ 14905 data_enum_node = ast_data_add_node(data_user, "amaflags"); 14906 if (!data_enum_node) { 14907 ast_data_remove_node(data_root, data_user); 14908 continue; 14909 } 14910 ast_data_add_int(data_enum_node, "value", user->amaflags); 14911 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags)); 14912 14913 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0); 14914 14915 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) { 14916 pstr = "REQ only"; 14917 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) { 14918 pstr = "disabled"; 14919 } else { 14920 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host"; 14921 } 14922 ast_data_add_str(data_user, "codec-preferences", pstr); 14923 14924 if (!ast_data_search_match(search, data_user)) { 14925 ast_data_remove_node(data_root, data_user); 14926 } 14927 } 14928 ao2_iterator_destroy(&i); 14929 14930 return 0; 14931 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 9208 of file chan_iax2.c.
References AST_LIST_TRAVERSE, f, iax_frame::oseqno, iax_frame::retries, and send_packet().
Referenced by socket_process().
09209 { 09210 struct iax_frame *f; 09211 09212 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) { 09213 /* Send a copy immediately */ 09214 if (((unsigned char) (f->oseqno - last) < 128) && 09215 (f->retries >= 0)) { 09216 send_packet(f); 09217 } 09218 } 09219 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5365 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, iaxs, iaxsl, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
05366 { 05367 unsigned short callno = pvt->callno; 05368 05369 if (!pvt->peercallno) { 05370 /* We don't know the remote side's call number, yet. :( */ 05371 int count = 10; 05372 while (count-- && pvt && !pvt->peercallno) { 05373 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05374 pvt = iaxs[callno]; 05375 } 05376 if (!pvt || !pvt->peercallno) { 05377 return -1; 05378 } 05379 } 05380 05381 return 0; 05382 }
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 383 of file chan_iax2.c.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_async_goto(), ast_call_forward(), ast_cdr_setaccount(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_set_owners_and_peers(), begin_dial_channel(), build_peer(), check_peer_ok(), create_addr_from_peer(), dahdi_new(), dial_exec_full(), disa_exec(), do_forward(), findmeexec(), func_channel_write_real(), gtalk_new(), jingle_new(), local_call(), sip_new(), skinny_new(), tds_log(), and wait_for_answer().
int adsi = 0 [static] |
Definition at line 387 of file chan_iax2.c.
int amaflags = 0 [static] |
Definition at line 386 of file chan_iax2.c.
Referenced by ast_async_goto().
int authdebug = 1 [static] |
Definition at line 294 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 295 of file chan_iax2.c.
struct ao2_container* callno_pool [static] |
table of available call numbers
Definition at line 849 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 854 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 852 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
Definition at line 14403 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 14943 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 14289 of file chan_iax2.c.
Referenced by __unload_module(), and load_module().
struct ast_channel_tech iax2_tech [static] |
Definition at line 1216 of file chan_iax2.c.
Referenced by __unload_module(), acf_channel_read(), ast_iax2_new(), function_iaxpeer(), iax2_bridge(), iax2_prov_app(), and load_module().
struct ast_datastore_info iax2_variable_datastore_info [static] |
{ .type = "IAX2_VARIABLE", .duplicate = iax2_dup_variable_datastore, .destroy = iax2_free_variable_datastore, }
Definition at line 1414 of file chan_iax2.c.
Referenced by acf_iaxvar_read(), acf_iaxvar_write(), ast_iax2_new(), authenticate_reply(), iax2_call(), and socket_process().
struct ao2_container* iax_peercallno_pvts [static] |
Another container of iax2_pvt structures.
Active IAX2 pvt structs are also stored in this container, if they are a part of an active call where we know the remote side's call number. The reason for this is that incoming media frames do not contain our call number. So, instead of having to iterate the entire iaxs array, we use this container to look up calls where the remote side is using a given call number.
Definition at line 1078 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_peercallno(), and store_by_peercallno().
struct ao2_container* iax_transfercallno_pvts [static] |
Another container of iax2_pvt structures.
* Active IAX2 pvt stucts used during transfering a call are stored here.
Definition at line 1094 of file chan_iax2.c.
Referenced by __find_callno(), __unload_module(), load_objects(), remove_by_transfercallno(), and store_by_transfercallno().
int iaxactivethreadcount = 0 [static] |
Definition at line 638 of file chan_iax2.c.
Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 296 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 371 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 299 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 301 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 636 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxdynamicthreadnum = 0 [static] |
Definition at line 637 of file chan_iax2.c.
Referenced by find_idle_thread().
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
Definition at line 635 of file chan_iax2.c.
Referenced by find_idle_thread(), and set_config().
struct ast_custom_function iaxpeer_function [static] |
{ .name = "IAXPEER", .read = function_iaxpeer, }
Definition at line 14209 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 10024 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 12132 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 14933 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 14938 of file chan_iax2.c.