#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 | active_list |
struct | addr_range |
struct | callno_entry |
struct | chan_iax2_pvt |
struct | chan_iax2_pvt::signaling_queue |
struct | create_addr_info |
struct | dpcache |
struct | dpreq_data |
struct | dynamic_list |
struct | firmwares |
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 | idle_list |
struct | parsed_dial_string |
struct | peercnt |
struct | registrations |
struct | signaling_queue_entry |
struct | tpeers |
Defines | |
#define | ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
#define | ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
#define | CALLNO_TO_PTR(a) ((void *)(unsigned long)(a)) |
#define | CALLTOKEN_HASH_FORMAT "%s%d%u%d" |
#define | CALLTOKEN_IE_FORMAT "%u?%s" |
#define | DATA_EXPORT_IAX2_PEER(MEMBER) |
#define | DATA_EXPORT_IAX2_USER(MEMBER) |
#define | DEBUG_SCHED_MULTITHREAD |
#define | DEBUG_SUPPORT |
#define | DEFAULT_CONTEXT "default" |
#define | DEFAULT_DROP 3 |
#define | DEFAULT_FREQ_NOTOK 10 * 1000 |
#define | DEFAULT_FREQ_OK 60 * 1000 |
#define | DEFAULT_MAX_THREAD_COUNT 100 |
#define | DEFAULT_MAXMS 2000 |
#define | DEFAULT_RETRY_TIME 1000 |
#define | DEFAULT_THREAD_COUNT 10 |
#define | DEFAULT_TRUNKDATA 640 * 10 |
#define | DONT_RESCHEDULE -2 |
#define | FORMAT "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d %-5.5dms %-4.4dms %-4.4dms %-6.6s %s%s %3s%s\n" |
#define | FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" |
#define | FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" |
#define | FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" |
#define | FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" |
#define | FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" |
#define | FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" |
#define | FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" |
#define | FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" |
#define | GAMMA (0.01) |
#define | IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
#define | IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26) |
#define | IAX_ALREADYGONE (uint64_t)(1 << 9) |
#define | IAX_CALLENCRYPTED(pvt) (ast_test_flag64(pvt, IAX_ENCRYPTED) && ast_test_flag64(pvt, IAX_KEYPOPULATED)) |
#define | IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
#define | IAX_CAPABILITY_LOWBANDWIDTH |
#define | IAX_CAPABILITY_LOWFREE |
#define | IAX_CAPABILITY_MEDBANDWIDTH |
#define | IAX_CODEC_NOCAP (uint64_t)(1 << 16) |
#define | IAX_CODEC_NOPREFS (uint64_t)(1 << 15) |
#define | IAX_CODEC_USER_FIRST (uint64_t)(1 << 14) |
#define | IAX_DEBUGDIGEST(msg, key) |
#define | IAX_DELAYPBXSTART (uint64_t)(1 << 25) |
#define | IAX_DELME (uint64_t)(1 << 1) |
#define | IAX_DYNAMIC (uint64_t)(1 << 6) |
#define | IAX_ENCRYPTED (uint64_t)(1 << 12) |
#define | IAX_FORCE_ENCRYPT (uint64_t)(1 << 30) |
#define | IAX_FORCEJITTERBUF (uint64_t)(1 << 20) |
#define | IAX_HASCALLERID (uint64_t)(1 << 0) |
#define | IAX_IMMEDIATE (uint64_t)(1 << 27) |
#define | IAX_KEYPOPULATED (uint64_t)(1 << 13) |
#define | IAX_MAXAUTHREQ (uint64_t)(1 << 24) |
#define | IAX_NOTRANSFER (uint64_t)(1 << 4) |
#define | IAX_PROVISION (uint64_t)(1 << 10) |
#define | IAX_QUELCH (uint64_t)(1 << 11) |
#define | IAX_RECVCONNECTEDLINE (uint64_t)(1 << 29) |
#define | IAX_RTAUTOCLEAR (uint64_t)(1 << 19) |
#define | IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
#define | IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
#define | IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
#define | IAX_RTUPDATE (uint64_t)(1 << 18) |
#define | IAX_SENDANI (uint64_t)(1 << 7) |
#define | IAX_SENDCONNECTEDLINE (uint64_t)(1 << 28) |
#define | IAX_SHRINKCALLERID (uint64_t)(1 << 31) |
#define | IAX_TEMPONLY (uint64_t)(1 << 2) |
#define | IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
#define | IAX_TRUNK (uint64_t)(1 << 3) |
#define | IAX_TRUNKTIMESTAMPS (uint64_t)(1 << 22) |
#define | IAX_USEJITTERBUF (uint64_t)(1 << 5) |
#define | MARK_IAX_SUBCLASS_TX 0x8000 |
#define | MAX_JITTER_BUFFER 50 |
#define | MAX_PEER_BUCKETS 563 |
#define | MAX_RETRY_TIME 10000 |
#define | MAX_TIMESTAMP_SKEW 160 |
#define | MAX_TRUNK_MTU 1240 |
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240. | |
#define | MAX_TRUNKDATA 640 * 200 |
#define | MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define | MEMORY_SIZE 100 |
#define | MIN_JITTER_BUFFER 10 |
#define | MIN_RETRY_TIME 100 |
#define | MIN_REUSE_TIME 60 |
#define | PTR_TO_CALLNO(a) ((unsigned short)(unsigned long)(a)) |
#define | SCHED_MULTITHREADED |
#define | schedule_action(func, data) __schedule_action(func, data, __PRETTY_FUNCTION__) |
#define | TRUNK_CALL_START IAX_MAX_CALLS / 2 |
#define | TS_GAP_FOR_JB_RESYNC 5000 |
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 void | __reg_module (void) |
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 void | __unreg_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) |
Create new call, interface with the PBX core. | |
static int | attempt_transmit (const void *data) |
static int | auth_fail (int callno, int failcode) |
static int | auth_reject (const void *data) |
static int | authenticate (const char *challenge, const char *secret, const char *keyn, int authmethods, struct iax_ie_data *ied, struct sockaddr_in *sin, struct chan_iax2_pvt *pvt) |
static int | authenticate_reply (struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey) |
static int | authenticate_request (int call_num) |
static int | authenticate_verify (struct chan_iax2_pvt *p, struct iax_ies *ies) |
static int | auto_congest (const void *data) |
static int | auto_hangup (const void *data) |
static void | build_callno_limits (struct ast_variable *v) |
static struct iax2_context * | build_context (const char *context) |
static void | build_ecx_key (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static void | build_encryption_keys (const unsigned char *digest, struct chan_iax2_pvt *pvt) |
static struct iax2_peer * | build_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create peer structure based on configuration. | |
static void | build_rand_pad (unsigned char *buf, ssize_t len) |
static struct iax2_user * | build_user (const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly) |
Create in-memory user structure from configuration. | |
static int | cache_get_callno_locked (const char *data) |
static unsigned int | calc_rxstamp (struct chan_iax2_pvt *p, unsigned int offset) |
static unsigned int | calc_timestamp (struct chan_iax2_pvt *p, unsigned int ts, struct ast_frame *f) |
static unsigned int | calc_txpeerstamp (struct iax2_trunk_peer *tpeer, int sampms, struct timeval *now) |
static int | callno_hash (const void *obj, const int flags) |
static int | calltoken_required (struct sockaddr_in *sin, const char *name, int subclass) |
static int | check_access (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
static int | check_provisioning (struct sockaddr_in *sin, int sockfd, char *si, unsigned int ver) |
static int | check_srcaddr (struct sockaddr *sa, socklen_t salen) |
Check if address can be used as packet source. | |
static void | cleanup_thread_list (void *head) |
static int | complete_dpreply (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static char * | complete_iax2_peers (const char *line, const char *word, int pos, int state, uint64_t flags) |
static char * | complete_iax2_unregister (const char *line, const char *word, int pos, int state) |
static int | complete_transfer (int callno, struct iax_ies *ies) |
static unsigned char | compress_subclass (format_t subclass) |
static void | construct_rr (struct chan_iax2_pvt *pvt, struct iax_ie_data *iep) |
static int | create_addr (const char *peername, struct ast_channel *c, struct sockaddr_in *sin, struct create_addr_info *cai) |
static int | create_callno_pools (void) |
static int | decode_frame (ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static int | decrypt_frame (int callno, struct ast_iax2_full_hdr *fh, struct ast_frame *f, int *datalen) |
static void | defer_full_frame (struct iax2_thread *from_here, struct iax2_thread *to_here) |
Queue the last read full frame for processing by a certain thread. | |
static void | delete_users (void) |
static void | destroy_firmware (struct iax_firmware *cur) |
static void | dp_lookup (int callno, const char *context, const char *callednum, const char *callerid, int skiplock) |
static void * | dp_lookup_thread (void *data) |
static void | encmethods_to_str (int e, struct ast_str *buf) |
static int | encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
static int | expire_registry (const void *data) |
static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
static struct iax2_thread * | find_idle_thread (void) |
static struct iax2_peer * | find_peer (const char *name, int realtime) |
static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
static struct iax2_user * | find_user (const char *name) |
static unsigned int | fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts) |
static void | free_context (struct iax2_context *con) |
static void | free_signaling_queue_entry (struct signaling_queue_entry *s) |
static int | function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
static int | get_auth_methods (const char *value) |
static int | get_encrypt_methods (const char *s) |
static int | get_from_jb (const void *p) |
static struct callno_entry * | get_unused_callno (int trunk, int validated) |
static int | handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd) |
static char * | handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Set trunk MTU from CLI. | |
static char * | handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
Show one peer in detail. | |
static char * | handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static char * | handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
static void | handle_deferred_full_frames (struct iax2_thread *thread) |
Handle any deferred full frames for this thread. | |
static int | handle_error (void) |
static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
Acknowledgment received for OUR registration. | |
static int attribute_pure | iax2_allow_new (int frametype, int subclass, int inbound) |
static void | iax2_ami_channelupdate (struct chan_iax2_pvt *pvt) |
Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers. | |
static int | iax2_answer (struct ast_channel *c) |
static int | iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta) |
static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
part of the IAX2 dial plan switch interface | |
static unsigned int | iax2_datetime (const char *tz) |
static void | iax2_destroy (int callno) |
static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
static int | iax2_devicestate (void *data) |
Part of the device state notification system ---. | |
static int | iax2_digit_begin (struct ast_channel *c, char digit) |
static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
static int | iax2_do_register (struct iax2_registry *reg) |
static int | iax2_do_register_s (const void *data) |
static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
static void * | iax2_dup_variable_datastore (void *) |
static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Execute IAX2 dialplan switch. | |
static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 switch interface. | |
static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
static void | iax2_frame_free (struct iax_frame *fr) |
static void | iax2_free_variable_datastore (void *) |
static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
static int | iax2_getpeertrunk (struct sockaddr_in sin) |
static int | iax2_hangup (struct ast_channel *c) |
static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
static int | iax2_key_rotate (const void *vpvt) |
static void | iax2_lock_owner (int callno) |
static int | iax2_matchmore (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
Part of the IAX2 Switch interface. | |
static int | iax2_poke_noanswer (const void *data) |
static int | iax2_poke_peer (struct iax2_peer *peer, int heldcall) |
static int | iax2_poke_peer_cb (void *obj, void *arg, int flags) |
static int | iax2_poke_peer_s (const void *data) |
static int | iax2_predestroy (int callno) |
static void * | iax2_process_thread (void *data) |
static void | iax2_process_thread_cleanup (void *data) |
static int | iax2_prov_app (struct ast_channel *chan, const char *data) |
static int | iax2_provision (struct sockaddr_in *end, int sockfd, const char *dest, const char *template, int force) |
static int | iax2_queryoption (struct ast_channel *c, int option, void *data, int *datalen) |
static int | iax2_queue_control_data (int callno, enum ast_control_frame_type control, const void *data, size_t datalen) |
Queue a control frame on the ast_channel owner. | |
static int | iax2_queue_frame (int callno, struct ast_frame *f) |
Queue a frame to a call's owning asterisk channel. | |
static int | iax2_queue_hangup (int callno) |
Queue a hangup frame on the ast_channel owner. | |
static struct ast_frame * | iax2_read (struct ast_channel *c) |
static int | iax2_register (const char *value, int lineno) |
static struct ast_channel * | iax2_request (const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause) |
static int | iax2_sched_add (struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
static int | iax2_sched_replace (int id, struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
static int | iax2_sendtext (struct ast_channel *c, const char *text) |
static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
static int | iax2_transfer (struct ast_channel *c, const char *dest) |
static int | iax2_transmit (struct iax_frame *fr) |
static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
static int | iax2_vnak (int callno) |
static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
static int | iax_check_version (char *dev) |
static void | iax_debug_output (const char *data) |
static void | iax_error_output (const char *data) |
static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
static void | iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen) |
static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2, const char *parkexten) |
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 void | update_max_nontrunk (void) |
static void | update_max_trunk (void) |
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 struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } |
static char | accountcode [AST_MAX_ACCOUNT_CODE] |
static int | adsi = 0 |
static int | amaflags = 0 |
static struct ast_module_info * | ast_module_info = &__mod_info |
static int | authdebug = 1 |
static int | autokill = 0 |
static struct ao2_container * | callno_limits |
static struct ao2_container * | callno_pool |
static const unsigned int | CALLNO_POOL_BUCKETS = 2699 |
static struct ao2_container * | callno_pool_trunk |
static struct ao2_container * | calltoken_ignores |
static struct ast_cli_entry | cli_iax2 [] |
static struct sockaddr_in | debugaddr |
static uint16_t | DEFAULT_MAXCALLNO_LIMIT = 2048 |
static uint16_t | DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 |
static char | default_parkinglot [AST_MAX_CONTEXT] |
static int | defaultsockfd = -1 |
static int | delayreject = 0 |
struct { | |
iax_frame * first | |
iax_frame * last | |
} | frame_queue [IAX_MAX_CALLS+1] |
a list of frames that may need to be retransmitted | |
static int | global_max_trunk_mtu |
static uint16_t | global_maxcallno |
static uint16_t | global_maxcallno_nonval |
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+1] |
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 const time_t | MAX_CALLTOKEN_DELAY = 10 |
static int | max_reg_expire |
static int | max_retries = 4 |
static int | maxauthreq = 3 |
static int | maxjitterbuffer = 1000 |
static int | maxjitterinterps = 10 |
static int | maxnontrunkcall = 1 |
static int | maxtrunkcall = TRUNK_CALL_START |
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 ao2_container * | peercnts |
static struct ao2_container * | peers |
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 int | randomcalltokendata |
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 uint16_t | total_nonval_callno_used = 0 |
static struct ast_taskprocessor * | transmit_processor |
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 ao2_container * | users |
static struct ast_data_handler | users_data_provider |
Definition in file chan_iax2.c.
#define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
Referenced by ast_cli_netstats().
#define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
Referenced by ast_cli_netstats().
#define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 238 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 14393 of file chan_iax2.c.
#define DATA_EXPORT_IAX2_USER | ( | MEMBER | ) |
Definition at line 14470 of file chan_iax2.c.
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 230 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 246 of file chan_iax2.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 265 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), and users_data_provider_get().
#define DEFAULT_DROP 3 |
Definition at line 244 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 340 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
#define DEFAULT_FREQ_OK 60 * 1000 |
#define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 241 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 338 of file chan_iax2.c.
Referenced by build_peer(), iax2_poke_peer(), and set_config().
#define DEFAULT_RETRY_TIME 1000 |
#define DEFAULT_THREAD_COUNT 10 |
Definition at line 240 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 619 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define DONT_RESCHEDULE -2 |
Definition at line 362 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 251 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)) |
#define IAX_ALLOWFWDOWNLOAD (uint64_t)(1 << 26) |
Allow the FWDOWNL command?
Definition at line 428 of file chan_iax2.c.
Referenced by set_config(), and socket_process().
#define IAX_ALREADYGONE (uint64_t)(1 << 9) |
Already disconnected
Definition at line 411 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 343 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 317 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
#define IAX_CAPABILITY_LOWBANDWIDTH |
Value:
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 329 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 334 of file chan_iax2.c.
#define IAX_CAPABILITY_MEDBANDWIDTH |
#define IAX_CODEC_NOCAP (uint64_t)(1 << 16) |
only consider requested format and ignore capabilities
Definition at line 418 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 417 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 416 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 | ) |
#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 427 of file chan_iax2.c.
Referenced by socket_process().
#define IAX_DELME (uint64_t)(1 << 1) |
Needs to be deleted
Definition at line 403 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 408 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(), register_verify(), and set_config().
#define IAX_ENCRYPTED (uint64_t)(1 << 12) |
Whether we should assume encrypted tx/rx
Definition at line 414 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 432 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 422 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 402 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 429 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 415 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 426 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 406 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), 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 412 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 413 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 431 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 421 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), and set_config().
#define IAX_RTCACHEFRIENDS (uint64_t)(1 << 17) |
let realtime stay till your reload
Definition at line 419 of file chan_iax2.c.
Referenced by __expire_registry(), handle_cli_iax2_prune_realtime(), prune_peers(), prune_users(), set_config(), and update_registry().
#define IAX_RTIGNOREREGEXPIRE (uint64_t)(1 << 21) |
When using realtime, ignore registration expiration
Definition at line 423 of file chan_iax2.c.
Referenced by set_config().
#define IAX_RTSAVE_SYSNAME (uint64_t)(1 << 8) |
Save Systname on Realtime Updates
Definition at line 410 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 420 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 409 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 430 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 433 of file chan_iax2.c.
Referenced by check_access(), and set_config().
#define IAX_TEMPONLY (uint64_t)(1 << 2) |
Temporary (realtime)
Definition at line 404 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
#define IAX_TRANSFERMEDIA (uint64_t)(1 << 23) |
When doing IAX2 transfers, transfer media only
Definition at line 425 of file chan_iax2.c.
Referenced by __find_callno(), build_peer(), build_user(), check_access(), create_addr(), iax2_request(), set_config(), and set_config_destroy().
#define IAX_TRUNK (uint64_t)(1 << 3) |
Treat as a trunk
Definition at line 405 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 424 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 407 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 627 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 616 of file chan_iax2.c.
#define MAX_PEER_BUCKETS 563 |
This module will get much higher performance when doing a lot of user and peer lookups if the number of buckets is increased from 1. However, to maintain old behavior for Asterisk 1.4, these are set to 1 by default. When using multiple buckets, search order through these containers is considered random, so you will not be able to depend on the order the entires are specified in iax.conf for matching order.
Definition at line 878 of file chan_iax2.c.
Referenced by load_objects().
#define MAX_RETRY_TIME 10000 |
#define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 621 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 260 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 284 of file chan_iax2.c.
Referenced by set_config(), and set_config_destroy().
#define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
#define MEMORY_SIZE 100 |
Definition at line 243 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 617 of file chan_iax2.c.
#define MIN_RETRY_TIME 100 |
#define MIN_REUSE_TIME 60 |
#define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 237 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 226 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1487 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 1093 of file chan_iax2.c.
Referenced by __find_callno(), create_callno_pools(), make_trunk(), replace_callno(), update_max_nontrunk(), and update_max_trunk().
#define TS_GAP_FOR_JB_RESYNC 5000 |
Definition at line 624 of file chan_iax2.c.
anonymous enum |
Definition at line 938 of file chan_iax2.c.
00938 { 00939 /*! Extension exists */ 00940 CACHE_FLAG_EXISTS = (1 << 0), 00941 /*! Extension is nonexistent */ 00942 CACHE_FLAG_NONEXISTENT = (1 << 1), 00943 /*! Extension can exist */ 00944 CACHE_FLAG_CANEXIST = (1 << 2), 00945 /*! Waiting to hear back response */ 00946 CACHE_FLAG_PENDING = (1 << 3), 00947 /*! Timed out */ 00948 CACHE_FLAG_TIMEOUT = (1 << 4), 00949 /*! Request transmitted */ 00950 CACHE_FLAG_TRANSMITTED = (1 << 5), 00951 /*! Timeout */ 00952 CACHE_FLAG_UNKNOWN = (1 << 6), 00953 /*! Matchmore */ 00954 CACHE_FLAG_MATCHMORE = (1 << 7), 00955 };
anonymous enum |
Definition at line 1972 of file chan_iax2.c.
01972 { 01973 /* do not allow a new call number, only search ones in use for match */ 01974 NEW_PREVENT = 0, 01975 /* search for match first, then allow a new one to be allocated */ 01976 NEW_ALLOW = 1, 01977 /* do not search for match, force a new call number */ 01978 NEW_FORCE = 2, 01979 /* do not search for match, force a new call number. Signifies call number 01980 * has been calltoken validated */ 01981 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01982 };
enum calltoken_peer_enum |
Call token validation settings.
Definition at line 441 of file chan_iax2.c.
00441 { 00442 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00443 CALLTOKEN_DEFAULT = 0, 00444 /*! \brief Require call token validation. */ 00445 CALLTOKEN_YES = 1, 00446 /*! \brief Require call token validation after a successful registration 00447 * using call token validation occurs. */ 00448 CALLTOKEN_AUTO = 2, 00449 /*! \brief Do not require call token validation. */ 00450 CALLTOKEN_NO = 3, 00451 };
enum iax2_state |
Definition at line 390 of file chan_iax2.c.
00390 { 00391 IAX_STATE_STARTED = (1 << 0), 00392 IAX_STATE_AUTHENTICATED = (1 << 1), 00393 IAX_STATE_TBD = (1 << 2), 00394 };
enum iax2_thread_iostate |
Definition at line 979 of file chan_iax2.c.
00979 { 00980 IAX_IOSTATE_IDLE, 00981 IAX_IOSTATE_READY, 00982 IAX_IOSTATE_PROCESSING, 00983 IAX_IOSTATE_SCHEDREADY, 00984 };
enum iax2_thread_type |
Definition at line 986 of file chan_iax2.c.
00986 { 00987 IAX_THREAD_TYPE_POOL, 00988 IAX_THREAD_TYPE_DYNAMIC, 00989 };
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 572 of file chan_iax2.c.
00572 { 00573 REG_STATE_UNREGISTERED = 0, 00574 REG_STATE_REGSENT, 00575 REG_STATE_AUTHSENT, 00576 REG_STATE_REGISTERED, 00577 REG_STATE_REJECTED, 00578 REG_STATE_TIMEOUT, 00579 REG_STATE_NOAUTH 00580 };
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 582 of file chan_iax2.c.
00582 { 00583 TRANSFER_NONE = 0, 00584 TRANSFER_BEGIN, 00585 TRANSFER_READY, 00586 TRANSFER_RELEASED, 00587 TRANSFER_PASSTHROUGH, 00588 TRANSFER_MBEGIN, 00589 TRANSFER_MREADY, 00590 TRANSFER_MRELEASED, 00591 TRANSFER_MPASSTHROUGH, 00592 TRANSFER_MEDIA, 00593 TRANSFER_MEDIAPASS 00594 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3465 of file chan_iax2.c.
References 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, frame_queue, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, iaxs, iaxsl, iax2_trunk_peer::list, LOG_WARNING, MAX_RETRY_TIME, ast_format::name, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), send_packet(), update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
03466 { 03467 /* Attempt to transmit the frame to the remote peer... 03468 Called without iaxsl held. */ 03469 struct iax_frame *f = (struct iax_frame *)data; 03470 int freeme = 0; 03471 int callno = f->callno; 03472 /* Make sure this call is still active */ 03473 if (callno) 03474 ast_mutex_lock(&iaxsl[callno]); 03475 if (callno && iaxs[callno]) { 03476 if ((f->retries < 0) /* Already ACK'd */ || 03477 (f->retries >= max_retries) /* Too many attempts */) { 03478 /* Record an error if we've transmitted too many times */ 03479 if (f->retries >= max_retries) { 03480 if (f->transfer) { 03481 /* Transfer timeout */ 03482 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03483 } else if (f->final) { 03484 iax2_destroy(callno); 03485 } else { 03486 if (iaxs[callno]->owner) 03487 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %u, ts=%d, seqno=%d)\n", ast_inet_ntoa(iaxs[f->callno]->addr.sin_addr),iaxs[f->callno]->owner->name , f->af.frametype, f->af.subclass.integer, f->ts, f->oseqno); 03488 iaxs[callno]->error = ETIMEDOUT; 03489 if (iaxs[callno]->owner) { 03490 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03491 /* Hangup the fd */ 03492 iax2_queue_frame(callno, &fr); /* XXX */ 03493 /* Remember, owner could disappear */ 03494 if (iaxs[callno] && iaxs[callno]->owner) 03495 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03496 } else { 03497 if (iaxs[callno]->reg) { 03498 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03499 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03500 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03501 } 03502 iax2_destroy(callno); 03503 } 03504 } 03505 03506 } 03507 freeme = 1; 03508 } else { 03509 /* Update it if it needs it */ 03510 update_packet(f); 03511 /* Attempt transmission */ 03512 send_packet(f); 03513 f->retries++; 03514 /* Try again later after 10 times as long */ 03515 f->retrytime *= 10; 03516 if (f->retrytime > MAX_RETRY_TIME) 03517 f->retrytime = MAX_RETRY_TIME; 03518 /* Transfer messages max out at one second */ 03519 if (f->transfer && (f->retrytime > 1000)) 03520 f->retrytime = 1000; 03521 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03522 } 03523 } else { 03524 /* Make sure it gets freed */ 03525 f->retries = -1; 03526 freeme = 1; 03527 } 03528 03529 if (freeme) { 03530 /* Don't attempt delivery, just remove it from the queue */ 03531 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03532 ast_mutex_unlock(&iaxsl[callno]); 03533 f->retrans = -1; /* this is safe because this is the scheduled function */ 03534 /* Free the IAX frame */ 03535 iax2_frame_free(f); 03536 } else if (callno) { 03537 ast_mutex_unlock(&iaxsl[callno]); 03538 } 03539 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 8931 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_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auth_reject().
08932 { 08933 /* Called from IAX thread only, without iaxs lock */ 08934 int callno = (int)(long)(nothing); 08935 struct iax_ie_data ied; 08936 ast_mutex_lock(&iaxsl[callno]); 08937 if (iaxs[callno]) { 08938 memset(&ied, 0, sizeof(ied)); 08939 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 08940 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 08941 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 08942 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 08943 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 08944 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08945 } 08946 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 08947 } 08948 ast_mutex_unlock(&iaxsl[callno]); 08949 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4635 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock, ast_mutex_unlock, f, iax2_queue_frame(), iaxs, iaxsl, chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
04636 { 04637 int callno = PTR_TO_CALLNO(nothing); 04638 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } }; 04639 ast_mutex_lock(&iaxsl[callno]); 04640 if (iaxs[callno]) { 04641 iaxs[callno]->initid = -1; 04642 iax2_queue_frame(callno, &f); 04643 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04644 } 04645 ast_mutex_unlock(&iaxsl[callno]); 04646 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 8980 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iaxs, iaxsl, and send_command_final().
Referenced by auto_hangup().
08981 { 08982 /* Called from IAX thread only, without iaxs lock */ 08983 int callno = (int)(long)(nothing); 08984 struct iax_ie_data ied; 08985 ast_mutex_lock(&iaxsl[callno]); 08986 if (iaxs[callno]) { 08987 memset(&ied, 0, sizeof(ied)); 08988 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 08989 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 08990 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 08991 } 08992 ast_mutex_unlock(&iaxsl[callno]); 08993 }
static int __do_deliver | ( | void * | data | ) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it. This function calls iax2_queue_frame(), which may unlock and lock the mutex associated with this callno, meaning that another thread may grab it and destroy the call.
Definition at line 3251 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().
03252 { 03253 /* Just deliver the packet by using queueing. This is called by 03254 the IAX thread with the iaxsl lock held. */ 03255 struct iax_frame *fr = data; 03256 fr->retrans = -1; 03257 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03258 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE)) 03259 iax2_queue_frame(fr->callno, &fr->af); 03260 /* Free our iax frame */ 03261 iax2_frame_free(fr); 03262 /* And don't run again */ 03263 return 0; 03264 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8562 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_debug, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_test_flag64, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, globalflags, iax2_regfunk, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_TEMPONLY, manager_event, iax2_peer::name, peer_unref(), peercnt_modify(), realtime_update_peer(), register_peer_exten(), and unlink_peer().
Referenced by expire_registry().
08563 { 08564 struct iax2_peer *peer = (struct iax2_peer *) data; 08565 08566 if (!peer) 08567 return; 08568 08569 peer->expire = -1; 08570 08571 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08572 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08573 realtime_update_peer(peer->name, &peer->addr, 0); 08574 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08575 /* modify entry in peercnts table as _not_ registered */ 08576 peercnt_modify(0, 0, &peer->addr); 08577 /* Reset the address */ 08578 memset(&peer->addr, 0, sizeof(peer->addr)); 08579 /* Reset expiry value */ 08580 peer->expiry = min_reg_expire; 08581 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08582 ast_db_del("IAX/Registry", peer->name); 08583 register_peer_exten(peer, 0); 08584 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 08585 if (iax2_regfunk) 08586 iax2_regfunk(peer->name, 0); 08587 08588 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08589 unlink_peer(peer); 08590 08591 peer_unref(peer); 08592 }
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 2754 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, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), globalflags, 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(), sched, send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
02755 { 02756 int res = 0; 02757 int x; 02758 /* this call is calltoken validated as long as it is either NEW_FORCE 02759 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02760 int validated = (new > NEW_ALLOW) ? 1 : 0; 02761 char host[80]; 02762 02763 if (new <= NEW_ALLOW) { 02764 if (callno) { 02765 struct chan_iax2_pvt *pvt; 02766 struct chan_iax2_pvt tmp_pvt = { 02767 .callno = dcallno, 02768 .peercallno = callno, 02769 .transfercallno = callno, 02770 /* hack!! */ 02771 .frames_received = check_dcallno, 02772 }; 02773 02774 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02775 /* this works for finding normal call numbers not involving transfering */ 02776 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02777 if (return_locked) { 02778 ast_mutex_lock(&iaxsl[pvt->callno]); 02779 } 02780 res = pvt->callno; 02781 ao2_ref(pvt, -1); 02782 pvt = NULL; 02783 return res; 02784 } 02785 /* this searches for transfer call numbers that might not get caught otherwise */ 02786 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02787 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02788 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02789 if (return_locked) { 02790 ast_mutex_lock(&iaxsl[pvt->callno]); 02791 } 02792 res = pvt->callno; 02793 ao2_ref(pvt, -1); 02794 pvt = NULL; 02795 return res; 02796 } 02797 } 02798 /* This will occur on the first response to a message that we initiated, 02799 * such as a PING. */ 02800 if (dcallno) { 02801 ast_mutex_lock(&iaxsl[dcallno]); 02802 } 02803 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02804 iaxs[dcallno]->peercallno = callno; 02805 res = dcallno; 02806 store_by_peercallno(iaxs[dcallno]); 02807 if (!res || !return_locked) { 02808 ast_mutex_unlock(&iaxsl[dcallno]); 02809 } 02810 return res; 02811 } 02812 if (dcallno) { 02813 ast_mutex_unlock(&iaxsl[dcallno]); 02814 } 02815 #ifdef IAX_OLD_FIND 02816 /* If we get here, we SHOULD NOT find a call structure for this 02817 callno; if we do, it means that there is a call structure that 02818 has a peer callno but did NOT get entered into the hash table, 02819 which is bad. 02820 02821 If we find a call structure using this old, slow method, output a log 02822 message so we'll know about it. After a few months of leaving this in 02823 place, if we don't hear about people seeing these messages, we can 02824 remove this code for good. 02825 */ 02826 02827 for (x = 1; !res && x < maxnontrunkcall; x++) { 02828 ast_mutex_lock(&iaxsl[x]); 02829 if (iaxs[x]) { 02830 /* Look for an exact match */ 02831 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02832 res = x; 02833 } 02834 } 02835 if (!res || !return_locked) 02836 ast_mutex_unlock(&iaxsl[x]); 02837 } 02838 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02839 ast_mutex_lock(&iaxsl[x]); 02840 if (iaxs[x]) { 02841 /* Look for an exact match */ 02842 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02843 res = x; 02844 } 02845 } 02846 if (!res || !return_locked) 02847 ast_mutex_unlock(&iaxsl[x]); 02848 } 02849 #endif 02850 } 02851 if (!res && (new >= NEW_ALLOW)) { 02852 struct callno_entry *callno_entry; 02853 /* It may seem odd that we look through the peer list for a name for 02854 * this *incoming* call. Well, it is weird. However, users don't 02855 * have an IP address/port number that we can match against. So, 02856 * this is just checking for a peer that has that IP/port and 02857 * assuming that we have a user of the same name. This isn't always 02858 * correct, but it will be changed if needed after authentication. */ 02859 if (!iax2_getpeername(*sin, host, sizeof(host))) 02860 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02861 02862 if (peercnt_add(sin)) { 02863 /* This address has hit its callnumber limit. When the limit 02864 * is reached, the connection is not added to the peercnts table.*/ 02865 return 0; 02866 } 02867 02868 if (!(callno_entry = get_unused_callno(0, validated))) { 02869 /* since we ran out of space, remove the peercnt 02870 * entry we added earlier */ 02871 peercnt_remove_by_addr(sin); 02872 ast_log(LOG_WARNING, "No more space\n"); 02873 return 0; 02874 } 02875 x = callno_entry->callno; 02876 ast_mutex_lock(&iaxsl[x]); 02877 02878 iaxs[x] = new_iax(sin, host); 02879 update_max_nontrunk(); 02880 if (iaxs[x]) { 02881 if (iaxdebug) 02882 ast_debug(1, "Creating new call structure %d\n", x); 02883 iaxs[x]->callno_entry = callno_entry; 02884 iaxs[x]->sockfd = sockfd; 02885 iaxs[x]->addr.sin_port = sin->sin_port; 02886 iaxs[x]->addr.sin_family = sin->sin_family; 02887 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02888 iaxs[x]->peercallno = callno; 02889 iaxs[x]->callno = x; 02890 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02891 iaxs[x]->expiry = min_reg_expire; 02892 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02893 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02894 iaxs[x]->amaflags = amaflags; 02895 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 02896 ast_string_field_set(iaxs[x], accountcode, accountcode); 02897 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02898 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02899 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02900 02901 if (iaxs[x]->peercallno) { 02902 store_by_peercallno(iaxs[x]); 02903 } 02904 } else { 02905 ast_log(LOG_WARNING, "Out of resources\n"); 02906 ast_mutex_unlock(&iaxsl[x]); 02907 replace_callno(callno_entry); 02908 return 0; 02909 } 02910 if (!return_locked) 02911 ast_mutex_unlock(&iaxsl[x]); 02912 res = x; 02913 } 02914 return res; 02915 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4042 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, iax2_trunk_peer::next, 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().
04043 { 04044 int callno = PTR_TO_CALLNO(p); 04045 struct chan_iax2_pvt *pvt = NULL; 04046 struct iax_frame *fr; 04047 jb_frame frame; 04048 int ret; 04049 long ms; 04050 long next; 04051 struct timeval now = ast_tvnow(); 04052 04053 /* Make sure we have a valid private structure before going on */ 04054 ast_mutex_lock(&iaxsl[callno]); 04055 pvt = iaxs[callno]; 04056 if (!pvt) { 04057 /* No go! */ 04058 ast_mutex_unlock(&iaxsl[callno]); 04059 return; 04060 } 04061 04062 pvt->jbid = -1; 04063 04064 /* round up a millisecond since ast_sched_runq does; */ 04065 /* prevents us from spinning while waiting for our now */ 04066 /* to catch up with runq's now */ 04067 now.tv_usec += 1000; 04068 04069 ms = ast_tvdiff_ms(now, pvt->rxcore); 04070 04071 if(ms >= (next = jb_next(pvt->jb))) { 04072 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 04073 switch(ret) { 04074 case JB_OK: 04075 fr = frame.data; 04076 __do_deliver(fr); 04077 /* __do_deliver() can cause the call to disappear */ 04078 pvt = iaxs[callno]; 04079 break; 04080 case JB_INTERP: 04081 { 04082 struct ast_frame af = { 0, }; 04083 04084 /* create an interpolation frame */ 04085 af.frametype = AST_FRAME_VOICE; 04086 af.subclass.codec = pvt->voiceformat; 04087 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 04088 af.src = "IAX2 JB interpolation"; 04089 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 04090 af.offset = AST_FRIENDLY_OFFSET; 04091 04092 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 04093 * which we'd need to malloc, and then it would free it. That seems like a drag */ 04094 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 04095 iax2_queue_frame(callno, &af); 04096 /* iax2_queue_frame() could cause the call to disappear */ 04097 pvt = iaxs[callno]; 04098 } 04099 } 04100 break; 04101 case JB_DROP: 04102 iax2_frame_free(frame.data); 04103 break; 04104 case JB_NOFRAME: 04105 case JB_EMPTY: 04106 /* do nothing */ 04107 break; 04108 default: 04109 /* shouldn't happen */ 04110 break; 04111 } 04112 } 04113 if (pvt) 04114 update_jbsched(pvt); 04115 ast_mutex_unlock(&iaxsl[callno]); 04116 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8238 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08239 { 08240 struct iax2_registry *reg = (struct iax2_registry *)data; 08241 reg->expire = -1; 08242 iax2_do_register(reg); 08243 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11864 of file chan_iax2.c.
References AST_DEVICE_UNAVAILABLE, 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, iax2_peer::name, peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, and sched.
Referenced by iax2_poke_noanswer().
11865 { 11866 struct iax2_peer *peer = (struct iax2_peer *)data; 11867 int callno; 11868 11869 if (peer->lastms > -1) { 11870 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 11871 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 11872 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 11873 } 11874 if ((callno = peer->callno) > 0) { 11875 ast_mutex_lock(&iaxsl[callno]); 11876 iax2_destroy(callno); 11877 ast_mutex_unlock(&iaxsl[callno]); 11878 } 11879 peer->callno = 0; 11880 peer->lastms = -1; 11881 /* Try again quickly */ 11882 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11883 if (peer->pokeexpire == -1) 11884 peer_unref(peer); 11885 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9040 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
09041 { 09042 struct iax2_peer *peer = (struct iax2_peer *)data; 09043 iax2_poke_peer(peer, 0); 09044 peer_unref(peer); 09045 }
static int __iax2_show_peers | ( | int | fd, | |
int * | total, | |||
struct mansession * | s, | |||
const int | argc, | |||
const char *const | argv[] | |||
) | [static] |
Definition at line 6603 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, iax2_peer::name, name, peer_status(), peer_unref(), peers, RESULT_SHOWUSAGE, RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().
06604 { 06605 regex_t regexbuf; 06606 int havepattern = 0; 06607 int total_peers = 0; 06608 int online_peers = 0; 06609 int offline_peers = 0; 06610 int unmonitored_peers = 0; 06611 struct ao2_iterator i; 06612 06613 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" 06614 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" 06615 06616 struct iax2_peer *peer = NULL; 06617 char name[256]; 06618 struct ast_str *encmethods = ast_str_alloca(256); 06619 int registeredonly=0; 06620 char idtext[256] = ""; 06621 switch (argc) { 06622 case 6: 06623 if (!strcasecmp(argv[3], "registered")) 06624 registeredonly = 1; 06625 else 06626 return RESULT_SHOWUSAGE; 06627 if (!strcasecmp(argv[4], "like")) { 06628 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06629 return RESULT_SHOWUSAGE; 06630 havepattern = 1; 06631 } else 06632 return RESULT_SHOWUSAGE; 06633 break; 06634 case 5: 06635 if (!strcasecmp(argv[3], "like")) { 06636 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06637 return RESULT_SHOWUSAGE; 06638 havepattern = 1; 06639 } else 06640 return RESULT_SHOWUSAGE; 06641 break; 06642 case 4: 06643 if (!strcasecmp(argv[3], "registered")) 06644 registeredonly = 1; 06645 else 06646 return RESULT_SHOWUSAGE; 06647 break; 06648 case 3: 06649 break; 06650 default: 06651 return RESULT_SHOWUSAGE; 06652 } 06653 06654 06655 if (!s) 06656 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status"); 06657 06658 i = ao2_iterator_init(peers, 0); 06659 for (peer = ao2_iterator_next(&i); peer; 06660 peer_unref(peer), peer = ao2_iterator_next(&i)) { 06661 char nm[20]; 06662 char status[20]; 06663 int retstatus; 06664 struct sockaddr_in peer_addr; 06665 06666 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 06667 06668 if (registeredonly && !peer_addr.sin_addr.s_addr) { 06669 continue; 06670 } 06671 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 06672 continue; 06673 } 06674 06675 if (!ast_strlen_zero(peer->username)) 06676 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06677 else 06678 ast_copy_string(name, peer->name, sizeof(name)); 06679 06680 encmethods_to_str(peer->encmethods, encmethods); 06681 retstatus = peer_status(peer, status, sizeof(status)); 06682 if (retstatus > 0) 06683 online_peers++; 06684 else if (!retstatus) 06685 offline_peers++; 06686 else 06687 unmonitored_peers++; 06688 06689 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06690 06691 if (s) { 06692 astman_append(s, 06693 "Event: PeerEntry\r\n%s" 06694 "Channeltype: IAX2\r\n" 06695 "ObjectName: %s\r\n" 06696 "ChanObjectType: peer\r\n" 06697 "IPaddress: %s\r\n" 06698 "IPport: %d\r\n" 06699 "Dynamic: %s\r\n" 06700 "Trunk: %s\r\n" 06701 "Encryption: %s\r\n" 06702 "Status: %s\r\n\r\n", 06703 idtext, 06704 name, 06705 ast_sockaddr_stringify_addr(&peer->addr), 06706 ast_sockaddr_port(&peer->addr), 06707 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06708 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06709 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06710 status); 06711 } else { 06712 ast_cli(fd, FORMAT, name, 06713 ast_sockaddr_stringify_addr(&peer->addr), 06714 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06715 nm, 06716 ast_sockaddr_port(&peer->addr), 06717 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06718 peer->encmethods ? "(E)" : " ", 06719 status); 06720 } 06721 total_peers++; 06722 } 06723 ao2_iterator_destroy(&i); 06724 06725 if (!s) 06726 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n", 06727 total_peers, online_peers, offline_peers, unmonitored_peers); 06728 06729 if (havepattern) 06730 regfree(®exbuf); 06731 06732 if (total) 06733 *total = total_peers; 06734 06735 return RESULT_SUCCESS; 06736 #undef FORMAT 06737 #undef FORMAT2 06738 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 14698 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 1462 of file chan_iax2.c.
References ast_copy_string(), ast_debug, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, signal_condition(), and thread.
01463 { 01464 struct iax2_thread *thread = NULL; 01465 static time_t lasterror; 01466 static time_t t; 01467 01468 thread = find_idle_thread(); 01469 01470 if (thread != NULL) { 01471 thread->schedfunc = func; 01472 thread->scheddata = data; 01473 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01474 #ifdef DEBUG_SCHED_MULTITHREAD 01475 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01476 #endif 01477 signal_condition(&thread->lock, &thread->cond); 01478 return 0; 01479 } 01480 time(&t); 01481 if (t != lasterror) 01482 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01483 lasterror = t; 01484 01485 return -1; 01486 }
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 7430 of file chan_iax2.c.
References f, iax2_send(), and queue_signalling().
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
07432 { 07433 struct ast_frame f = { 0, }; 07434 int res = 0; 07435 07436 f.frametype = type; 07437 f.subclass.integer = command; 07438 f.datalen = datalen; 07439 f.src = __FUNCTION__; 07440 f.data.ptr = (void *) data; 07441 07442 if ((res = queue_signalling(i, &f)) <= 0) { 07443 return res; 07444 } 07445 07446 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07447 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1573 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_LAGRQ, iaxs, iaxsl, chan_iax2_pvt::lagid, sched, send_command(), and send_lagrq().
Referenced by send_lagrq().
01574 { 01575 int callno = (long) data; 01576 01577 ast_mutex_lock(&iaxsl[callno]); 01578 01579 if (iaxs[callno]) { 01580 if (iaxs[callno]->peercallno) { 01581 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01582 if (iaxs[callno]->lagid != DONT_RESCHEDULE) { 01583 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01584 } 01585 } 01586 } else { 01587 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01588 } 01589 01590 ast_mutex_unlock(&iaxsl[callno]); 01591 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1506 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iax2_sched_add(), IAX_COMMAND_PING, iaxs, iaxsl, chan_iax2_pvt::pingid, sched, send_command(), and send_ping().
Referenced by send_ping().
01507 { 01508 int callno = (long) data; 01509 01510 ast_mutex_lock(&iaxsl[callno]); 01511 01512 if (iaxs[callno]) { 01513 if (iaxs[callno]->peercallno) { 01514 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01515 if (iaxs[callno]->pingid != DONT_RESCHEDULE) { 01516 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01517 } 01518 } 01519 } else { 01520 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01521 } 01522 01523 ast_mutex_unlock(&iaxsl[callno]); 01524 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 14198 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(), callno_limits, calltoken_ignores, cleanup_thread_list(), cli_iax2, delete_users(), iax2_destroy(), iax2_switch, iax2_tech, iax_peercallno_pvts, iax_provision_unload(), iax_transfercallno_pvts, iaxs, iaxsl, netsock, network_change_event_unsubscribe(), outsock, papp, peercnts, peers, reload_firmware(), sched, timer, and users.
14199 { 14200 struct ast_context *con; 14201 int x; 14202 14203 network_change_event_unsubscribe(); 14204 14205 ast_manager_unregister("IAXpeers"); 14206 ast_manager_unregister("IAXpeerlist"); 14207 ast_manager_unregister("IAXnetstats"); 14208 ast_manager_unregister("IAXregistry"); 14209 ast_unregister_application(papp); 14210 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14211 ast_unregister_switch(&iax2_switch); 14212 ast_channel_unregister(&iax2_tech); 14213 14214 if (netthreadid != AST_PTHREADT_NULL) { 14215 pthread_cancel(netthreadid); 14216 pthread_kill(netthreadid, SIGURG); 14217 pthread_join(netthreadid, NULL); 14218 } 14219 14220 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14221 if (iaxs[x]) { 14222 iax2_destroy(x); 14223 } 14224 } 14225 14226 /* Call for all threads to halt */ 14227 cleanup_thread_list(&idle_list); 14228 cleanup_thread_list(&active_list); 14229 cleanup_thread_list(&dynamic_list); 14230 14231 ast_netsock_release(netsock); 14232 ast_netsock_release(outsock); 14233 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14234 if (iaxs[x]) { 14235 iax2_destroy(x); 14236 } 14237 } 14238 ast_manager_unregister( "IAXpeers" ); 14239 ast_manager_unregister( "IAXpeerlist" ); 14240 ast_manager_unregister( "IAXnetstats" ); 14241 ast_manager_unregister( "IAXregistry" ); 14242 ast_unregister_application(papp); 14243 #ifdef TEST_FRAMEWORK 14244 AST_TEST_UNREGISTER(test_iax2_peers_get); 14245 AST_TEST_UNREGISTER(test_iax2_users_get); 14246 #endif 14247 ast_data_unregister(NULL); 14248 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14249 ast_unregister_switch(&iax2_switch); 14250 ast_channel_unregister(&iax2_tech); 14251 delete_users(); 14252 iax_provision_unload(); 14253 reload_firmware(1); 14254 14255 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14256 ast_mutex_destroy(&iaxsl[x]); 14257 } 14258 14259 ao2_ref(peers, -1); 14260 ao2_ref(users, -1); 14261 ao2_ref(iax_peercallno_pvts, -1); 14262 ao2_ref(iax_transfercallno_pvts, -1); 14263 ao2_ref(peercnts, -1); 14264 ao2_ref(callno_limits, -1); 14265 ao2_ref(calltoken_ignores, -1); 14266 ao2_ref(callno_pool, -1); 14267 ao2_ref(callno_pool_trunk, -1); 14268 if (timer) { 14269 ast_timer_close(timer); 14270 } 14271 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 14272 sched = ast_sched_thread_destroy(sched); 14273 14274 con = ast_context_find(regcontext); 14275 if (con) 14276 ast_context_destroy(con, "IAX2"); 14277 ast_unload_realtime("iaxpeers"); 14278 return 0; 14279 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 14698 of file chan_iax2.c.
static int acf_channel_read | ( | struct ast_channel * | chan, | |
const char * | funcname, | |||
char * | preparse, | |||
char * | buf, | |||
size_t | buflen | |||
) | [static] |
Definition at line 13838 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_mutex_lock, ast_mutex_unlock, iax2_tech, IAX_CALLENCRYPTED, iaxs, iaxsl, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and chan_iax2_pvt::username.
13839 { 13840 struct chan_iax2_pvt *pvt; 13841 unsigned int callno; 13842 int res = 0; 13843 13844 if (!chan || chan->tech != &iax2_tech) { 13845 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13846 return -1; 13847 } 13848 13849 callno = PTR_TO_CALLNO(chan->tech_pvt); 13850 ast_mutex_lock(&iaxsl[callno]); 13851 if (!(pvt = iaxs[callno])) { 13852 ast_mutex_unlock(&iaxsl[callno]); 13853 return -1; 13854 } 13855 13856 if (!strcasecmp(args, "osptoken")) { 13857 ast_copy_string(buf, pvt->osptoken, buflen); 13858 } else if (!strcasecmp(args, "peerip")) { 13859 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 13860 } else if (!strcasecmp(args, "peername")) { 13861 ast_copy_string(buf, pvt->username, buflen); 13862 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) { 13863 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : ""); 13864 } else { 13865 res = -1; 13866 } 13867 13868 ast_mutex_unlock(&iaxsl[callno]); 13869 13870 return res; 13871 }
static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 9708 of file chan_iax2.c.
References ast_channel_datastore_find(), ast_copy_string(), AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_datastore::data, ast_var_t::entries, iax2_variable_datastore_info, and var.
09709 { 09710 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09711 AST_LIST_HEAD(, ast_var_t) *varlist; 09712 struct ast_var_t *var; 09713 09714 if (!variablestore) { 09715 *buf = '\0'; 09716 return 0; 09717 } 09718 varlist = variablestore->data; 09719 09720 AST_LIST_LOCK(varlist); 09721 AST_LIST_TRAVERSE(varlist, var, entries) { 09722 if (strcmp(var->name, data) == 0) { 09723 ast_copy_string(buf, var->value, len); 09724 break; 09725 } 09726 } 09727 AST_LIST_UNLOCK(varlist); 09728 return 0; 09729 }
static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 9731 of file chan_iax2.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, 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, ast_var_t::entries, iax2_variable_datastore_info, ast_datastore::inheritance, LOG_ERROR, and var.
09732 { 09733 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09734 AST_LIST_HEAD(, ast_var_t) *varlist; 09735 struct ast_var_t *var; 09736 09737 if (!variablestore) { 09738 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09739 if (!variablestore) { 09740 ast_log(LOG_ERROR, "Memory allocation error\n"); 09741 return -1; 09742 } 09743 varlist = ast_calloc(1, sizeof(*varlist)); 09744 if (!varlist) { 09745 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09746 return -1; 09747 } 09748 09749 AST_LIST_HEAD_INIT(varlist); 09750 variablestore->data = varlist; 09751 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09752 ast_channel_datastore_add(chan, variablestore); 09753 } else 09754 varlist = variablestore->data; 09755 09756 AST_LIST_LOCK(varlist); 09757 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09758 if (strcmp(var->name, data) == 0) { 09759 AST_LIST_REMOVE_CURRENT(entries); 09760 ast_var_delete(var); 09761 break; 09762 } 09763 } 09764 AST_LIST_TRAVERSE_SAFE_END; 09765 var = ast_var_assign(data, value); 09766 if (var) 09767 AST_LIST_INSERT_TAIL(varlist, var, entries); 09768 else 09769 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09770 AST_LIST_UNLOCK(varlist); 09771 return 0; 09772 }
static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2496 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(), calltoken_ignores, addr_range::ha, LOG_WARNING, and OBJ_POINTER.
Referenced by set_config().
02497 { 02498 struct addr_range tmp; 02499 struct addr_range *addr_range = NULL; 02500 struct ast_ha *ha = NULL; 02501 int error = 0; 02502 02503 if (ast_strlen_zero(addr)) { 02504 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02505 return -1; 02506 } 02507 02508 ha = ast_append_ha("permit", addr, NULL, &error); 02509 02510 /* check for valid config information */ 02511 if (error) { 02512 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02513 return -1; 02514 } 02515 02516 ast_copy_ha(ha, &tmp.ha); 02517 /* find or create the addr_range */ 02518 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02519 ao2_lock(addr_range); 02520 addr_range->delme = 0; 02521 ao2_unlock(addr_range); 02522 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02523 /* copy over config data into addr_range object */ 02524 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02525 ao2_link(calltoken_ignores, addr_range); 02526 } else { 02527 ast_free_ha(ha); 02528 return -1; 02529 } 02530 02531 ast_free_ha(ha); 02532 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02533 02534 return 0; 02535 }
static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | ied | |||
) | [static] |
Definition at line 4709 of file chan_iax2.c.
References iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, 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().
04710 { 04711 /* first make sure their are two empty bytes left in ied->buf */ 04712 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04713 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04714 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04715 pvt->calltoken_ie_len = 2; 04716 } 04717 }
static int addr_range_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2148 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().
02149 { 02150 struct addr_range *lim1 = obj, *lim2 = arg; 02151 return (!(ast_sockaddr_cmp_addr(&lim1->ha.addr, &lim2->ha.addr)) && 02152 !(ast_sockaddr_cmp_addr(&lim1->ha.netmask, &lim2->ha.netmask))) ? 02153 CMP_MATCH | CMP_STOP : 0; 02154 }
static int addr_range_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2133 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
02134 { 02135 struct addr_range *lim = obj; 02136 lim->delme = 1; 02137 return 0; 02138 }
static int addr_range_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2140 of file chan_iax2.c.
References ast_ha::addr, ast_sockaddr_to_sin, and addr_range::ha.
Referenced by load_objects().
02141 { 02142 const struct addr_range *lim = obj; 02143 struct sockaddr_in sin; 02144 ast_sockaddr_to_sin(&lim->ha.addr, &sin); 02145 return abs((int) sin.sin_addr.s_addr); 02146 }
static int addr_range_match_address_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2168 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().
02169 { 02170 struct addr_range *addr_range = obj; 02171 struct sockaddr_in *sin = arg; 02172 struct sockaddr_in ha_netmask_sin; 02173 struct sockaddr_in ha_addr_sin; 02174 02175 ast_sockaddr_to_sin(&addr_range->ha.netmask, &ha_netmask_sin); 02176 ast_sockaddr_to_sin(&addr_range->ha.addr, &ha_addr_sin); 02177 02178 if ((sin->sin_addr.s_addr & ha_netmask_sin.sin_addr.s_addr) == ha_addr_sin.sin_addr.s_addr) { 02179 return CMP_MATCH | CMP_STOP; 02180 } 02181 return 0; 02182 }
static int apply_context | ( | struct iax2_context * | con, | |
const char * | context | |||
) | [static] |
Definition at line 7488 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
07489 { 07490 while(con) { 07491 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 07492 return -1; 07493 con = con->next; 07494 } 07495 return 0; 07496 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 7189 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, iax_rr::delay, iax_rr::dropped, chan_iax2_pvt::first_iax_message, jb_info::frames_dropped, jb_info::frames_lost, jb_info::frames_ooo, chan_iax2_pvt::frames_received, iax_frame_subclass2str(), IAX_USEJITTERBUF, iaxs, iaxsl, jb_getinfo(), iax_rr::jitter, jb_info::jitter, chan_iax2_pvt::last_iax_message, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, MARK_IAX_SUBCLASS_TX, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.
Referenced by handle_cli_iax2_show_netstats(), and manager_iax2_show_netstats().
07190 { 07191 int x; 07192 int numchans = 0; 07193 char first_message[10] = { 0, }; 07194 char last_message[10] = { 0, }; 07195 #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" 07196 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 07197 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07198 ast_mutex_lock(&iaxsl[x]); 07199 if (iaxs[x]) { 07200 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 07201 jb_info jbinfo; 07202 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07203 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07204 07205 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07206 jb_getinfo(iaxs[x]->jb, &jbinfo); 07207 localjitter = jbinfo.jitter; 07208 localdelay = jbinfo.current - jbinfo.min; 07209 locallost = jbinfo.frames_lost; 07210 locallosspct = jbinfo.losspct/1000; 07211 localdropped = jbinfo.frames_dropped; 07212 localooo = jbinfo.frames_ooo; 07213 } else { 07214 localjitter = -1; 07215 localdelay = 0; 07216 locallost = -1; 07217 locallosspct = -1; 07218 localdropped = 0; 07219 localooo = -1; 07220 } 07221 if (s) 07222 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07223 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07224 iaxs[x]->pingtime, 07225 localjitter, 07226 localdelay, 07227 locallost, 07228 locallosspct, 07229 localdropped, 07230 localooo, 07231 iaxs[x]->frames_received/1000, 07232 iaxs[x]->remote_rr.jitter, 07233 iaxs[x]->remote_rr.delay, 07234 iaxs[x]->remote_rr.losscnt, 07235 iaxs[x]->remote_rr.losspct, 07236 iaxs[x]->remote_rr.dropped, 07237 iaxs[x]->remote_rr.ooo, 07238 iaxs[x]->remote_rr.packets/1000, 07239 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07240 first_message, 07241 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07242 last_message); 07243 else 07244 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07245 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07246 iaxs[x]->pingtime, 07247 localjitter, 07248 localdelay, 07249 locallost, 07250 locallosspct, 07251 localdropped, 07252 localooo, 07253 iaxs[x]->frames_received/1000, 07254 iaxs[x]->remote_rr.jitter, 07255 iaxs[x]->remote_rr.delay, 07256 iaxs[x]->remote_rr.losscnt, 07257 iaxs[x]->remote_rr.losspct, 07258 iaxs[x]->remote_rr.dropped, 07259 iaxs[x]->remote_rr.ooo, 07260 iaxs[x]->remote_rr.packets/1000, 07261 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07262 first_message, 07263 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07264 last_message); 07265 numchans++; 07266 } 07267 ast_mutex_unlock(&iaxsl[x]); 07268 } 07269 07270 return numchans; 07271 }
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 | |||
) | [static] |
Create new call, interface with the PBX core.
Definition at line 5682 of file chan_iax2.c.
References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, ast_party_caller::ani, chan_iax2_pvt::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_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, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_channel::context, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_channel::dialed, chan_iax2_pvt::dnid, ast_var_t::entries, ast_channel::exten, chan_iax2_pvt::exten, ast_party_redirecting::from, chan_iax2_pvt::host, iax2_ami_channelupdate(), iax2_tech, iax2_variable_datastore_info, iaxs, iaxsl, chan_iax2_pvt::iaxvars, ast_party_caller::id, ast_datastore::inheritance, chan_iax2_pvt::language, 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, chan_iax2_pvt::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, chan_iax2_pvt::rdnis, 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, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
05683 { 05684 struct ast_channel *tmp; 05685 struct chan_iax2_pvt *i; 05686 struct ast_variable *v = NULL; 05687 05688 if (!(i = iaxs[callno])) { 05689 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05690 return NULL; 05691 } 05692 05693 /* Don't hold call lock */ 05694 ast_mutex_unlock(&iaxsl[callno]); 05695 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); 05696 ast_mutex_lock(&iaxsl[callno]); 05697 if (i != iaxs[callno]) { 05698 if (tmp) { 05699 /* unlock and relock iaxsl[callno] to preserve locking order */ 05700 ast_mutex_unlock(&iaxsl[callno]); 05701 tmp = ast_channel_release(tmp); 05702 ast_mutex_lock(&iaxsl[callno]); 05703 } 05704 return NULL; 05705 } 05706 iax2_ami_channelupdate(i); 05707 if (!tmp) 05708 return NULL; 05709 tmp->tech = &iax2_tech; 05710 /* We can support any format by default, until we get restricted */ 05711 tmp->nativeformats = capability; 05712 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05713 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05714 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05715 05716 if (!ast_strlen_zero(i->parkinglot)) 05717 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05718 /* Don't use ast_set_callerid() here because it will 05719 * generate a NewCallerID event before the NewChannel event */ 05720 if (!ast_strlen_zero(i->ani)) { 05721 tmp->caller.ani.number.valid = 1; 05722 tmp->caller.ani.number.str = ast_strdup(i->ani); 05723 } else if (!ast_strlen_zero(i->cid_num)) { 05724 tmp->caller.ani.number.valid = 1; 05725 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 05726 } 05727 tmp->dialed.number.str = ast_strdup(i->dnid); 05728 tmp->redirecting.from.number.valid = 1; 05729 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 05730 tmp->caller.id.name.presentation = i->calling_pres; 05731 tmp->caller.id.number.presentation = i->calling_pres; 05732 tmp->caller.id.number.plan = i->calling_ton; 05733 tmp->dialed.transit_network_select = i->calling_tns; 05734 if (!ast_strlen_zero(i->language)) 05735 ast_string_field_set(tmp, language, i->language); 05736 if (!ast_strlen_zero(i->accountcode)) 05737 ast_string_field_set(tmp, accountcode, i->accountcode); 05738 if (i->amaflags) 05739 tmp->amaflags = i->amaflags; 05740 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05741 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05742 if (i->adsi) 05743 tmp->adsicpe = i->peeradsicpe; 05744 else 05745 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05746 i->owner = tmp; 05747 i->capability = capability; 05748 05749 /* Set inherited variables */ 05750 if (i->vars) { 05751 for (v = i->vars ; v ; v = v->next) 05752 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05753 } 05754 if (i->iaxvars) { 05755 struct ast_datastore *variablestore; 05756 struct ast_variable *var, *prev = NULL; 05757 AST_LIST_HEAD(, ast_var_t) *varlist; 05758 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05759 varlist = ast_calloc(1, sizeof(*varlist)); 05760 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05761 if (variablestore && varlist) { 05762 variablestore->data = varlist; 05763 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05764 AST_LIST_HEAD_INIT(varlist); 05765 for (var = i->iaxvars; var; var = var->next) { 05766 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05767 if (prev) 05768 ast_free(prev); 05769 prev = var; 05770 if (!newvar) { 05771 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05772 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05773 } else { 05774 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05775 } 05776 } 05777 if (prev) 05778 ast_free(prev); 05779 i->iaxvars = NULL; 05780 ast_channel_datastore_add(i->owner, variablestore); 05781 } else { 05782 if (variablestore) { 05783 ast_datastore_free(variablestore); 05784 } 05785 if (varlist) { 05786 ast_free(varlist); 05787 } 05788 } 05789 } 05790 05791 if (state != AST_STATE_DOWN) { 05792 if (ast_pbx_start(tmp)) { 05793 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05794 ast_hangup(tmp); 05795 i->owner = NULL; 05796 return NULL; 05797 } 05798 } 05799 05800 ast_module_ref(ast_module_info->self); 05801 return tmp; 05802 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3541 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03542 { 03543 #ifdef SCHED_MULTITHREADED 03544 if (schedule_action(__attempt_transmit, data)) 03545 #endif 03546 __attempt_transmit(data); 03547 return 0; 03548 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 8965 of file chan_iax2.c.
References auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, iax2_sched_replace(), iaxs, and sched.
Referenced by socket_process().
08966 { 08967 /* Schedule sending the authentication failure in one second, to prevent 08968 guessing */ 08969 if (iaxs[callno]) { 08970 iaxs[callno]->authfail = failcode; 08971 if (delayreject) { 08972 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 08973 sched, 1000, auth_reject, (void *)(long)callno); 08974 } else 08975 auth_reject((void *)(long)callno); 08976 } 08977 return 0; 08978 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 8951 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().
08952 { 08953 int callno = (int)(long)(data); 08954 ast_mutex_lock(&iaxsl[callno]); 08955 if (iaxs[callno]) 08956 iaxs[callno]->authid = -1; 08957 ast_mutex_unlock(&iaxsl[callno]); 08958 #ifdef SCHED_MULTITHREADED 08959 if (schedule_action(__auth_reject, data)) 08960 #endif 08961 __auth_reject(data); 08962 return 0; 08963 }
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 8060 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, md5(), MD5Final(), MD5Init(), and MD5Update().
Referenced by action_login(), authenticate_reply(), and registry_rerequest().
08061 { 08062 int res = -1; 08063 int x; 08064 if (!ast_strlen_zero(keyn)) { 08065 if (!(authmethods & IAX_AUTH_RSA)) { 08066 if (ast_strlen_zero(secret)) 08067 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)); 08068 } else if (ast_strlen_zero(challenge)) { 08069 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 08070 } else { 08071 char sig[256]; 08072 struct ast_key *key; 08073 key = ast_key_get(keyn, AST_KEY_PRIVATE); 08074 if (!key) { 08075 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 08076 } else { 08077 if (ast_sign(key, (char*)challenge, sig)) { 08078 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 08079 res = -1; 08080 } else { 08081 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 08082 res = 0; 08083 } 08084 } 08085 } 08086 } 08087 /* Fall back */ 08088 if (res && !ast_strlen_zero(secret)) { 08089 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 08090 struct MD5Context md5; 08091 unsigned char digest[16]; 08092 char digres[128]; 08093 MD5Init(&md5); 08094 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 08095 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 08096 MD5Final(digest, &md5); 08097 /* If they support md5, authenticate with it. */ 08098 for (x=0;x<16;x++) 08099 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 08100 if (pvt) { 08101 build_encryption_keys(digest, pvt); 08102 } 08103 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 08104 res = 0; 08105 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 08106 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 08107 res = 0; 08108 } else 08109 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 08110 } 08111 return res; 08112 }
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 8118 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, chan_iax2_pvt::callno, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, iax_ies::encmethods, ast_var_t::entries, 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(), iax2_peer::name, iax2_peer::outkey, peer_unref(), peers, realtime_peer(), iax2_peer::secret, send_command(), iax2_peer::username, iax_ies::username, var, and iax_ies::vars.
Referenced by socket_process().
08119 { 08120 struct iax2_peer *peer = NULL; 08121 /* Start pessimistic */ 08122 int res = -1; 08123 int authmethods = 0; 08124 struct iax_ie_data ied; 08125 uint16_t callno = p->callno; 08126 08127 memset(&ied, 0, sizeof(ied)); 08128 08129 if (ies->username) 08130 ast_string_field_set(p, username, ies->username); 08131 if (ies->challenge) 08132 ast_string_field_set(p, challenge, ies->challenge); 08133 if (ies->authmethods) 08134 authmethods = ies->authmethods; 08135 if (authmethods & IAX_AUTH_MD5) 08136 merge_encryption(p, ies->encmethods); 08137 else 08138 p->encmethods = 0; 08139 08140 /* Check for override RSA authentication first */ 08141 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 08142 /* Normal password authentication */ 08143 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 08144 } else { 08145 struct ao2_iterator i = ao2_iterator_init(peers, 0); 08146 while ((peer = ao2_iterator_next(&i))) { 08147 struct sockaddr_in peer_addr; 08148 08149 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 08150 08151 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 08152 /* No peer specified at our end, or this is the peer */ 08153 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 08154 /* No username specified in peer rule, or this is the right username */ 08155 && (!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))) 08156 /* No specified host, or this is our host */ 08157 ) { 08158 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 08159 if (!res) { 08160 peer_unref(peer); 08161 break; 08162 } 08163 } 08164 peer_unref(peer); 08165 } 08166 ao2_iterator_destroy(&i); 08167 if (!peer) { 08168 /* We checked our list and didn't find one. It's unlikely, but possible, 08169 that we're trying to authenticate *to* a realtime peer */ 08170 const char *peer_name = ast_strdupa(p->peer); 08171 ast_mutex_unlock(&iaxsl[callno]); 08172 if ((peer = realtime_peer(peer_name, NULL))) { 08173 ast_mutex_lock(&iaxsl[callno]); 08174 if (!(p = iaxs[callno])) { 08175 peer_unref(peer); 08176 return -1; 08177 } 08178 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 08179 peer_unref(peer); 08180 } 08181 if (!peer) { 08182 ast_mutex_lock(&iaxsl[callno]); 08183 if (!(p = iaxs[callno])) 08184 return -1; 08185 } 08186 } 08187 } 08188 08189 if (ies->encmethods) { 08190 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 08191 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 08192 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set"); 08193 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 08194 } 08195 if (!res) { 08196 struct ast_datastore *variablestore; 08197 struct ast_variable *var, *prev = NULL; 08198 AST_LIST_HEAD(, ast_var_t) *varlist; 08199 varlist = ast_calloc(1, sizeof(*varlist)); 08200 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 08201 if (variablestore && varlist && p->owner) { 08202 variablestore->data = varlist; 08203 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 08204 AST_LIST_HEAD_INIT(varlist); 08205 for (var = ies->vars; var; var = var->next) { 08206 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 08207 if (prev) 08208 ast_free(prev); 08209 prev = var; 08210 if (!newvar) { 08211 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 08212 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08213 } else { 08214 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 08215 } 08216 } 08217 if (prev) 08218 ast_free(prev); 08219 ies->vars = NULL; 08220 ast_channel_datastore_add(p->owner, variablestore); 08221 } else { 08222 if (p->owner) 08223 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08224 if (variablestore) 08225 ast_datastore_free(variablestore); 08226 if (varlist) 08227 ast_free(varlist); 08228 } 08229 } 08230 08231 if (!res) 08232 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08233 return res; 08234 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7766 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, chan_iax2_pvt::challenge, 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, OBJ_POINTER, send_command(), send_command_final(), user, user_unref(), chan_iax2_pvt::username, and users.
Referenced by socket_process().
07767 { 07768 struct iax_ie_data ied; 07769 int res = -1, authreq_restrict = 0; 07770 char challenge[10]; 07771 struct chan_iax2_pvt *p = iaxs[call_num]; 07772 07773 memset(&ied, 0, sizeof(ied)); 07774 07775 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07776 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07777 struct iax2_user *user, tmp_user = { 07778 .name = p->username, 07779 }; 07780 07781 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07782 if (user) { 07783 if (user->curauthreq == user->maxauthreq) 07784 authreq_restrict = 1; 07785 else 07786 user->curauthreq++; 07787 user = user_unref(user); 07788 } 07789 } 07790 07791 /* If the AUTHREQ limit test failed, send back an error */ 07792 if (authreq_restrict) { 07793 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07794 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07795 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07796 return 0; 07797 } 07798 07799 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07800 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07801 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07802 ast_string_field_set(p, challenge, challenge); 07803 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07804 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07805 } 07806 if (p->encmethods) 07807 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07808 07809 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07810 07811 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07812 07813 if (p->encmethods) 07814 ast_set_flag64(p, IAX_ENCRYPTED); 07815 07816 return res; 07817 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7819 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, chan_iax2_pvt::challenge, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_FORCE_ENCRYPT, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_NOTICE, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user, user_unref(), chan_iax2_pvt::username, and users.
Referenced by socket_process().
07820 { 07821 char requeststr[256]; 07822 char md5secret[256] = ""; 07823 char secret[256] = ""; 07824 char rsasecret[256] = ""; 07825 int res = -1; 07826 int x; 07827 struct iax2_user *user, tmp_user = { 07828 .name = p->username, 07829 }; 07830 07831 if (p->authrej) { 07832 return res; 07833 } 07834 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07835 if (user) { 07836 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07837 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07838 ast_clear_flag64(p, IAX_MAXAUTHREQ); 07839 } 07840 ast_string_field_set(p, host, user->name); 07841 user = user_unref(user); 07842 } 07843 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 07844 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled."); 07845 return res; 07846 } 07847 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07848 return res; 07849 if (ies->password) 07850 ast_copy_string(secret, ies->password, sizeof(secret)); 07851 if (ies->md5_result) 07852 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07853 if (ies->rsa_result) 07854 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07855 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07856 struct ast_key *key; 07857 char *keyn; 07858 char tmpkey[256]; 07859 char *stringp=NULL; 07860 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07861 stringp=tmpkey; 07862 keyn = strsep(&stringp, ":"); 07863 while(keyn) { 07864 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07865 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07866 res = 0; 07867 break; 07868 } else if (!key) 07869 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07870 keyn = strsep(&stringp, ":"); 07871 } 07872 } else if (p->authmethods & IAX_AUTH_MD5) { 07873 struct MD5Context md5; 07874 unsigned char digest[16]; 07875 char *tmppw, *stringp; 07876 07877 tmppw = ast_strdupa(p->secret); 07878 stringp = tmppw; 07879 while((tmppw = strsep(&stringp, ";"))) { 07880 MD5Init(&md5); 07881 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07882 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07883 MD5Final(digest, &md5); 07884 /* If they support md5, authenticate with it. */ 07885 for (x=0;x<16;x++) 07886 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07887 if (!strcasecmp(requeststr, md5secret)) { 07888 res = 0; 07889 break; 07890 } 07891 } 07892 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07893 if (!strcmp(secret, p->secret)) 07894 res = 0; 07895 } 07896 return res; 07897 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4648 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), sip_call(), and sip_show_sched().
04649 { 04650 #ifdef SCHED_MULTITHREADED 04651 if (schedule_action(__auto_congest, data)) 04652 #endif 04653 __auto_congest(data); 04654 return 0; 04655 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 8995 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().
08996 { 08997 int callno = (int)(long)(data); 08998 ast_mutex_lock(&iaxsl[callno]); 08999 if (iaxs[callno]) { 09000 iaxs[callno]->autoid = -1; 09001 } 09002 ast_mutex_unlock(&iaxsl[callno]); 09003 #ifdef SCHED_MULTITHREADED 09004 if (schedule_action(__auto_hangup, data)) 09005 #endif 09006 __auto_hangup(data); 09007 return 0; 09008 }
static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2441 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(), callno_limits, addr_range::ha, LOG_ERROR, ast_variable::name, ast_variable::next, OBJ_POINTER, and ast_variable::value.
Referenced by set_config().
02442 { 02443 struct addr_range *addr_range = NULL; 02444 struct addr_range tmp; 02445 struct ast_ha *ha; 02446 int limit; 02447 int error; 02448 int found; 02449 02450 for (; v; v = v->next) { 02451 limit = -1; 02452 error = 0; 02453 found = 0; 02454 ha = ast_append_ha("permit", v->name, NULL, &error); 02455 02456 /* check for valid config information */ 02457 if (error) { 02458 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02459 continue; 02460 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02461 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02462 ast_free_ha(ha); 02463 continue; 02464 } 02465 02466 ast_copy_ha(ha, &tmp.ha); 02467 /* find or create the addr_range */ 02468 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02469 ao2_lock(addr_range); 02470 found = 1; 02471 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02472 ast_free_ha(ha); 02473 return; /* out of memory */ 02474 } 02475 02476 /* copy over config data into addr_range object */ 02477 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02478 ast_free_ha(ha); /* cleanup the tmp ha */ 02479 addr_range->limit = limit; 02480 addr_range->delme = 0; 02481 02482 /* cleanup */ 02483 if (found) { 02484 ao2_unlock(addr_range); 02485 } else { 02486 ao2_link(callno_limits, addr_range); 02487 } 02488 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02489 } 02490 }
static struct iax2_context* build_context | ( | const char * | context | ) | [static] |
Definition at line 12118 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
12119 { 12120 struct iax2_context *con; 12121 12122 if ((con = ast_calloc(1, sizeof(*con)))) 12123 ast_copy_string(con->context, context, sizeof(con->context)); 12124 12125 return con; 12126 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6145 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().
06146 { 06147 /* it is required to hold the corresponding decrypt key to our encrypt key 06148 * in the pvt struct because queued frames occasionally need to be decrypted and 06149 * re-encrypted when updated for a retransmission */ 06150 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 06151 ast_aes_set_encrypt_key(digest, &pvt->ecx); 06152 ast_aes_set_decrypt_key(digest, &pvt->mydcx); 06153 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6139 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().
06140 { 06141 build_ecx_key(digest, pvt); 06142 ast_aes_set_decrypt_key(digest, &pvt->dcx); 06143 }
static struct iax2_peer * build_peer | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create peer structure based on configuration.
Definition at line 12268 of file chan_iax2.c.
References 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(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, context, iax2_peer::dbsecret, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, get_auth_methods(), get_encrypt_methods(), globalflags, 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, inet_aton(), ast_variable::lineno, LOG_WARNING, mailbox, mwi_event_cb(), ast_variable::name, iax2_peer::name, ast_variable::next, OBJ_POINTER, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::peercontext, peers, prefs, S_OR, sched, secret, strsep(), timer, unlink_peer(), ast_variable::value, and zonetag.
12269 { 12270 struct iax2_peer *peer = NULL; 12271 struct ast_ha *oldha = NULL; 12272 int maskfound = 0; 12273 int found = 0; 12274 int firstpass = 1; 12275 struct iax2_peer tmp_peer = { 12276 .name = name, 12277 }; 12278 12279 if (!temponly) { 12280 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 12281 if (peer && !ast_test_flag64(peer, IAX_DELME)) 12282 firstpass = 0; 12283 } 12284 12285 if (peer) { 12286 found++; 12287 if (firstpass) { 12288 oldha = peer->ha; 12289 peer->ha = NULL; 12290 } 12291 unlink_peer(peer); 12292 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 12293 peer->expire = -1; 12294 peer->pokeexpire = -1; 12295 peer->sockfd = defaultsockfd; 12296 if (ast_string_field_init(peer, 32)) 12297 peer = peer_unref(peer); 12298 } 12299 12300 if (peer) { 12301 if (firstpass) { 12302 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12303 peer->encmethods = iax2_encryption; 12304 peer->adsi = adsi; 12305 ast_string_field_set(peer,secret,""); 12306 if (!found) { 12307 ast_string_field_set(peer, name, name); 12308 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12309 peer->expiry = min_reg_expire; 12310 } 12311 peer->prefs = prefs; 12312 peer->capability = iax2_capability; 12313 peer->smoothing = 0; 12314 peer->pokefreqok = DEFAULT_FREQ_OK; 12315 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 12316 peer->maxcallno = 0; 12317 peercnt_modify(0, 0, &peer->addr); 12318 peer->calltoken_required = CALLTOKEN_DEFAULT; 12319 ast_string_field_set(peer,context,""); 12320 ast_string_field_set(peer,peercontext,""); 12321 ast_clear_flag64(peer, IAX_HASCALLERID); 12322 ast_string_field_set(peer, cid_name, ""); 12323 ast_string_field_set(peer, cid_num, ""); 12324 ast_string_field_set(peer, mohinterpret, mohinterpret); 12325 ast_string_field_set(peer, mohsuggest, mohsuggest); 12326 } 12327 12328 if (!v) { 12329 v = alt; 12330 alt = NULL; 12331 } 12332 while(v) { 12333 if (!strcasecmp(v->name, "secret")) { 12334 ast_string_field_set(peer, secret, v->value); 12335 } else if (!strcasecmp(v->name, "mailbox")) { 12336 ast_string_field_set(peer, mailbox, v->value); 12337 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12338 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12339 ast_string_field_set(peer, mailbox, name); 12340 } 12341 } else if (!strcasecmp(v->name, "mohinterpret")) { 12342 ast_string_field_set(peer, mohinterpret, v->value); 12343 } else if (!strcasecmp(v->name, "mohsuggest")) { 12344 ast_string_field_set(peer, mohsuggest, v->value); 12345 } else if (!strcasecmp(v->name, "dbsecret")) { 12346 ast_string_field_set(peer, dbsecret, v->value); 12347 } else if (!strcasecmp(v->name, "trunk")) { 12348 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12349 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12350 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12351 ast_clear_flag64(peer, IAX_TRUNK); 12352 } 12353 } else if (!strcasecmp(v->name, "auth")) { 12354 peer->authmethods = get_auth_methods(v->value); 12355 } else if (!strcasecmp(v->name, "encryption")) { 12356 peer->encmethods |= get_encrypt_methods(v->value); 12357 if (!peer->encmethods) { 12358 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12359 } 12360 } else if (!strcasecmp(v->name, "forceencryption")) { 12361 if (ast_false(v->value)) { 12362 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12363 } else { 12364 peer->encmethods |= get_encrypt_methods(v->value); 12365 if (peer->encmethods) { 12366 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12367 } 12368 } 12369 } else if (!strcasecmp(v->name, "transfer")) { 12370 if (!strcasecmp(v->value, "mediaonly")) { 12371 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12372 } else if (ast_true(v->value)) { 12373 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12374 } else 12375 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12376 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12377 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12378 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12379 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12380 } else if (!strcasecmp(v->name, "host")) { 12381 if (!strcasecmp(v->value, "dynamic")) { 12382 /* They'll register with us */ 12383 ast_set_flag64(peer, IAX_DYNAMIC); 12384 if (!found) { 12385 /* Initialize stuff iff we're not found, otherwise 12386 we keep going with what we had */ 12387 if (ast_sockaddr_port(&peer->addr)) { 12388 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr)); 12389 } 12390 ast_sockaddr_setnull(&peer->addr); 12391 } 12392 } else { 12393 /* Non-dynamic. Make sure we become that way if we're not */ 12394 ast_sched_thread_del(sched, peer->expire); 12395 ast_clear_flag64(peer, IAX_DYNAMIC); 12396 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12397 return peer_unref(peer); 12398 if (!ast_sockaddr_port(&peer->addr)) { 12399 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12400 } 12401 } 12402 if (!maskfound) 12403 inet_aton("255.255.255.255", &peer->mask); 12404 } else if (!strcasecmp(v->name, "defaultip")) { 12405 struct ast_sockaddr peer_defaddr_tmp; 12406 12407 if (ast_get_ip(&peer_defaddr_tmp, v->value)) { 12408 return peer_unref(peer); 12409 } 12410 ast_sockaddr_to_sin(&peer_defaddr_tmp, 12411 &peer->defaddr); 12412 } else if (!strcasecmp(v->name, "sourceaddress")) { 12413 peer_set_srcaddr(peer, v->value); 12414 } else if (!strcasecmp(v->name, "permit") || 12415 !strcasecmp(v->name, "deny")) { 12416 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12417 } else if (!strcasecmp(v->name, "mask")) { 12418 maskfound++; 12419 inet_aton(v->value, &peer->mask); 12420 } else if (!strcasecmp(v->name, "context")) { 12421 ast_string_field_set(peer, context, v->value); 12422 } else if (!strcasecmp(v->name, "regexten")) { 12423 ast_string_field_set(peer, regexten, v->value); 12424 } else if (!strcasecmp(v->name, "peercontext")) { 12425 ast_string_field_set(peer, peercontext, v->value); 12426 } else if (!strcasecmp(v->name, "port")) { 12427 if (ast_test_flag64(peer, IAX_DYNAMIC)) { 12428 peer->defaddr.sin_port = htons(atoi(v->value)); 12429 } else { 12430 ast_sockaddr_set_port(&peer->addr, atoi(v->value)); 12431 } 12432 } else if (!strcasecmp(v->name, "username")) { 12433 ast_string_field_set(peer, username, v->value); 12434 } else if (!strcasecmp(v->name, "allow")) { 12435 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12436 } else if (!strcasecmp(v->name, "disallow")) { 12437 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12438 } else if (!strcasecmp(v->name, "callerid")) { 12439 if (!ast_strlen_zero(v->value)) { 12440 char name2[80]; 12441 char num2[80]; 12442 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12443 ast_string_field_set(peer, cid_name, name2); 12444 ast_string_field_set(peer, cid_num, num2); 12445 } else { 12446 ast_string_field_set(peer, cid_name, ""); 12447 ast_string_field_set(peer, cid_num, ""); 12448 } 12449 ast_set_flag64(peer, IAX_HASCALLERID); 12450 } else if (!strcasecmp(v->name, "fullname")) { 12451 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12452 ast_set_flag64(peer, IAX_HASCALLERID); 12453 } else if (!strcasecmp(v->name, "cid_number")) { 12454 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12455 ast_set_flag64(peer, IAX_HASCALLERID); 12456 } else if (!strcasecmp(v->name, "sendani")) { 12457 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12458 } else if (!strcasecmp(v->name, "inkeys")) { 12459 ast_string_field_set(peer, inkeys, v->value); 12460 } else if (!strcasecmp(v->name, "outkey")) { 12461 ast_string_field_set(peer, outkey, v->value); 12462 } else if (!strcasecmp(v->name, "qualify")) { 12463 if (!strcasecmp(v->value, "no")) { 12464 peer->maxms = 0; 12465 } else if (!strcasecmp(v->value, "yes")) { 12466 peer->maxms = DEFAULT_MAXMS; 12467 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12468 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); 12469 peer->maxms = 0; 12470 } 12471 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12472 peer->smoothing = ast_true(v->value); 12473 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12474 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12475 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); 12476 } 12477 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12478 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12479 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); 12480 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 12481 } else if (!strcasecmp(v->name, "timezone")) { 12482 ast_string_field_set(peer, zonetag, v->value); 12483 } else if (!strcasecmp(v->name, "adsi")) { 12484 peer->adsi = ast_true(v->value); 12485 } else if (!strcasecmp(v->name, "connectedline")) { 12486 if (ast_true(v->value)) { 12487 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12488 } else if (!strcasecmp(v->value, "send")) { 12489 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12490 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12491 } else if (!strcasecmp(v->value, "receive")) { 12492 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12493 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12494 } else { 12495 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12496 } 12497 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12498 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12499 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12500 } else { 12501 peercnt_modify(1, peer->maxcallno, &peer->addr); 12502 } 12503 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12504 /* default is required unless in optional ip list */ 12505 if (ast_false(v->value)) { 12506 peer->calltoken_required = CALLTOKEN_NO; 12507 } else if (!strcasecmp(v->value, "auto")) { 12508 peer->calltoken_required = CALLTOKEN_AUTO; 12509 } else if (ast_true(v->value)) { 12510 peer->calltoken_required = CALLTOKEN_YES; 12511 } else { 12512 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12513 } 12514 } /* else if (strcasecmp(v->name,"type")) */ 12515 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12516 v = v->next; 12517 if (!v) { 12518 v = alt; 12519 alt = NULL; 12520 } 12521 } 12522 if (!peer->authmethods) 12523 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12524 ast_clear_flag64(peer, IAX_DELME); 12525 } 12526 12527 if (oldha) 12528 ast_free_ha(oldha); 12529 12530 if (!ast_strlen_zero(peer->mailbox)) { 12531 char *mailbox, *context; 12532 context = mailbox = ast_strdupa(peer->mailbox); 12533 strsep(&context, "@"); 12534 if (ast_strlen_zero(context)) 12535 context = "default"; 12536 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12537 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12538 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12539 AST_EVENT_IE_END); 12540 } 12541 12542 return peer; 12543 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 6129 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
06130 { 06131 long tmp; 06132 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 06133 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 06134 buf += sizeof(tmp); 06135 len -= sizeof(tmp); 06136 } 06137 }
static struct iax2_user * build_user | ( | const char * | name, | |
struct ast_variable * | v, | |||
struct ast_variable * | alt, | |||
int | temponly | |||
) | [static] |
Create in-memory user structure from configuration.
Definition at line 12559 of file chan_iax2.c.
References 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(), build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, CALLTOKEN_YES, cid_name, cid_num, cleanup(), iax2_user::dbsecret, format, free_context(), get_auth_methods(), get_encrypt_methods(), globalflags, 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, iax2_user::inkeys, ast_variable::lineno, LOG_WARNING, ast_variable::name, iax2_user::name, ast_variable::next, OBJ_POINTER, parkinglot, prefs, secret, timer, user, user_destructor(), user_unref(), users, and ast_variable::value.
12560 { 12561 struct iax2_user *user = NULL; 12562 struct iax2_context *con, *conl = NULL; 12563 struct ast_ha *oldha = NULL; 12564 struct iax2_context *oldcon = NULL; 12565 int format; 12566 int firstpass=1; 12567 int oldcurauthreq = 0; 12568 char *varname = NULL, *varval = NULL; 12569 struct ast_variable *tmpvar = NULL; 12570 struct iax2_user tmp_user = { 12571 .name = name, 12572 }; 12573 12574 if (!temponly) { 12575 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12576 if (user && !ast_test_flag64(user, IAX_DELME)) 12577 firstpass = 0; 12578 } 12579 12580 if (user) { 12581 if (firstpass) { 12582 oldcurauthreq = user->curauthreq; 12583 oldha = user->ha; 12584 oldcon = user->contexts; 12585 user->ha = NULL; 12586 user->contexts = NULL; 12587 } 12588 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12589 ao2_unlink(users, user); 12590 } else { 12591 user = ao2_alloc(sizeof(*user), user_destructor); 12592 } 12593 12594 if (user) { 12595 if (firstpass) { 12596 ast_string_field_free_memory(user); 12597 memset(user, 0, sizeof(struct iax2_user)); 12598 if (ast_string_field_init(user, 32)) { 12599 user = user_unref(user); 12600 goto cleanup; 12601 } 12602 user->maxauthreq = maxauthreq; 12603 user->curauthreq = oldcurauthreq; 12604 user->prefs = prefs; 12605 user->capability = iax2_capability; 12606 user->encmethods = iax2_encryption; 12607 user->adsi = adsi; 12608 user->calltoken_required = CALLTOKEN_DEFAULT; 12609 ast_string_field_set(user, name, name); 12610 ast_string_field_set(user, language, language); 12611 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); 12612 ast_clear_flag64(user, IAX_HASCALLERID); 12613 ast_string_field_set(user, cid_name, ""); 12614 ast_string_field_set(user, cid_num, ""); 12615 ast_string_field_set(user, accountcode, accountcode); 12616 ast_string_field_set(user, mohinterpret, mohinterpret); 12617 ast_string_field_set(user, mohsuggest, mohsuggest); 12618 } 12619 if (!v) { 12620 v = alt; 12621 alt = NULL; 12622 } 12623 while(v) { 12624 if (!strcasecmp(v->name, "context")) { 12625 con = build_context(v->value); 12626 if (con) { 12627 if (conl) 12628 conl->next = con; 12629 else 12630 user->contexts = con; 12631 conl = con; 12632 } 12633 } else if (!strcasecmp(v->name, "permit") || 12634 !strcasecmp(v->name, "deny")) { 12635 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12636 } else if (!strcasecmp(v->name, "setvar")) { 12637 varname = ast_strdupa(v->value); 12638 if (varname && (varval = strchr(varname,'='))) { 12639 *varval = '\0'; 12640 varval++; 12641 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12642 tmpvar->next = user->vars; 12643 user->vars = tmpvar; 12644 } 12645 } 12646 } else if (!strcasecmp(v->name, "allow")) { 12647 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12648 } else if (!strcasecmp(v->name, "disallow")) { 12649 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12650 } else if (!strcasecmp(v->name, "trunk")) { 12651 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 12652 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 12653 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12654 ast_clear_flag64(user, IAX_TRUNK); 12655 } 12656 } else if (!strcasecmp(v->name, "auth")) { 12657 user->authmethods = get_auth_methods(v->value); 12658 } else if (!strcasecmp(v->name, "encryption")) { 12659 user->encmethods |= get_encrypt_methods(v->value); 12660 if (!user->encmethods) { 12661 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12662 } 12663 } else if (!strcasecmp(v->name, "forceencryption")) { 12664 if (ast_false(v->value)) { 12665 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12666 } else { 12667 user->encmethods |= get_encrypt_methods(v->value); 12668 if (user->encmethods) { 12669 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 12670 } 12671 } 12672 } else if (!strcasecmp(v->name, "transfer")) { 12673 if (!strcasecmp(v->value, "mediaonly")) { 12674 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12675 } else if (ast_true(v->value)) { 12676 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12677 } else 12678 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12679 } else if (!strcasecmp(v->name, "codecpriority")) { 12680 if(!strcasecmp(v->value, "caller")) 12681 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 12682 else if(!strcasecmp(v->value, "disabled")) 12683 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12684 else if(!strcasecmp(v->value, "reqonly")) { 12685 ast_set_flag64(user, IAX_CODEC_NOCAP); 12686 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12687 } 12688 } else if (!strcasecmp(v->name, "immediate")) { 12689 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 12690 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12691 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 12692 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12693 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12694 } else if (!strcasecmp(v->name, "dbsecret")) { 12695 ast_string_field_set(user, dbsecret, v->value); 12696 } else if (!strcasecmp(v->name, "secret")) { 12697 if (!ast_strlen_zero(user->secret)) { 12698 char *old = ast_strdupa(user->secret); 12699 12700 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12701 } else 12702 ast_string_field_set(user, secret, v->value); 12703 } else if (!strcasecmp(v->name, "callerid")) { 12704 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12705 char name2[80]; 12706 char num2[80]; 12707 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12708 ast_string_field_set(user, cid_name, name2); 12709 ast_string_field_set(user, cid_num, num2); 12710 ast_set_flag64(user, IAX_HASCALLERID); 12711 } else { 12712 ast_clear_flag64(user, IAX_HASCALLERID); 12713 ast_string_field_set(user, cid_name, ""); 12714 ast_string_field_set(user, cid_num, ""); 12715 } 12716 } else if (!strcasecmp(v->name, "fullname")) { 12717 if (!ast_strlen_zero(v->value)) { 12718 ast_string_field_set(user, cid_name, v->value); 12719 ast_set_flag64(user, IAX_HASCALLERID); 12720 } else { 12721 ast_string_field_set(user, cid_name, ""); 12722 if (ast_strlen_zero(user->cid_num)) 12723 ast_clear_flag64(user, IAX_HASCALLERID); 12724 } 12725 } else if (!strcasecmp(v->name, "cid_number")) { 12726 if (!ast_strlen_zero(v->value)) { 12727 ast_string_field_set(user, cid_num, v->value); 12728 ast_set_flag64(user, IAX_HASCALLERID); 12729 } else { 12730 ast_string_field_set(user, cid_num, ""); 12731 if (ast_strlen_zero(user->cid_name)) 12732 ast_clear_flag64(user, IAX_HASCALLERID); 12733 } 12734 } else if (!strcasecmp(v->name, "accountcode")) { 12735 ast_string_field_set(user, accountcode, v->value); 12736 } else if (!strcasecmp(v->name, "mohinterpret")) { 12737 ast_string_field_set(user, mohinterpret, v->value); 12738 } else if (!strcasecmp(v->name, "mohsuggest")) { 12739 ast_string_field_set(user, mohsuggest, v->value); 12740 } else if (!strcasecmp(v->name, "parkinglot")) { 12741 ast_string_field_set(user, parkinglot, v->value); 12742 } else if (!strcasecmp(v->name, "language")) { 12743 ast_string_field_set(user, language, v->value); 12744 } else if (!strcasecmp(v->name, "amaflags")) { 12745 format = ast_cdr_amaflags2int(v->value); 12746 if (format < 0) { 12747 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12748 } else { 12749 user->amaflags = format; 12750 } 12751 } else if (!strcasecmp(v->name, "inkeys")) { 12752 ast_string_field_set(user, inkeys, v->value); 12753 } else if (!strcasecmp(v->name, "maxauthreq")) { 12754 user->maxauthreq = atoi(v->value); 12755 if (user->maxauthreq < 0) 12756 user->maxauthreq = 0; 12757 } else if (!strcasecmp(v->name, "adsi")) { 12758 user->adsi = ast_true(v->value); 12759 } else if (!strcasecmp(v->name, "connectedline")) { 12760 if (ast_true(v->value)) { 12761 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12762 } else if (!strcasecmp(v->value, "send")) { 12763 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 12764 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 12765 } else if (!strcasecmp(v->value, "receive")) { 12766 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 12767 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 12768 } else { 12769 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12770 } 12771 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12772 /* default is required unless in optional ip list */ 12773 if (ast_false(v->value)) { 12774 user->calltoken_required = CALLTOKEN_NO; 12775 } else if (!strcasecmp(v->value, "auto")) { 12776 user->calltoken_required = CALLTOKEN_AUTO; 12777 } else if (ast_true(v->value)) { 12778 user->calltoken_required = CALLTOKEN_YES; 12779 } else { 12780 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12781 } 12782 } /* else if (strcasecmp(v->name,"type")) */ 12783 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12784 v = v->next; 12785 if (!v) { 12786 v = alt; 12787 alt = NULL; 12788 } 12789 } 12790 if (!user->authmethods) { 12791 if (!ast_strlen_zero(user->secret)) { 12792 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12793 if (!ast_strlen_zero(user->inkeys)) 12794 user->authmethods |= IAX_AUTH_RSA; 12795 } else if (!ast_strlen_zero(user->inkeys)) { 12796 user->authmethods = IAX_AUTH_RSA; 12797 } else { 12798 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12799 } 12800 } 12801 ast_clear_flag64(user, IAX_DELME); 12802 } 12803 cleanup: 12804 if (oldha) 12805 ast_free_ha(oldha); 12806 if (oldcon) 12807 free_context(oldcon); 12808 return user; 12809 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13443 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(), chan_iax2_pvt::capability, create_addr(), 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, LOG_WARNING, NEW_FORCE, parse_dial_string(), secret, and send_command().
Referenced by find_cache().
13444 { 13445 struct sockaddr_in sin; 13446 int x; 13447 int callno; 13448 struct iax_ie_data ied; 13449 struct create_addr_info cai; 13450 struct parsed_dial_string pds; 13451 char *tmpstr; 13452 13453 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13454 /* Look for an *exact match* call. Once a call is negotiated, it can only 13455 look up entries for a single context */ 13456 if (!ast_mutex_trylock(&iaxsl[x])) { 13457 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13458 return x; 13459 ast_mutex_unlock(&iaxsl[x]); 13460 } 13461 } 13462 13463 /* No match found, we need to create a new one */ 13464 13465 memset(&cai, 0, sizeof(cai)); 13466 memset(&ied, 0, sizeof(ied)); 13467 memset(&pds, 0, sizeof(pds)); 13468 13469 tmpstr = ast_strdupa(data); 13470 parse_dial_string(tmpstr, &pds); 13471 13472 if (ast_strlen_zero(pds.peer)) { 13473 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13474 return -1; 13475 } 13476 13477 /* Populate our address from the given */ 13478 if (create_addr(pds.peer, NULL, &sin, &cai)) 13479 return -1; 13480 13481 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13482 pds.peer, pds.username, pds.password, pds.context); 13483 13484 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13485 if (callno < 1) { 13486 ast_log(LOG_WARNING, "Unable to create call\n"); 13487 return -1; 13488 } 13489 13490 ast_string_field_set(iaxs[callno], dproot, data); 13491 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13492 13493 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13494 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13495 /* the string format is slightly different from a standard dial string, 13496 because the context appears in the 'exten' position 13497 */ 13498 if (pds.exten) 13499 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13500 if (pds.username) 13501 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13502 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13503 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13504 /* Keep password handy */ 13505 if (pds.password) 13506 ast_string_field_set(iaxs[callno], secret, pds.password); 13507 if (pds.key) 13508 ast_string_field_set(iaxs[callno], outkey, pds.key); 13509 /* Start the call going */ 13510 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13511 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13512 13513 return callno; 13514 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 5981 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().
05982 { 05983 /* Returns where in "receive time" we are. That is, how many ms 05984 since we received (or would have received) the frame with timestamp 0 */ 05985 int ms; 05986 #ifdef IAXTESTS 05987 int jit; 05988 #endif /* IAXTESTS */ 05989 /* Setup rxcore if necessary */ 05990 if (ast_tvzero(p->rxcore)) { 05991 p->rxcore = ast_tvnow(); 05992 if (iaxdebug) 05993 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 05994 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 05995 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 05996 #if 1 05997 if (iaxdebug) 05998 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 05999 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 06000 #endif 06001 } 06002 06003 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 06004 #ifdef IAXTESTS 06005 if (test_jit) { 06006 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 06007 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 06008 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 06009 jit = -jit; 06010 ms += jit; 06011 } 06012 } 06013 if (test_late) { 06014 ms += test_late; 06015 test_late = 0; 06016 } 06017 #endif /* IAXTESTS */ 06018 return ms; 06019 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 5848 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, f, iaxs, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, and chan_iax2_pvt::offset.
Referenced by iax2_send(), and socket_process().
05849 { 05850 int ms; 05851 int voice = 0; 05852 int genuine = 0; 05853 int adjust; 05854 int rate = ast_format_rate(f->subclass.codec) / 1000; 05855 struct timeval *delivery = NULL; 05856 05857 05858 /* What sort of frame do we have?: voice is self-explanatory 05859 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05860 non-genuine frames are CONTROL frames [ringing etc], DTMF 05861 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05862 the others need a timestamp slaved to the voice frames so that they go in sequence 05863 */ 05864 if (f) { 05865 if (f->frametype == AST_FRAME_VOICE) { 05866 voice = 1; 05867 delivery = &f->delivery; 05868 } else if (f->frametype == AST_FRAME_IAX) { 05869 genuine = 1; 05870 } else if (f->frametype == AST_FRAME_CNG) { 05871 p->notsilenttx = 0; 05872 } 05873 } 05874 if (ast_tvzero(p->offset)) { 05875 p->offset = ast_tvnow(); 05876 /* Round to nearest 20ms for nice looking traces */ 05877 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05878 } 05879 /* If the timestamp is specified, just send it as is */ 05880 if (ts) 05881 return ts; 05882 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05883 if (delivery && !ast_tvzero(*delivery)) { 05884 ms = ast_tvdiff_ms(*delivery, p->offset); 05885 if (ms < 0) { 05886 ms = 0; 05887 } 05888 if (iaxdebug) 05889 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05890 } else { 05891 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05892 if (ms < 0) 05893 ms = 0; 05894 if (voice) { 05895 /* On a voice frame, use predicted values if appropriate */ 05896 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05897 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05898 /* AN EXPLANATION: 05899 When we send voice, we usually send "calculated" timestamps worked out 05900 on the basis of the number of samples sent. When we send other frames, 05901 we usually send timestamps worked out from the real clock. 05902 The problem is that they can tend to drift out of step because the 05903 source channel's clock and our clock may not be exactly at the same rate. 05904 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05905 for this call. Moving it adjusts timestamps for non-voice frames. 05906 We make the adjustment in the style of a moving average. Each time we 05907 adjust p->offset by 10% of the difference between our clock-derived 05908 timestamp and the predicted timestamp. That's why you see "10000" 05909 below even though IAX2 timestamps are in milliseconds. 05910 The use of a moving average avoids offset moving too radically. 05911 Generally, "adjust" roams back and forth around 0, with offset hardly 05912 changing at all. But if a consistent different starts to develop it 05913 will be eliminated over the course of 10 frames (200-300msecs) 05914 */ 05915 adjust = (ms - p->nextpred); 05916 if (adjust < 0) 05917 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05918 else if (adjust > 0) 05919 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05920 05921 if (!p->nextpred) { 05922 p->nextpred = ms; /*f->samples / rate;*/ 05923 if (p->nextpred <= p->lastsent) 05924 p->nextpred = p->lastsent + 3; 05925 } 05926 ms = p->nextpred; 05927 } else { 05928 /* in this case, just use the actual 05929 * time, since we're either way off 05930 * (shouldn't happen), or we're ending a 05931 * silent period -- and seed the next 05932 * predicted time. Also, round ms to the 05933 * next multiple of frame size (so our 05934 * silent periods are multiples of 05935 * frame size too) */ 05936 05937 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05938 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05939 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05940 05941 if (f->samples >= rate) /* check to make sure we don't core dump */ 05942 { 05943 int diff = ms % (f->samples / rate); 05944 if (diff) 05945 ms += f->samples/rate - diff; 05946 } 05947 05948 p->nextpred = ms; 05949 p->notsilenttx = 1; 05950 } 05951 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05952 /* 05953 * IAX2 draft 03 says that timestamps MUST be in order. 05954 * It does not say anything about several frames having the same timestamp 05955 * When transporting video, we can have a frame that spans multiple iax packets 05956 * (so called slices), so it would make sense to use the same timestamp for all of 05957 * them 05958 * We do want to make sure that frames don't go backwards though 05959 */ 05960 if ( (unsigned int)ms < p->lastsent ) 05961 ms = p->lastsent; 05962 } else { 05963 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05964 it's a genuine frame */ 05965 if (genuine) { 05966 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05967 if (ms <= p->lastsent) 05968 ms = p->lastsent + 3; 05969 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05970 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05971 ms = p->lastsent + 3; 05972 } 05973 } 05974 } 05975 p->lastsent = ms; 05976 if (voice) 05977 p->nextpred = p->nextpred + f->samples / rate; 05978 return ms; 05979 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | now | |||
) | [static] |
Definition at line 5804 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().
05805 { 05806 unsigned long int mssincetx; /* unsigned to handle overflows */ 05807 long int ms, pred; 05808 05809 tpeer->trunkact = *now; 05810 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05811 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05812 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05813 tpeer->txtrunktime = *now; 05814 tpeer->lastsent = 999999; 05815 } 05816 /* Update last transmit time now */ 05817 tpeer->lasttxtime = *now; 05818 05819 /* Calculate ms offset */ 05820 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05821 /* Predict from last value */ 05822 pred = tpeer->lastsent + sampms; 05823 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05824 ms = pred; 05825 05826 /* We never send the same timestamp twice, so fudge a little if we must */ 05827 if (ms == tpeer->lastsent) 05828 ms = tpeer->lastsent + 1; 05829 tpeer->lastsent = ms; 05830 return ms; 05831 }
static int callno_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2657 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02658 { 02659 return abs(ast_random()); 02660 }
static int calltoken_required | ( | struct sockaddr_in * | sin, | |
const char * | name, | |||
int | subclass | |||
) | [static] |
Definition at line 2189 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_ignores, CALLTOKEN_NO, iax2_peer::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), realtime_peer(), realtime_user(), S_OR, user, and user_unref().
Referenced by handle_call_token().
02190 { 02191 struct addr_range *addr_range; 02192 struct iax2_peer *peer = NULL; 02193 struct iax2_user *user = NULL; 02194 /* if no username is given, check for guest accounts */ 02195 const char *find = S_OR(name, "guest"); 02196 int res = 1; /* required by default */ 02197 int optional = 0; 02198 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 02199 /* There are only two cases in which calltoken validation is not required. 02200 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 02201 * the peer definition has not set the requirecalltoken option. 02202 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 02203 */ 02204 02205 /* ----- Case 1 ----- */ 02206 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 02207 ao2_ref(addr_range, -1); 02208 optional = 1; 02209 } 02210 02211 /* ----- Case 2 ----- */ 02212 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 02213 calltoken_required = user->calltoken_required; 02214 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 02215 calltoken_required = user->calltoken_required; 02216 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 02217 calltoken_required = peer->calltoken_required; 02218 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 02219 calltoken_required = peer->calltoken_required; 02220 } 02221 02222 if (peer) { 02223 peer_unref(peer); 02224 } 02225 if (user) { 02226 user_unref(user); 02227 } 02228 02229 ast_debug(1, "Determining if address %s with username %s requires calltoken validation. Optional = %d calltoken_required = %d \n", ast_inet_ntoa(sin->sin_addr), name, optional, calltoken_required); 02230 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 02231 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 02232 res = 0; 02233 } 02234 02235 return res; 02236 }
static int check_access | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7499 of file chan_iax2.c.
References chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::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_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(), 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, chan_iax2_pvt::capability, iax_ies::capability, cid_name, cid_num, iax_ies::codec_prefs, chan_iax2_pvt::context, context, DEFAULT_CONTEXT, iax_ies::dnid, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, globalflags, 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, ast_variable::name, ast_variable::next, parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, user, user_unref(), iax_ies::username, users, ast_variable::value, chan_iax2_pvt::vars, iax_ies::version, and version.
Referenced by socket_process().
07500 { 07501 /* Start pessimistic */ 07502 int res = -1; 07503 int version = 2; 07504 struct iax2_user *user = NULL, *best = NULL; 07505 int bestscore = 0; 07506 int gotcapability = 0; 07507 struct ast_variable *v = NULL, *tmpvar = NULL; 07508 struct ao2_iterator i; 07509 struct ast_sockaddr addr; 07510 07511 if (!iaxs[callno]) 07512 return res; 07513 if (ies->called_number) 07514 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07515 if (ies->calling_number) { 07516 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07517 ast_shrink_phone_number(ies->calling_number); 07518 } 07519 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07520 } 07521 if (ies->calling_name) 07522 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07523 if (ies->calling_ani) 07524 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07525 if (ies->dnid) 07526 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07527 if (ies->rdnis) 07528 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07529 if (ies->called_context) 07530 ast_string_field_set(iaxs[callno], context, ies->called_context); 07531 if (ies->language) 07532 ast_string_field_set(iaxs[callno], language, ies->language); 07533 if (ies->username) 07534 ast_string_field_set(iaxs[callno], username, ies->username); 07535 if (ies->calling_ton > -1) 07536 iaxs[callno]->calling_ton = ies->calling_ton; 07537 if (ies->calling_tns > -1) 07538 iaxs[callno]->calling_tns = ies->calling_tns; 07539 if (ies->calling_pres > -1) 07540 iaxs[callno]->calling_pres = ies->calling_pres; 07541 if (ies->format) 07542 iaxs[callno]->peerformat = ies->format; 07543 if (ies->adsicpe) 07544 iaxs[callno]->peeradsicpe = ies->adsicpe; 07545 if (ies->capability) { 07546 gotcapability = 1; 07547 iaxs[callno]->peercapability = ies->capability; 07548 } 07549 if (ies->version) 07550 version = ies->version; 07551 07552 /* Use provided preferences until told otherwise for actual preferences */ 07553 if (ies->codec_prefs) { 07554 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07555 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07556 } 07557 07558 if (!gotcapability) 07559 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07560 if (version > IAX_PROTO_VERSION) { 07561 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07562 ast_inet_ntoa(sin->sin_addr), version); 07563 return res; 07564 } 07565 /* Search the userlist for a compatible entry, and fill in the rest */ 07566 i = ao2_iterator_init(users, 0); 07567 ast_sockaddr_from_sin(&addr, sin); 07568 while ((user = ao2_iterator_next(&i))) { 07569 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07570 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07571 && ast_apply_ha(user->ha, &addr) /* Access is permitted from this IP */ 07572 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07573 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07574 if (!ast_strlen_zero(iaxs[callno]->username)) { 07575 /* Exact match, stop right now. */ 07576 if (best) 07577 user_unref(best); 07578 best = user; 07579 break; 07580 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07581 /* No required authentication */ 07582 if (user->ha) { 07583 /* There was host authentication and we passed, bonus! */ 07584 if (bestscore < 4) { 07585 bestscore = 4; 07586 if (best) 07587 user_unref(best); 07588 best = user; 07589 continue; 07590 } 07591 } else { 07592 /* No host access, but no secret, either, not bad */ 07593 if (bestscore < 3) { 07594 bestscore = 3; 07595 if (best) 07596 user_unref(best); 07597 best = user; 07598 continue; 07599 } 07600 } 07601 } else { 07602 if (user->ha) { 07603 /* Authentication, but host access too, eh, it's something.. */ 07604 if (bestscore < 2) { 07605 bestscore = 2; 07606 if (best) 07607 user_unref(best); 07608 best = user; 07609 continue; 07610 } 07611 } else { 07612 /* Authentication and no host access... This is our baseline */ 07613 if (bestscore < 1) { 07614 bestscore = 1; 07615 if (best) 07616 user_unref(best); 07617 best = user; 07618 continue; 07619 } 07620 } 07621 } 07622 } 07623 user_unref(user); 07624 } 07625 ao2_iterator_destroy(&i); 07626 user = best; 07627 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07628 user = realtime_user(iaxs[callno]->username, sin); 07629 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07630 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 07631 user = user_unref(user); 07632 } 07633 } 07634 if (user) { 07635 /* We found our match (use the first) */ 07636 /* copy vars */ 07637 for (v = user->vars ; v ; v = v->next) { 07638 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07639 tmpvar->next = iaxs[callno]->vars; 07640 iaxs[callno]->vars = tmpvar; 07641 } 07642 } 07643 /* If a max AUTHREQ restriction is in place, activate it */ 07644 if (user->maxauthreq > 0) 07645 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07646 iaxs[callno]->prefs = user->prefs; 07647 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07648 iaxs[callno]->encmethods = user->encmethods; 07649 /* Store the requested username if not specified */ 07650 if (ast_strlen_zero(iaxs[callno]->username)) 07651 ast_string_field_set(iaxs[callno], username, user->name); 07652 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07653 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07654 iaxs[callno]->capability = user->capability; 07655 /* And use the default context */ 07656 if (ast_strlen_zero(iaxs[callno]->context)) { 07657 if (user->contexts) 07658 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07659 else 07660 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07661 } 07662 /* And any input keys */ 07663 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07664 /* And the permitted authentication methods */ 07665 iaxs[callno]->authmethods = user->authmethods; 07666 iaxs[callno]->adsi = user->adsi; 07667 /* If the user has callerid, override the remote caller id. */ 07668 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07669 iaxs[callno]->calling_tns = 0; 07670 iaxs[callno]->calling_ton = 0; 07671 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07672 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07673 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07674 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07675 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07676 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07677 } /* else user is allowed to set their own CID settings */ 07678 if (!ast_strlen_zero(user->accountcode)) 07679 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07680 if (!ast_strlen_zero(user->mohinterpret)) 07681 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07682 if (!ast_strlen_zero(user->mohsuggest)) 07683 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07684 if (!ast_strlen_zero(user->parkinglot)) 07685 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07686 if (user->amaflags) 07687 iaxs[callno]->amaflags = user->amaflags; 07688 if (!ast_strlen_zero(user->language)) 07689 ast_string_field_set(iaxs[callno], language, user->language); 07690 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07691 /* Keep this check last */ 07692 if (!ast_strlen_zero(user->dbsecret)) { 07693 char *family, *key=NULL; 07694 char buf[80]; 07695 family = ast_strdupa(user->dbsecret); 07696 key = strchr(family, '/'); 07697 if (key) { 07698 *key = '\0'; 07699 key++; 07700 } 07701 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07702 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07703 else 07704 ast_string_field_set(iaxs[callno], secret, buf); 07705 } else 07706 ast_string_field_set(iaxs[callno], secret, user->secret); 07707 res = 0; 07708 user = user_unref(user); 07709 } else { 07710 /* user was not found, but we should still fake an AUTHREQ. 07711 * Set authmethods to the last known authmethod used by the system 07712 * Set a fake secret, it's not looked at, just required to attempt authentication. 07713 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07714 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07715 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07716 iaxs[callno]->authrej = 1; 07717 if (!ast_strlen_zero(iaxs[callno]->username)) { 07718 /* only send the AUTHREQ if a username was specified. */ 07719 res = 0; 07720 } 07721 } 07722 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07723 return res; 07724 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 9315 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09316 { 09317 unsigned int ourver; 09318 char rsi[80]; 09319 snprintf(rsi, sizeof(rsi), "si-%s", si); 09320 if (iax_provision_version(&ourver, rsi, 1)) 09321 return 0; 09322 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09323 if (ourver != ver) 09324 iax2_provision(sin, sockfd, NULL, rsi, 1); 09325 return 0; 09326 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 12144 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
12145 { 12146 int sd; 12147 int res; 12148 12149 sd = socket(AF_INET, SOCK_DGRAM, 0); 12150 if (sd < 0) { 12151 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 12152 return -1; 12153 } 12154 12155 res = bind(sd, sa, salen); 12156 if (res < 0) { 12157 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 12158 close(sd); 12159 return 1; 12160 } 12161 12162 close(sd); 12163 return 0; 12164 }
static void cleanup_thread_list | ( | void * | head | ) | [static] |
Definition at line 14178 of file chan_iax2.c.
References AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, iax2_thread::list, signal_condition(), and thread.
Referenced by __unload_module().
14179 { 14180 AST_LIST_HEAD(iax2_thread_list, iax2_thread); 14181 struct iax2_thread_list *list_head = head; 14182 struct iax2_thread *thread; 14183 14184 AST_LIST_LOCK(list_head); 14185 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) { 14186 pthread_t thread_id = thread->threadid; 14187 14188 thread->stop = 1; 14189 signal_condition(&thread->lock, &thread->cond); 14190 14191 AST_LIST_UNLOCK(list_head); 14192 pthread_join(thread_id, NULL); 14193 AST_LIST_LOCK(list_head); 14194 } 14195 AST_LIST_UNLOCK(list_head); 14196 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8289 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, iax2_dpcache::peer_list, iax_ies::refresh, status, and iax2_dpcache::waiters.
Referenced by socket_process().
08290 { 08291 char exten[256] = ""; 08292 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08293 struct iax2_dpcache *dp = NULL; 08294 08295 if (ies->called_number) 08296 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08297 08298 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08299 status = CACHE_FLAG_EXISTS; 08300 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08301 status = CACHE_FLAG_CANEXIST; 08302 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08303 status = CACHE_FLAG_NONEXISTENT; 08304 08305 if (ies->refresh) 08306 expiry = ies->refresh; 08307 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08308 matchmore = CACHE_FLAG_MATCHMORE; 08309 08310 AST_LIST_LOCK(&dpcache); 08311 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08312 if (strcmp(dp->exten, exten)) 08313 continue; 08314 AST_LIST_REMOVE_CURRENT(peer_list); 08315 dp->callno = 0; 08316 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08317 if (dp->flags & CACHE_FLAG_PENDING) { 08318 dp->flags &= ~CACHE_FLAG_PENDING; 08319 dp->flags |= status; 08320 dp->flags |= matchmore; 08321 } 08322 /* Wake up waiters */ 08323 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08324 if (dp->waiters[x] > -1) { 08325 if (write(dp->waiters[x], "asdf", 4) < 0) { 08326 } 08327 } 08328 } 08329 } 08330 AST_LIST_TRAVERSE_SAFE_END; 08331 AST_LIST_UNLOCK(&dpcache); 08332 08333 return 0; 08334 }
static char * complete_iax2_peers | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
uint64_t | flags | |||
) | [static] |
Definition at line 3808 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_test_flag64, iax2_peer::name, peer_unref(), and peers.
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), and handle_cli_iax2_show_peer().
03809 { 03810 int which = 0; 03811 struct iax2_peer *peer; 03812 char *res = NULL; 03813 int wordlen = strlen(word); 03814 struct ao2_iterator i; 03815 03816 i = ao2_iterator_init(peers, 0); 03817 while ((peer = ao2_iterator_next(&i))) { 03818 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03819 && (!flags || ast_test_flag64(peer, flags))) { 03820 res = ast_strdup(peer->name); 03821 peer_unref(peer); 03822 break; 03823 } 03824 peer_unref(peer); 03825 } 03826 ao2_iterator_destroy(&i); 03827 03828 return res; 03829 }
static char * complete_iax2_unregister | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 6852 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::expire, iax2_peer::name, peer_unref(), and peers.
Referenced by handle_cli_iax2_unregister().
06853 { 06854 int which = 0; 06855 struct iax2_peer *p = NULL; 06856 char *res = NULL; 06857 int wordlen = strlen(word); 06858 06859 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06860 if (pos == 2) { 06861 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06862 while ((p = ao2_iterator_next(&i))) { 06863 if (!strncasecmp(p->name, word, wordlen) && 06864 ++which > state && p->expire > 0) { 06865 res = ast_strdup(p->name); 06866 peer_unref(p); 06867 break; 06868 } 06869 peer_unref(p); 06870 } 06871 ao2_iterator_destroy(&i); 06872 } 06873 06874 return res; 06875 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8336 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, frame_queue, 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, iax_frame::list, 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().
08337 { 08338 int peercallno = 0; 08339 struct chan_iax2_pvt *pvt = iaxs[callno]; 08340 struct iax_frame *cur; 08341 jb_frame frame; 08342 08343 if (ies->callno) 08344 peercallno = ies->callno; 08345 08346 if (peercallno < 1) { 08347 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08348 return -1; 08349 } 08350 remove_by_transfercallno(pvt); 08351 /* since a transfer has taken place, the address will change. 08352 * This must be accounted for in the peercnts table. Remove 08353 * the old address and add the new one */ 08354 peercnt_remove_by_addr(&pvt->addr); 08355 peercnt_add(&pvt->transfer); 08356 /* now copy over the new address */ 08357 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08358 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08359 /* Reset sequence numbers */ 08360 pvt->oseqno = 0; 08361 pvt->rseqno = 0; 08362 pvt->iseqno = 0; 08363 pvt->aseqno = 0; 08364 08365 if (pvt->peercallno) { 08366 remove_by_peercallno(pvt); 08367 } 08368 pvt->peercallno = peercallno; 08369 /*this is where the transfering call swiches hash tables */ 08370 store_by_peercallno(pvt); 08371 pvt->transferring = TRANSFER_NONE; 08372 pvt->svoiceformat = -1; 08373 pvt->voiceformat = 0; 08374 pvt->svideoformat = -1; 08375 pvt->videoformat = 0; 08376 pvt->transfercallno = 0; 08377 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08378 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08379 /* reset jitterbuffer */ 08380 while(jb_getall(pvt->jb,&frame) == JB_OK) 08381 iax2_frame_free(frame.data); 08382 jb_reset(pvt->jb); 08383 pvt->lag = 0; 08384 pvt->last = 0; 08385 pvt->lastsent = 0; 08386 pvt->nextpred = 0; 08387 pvt->pingtime = DEFAULT_RETRY_TIME; 08388 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08389 /* We must cancel any packets that would have been transmitted 08390 because now we're talking to someone new. It's okay, they 08391 were transmitted to someone that didn't care anyway. */ 08392 cur->retries = -1; 08393 } 08394 return 0; 08395 }
static unsigned char compress_subclass | ( | format_t | subclass | ) | [static] |
Definition at line 1609 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().
01610 { 01611 int x; 01612 int power=-1; 01613 /* If it's 64 or smaller, just return it */ 01614 if (subclass < IAX_FLAG_SC_LOG) 01615 return subclass; 01616 /* Otherwise find its power */ 01617 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01618 if (subclass & (1LL << x)) { 01619 if (power > -1) { 01620 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass); 01621 return 0; 01622 } else 01623 power = x; 01624 } 01625 } 01626 return power | IAX_FLAG_SC_LOG; 01627 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 9328 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().
09329 { 09330 jb_info stats; 09331 jb_getinfo(pvt->jb, &stats); 09332 09333 memset(iep, 0, sizeof(*iep)); 09334 09335 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09336 if(stats.frames_in == 0) stats.frames_in = 1; 09337 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09338 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09339 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09340 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09341 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09342 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 4536 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, iax2_peer::cid_name, create_addr_info::cid_name, iax2_peer::cid_num, create_addr_info::cid_num, iax2_peer::context, create_addr_info::context, iax2_peer::dbsecret, 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, iax2_peer::mohinterpret, create_addr_info::mohinterpret, iax2_peer::mohsuggest, create_addr_info::mohsuggest, ast_channel::nativeformats, iax2_peer::outkey, create_addr_info::outkey, peer_unref(), iax2_peer::peercontext, create_addr_info::peercontext, iax2_peer::prefs, create_addr_info::prefs, prefs, iax2_peer::secret, create_addr_info::secret, iax2_peer::sockfd, create_addr_info::sockfd, ast_sockaddr::ss, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.
04537 { 04538 struct iax2_peer *peer; 04539 int res = -1; 04540 struct ast_codec_pref ourprefs; 04541 struct sockaddr_in peer_addr; 04542 04543 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04544 cai->sockfd = defaultsockfd; 04545 cai->maxtime = 0; 04546 sin->sin_family = AF_INET; 04547 04548 if (!(peer = find_peer(peername, 1))) { 04549 struct ast_sockaddr sin_tmp; 04550 04551 cai->found = 0; 04552 sin_tmp.ss.ss_family = AF_INET; 04553 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) { 04554 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04555 return -1; 04556 } 04557 ast_sockaddr_to_sin(&sin_tmp, sin); 04558 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04559 /* use global iax prefs for unknown peer/user */ 04560 /* But move the calling channel's native codec to the top of the preference list */ 04561 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04562 if (c) 04563 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04564 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04565 return 0; 04566 } 04567 04568 cai->found = 1; 04569 04570 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 04571 04572 /* if the peer has no address (current or default), return failure */ 04573 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 04574 goto return_unref; 04575 } 04576 04577 /* if the peer is being monitored and is currently unreachable, return failure */ 04578 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04579 goto return_unref; 04580 04581 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04582 cai->maxtime = peer->maxms; 04583 cai->capability = peer->capability; 04584 cai->encmethods = peer->encmethods; 04585 cai->sockfd = peer->sockfd; 04586 cai->adsi = peer->adsi; 04587 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04588 /* Move the calling channel's native codec to the top of the preference list */ 04589 if (c) { 04590 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats); 04591 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04592 } 04593 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04594 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04595 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04596 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04597 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04598 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04599 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04600 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04601 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04602 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04603 if (ast_strlen_zero(peer->dbsecret)) { 04604 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04605 } else { 04606 char *family; 04607 char *key = NULL; 04608 04609 family = ast_strdupa(peer->dbsecret); 04610 key = strchr(family, '/'); 04611 if (key) 04612 *key++ = '\0'; 04613 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04614 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04615 goto return_unref; 04616 } 04617 } 04618 04619 if (peer_addr.sin_addr.s_addr) { 04620 sin->sin_addr = peer_addr.sin_addr; 04621 sin->sin_port = peer_addr.sin_port; 04622 } else { 04623 sin->sin_addr = peer->defaddr.sin_addr; 04624 sin->sin_port = peer->defaddr.sin_port; 04625 } 04626 04627 res = 0; 04628 04629 return_unref: 04630 peer_unref(peer); 04631 04632 return res; 04633 }
static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2662 of file chan_iax2.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, callno_hash(), and TRUNK_CALL_START.
Referenced by load_objects().
02663 { 02664 uint16_t i; 02665 02666 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02667 return -1; 02668 } 02669 02670 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02671 return -1; 02672 } 02673 02674 /* start at 2, 0 and 1 are reserved */ 02675 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02676 struct callno_entry *callno_entry; 02677 02678 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02679 return -1; 02680 } 02681 02682 callno_entry->callno = i; 02683 02684 if (i < TRUNK_CALL_START) { 02685 ao2_link(callno_pool, callno_entry); 02686 } else { 02687 ao2_link(callno_pool_trunk, callno_entry); 02688 } 02689 02690 ao2_ref(callno_entry, -1); 02691 } 02692 02693 return 0; 02694 }
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 6203 of file chan_iax2.c.
References ast_debug, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, f, IAX_FLAG_FULL, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame(), and update_packet().
06204 { 06205 int padding; 06206 unsigned char *workspace; 06207 06208 workspace = alloca(*datalen); 06209 memset(f, 0, sizeof(*f)); 06210 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06211 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06212 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06213 return -1; 06214 /* Decrypt */ 06215 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06216 06217 padding = 16 + (workspace[15] & 0x0f); 06218 if (iaxdebug) 06219 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 06220 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06221 return -1; 06222 06223 *datalen -= padding; 06224 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06225 f->frametype = fh->type; 06226 if (f->frametype == AST_FRAME_VIDEO) { 06227 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06228 } else if (f->frametype == AST_FRAME_VOICE) { 06229 f->subclass.codec = uncompress_subclass(fh->csub); 06230 } else { 06231 f->subclass.integer = uncompress_subclass(fh->csub); 06232 } 06233 } else { 06234 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06235 if (iaxdebug) 06236 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06237 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06238 return -1; 06239 /* Decrypt */ 06240 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06241 padding = 16 + (workspace[15] & 0x0f); 06242 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06243 return -1; 06244 *datalen -= padding; 06245 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06246 } 06247 return 0; 06248 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 6291 of file chan_iax2.c.
References ast_set_flag64, ast_strdupa, ast_test_flag64, build_encryption_keys(), decode_frame(), f, IAX_KEYPOPULATED, iaxs, md5(), MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by socket_process().
06292 { 06293 int res=-1; 06294 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06295 /* Search for possible keys, given secrets */ 06296 struct MD5Context md5; 06297 unsigned char digest[16]; 06298 char *tmppw, *stringp; 06299 06300 tmppw = ast_strdupa(iaxs[callno]->secret); 06301 stringp = tmppw; 06302 while ((tmppw = strsep(&stringp, ";"))) { 06303 MD5Init(&md5); 06304 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06305 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06306 MD5Final(digest, &md5); 06307 build_encryption_keys(digest, iaxs[callno]); 06308 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06309 if (!res) { 06310 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06311 break; 06312 } 06313 } 06314 } else 06315 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06316 return res; 06317 }
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 9475 of file chan_iax2.c.
References ast_calloc, AST_LIST_INSERT_BEFORE_CURRENT, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_mutex_lock, ast_mutex_unlock, iax2_pkt_buf::buf, iax2_thread::buf, iax2_thread::buf_len, iax2_thread::full_frames, iax2_thread::lock, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
09476 { 09477 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09478 struct ast_iax2_full_hdr *fh, *cur_fh; 09479 09480 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09481 return; 09482 09483 pkt_buf->len = from_here->buf_len; 09484 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09485 09486 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09487 ast_mutex_lock(&to_here->lock); 09488 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09489 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09490 if (fh->oseqno < cur_fh->oseqno) { 09491 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09492 break; 09493 } 09494 } 09495 AST_LIST_TRAVERSE_SAFE_END 09496 09497 if (!cur_pkt_buf) 09498 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09499 09500 ast_mutex_unlock(&to_here->lock); 09501 }
static void delete_users | ( | void | ) | [static] |
Definition at line 12829 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::entry, iax2_registry::expire, iax2_destroy(), iaxs, iaxsl, peer_delme_cb(), peers, chan_iax2_pvt::reg, sched, user_delme_cb(), and users.
12830 { 12831 struct iax2_registry *reg; 12832 12833 ao2_callback(users, 0, user_delme_cb, NULL); 12834 12835 AST_LIST_LOCK(®istrations); 12836 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 12837 if (sched) { 12838 ast_sched_thread_del(sched, reg->expire); 12839 } 12840 if (reg->callno) { 12841 int callno = reg->callno; 12842 ast_mutex_lock(&iaxsl[callno]); 12843 if (iaxs[callno]) { 12844 iaxs[callno]->reg = NULL; 12845 iax2_destroy(callno); 12846 } 12847 ast_mutex_unlock(&iaxsl[callno]); 12848 } 12849 if (reg->dnsmgr) 12850 ast_dnsmgr_release(reg->dnsmgr); 12851 ast_free(reg); 12852 } 12853 AST_LIST_UNLOCK(®istrations); 12854 12855 ao2_callback(peers, 0, peer_delme_cb, NULL); 12856 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2992 of file chan_iax2.c.
References ast_free, ast_iax2_firmware_header::datalen, iax_firmware::fd, and iax_firmware::fwh.
Referenced by reload_firmware().
02993 { 02994 /* Close firmware */ 02995 if (cur->fwh) { 02996 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 02997 } 02998 close(cur->fd); 02999 ast_free(cur); 03000 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 9177 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_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, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
09178 { 09179 unsigned short dpstatus = 0; 09180 struct iax_ie_data ied1; 09181 int mm; 09182 09183 memset(&ied1, 0, sizeof(ied1)); 09184 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 09185 /* Must be started */ 09186 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 09187 dpstatus = IAX_DPSTATUS_EXISTS; 09188 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 09189 dpstatus = IAX_DPSTATUS_CANEXIST; 09190 } else { 09191 dpstatus = IAX_DPSTATUS_NONEXISTENT; 09192 } 09193 if (ast_ignore_pattern(context, callednum)) 09194 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 09195 if (mm) 09196 dpstatus |= IAX_DPSTATUS_MATCHMORE; 09197 if (!skiplock) 09198 ast_mutex_lock(&iaxsl[callno]); 09199 if (iaxs[callno]) { 09200 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 09201 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 09202 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 09203 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 09204 } 09205 if (!skiplock) 09206 ast_mutex_unlock(&iaxsl[callno]); 09207 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 9209 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().
09210 { 09211 /* Look up for dpreq */ 09212 struct dpreq_data *dpr = data; 09213 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 09214 if (dpr->callerid) 09215 ast_free(dpr->callerid); 09216 ast_free(dpr); 09217 return NULL; 09218 }
static void encmethods_to_str | ( | int | e, | |
struct ast_str * | buf | |||
) | [static] |
Definition at line 1543 of file chan_iax2.c.
References ast_str_append(), ast_str_set(), ast_str_strlen(), iax2_thread::buf, 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().
01544 { 01545 ast_str_set(&buf, 0, "("); 01546 if (e & IAX_ENCRYPT_AES128) { 01547 ast_str_append(&buf, 0, "aes128"); 01548 } 01549 if (e & IAX_ENCRYPT_KEYROTATE) { 01550 ast_str_append(&buf, 0, ",keyrotate"); 01551 } 01552 if (ast_str_strlen(buf) > 1) { 01553 ast_str_append(&buf, 0, ")"); 01554 } else { 01555 ast_str_set(&buf, 0, "No"); 01556 } 01557 }
static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 6250 of file chan_iax2.c.
References 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().
06251 { 06252 int padding; 06253 unsigned char *workspace; 06254 workspace = alloca(*datalen + 32); 06255 if (!workspace) 06256 return -1; 06257 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06258 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06259 if (iaxdebug) 06260 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06261 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06262 padding = 16 + (padding & 0xf); 06263 memcpy(workspace, poo, padding); 06264 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06265 workspace[15] &= 0xf0; 06266 workspace[15] |= (padding & 0xf); 06267 if (iaxdebug) 06268 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 06269 *datalen += padding; 06270 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06271 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06272 memcpy(poo, workspace + *datalen - 32, 32); 06273 } else { 06274 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06275 if (iaxdebug) 06276 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06277 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06278 padding = 16 + (padding & 0xf); 06279 memcpy(workspace, poo, padding); 06280 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06281 workspace[15] &= 0xf0; 06282 workspace[15] |= (padding & 0x0f); 06283 *datalen += padding; 06284 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06285 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06286 memcpy(poo, workspace + *datalen - 32, 32); 06287 } 06288 return 0; 06289 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8594 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), reg_source_db(), and update_registry().
08595 { 08596 #ifdef SCHED_MULTITHREADED 08597 if (schedule_action(__expire_registry, data)) 08598 #endif 08599 __expire_registry(data); 08600 return 0; 08601 }
static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
const char * | data, | |||
const char * | context, | |||
const char * | exten, | |||
int | priority | |||
) | [static] |
Definition at line 13516 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_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, state, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
13517 { 13518 struct iax2_dpcache *dp = NULL; 13519 struct timeval now = ast_tvnow(); 13520 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13521 struct ast_channel *c = NULL; 13522 struct ast_frame *f = NULL; 13523 13524 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13525 if (ast_tvcmp(now, dp->expiry) > 0) { 13526 AST_LIST_REMOVE_CURRENT(cache_list); 13527 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13528 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13529 else 13530 ast_free(dp); 13531 continue; 13532 } 13533 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13534 break; 13535 } 13536 AST_LIST_TRAVERSE_SAFE_END; 13537 13538 if (!dp) { 13539 /* No matching entry. Create a new one. */ 13540 /* First, can we make a callno? */ 13541 if ((callno = cache_get_callno_locked(data)) < 0) { 13542 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13543 return NULL; 13544 } 13545 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13546 ast_mutex_unlock(&iaxsl[callno]); 13547 return NULL; 13548 } 13549 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13550 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13551 dp->expiry = ast_tvnow(); 13552 dp->orig = dp->expiry; 13553 /* Expires in 30 mins by default */ 13554 dp->expiry.tv_sec += iaxdefaultdpcache; 13555 dp->flags = CACHE_FLAG_PENDING; 13556 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13557 dp->waiters[x] = -1; 13558 /* Insert into the lists */ 13559 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13560 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13561 /* Send the request if we're already up */ 13562 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13563 iax2_dprequest(dp, callno); 13564 ast_mutex_unlock(&iaxsl[callno]); 13565 } 13566 13567 /* By here we must have a dp */ 13568 if (dp->flags & CACHE_FLAG_PENDING) { 13569 /* Okay, here it starts to get nasty. We need a pipe now to wait 13570 for a reply to come back so long as it's pending */ 13571 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13572 /* Find an empty slot */ 13573 if (dp->waiters[x] < 0) 13574 break; 13575 } 13576 if (x >= ARRAY_LEN(dp->waiters)) { 13577 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13578 return NULL; 13579 } 13580 if (pipe(com)) { 13581 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13582 return NULL; 13583 } 13584 dp->waiters[x] = com[1]; 13585 /* Okay, now we wait */ 13586 timeout = iaxdefaulttimeout * 1000; 13587 /* Temporarily unlock */ 13588 AST_LIST_UNLOCK(&dpcache); 13589 /* Defer any dtmf */ 13590 if (chan) 13591 old = ast_channel_defer_dtmf(chan); 13592 doabort = 0; 13593 while(timeout) { 13594 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 13595 if (outfd > -1) 13596 break; 13597 if (!c) 13598 continue; 13599 if (!(f = ast_read(c))) { 13600 doabort = 1; 13601 break; 13602 } 13603 ast_frfree(f); 13604 } 13605 if (!timeout) { 13606 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13607 } 13608 AST_LIST_LOCK(&dpcache); 13609 dp->waiters[x] = -1; 13610 close(com[1]); 13611 close(com[0]); 13612 if (doabort) { 13613 /* Don't interpret anything, just abort. Not sure what th epoint 13614 of undeferring dtmf on a hung up channel is but hey whatever */ 13615 if (!old && chan) 13616 ast_channel_undefer_dtmf(chan); 13617 return NULL; 13618 } 13619 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13620 /* Now to do non-independent analysis the results of our wait */ 13621 if (dp->flags & CACHE_FLAG_PENDING) { 13622 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13623 pending. Don't let it take as long to timeout. */ 13624 dp->flags &= ~CACHE_FLAG_PENDING; 13625 dp->flags |= CACHE_FLAG_TIMEOUT; 13626 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 13627 systems without leaving it unavailable once the server comes back online */ 13628 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 13629 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13630 if (dp->waiters[x] > -1) { 13631 if (write(dp->waiters[x], "asdf", 4) < 0) { 13632 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13633 } 13634 } 13635 } 13636 } 13637 } 13638 /* Our caller will obtain the rest */ 13639 if (!old && chan) 13640 ast_channel_undefer_dtmf(chan); 13641 } 13642 return dp; 13643 }
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 2917 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02917 { 02918 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02919 }
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 2921 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().
02921 { 02922 02923 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02924 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 1395 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_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_trunk_peer::list, and thread.
Referenced by __schedule_action(), and socket_read().
01396 { 01397 struct iax2_thread *thread = NULL; 01398 01399 /* Pop the head of the idle list off */ 01400 AST_LIST_LOCK(&idle_list); 01401 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01402 AST_LIST_UNLOCK(&idle_list); 01403 01404 /* If we popped a thread off the idle list, just return it */ 01405 if (thread) { 01406 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01407 return thread; 01408 } 01409 01410 /* Pop the head of the dynamic list off */ 01411 AST_LIST_LOCK(&dynamic_list); 01412 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01413 AST_LIST_UNLOCK(&dynamic_list); 01414 01415 /* If we popped a thread off the dynamic list, just return it */ 01416 if (thread) { 01417 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01418 return thread; 01419 } 01420 01421 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01422 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01423 return NULL; 01424 01425 /* Set default values */ 01426 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01427 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01428 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01429 01430 /* Initialize lock and condition */ 01431 ast_mutex_init(&thread->lock); 01432 ast_cond_init(&thread->cond, NULL); 01433 ast_mutex_init(&thread->init_lock); 01434 ast_cond_init(&thread->init_cond, NULL); 01435 ast_mutex_lock(&thread->init_lock); 01436 01437 /* Create thread and send it on it's way */ 01438 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01439 ast_cond_destroy(&thread->cond); 01440 ast_mutex_destroy(&thread->lock); 01441 ast_mutex_unlock(&thread->init_lock); 01442 ast_cond_destroy(&thread->init_cond); 01443 ast_mutex_destroy(&thread->init_lock); 01444 ast_free(thread); 01445 return NULL; 01446 } 01447 01448 /* this thread is not processing a full frame (since it is idle), 01449 so ensure that the field for the full frame call number is empty */ 01450 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01451 01452 /* Wait for the thread to be ready before returning it to the caller */ 01453 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01454 01455 /* Done with init_lock */ 01456 ast_mutex_unlock(&thread->init_lock); 01457 01458 return thread; 01459 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1687 of file chan_iax2.c.
References ao2_find, iax2_peer::name, OBJ_POINTER, peers, and realtime_peer().
01688 { 01689 struct iax2_peer *peer = NULL; 01690 struct iax2_peer tmp_peer = { 01691 .name = name, 01692 }; 01693 01694 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01695 01696 /* Now go for realtime if applicable */ 01697 if(!peer && realtime) 01698 peer = realtime_peer(name, NULL); 01699 01700 return peer; 01701 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 6021 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::list, and iax2_trunk_peer::lock.
Referenced by iax2_trunk_queue(), and socket_process_meta().
06022 { 06023 struct iax2_trunk_peer *tpeer = NULL; 06024 06025 /* Finds and locks trunk peer */ 06026 AST_LIST_LOCK(&tpeers); 06027 06028 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 06029 if (!inaddrcmp(&tpeer->addr, sin)) { 06030 ast_mutex_lock(&tpeer->lock); 06031 break; 06032 } 06033 } 06034 06035 if (!tpeer) { 06036 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 06037 ast_mutex_init(&tpeer->lock); 06038 tpeer->lastsent = 9999; 06039 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 06040 tpeer->trunkact = ast_tvnow(); 06041 ast_mutex_lock(&tpeer->lock); 06042 tpeer->sockfd = fd; 06043 #ifdef SO_NO_CHECK 06044 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 06045 #endif 06046 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06047 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 06048 } 06049 } 06050 06051 AST_LIST_UNLOCK(&tpeers); 06052 06053 return tpeer; 06054 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1715 of file chan_iax2.c.
References ao2_find, iax2_user::name, OBJ_POINTER, and users.
01716 { 01717 struct iax2_user tmp_user = { 01718 .name = name, 01719 }; 01720 01721 return ao2_find(users, &tmp_user, OBJ_POINTER); 01722 }
static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 5833 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05834 { 05835 long ms; /* NOT unsigned */ 05836 if (ast_tvzero(iaxs[callno]->rxcore)) { 05837 /* Initialize rxcore time if appropriate */ 05838 iaxs[callno]->rxcore = ast_tvnow(); 05839 /* Round to nearest 20ms so traces look pretty */ 05840 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05841 } 05842 /* Calculate difference between trunk and channel */ 05843 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05844 /* Return as the sum of trunk time and the difference between trunk and real time */ 05845 return ms + ts; 05846 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 11978 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
11979 { 11980 struct iax2_context *conl; 11981 while(con) { 11982 conl = con; 11983 con = con->next; 11984 ast_free(conl); 11985 } 11986 }
static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1821 of file chan_iax2.c.
References ast_free, ast_frame::data, 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 13766 of file chan_iax2.c.
References iax2_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::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), iax2_tech, IAX_DYNAMIC, iaxs, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
13767 { 13768 struct iax2_peer *peer; 13769 char *peername, *colname; 13770 13771 peername = ast_strdupa(data); 13772 13773 /* if our channel, return the IP address of the endpoint of current channel */ 13774 if (!strcmp(peername,"CURRENTCHANNEL")) { 13775 unsigned short callno; 13776 if (chan->tech != &iax2_tech) 13777 return -1; 13778 callno = PTR_TO_CALLNO(chan->tech_pvt); 13779 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 13780 return 0; 13781 } 13782 13783 if ((colname = strchr(peername, ','))) 13784 *colname++ = '\0'; 13785 else 13786 colname = "ip"; 13787 13788 if (!(peer = find_peer(peername, 1))) 13789 return -1; 13790 13791 if (!strcasecmp(colname, "ip")) { 13792 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 13793 } else if (!strcasecmp(colname, "status")) { 13794 peer_status(peer, buf, len); 13795 } else if (!strcasecmp(colname, "mailbox")) { 13796 ast_copy_string(buf, peer->mailbox, len); 13797 } else if (!strcasecmp(colname, "context")) { 13798 ast_copy_string(buf, peer->context, len); 13799 } else if (!strcasecmp(colname, "expire")) { 13800 snprintf(buf, len, "%d", peer->expire); 13801 } else if (!strcasecmp(colname, "dynamic")) { 13802 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 13803 } else if (!strcasecmp(colname, "callerid_name")) { 13804 ast_copy_string(buf, peer->cid_name, len); 13805 } else if (!strcasecmp(colname, "callerid_num")) { 13806 ast_copy_string(buf, peer->cid_num, len); 13807 } else if (!strcasecmp(colname, "codecs")) { 13808 ast_getformatname_multiple(buf, len -1, peer->capability); 13809 } else if (!strncasecmp(colname, "codec[", 6)) { 13810 char *codecnum, *ptr; 13811 int codec = 0; 13812 13813 codecnum = strchr(colname, '['); 13814 *codecnum = '\0'; 13815 codecnum++; 13816 if ((ptr = strchr(codecnum, ']'))) { 13817 *ptr = '\0'; 13818 } 13819 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 13820 ast_copy_string(buf, ast_getformatname(codec), len); 13821 } else { 13822 buf[0] = '\0'; 13823 } 13824 } else { 13825 buf[0] = '\0'; 13826 } 13827 13828 peer_unref(peer); 13829 13830 return 0; 13831 }
static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 12128 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
12129 { 12130 int methods = 0; 12131 if (strstr(value, "rsa")) 12132 methods |= IAX_AUTH_RSA; 12133 if (strstr(value, "md5")) 12134 methods |= IAX_AUTH_MD5; 12135 if (strstr(value, "plaintext")) 12136 methods |= IAX_AUTH_PLAINTEXT; 12137 return methods; 12138 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1559 of file chan_iax2.c.
References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by build_peer(), build_user(), and set_config().
01560 { 01561 int e; 01562 if (!strcasecmp(s, "aes128")) 01563 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01564 else if (ast_true(s)) 01565 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01566 else 01567 e = 0; 01568 return e; 01569 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4118 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
04119 { 04120 #ifdef SCHED_MULTITHREADED 04121 if (schedule_action(__get_from_jb, data)) 04122 #endif 04123 __get_from_jb(data); 04124 return 0; 04125 }
static struct callno_entry * get_unused_callno | ( | int | trunk, | |
int | validated | |||
) | [static] |
Definition at line 2595 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().
02596 { 02597 struct callno_entry *callno_entry = NULL; 02598 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02599 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02600 /* Minor optimization for the extreme case. */ 02601 return NULL; 02602 } 02603 02604 /* the callno_pool container is locked here primarily to ensure thread 02605 * safety of the total_nonval_callno_used check and increment */ 02606 ao2_lock(callno_pool); 02607 02608 /* only a certain number of nonvalidated call numbers should be allocated. 02609 * If there ever is an attack, this separates the calltoken validating 02610 * users from the non calltoken validating users. */ 02611 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02612 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02613 ao2_unlock(callno_pool); 02614 return NULL; 02615 } 02616 02617 /* unlink the object from the container, taking over ownership 02618 * of the reference the container had to the object */ 02619 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02620 02621 if (callno_entry) { 02622 callno_entry->validated = validated; 02623 if (!validated) { 02624 total_nonval_callno_used++; 02625 } 02626 } 02627 02628 ao2_unlock(callno_pool); 02629 return callno_entry; 02630 }
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 4841 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().
04843 { 04844 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04845 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04846 struct ast_str *buf = ast_str_alloca(256); 04847 time_t t = time(NULL); 04848 char hash[41]; /* 40 char sha1 hash */ 04849 int subclass = uncompress_subclass(fh->csub); 04850 04851 /* ----- Case 1 ----- */ 04852 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04853 struct iax_ie_data ied = { 04854 .buf = { 0 }, 04855 .pos = 0, 04856 }; 04857 04858 /* create the hash with their address data and our timestamp */ 04859 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04860 ast_sha1_hash(hash, ast_str_buffer(buf)); 04861 04862 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04863 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04864 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04865 04866 return 1; 04867 04868 /* ----- Case 2 ----- */ 04869 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04870 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04871 char *rec_ts = NULL; /* received timestamp */ 04872 unsigned int rec_time; /* received time_t */ 04873 04874 /* split the timestamp from the hash data */ 04875 rec_hash = strchr((char *) ies->calltokendata, '?'); 04876 if (rec_hash) { 04877 *rec_hash++ = '\0'; 04878 rec_ts = (char *) ies->calltokendata; 04879 } 04880 04881 /* check that we have valid data before we do any comparisons */ 04882 if (!rec_hash || !rec_ts) { 04883 goto reject; 04884 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04885 goto reject; 04886 } 04887 04888 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04889 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04890 ast_sha1_hash(hash, ast_str_buffer(buf)); 04891 04892 /* compare hashes and then check timestamp delay */ 04893 if (strcmp(hash, rec_hash)) { 04894 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04895 goto reject; /* received hash does not match ours, reject */ 04896 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04897 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04898 goto reject; /* too much delay, reject */ 04899 } 04900 04901 /* at this point the call token is valid, returning 0 04902 * will allow socket_process to continue as usual */ 04903 requirecalltoken_mark_auto(ies->username, subclass); 04904 return 0; 04905 04906 /* ----- Case 3 ----- */ 04907 } else { /* calltokens are not supported for this client, how do we respond? */ 04908 if (calltoken_required(sin, ies->username, subclass)) { 04909 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")); 04910 goto reject; 04911 } 04912 return 0; /* calltoken is not required for this addr, so permit it. */ 04913 } 04914 04915 reject: 04916 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04917 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04918 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04919 } else { 04920 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04921 } 04922 04923 return 1; 04924 }
static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 11825 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.
11826 { 11827 int force = 0; 11828 int res; 11829 11830 switch (cmd) { 11831 case CLI_INIT: 11832 e->command = "iax2 provision"; 11833 e->usage = 11834 "Usage: iax2 provision <host> <template> [forced]\n" 11835 " Provisions the given peer or IP address using a template\n" 11836 " matching either 'template' or '*' if the template is not\n" 11837 " found. If 'forced' is specified, even empty provisioning\n" 11838 " fields will be provisioned as empty fields.\n"; 11839 return NULL; 11840 case CLI_GENERATE: 11841 if (a->pos == 3) 11842 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 11843 return NULL; 11844 } 11845 11846 if (a->argc < 4) 11847 return CLI_SHOWUSAGE; 11848 if (a->argc > 4) { 11849 if (!strcasecmp(a->argv[4], "forced")) 11850 force = 1; 11851 else 11852 return CLI_SHOWUSAGE; 11853 } 11854 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 11855 if (res < 0) 11856 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 11857 else if (res < 1) 11858 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 11859 else 11860 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 11861 return CLI_SUCCESS; 11862 }
static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3550 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, user_unref(), users, and ast_cli_args::word.
03551 { 03552 struct iax2_peer *peer = NULL; 03553 struct iax2_user *user = NULL; 03554 static const char * const choices[] = { "all", NULL }; 03555 char *cmplt; 03556 03557 switch (cmd) { 03558 case CLI_INIT: 03559 e->command = "iax2 prune realtime"; 03560 e->usage = 03561 "Usage: iax2 prune realtime [<peername>|all]\n" 03562 " Prunes object(s) from the cache\n"; 03563 return NULL; 03564 case CLI_GENERATE: 03565 if (a->pos == 3) { 03566 cmplt = ast_cli_complete(a->word, choices, a->n); 03567 if (!cmplt) 03568 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03569 return cmplt; 03570 } 03571 return NULL; 03572 } 03573 if (a->argc != 4) 03574 return CLI_SHOWUSAGE; 03575 if (!strcmp(a->argv[3], "all")) { 03576 prune_users(); 03577 prune_peers(); 03578 ast_cli(a->fd, "Cache flushed successfully.\n"); 03579 return CLI_SUCCESS; 03580 } 03581 peer = find_peer(a->argv[3], 0); 03582 user = find_user(a->argv[3]); 03583 if (peer || user) { 03584 if (peer) { 03585 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 03586 ast_set_flag64(peer, IAX_RTAUTOCLEAR); 03587 expire_registry(peer_ref(peer)); 03588 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03589 } else { 03590 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03591 } 03592 peer_unref(peer); 03593 } 03594 if (user) { 03595 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 03596 ast_set_flag64(user, IAX_RTAUTOCLEAR); 03597 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03598 } else { 03599 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03600 } 03601 ao2_unlink(users,user); 03602 user_unref(user); 03603 } 03604 } else { 03605 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03606 } 03607 03608 return CLI_SUCCESS; 03609 }
static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 13420 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
13421 { 13422 switch (cmd) { 13423 case CLI_INIT: 13424 e->command = "iax2 reload"; 13425 e->usage = 13426 "Usage: iax2 reload\n" 13427 " Reloads IAX configuration from iax.conf\n"; 13428 return NULL; 13429 case CLI_GENERATE: 13430 return NULL; 13431 } 13432 13433 reload_config(); 13434 13435 return CLI_SUCCESS; 13436 }
static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7296 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.
07297 { 07298 switch (cmd) { 07299 case CLI_INIT: 07300 e->command = "iax2 set debug {on|off|peer}"; 07301 e->usage = 07302 "Usage: iax2 set debug {on|off|peer peername}\n" 07303 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07304 return NULL; 07305 case CLI_GENERATE: 07306 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07307 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07308 return NULL; 07309 } 07310 07311 if (a->argc < e->args || a->argc > e->args + 1) 07312 return CLI_SHOWUSAGE; 07313 07314 if (!strcasecmp(a->argv[3], "peer")) { 07315 struct iax2_peer *peer; 07316 struct sockaddr_in peer_addr; 07317 07318 07319 if (a->argc != e->args + 1) 07320 return CLI_SHOWUSAGE; 07321 07322 peer = find_peer(a->argv[4], 1); 07323 07324 if (!peer) { 07325 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07326 return CLI_FAILURE; 07327 } 07328 07329 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 07330 07331 debugaddr.sin_addr = peer_addr.sin_addr; 07332 debugaddr.sin_port = peer_addr.sin_port; 07333 07334 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07335 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07336 07337 ao2_ref(peer, -1); 07338 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07339 iaxdebug = 1; 07340 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07341 } else { 07342 iaxdebug = 0; 07343 memset(&debugaddr, 0, sizeof(debugaddr)); 07344 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07345 } 07346 return CLI_SUCCESS; 07347 }
static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7375 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.
07376 { 07377 switch (cmd) { 07378 case CLI_INIT: 07379 e->command = "iax2 set debug jb {on|off}"; 07380 e->usage = 07381 "Usage: iax2 set debug jb {on|off}\n" 07382 " Enables/Disables jitterbuffer debugging information\n"; 07383 return NULL; 07384 case CLI_GENERATE: 07385 return NULL; 07386 } 07387 07388 if (a->argc != e->args) 07389 return CLI_SHOWUSAGE; 07390 07391 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07392 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07393 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07394 } else { 07395 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07396 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07397 } 07398 return CLI_SUCCESS; 07399 }
static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7349 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.
07350 { 07351 switch (cmd) { 07352 case CLI_INIT: 07353 e->command = "iax2 set debug trunk {on|off}"; 07354 e->usage = 07355 "Usage: iax2 set debug trunk {on|off}\n" 07356 " Enables/Disables debugging of IAX trunking\n"; 07357 return NULL; 07358 case CLI_GENERATE: 07359 return NULL; 07360 } 07361 07362 if (a->argc != e->args) 07363 return CLI_SHOWUSAGE; 07364 07365 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07366 iaxtrunkdebug = 1; 07367 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07368 } else { 07369 iaxtrunkdebug = 0; 07370 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07371 } 07372 return CLI_SUCCESS; 07373 }
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 3877 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.
03878 { 03879 int mtuv; 03880 03881 switch (cmd) { 03882 case CLI_INIT: 03883 e->command = "iax2 set mtu"; 03884 e->usage = 03885 "Usage: iax2 set mtu <value>\n" 03886 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03887 " zero to disable. Disabling means that the operating system\n" 03888 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03889 " packet exceeds the UDP payload size. This is substantially\n" 03890 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03891 " greater for G.711 samples.\n"; 03892 return NULL; 03893 case CLI_GENERATE: 03894 return NULL; 03895 } 03896 03897 if (a->argc != 4) 03898 return CLI_SHOWUSAGE; 03899 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03900 mtuv = MAX_TRUNK_MTU; 03901 else 03902 mtuv = atoi(a->argv[3]); 03903 03904 if (mtuv == 0) { 03905 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03906 global_max_trunk_mtu = 0; 03907 return CLI_SUCCESS; 03908 } 03909 if (mtuv < 172 || mtuv > 4000) { 03910 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03911 return CLI_SHOWUSAGE; 03912 } 03913 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03914 global_max_trunk_mtu = mtuv; 03915 return CLI_SUCCESS; 03916 }
static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3918 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.
03919 { 03920 struct iax2_dpcache *dp = NULL; 03921 char tmp[1024], *pc = NULL; 03922 int s, x, y; 03923 struct timeval now = ast_tvnow(); 03924 03925 switch (cmd) { 03926 case CLI_INIT: 03927 e->command = "iax2 show cache"; 03928 e->usage = 03929 "Usage: iax2 show cache\n" 03930 " Display currently cached IAX Dialplan results.\n"; 03931 return NULL; 03932 case CLI_GENERATE: 03933 return NULL; 03934 } 03935 03936 AST_LIST_LOCK(&dpcache); 03937 03938 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03939 03940 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 03941 s = dp->expiry.tv_sec - now.tv_sec; 03942 tmp[0] = '\0'; 03943 if (dp->flags & CACHE_FLAG_EXISTS) 03944 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03945 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03946 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03947 if (dp->flags & CACHE_FLAG_CANEXIST) 03948 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03949 if (dp->flags & CACHE_FLAG_PENDING) 03950 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03951 if (dp->flags & CACHE_FLAG_TIMEOUT) 03952 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03953 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03954 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03955 if (dp->flags & CACHE_FLAG_MATCHMORE) 03956 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03957 if (dp->flags & CACHE_FLAG_UNKNOWN) 03958 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03959 /* Trim trailing pipe */ 03960 if (!ast_strlen_zero(tmp)) { 03961 tmp[strlen(tmp) - 1] = '\0'; 03962 } else { 03963 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03964 } 03965 y = 0; 03966 pc = strchr(dp->peercontext, '@'); 03967 if (!pc) { 03968 pc = dp->peercontext; 03969 } else { 03970 pc++; 03971 } 03972 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 03973 if (dp->waiters[x] > -1) 03974 y++; 03975 } 03976 if (s > 0) { 03977 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03978 } else { 03979 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 03980 } 03981 } 03982 03983 AST_LIST_UNLOCK(&dpcache); 03984 03985 return CLI_SUCCESS; 03986 }
static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 2537 of file chan_iax2.c.
References peercnt::addr, 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, peercnt::cur, ast_cli_args::fd, peercnt::limit, peercnts, and ast_cli_entry::usage.
02538 { 02539 struct ao2_iterator i; 02540 struct peercnt *peercnt; 02541 struct sockaddr_in sin; 02542 int found = 0; 02543 02544 switch (cmd) { 02545 case CLI_INIT: 02546 e->command = "iax2 show callnumber usage"; 02547 e->usage = 02548 "Usage: iax2 show callnumber usage [IP address]\n" 02549 " Shows current IP addresses which are consuming iax2 call numbers\n"; 02550 return NULL; 02551 case CLI_GENERATE: 02552 return NULL; 02553 case CLI_HANDLER: 02554 if (a->argc < 4 || a->argc > 5) 02555 return CLI_SHOWUSAGE; 02556 02557 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02558 i = ao2_iterator_init(peercnts, 0); 02559 while ((peercnt = ao2_iterator_next(&i))) { 02560 sin.sin_addr.s_addr = peercnt->addr; 02561 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) { 02562 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02563 found = 1; 02564 break; 02565 } else { 02566 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02567 } 02568 ao2_ref(peercnt, -1); 02569 } 02570 ao2_iterator_destroy(&i); 02571 02572 if (a->argc == 4) { 02573 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n" 02574 "Non-CallToken Validated Callno Used: %d\n", 02575 global_maxcallno_nonval, 02576 total_nonval_callno_used); 02577 02578 ast_cli(a->fd, "Total Available Callno: %d\n" 02579 "Regular Callno Available: %d\n" 02580 "Trunk Callno Available: %d\n", 02581 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk), 02582 ao2_container_count(callno_pool), 02583 ao2_container_count(callno_pool_trunk)); 02584 } else if (a->argc == 5 && !found) { 02585 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] ); 02586 } 02587 02588 02589 return CLI_SUCCESS; 02590 default: 02591 return NULL; 02592 } 02593 }
static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7123 of file chan_iax2.c.
References 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, iax_rr::delay, 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, ast_channel::name, chan_iax2_pvt::owner, chan_iax2_pvt::remote_rr, S_OR, and ast_cli_entry::usage.
07124 { 07125 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 07126 #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" 07127 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 07128 int x; 07129 int numchans = 0; 07130 char first_message[10] = { 0, }; 07131 char last_message[10] = { 0, }; 07132 07133 switch (cmd) { 07134 case CLI_INIT: 07135 e->command = "iax2 show channels"; 07136 e->usage = 07137 "Usage: iax2 show channels\n" 07138 " Lists all currently active IAX channels.\n"; 07139 return NULL; 07140 case CLI_GENERATE: 07141 return NULL; 07142 } 07143 07144 if (a->argc != 3) 07145 return CLI_SHOWUSAGE; 07146 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 07147 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07148 ast_mutex_lock(&iaxsl[x]); 07149 if (iaxs[x]) { 07150 int lag, jitter, localdelay; 07151 jb_info jbinfo; 07152 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07153 jb_getinfo(iaxs[x]->jb, &jbinfo); 07154 jitter = jbinfo.jitter; 07155 localdelay = jbinfo.current - jbinfo.min; 07156 } else { 07157 jitter = -1; 07158 localdelay = 0; 07159 } 07160 07161 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07162 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07163 lag = iaxs[x]->remote_rr.delay; 07164 ast_cli(a->fd, FORMAT, 07165 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07166 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 07167 S_OR(iaxs[x]->username, "(None)"), 07168 iaxs[x]->callno, iaxs[x]->peercallno, 07169 iaxs[x]->oseqno, iaxs[x]->iseqno, 07170 lag, 07171 jitter, 07172 localdelay, 07173 ast_getformatname(iaxs[x]->voiceformat), 07174 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07175 first_message, 07176 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07177 last_message); 07178 numchans++; 07179 } 07180 ast_mutex_unlock(&iaxsl[x]); 07181 } 07182 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07183 return CLI_SUCCESS; 07184 #undef FORMAT 07185 #undef FORMAT2 07186 #undef FORMATB 07187 }
static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6909 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_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, ast_cli_args::fd, iax_firmware::fwh, iax_firmware::list, ast_cli_entry::usage, and ast_iax2_firmware_header::version.
06910 { 06911 struct iax_firmware *cur = NULL; 06912 06913 switch (cmd) { 06914 case CLI_INIT: 06915 e->command = "iax2 show firmware"; 06916 e->usage = 06917 "Usage: iax2 show firmware\n" 06918 " Lists all known IAX firmware images.\n"; 06919 return NULL; 06920 case CLI_GENERATE: 06921 return NULL; 06922 } 06923 06924 if (a->argc != 3 && a->argc != 4) 06925 return CLI_SHOWUSAGE; 06926 06927 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 06928 AST_LIST_LOCK(&firmwares); 06929 AST_LIST_TRAVERSE(&firmwares, cur, list) { 06930 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 06931 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 06932 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 06933 } 06934 } 06935 AST_LIST_UNLOCK(&firmwares); 06936 06937 return CLI_SUCCESS; 06938 }
static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7273 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.
07274 { 07275 int numchans = 0; 07276 07277 switch (cmd) { 07278 case CLI_INIT: 07279 e->command = "iax2 show netstats"; 07280 e->usage = 07281 "Usage: iax2 show netstats\n" 07282 " Lists network status for all currently active IAX channels.\n"; 07283 return NULL; 07284 case CLI_GENERATE: 07285 return NULL; 07286 } 07287 if (a->argc != 3) 07288 return CLI_SHOWUSAGE; 07289 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 07290 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 07291 numchans = ast_cli_netstats(NULL, a->fd, 1); 07292 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07293 return CLI_SUCCESS; 07294 }
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 3725 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, iax2_peer::cid_name, iax2_peer::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), iax2_peer::context, 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::mailbox, iax2_peer::maxcallno, ast_cli_args::n, iax2_peer::name, iax2_peer::parkinglot, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::secret, iax2_peer::smoothing, status, ast_cli_entry::usage, iax2_peer::username, and ast_cli_args::word.
03726 { 03727 char status[30]; 03728 char cbuf[256]; 03729 struct iax2_peer *peer; 03730 char codec_buf[512]; 03731 struct ast_str *encmethods = ast_str_alloca(256); 03732 int x = 0, codec = 0, load_realtime = 0; 03733 03734 switch (cmd) { 03735 case CLI_INIT: 03736 e->command = "iax2 show peer"; 03737 e->usage = 03738 "Usage: iax2 show peer <name>\n" 03739 " Display details on specific IAX peer\n"; 03740 return NULL; 03741 case CLI_GENERATE: 03742 if (a->pos == 3) 03743 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03744 return NULL; 03745 } 03746 03747 if (a->argc < 4) 03748 return CLI_SHOWUSAGE; 03749 03750 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03751 03752 peer = find_peer(a->argv[3], load_realtime); 03753 if (peer) { 03754 struct sockaddr_in peer_addr; 03755 03756 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 03757 03758 encmethods_to_str(peer->encmethods, encmethods); 03759 ast_cli(a->fd, "\n\n"); 03760 ast_cli(a->fd, " * Name : %s\n", peer->name); 03761 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03762 ast_cli(a->fd, " Context : %s\n", peer->context); 03763 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03764 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03765 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03766 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03767 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03768 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 03769 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03770 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03771 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03772 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03773 ast_cli(a->fd, " Addr->IP : %s Port %d\n", peer_addr.sin_addr.s_addr ? ast_inet_ntoa(peer_addr.sin_addr) : "(Unspecified)", ntohs(peer_addr.sin_port)); 03774 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03775 ast_cli(a->fd, " Username : %s\n", peer->username); 03776 ast_cli(a->fd, " Codecs : "); 03777 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03778 ast_cli(a->fd, "%s\n", codec_buf); 03779 03780 ast_cli(a->fd, " Codec Order : ("); 03781 for(x = 0; x < 32 ; x++) { 03782 codec = ast_codec_pref_index(&peer->prefs,x); 03783 if(!codec) 03784 break; 03785 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03786 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03787 ast_cli(a->fd, "|"); 03788 } 03789 03790 if (!x) 03791 ast_cli(a->fd, "none"); 03792 ast_cli(a->fd, ")\n"); 03793 03794 ast_cli(a->fd, " Status : "); 03795 peer_status(peer, status, sizeof(status)); 03796 ast_cli(a->fd, "%s\n",status); 03797 ast_cli(a->fd, " Qualify : every %dms when OK, every %dms when UNREACHABLE (sample smoothing %s)\n", peer->pokefreqok, peer->pokefreqnotok, peer->smoothing ? "On" : "Off"); 03798 ast_cli(a->fd, "\n"); 03799 peer_unref(peer); 03800 } else { 03801 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03802 ast_cli(a->fd, "\n"); 03803 } 03804 03805 return CLI_SUCCESS; 03806 }
static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6877 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.
06878 { 06879 switch (cmd) { 06880 case CLI_INIT: 06881 e->command = "iax2 show peers"; 06882 e->usage = 06883 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06884 " Lists all known IAX2 peers.\n" 06885 " Optional 'registered' argument lists only peers with known addresses.\n" 06886 " Optional regular expression pattern is used to filter the peer list.\n"; 06887 return NULL; 06888 case CLI_GENERATE: 06889 return NULL; 06890 } 06891 06892 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) { 06893 case RESULT_SHOWUSAGE: 06894 return CLI_SHOWUSAGE; 06895 case RESULT_FAILURE: 06896 return CLI_FAILURE; 06897 default: 06898 return CLI_SUCCESS; 06899 } 06900 }
static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7032 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, iax2_registry::entry, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.
07033 { 07034 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 07035 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 07036 struct iax2_registry *reg = NULL; 07037 char host[80]; 07038 char perceived[80]; 07039 int counter = 0; 07040 07041 switch (cmd) { 07042 case CLI_INIT: 07043 e->command = "iax2 show registry"; 07044 e->usage = 07045 "Usage: iax2 show registry\n" 07046 " Lists all registration requests and status.\n"; 07047 return NULL; 07048 case CLI_GENERATE: 07049 return NULL; 07050 } 07051 if (a->argc != 3) 07052 return CLI_SHOWUSAGE; 07053 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 07054 AST_LIST_LOCK(®istrations); 07055 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07056 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07057 if (reg->us.sin_addr.s_addr) 07058 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07059 else 07060 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07061 ast_cli(a->fd, FORMAT, host, 07062 (reg->dnsmgr) ? "Y" : "N", 07063 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 07064 counter++; 07065 } 07066 AST_LIST_UNLOCK(®istrations); 07067 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 07068 return CLI_SUCCESS; 07069 #undef FORMAT 07070 #undef FORMAT2 07071 }
static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3831 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, frame_queue, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iaxsl, iax2_trunk_peer::list, iax_frame::retries, and ast_cli_entry::usage.
03832 { 03833 struct iax_frame *cur; 03834 int cnt = 0, dead = 0, final = 0, i = 0; 03835 03836 switch (cmd) { 03837 case CLI_INIT: 03838 e->command = "iax2 show stats"; 03839 e->usage = 03840 "Usage: iax2 show stats\n" 03841 " Display statistics on IAX channel driver.\n"; 03842 return NULL; 03843 case CLI_GENERATE: 03844 return NULL; 03845 } 03846 03847 if (a->argc != 3) 03848 return CLI_SHOWUSAGE; 03849 03850 for (i = 0; i < ARRAY_LEN(frame_queue); i++) { 03851 ast_mutex_lock(&iaxsl[i]); 03852 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) { 03853 if (cur->retries < 0) 03854 dead++; 03855 if (cur->final) 03856 final++; 03857 cnt++; 03858 } 03859 ast_mutex_unlock(&iaxsl[i]); 03860 } 03861 03862 ast_cli(a->fd, " IAX Statistics\n"); 03863 ast_cli(a->fd, "---------------------\n"); 03864 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03865 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03866 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03867 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03868 03869 trunk_timed = trunk_untimed = 0; 03870 if (trunk_maxmtu > trunk_nmaxmtu) 03871 trunk_nmaxmtu = trunk_maxmtu; 03872 03873 return CLI_SUCCESS; 03874 }
static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6740 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, iax2_thread::list, thread, and ast_cli_entry::usage.
06741 { 06742 struct iax2_thread *thread = NULL; 06743 time_t t; 06744 int threadcount = 0, dynamiccount = 0; 06745 char type; 06746 06747 switch (cmd) { 06748 case CLI_INIT: 06749 e->command = "iax2 show threads"; 06750 e->usage = 06751 "Usage: iax2 show threads\n" 06752 " Lists status of IAX helper threads\n"; 06753 return NULL; 06754 case CLI_GENERATE: 06755 return NULL; 06756 } 06757 if (a->argc != 3) 06758 return CLI_SHOWUSAGE; 06759 06760 ast_cli(a->fd, "IAX2 Thread Information\n"); 06761 time(&t); 06762 ast_cli(a->fd, "Idle Threads:\n"); 06763 AST_LIST_LOCK(&idle_list); 06764 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06765 #ifdef DEBUG_SCHED_MULTITHREAD 06766 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06767 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06768 #else 06769 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06770 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06771 #endif 06772 threadcount++; 06773 } 06774 AST_LIST_UNLOCK(&idle_list); 06775 ast_cli(a->fd, "Active Threads:\n"); 06776 AST_LIST_LOCK(&active_list); 06777 AST_LIST_TRAVERSE(&active_list, thread, list) { 06778 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06779 type = 'D'; 06780 else 06781 type = 'P'; 06782 #ifdef DEBUG_SCHED_MULTITHREAD 06783 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06784 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06785 #else 06786 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06787 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06788 #endif 06789 threadcount++; 06790 } 06791 AST_LIST_UNLOCK(&active_list); 06792 ast_cli(a->fd, "Dynamic Threads:\n"); 06793 AST_LIST_LOCK(&dynamic_list); 06794 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06795 #ifdef DEBUG_SCHED_MULTITHREAD 06796 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06797 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06798 #else 06799 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06800 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06801 #endif 06802 dynamiccount++; 06803 } 06804 AST_LIST_UNLOCK(&dynamic_list); 06805 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06806 return CLI_SUCCESS; 06807 }
static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6529 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, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, ast_cli_entry::usage, user, user_unref(), and users.
06530 { 06531 regex_t regexbuf; 06532 int havepattern = 0; 06533 06534 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06535 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06536 06537 struct iax2_user *user = NULL; 06538 char auth[90]; 06539 char *pstr = ""; 06540 struct ao2_iterator i; 06541 06542 switch (cmd) { 06543 case CLI_INIT: 06544 e->command = "iax2 show users [like]"; 06545 e->usage = 06546 "Usage: iax2 show users [like <pattern>]\n" 06547 " Lists all known IAX2 users.\n" 06548 " Optional regular expression pattern is used to filter the user list.\n"; 06549 return NULL; 06550 case CLI_GENERATE: 06551 return NULL; 06552 } 06553 06554 switch (a->argc) { 06555 case 5: 06556 if (!strcasecmp(a->argv[3], "like")) { 06557 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06558 return CLI_SHOWUSAGE; 06559 havepattern = 1; 06560 } else 06561 return CLI_SHOWUSAGE; 06562 case 3: 06563 break; 06564 default: 06565 return CLI_SHOWUSAGE; 06566 } 06567 06568 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06569 i = ao2_iterator_init(users, 0); 06570 for (user = ao2_iterator_next(&i); user; 06571 user_unref(user), user = ao2_iterator_next(&i)) { 06572 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06573 continue; 06574 06575 if (!ast_strlen_zero(user->secret)) { 06576 ast_copy_string(auth,user->secret, sizeof(auth)); 06577 } else if (!ast_strlen_zero(user->inkeys)) { 06578 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06579 } else 06580 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06581 06582 if(ast_test_flag64(user, IAX_CODEC_NOCAP)) 06583 pstr = "REQ Only"; 06584 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS)) 06585 pstr = "Disabled"; 06586 else 06587 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06588 06589 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06590 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06591 user->ha ? "Yes" : "No", pstr); 06592 } 06593 ao2_iterator_destroy(&i); 06594 06595 if (havepattern) 06596 regfree(®exbuf); 06597 06598 return CLI_SUCCESS; 06599 #undef FORMAT 06600 #undef FORMAT2 06601 }
static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3611 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.
03612 { 03613 switch (cmd) { 03614 case CLI_INIT: 03615 e->command = "iax2 test losspct"; 03616 e->usage = 03617 "Usage: iax2 test losspct <percentage>\n" 03618 " For testing, throws away <percentage> percent of incoming packets\n"; 03619 return NULL; 03620 case CLI_GENERATE: 03621 return NULL; 03622 } 03623 if (a->argc != 4) 03624 return CLI_SHOWUSAGE; 03625 03626 test_losspct = atoi(a->argv[3]); 03627 03628 return CLI_SUCCESS; 03629 }
static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6809 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, iax2_peer::name, OBJ_POINTER, peer_ref(), peer_unref(), peers, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
06810 { 06811 struct iax2_peer *p; 06812 06813 switch (cmd) { 06814 case CLI_INIT: 06815 e->command = "iax2 unregister"; 06816 e->usage = 06817 "Usage: iax2 unregister <peername>\n" 06818 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06819 return NULL; 06820 case CLI_GENERATE: 06821 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06822 } 06823 06824 if (a->argc != 3) 06825 return CLI_SHOWUSAGE; 06826 06827 p = find_peer(a->argv[2], 1); 06828 if (p) { 06829 if (p->expire > 0) { 06830 struct iax2_peer tmp_peer = { 06831 .name = a->argv[2], 06832 }; 06833 struct iax2_peer *peer; 06834 06835 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06836 if (peer) { 06837 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06838 peer_unref(peer); /* ref from ao2_find() */ 06839 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06840 } else { 06841 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06842 } 06843 } else { 06844 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06845 } 06846 } else { 06847 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06848 } 06849 return CLI_SUCCESS; 06850 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9445 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock, ast_mutex_unlock, iax2_pkt_buf::buf, iax2_pkt_buf::entry, iax2_pkt_buf::len, socket_process(), and thread.
09446 { 09447 struct iax2_pkt_buf *pkt_buf; 09448 09449 ast_mutex_lock(&thread->lock); 09450 09451 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09452 ast_mutex_unlock(&thread->lock); 09453 09454 thread->buf = pkt_buf->buf; 09455 thread->buf_len = pkt_buf->len; 09456 thread->buf_size = pkt_buf->len + 1; 09457 09458 socket_process(thread); 09459 09460 thread->buf = NULL; 09461 ast_free(pkt_buf); 09462 09463 ast_mutex_lock(&thread->lock); 09464 } 09465 09466 ast_mutex_unlock(&thread->lock); 09467 }
static int handle_error | ( | void | ) | [static] |
Definition at line 3266 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().
03267 { 03268 /* XXX Ideally we should figure out why an error occurred and then abort those 03269 rather than continuing to try. Unfortunately, the published interface does 03270 not seem to work XXX */ 03271 #if 0 03272 struct sockaddr_in *sin; 03273 int res; 03274 struct msghdr m; 03275 struct sock_extended_err e; 03276 m.msg_name = NULL; 03277 m.msg_namelen = 0; 03278 m.msg_iov = NULL; 03279 m.msg_control = &e; 03280 m.msg_controllen = sizeof(e); 03281 m.msg_flags = 0; 03282 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03283 if (res < 0) 03284 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03285 else { 03286 if (m.msg_controllen) { 03287 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03288 if (sin) 03289 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03290 else 03291 ast_log(LOG_WARNING, "No address detected??\n"); 03292 } else { 03293 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03294 } 03295 } 03296 #endif 03297 return 0; 03298 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 8398 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, sched, iax2_registry::us, and iax_ies::username.
Referenced by socket_process().
08399 { 08400 struct iax2_registry *reg; 08401 /* Start pessimistic */ 08402 char peer[256] = ""; 08403 char msgstatus[60]; 08404 int refresh = 60; 08405 char ourip[256] = "<Unspecified>"; 08406 struct sockaddr_in oldus; 08407 struct sockaddr_in us; 08408 int oldmsgs; 08409 struct sockaddr_in reg_addr; 08410 08411 memset(&us, 0, sizeof(us)); 08412 if (ies->apparent_addr) 08413 memmove(&us, ies->apparent_addr, sizeof(us)); 08414 if (ies->username) 08415 ast_copy_string(peer, ies->username, sizeof(peer)); 08416 if (ies->refresh) 08417 refresh = ies->refresh; 08418 if (ies->calling_number) { 08419 /* We don't do anything with it really, but maybe we should */ 08420 } 08421 reg = iaxs[callno]->reg; 08422 if (!reg) { 08423 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08424 return -1; 08425 } 08426 memcpy(&oldus, ®->us, sizeof(oldus)); 08427 oldmsgs = reg->messages; 08428 ast_sockaddr_to_sin(®->addr, ®_addr); 08429 if (inaddrcmp(®_addr, sin)) { 08430 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08431 return -1; 08432 } 08433 memcpy(®->us, &us, sizeof(reg->us)); 08434 if (ies->msgcount >= 0) 08435 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08436 /* always refresh the registration at the interval requested by the server 08437 we are registering to 08438 */ 08439 reg->refresh = refresh; 08440 reg->expire = iax2_sched_replace(reg->expire, sched, 08441 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08442 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08443 if (reg->messages > 255) 08444 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08445 else if (reg->messages > 1) 08446 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 08447 else if (reg->messages > 0) 08448 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus)); 08449 else 08450 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus)); 08451 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08452 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08453 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08454 } 08455 reg->regstate = REG_STATE_REGISTERED; 08456 return 0; 08457 }
static int attribute_pure iax2_allow_new | ( | int | frametype, | |
int | subclass, | |||
int | inbound | |||
) | [inline, static] |
Definition at line 2731 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().
02732 { 02733 if (frametype != AST_FRAME_IAX) { 02734 return 0; 02735 } 02736 switch (subclass) { 02737 case IAX_COMMAND_NEW: 02738 case IAX_COMMAND_REGREQ: 02739 case IAX_COMMAND_FWDOWNL: 02740 case IAX_COMMAND_REGREL: 02741 return 1; 02742 case IAX_COMMAND_POKE: 02743 if (!inbound) { 02744 return 1; 02745 } 02746 break; 02747 } 02748 return 0; 02749 }
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 1324 of file chan_iax2.c.
References chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, ast_channel::name, chan_iax2_pvt::owner, chan_iax2_pvt::peer, and chan_iax2_pvt::peercallno.
Referenced by ast_iax2_new(), and iax2_answer().
01325 { 01326 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01327 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01328 pvt->owner ? pvt->owner->name : "", 01329 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01330 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5581 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.
05582 { 05583 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05584 ast_debug(1, "Answering IAX2 call\n"); 05585 ast_mutex_lock(&iaxsl[callno]); 05586 if (iaxs[callno]) 05587 iax2_ami_channelupdate(iaxs[callno]); 05588 ast_mutex_unlock(&iaxsl[callno]); 05589 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05590 }
static int iax2_append_register | ( | const char * | hostname, | |
const char * | username, | |||
const char * | secret, | |||
const char * | porta | |||
) | [static] |
Definition at line 8459 of file chan_iax2.c.
References 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::entry, IAX_DEFAULT_PORTNO, and IAX_DEFAULT_REG_EXPIRE.
Referenced by iax2_register().
08461 { 08462 struct iax2_registry *reg; 08463 08464 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08465 return -1; 08466 08467 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08468 ast_free(reg); 08469 return -1; 08470 } 08471 08472 ast_copy_string(reg->username, username, sizeof(reg->username)); 08473 08474 if (secret) 08475 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08476 08477 reg->expire = -1; 08478 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08479 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); 08480 08481 AST_LIST_LOCK(®istrations); 08482 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08483 AST_LIST_UNLOCK(®istrations); 08484 08485 return 0; 08486 }
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 5426 of file chan_iax2.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_mutex_lock, ast_mutex_unlock, ast_verb, chan_iax2_pvt::bridgecallno, f, iax2_tech, iaxs, iaxsl, lock_both(), PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and unlock_both().
05427 { 05428 struct ast_channel *cs[3]; 05429 struct ast_channel *who, *other; 05430 int to = -1; 05431 int res = -1; 05432 int transferstarted=0; 05433 struct ast_frame *f; 05434 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05435 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05436 struct timeval waittimer = {0, 0}; 05437 05438 /* We currently do not support native bridging if a timeoutms value has been provided */ 05439 if (timeoutms > 0) { 05440 return AST_BRIDGE_FAILED; 05441 } 05442 05443 timeoutms = -1; 05444 05445 lock_both(callno0, callno1); 05446 if (!iaxs[callno0] || !iaxs[callno1]) { 05447 unlock_both(callno0, callno1); 05448 return AST_BRIDGE_FAILED; 05449 } 05450 /* Put them in native bridge mode */ 05451 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05452 iaxs[callno0]->bridgecallno = callno1; 05453 iaxs[callno1]->bridgecallno = callno0; 05454 } 05455 unlock_both(callno0, callno1); 05456 05457 /* If not, try to bridge until we can execute a transfer, if we can */ 05458 cs[0] = c0; 05459 cs[1] = c1; 05460 for (/* ever */;;) { 05461 /* Check in case we got masqueraded into */ 05462 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05463 ast_verb(3, "Can't masquerade, we're different...\n"); 05464 /* Remove from native mode */ 05465 if (c0->tech == &iax2_tech) { 05466 ast_mutex_lock(&iaxsl[callno0]); 05467 iaxs[callno0]->bridgecallno = 0; 05468 ast_mutex_unlock(&iaxsl[callno0]); 05469 } 05470 if (c1->tech == &iax2_tech) { 05471 ast_mutex_lock(&iaxsl[callno1]); 05472 iaxs[callno1]->bridgecallno = 0; 05473 ast_mutex_unlock(&iaxsl[callno1]); 05474 } 05475 return AST_BRIDGE_FAILED_NOWARN; 05476 } 05477 if (c0->nativeformats != c1->nativeformats) { 05478 char buf0[256]; 05479 char buf1[256]; 05480 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats); 05481 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats); 05482 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1); 05483 /* Remove from native mode */ 05484 lock_both(callno0, callno1); 05485 if (iaxs[callno0]) 05486 iaxs[callno0]->bridgecallno = 0; 05487 if (iaxs[callno1]) 05488 iaxs[callno1]->bridgecallno = 0; 05489 unlock_both(callno0, callno1); 05490 return AST_BRIDGE_FAILED_NOWARN; 05491 } 05492 /* check if transfered and if we really want native bridging */ 05493 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) { 05494 /* Try the transfer */ 05495 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05496 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA))) 05497 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05498 transferstarted = 1; 05499 } 05500 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05501 /* Call has been transferred. We're no longer involved */ 05502 struct timeval now = ast_tvnow(); 05503 if (ast_tvzero(waittimer)) { 05504 waittimer = now; 05505 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05506 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05507 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05508 *fo = NULL; 05509 *rc = c0; 05510 res = AST_BRIDGE_COMPLETE; 05511 break; 05512 } 05513 } 05514 to = 1000; 05515 who = ast_waitfor_n(cs, 2, &to); 05516 if (timeoutms > -1) { 05517 timeoutms -= (1000 - to); 05518 if (timeoutms < 0) 05519 timeoutms = 0; 05520 } 05521 if (!who) { 05522 if (!timeoutms) { 05523 res = AST_BRIDGE_RETRY; 05524 break; 05525 } 05526 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05527 res = AST_BRIDGE_FAILED; 05528 break; 05529 } 05530 continue; 05531 } 05532 f = ast_read(who); 05533 if (!f) { 05534 *fo = NULL; 05535 *rc = who; 05536 res = AST_BRIDGE_COMPLETE; 05537 break; 05538 } 05539 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) { 05540 *fo = f; 05541 *rc = who; 05542 res = AST_BRIDGE_COMPLETE; 05543 break; 05544 } 05545 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05546 if ((f->frametype == AST_FRAME_VOICE) || 05547 (f->frametype == AST_FRAME_TEXT) || 05548 (f->frametype == AST_FRAME_VIDEO) || 05549 (f->frametype == AST_FRAME_IMAGE) || 05550 (f->frametype == AST_FRAME_DTMF) || 05551 (f->frametype == AST_FRAME_CONTROL)) { 05552 /* monitored dtmf take out of the bridge. 05553 * check if we monitor the specific source. 05554 */ 05555 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05556 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 05557 *rc = who; 05558 *fo = f; 05559 res = AST_BRIDGE_COMPLETE; 05560 /* Remove from native mode */ 05561 break; 05562 } 05563 /* everything else goes to the other side */ 05564 ast_write(other, f); 05565 } 05566 ast_frfree(f); 05567 /* Swap who gets priority */ 05568 cs[2] = cs[0]; 05569 cs[0] = cs[1]; 05570 cs[1] = cs[2]; 05571 } 05572 lock_both(callno0, callno1); 05573 if(iaxs[callno0]) 05574 iaxs[callno0]->bridgecallno = 0; 05575 if(iaxs[callno1]) 05576 iaxs[callno1]->bridgecallno = 0; 05577 unlock_both(callno0, callno1); 05578 return res; 05579 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 4984 of file chan_iax2.c.
References ast_channel::_state, add_empty_calltoken_ie(), 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(), CALLNO_TO_PTR, capability, ast_channel::connected, context, ast_channel::context, create_addr(), ast_datastore::data, ast_channel::dialed, chan_iax2_pvt::encmethods, 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, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, chan_iax2_pvt::mohinterpret, chan_iax2_pvt::mohsuggest, ast_party_id::name, ast_channel::name, ast_channel::nativeformats, ast_party_dialed::number, ast_party_id::number, parse_dial_string(), pbx_builtin_getvar_helper(), chan_iax2_pvt::pingtime, ast_party_number::plan, PTR_TO_CALLNO, ast_channel::redirecting, sched, secret, send_command(), chan_iax2_pvt::sockfd, ast_party_dialed::str, ast_party_name::str, ast_party_number::str, ast_channel::tech_pvt, ast_party_dialed::transit_network_select, chan_iax2_pvt::username, ast_party_name::valid, ast_party_number::valid, and var.
04985 { 04986 struct sockaddr_in sin; 04987 char *l=NULL, *n=NULL, *tmpstr; 04988 struct iax_ie_data ied; 04989 char *defaultrdest = "s"; 04990 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04991 struct parsed_dial_string pds; 04992 struct create_addr_info cai; 04993 struct ast_var_t *var; 04994 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 04995 const char* osp_token_ptr; 04996 unsigned int osp_token_length; 04997 unsigned char osp_block_index; 04998 unsigned int osp_block_length; 04999 unsigned char osp_buffer[256]; 05000 05001 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 05002 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 05003 return -1; 05004 } 05005 05006 memset(&cai, 0, sizeof(cai)); 05007 cai.encmethods = iax2_encryption; 05008 05009 memset(&pds, 0, sizeof(pds)); 05010 tmpstr = ast_strdupa(dest); 05011 parse_dial_string(tmpstr, &pds); 05012 05013 if (ast_strlen_zero(pds.peer)) { 05014 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 05015 return -1; 05016 } 05017 if (!pds.exten) { 05018 pds.exten = defaultrdest; 05019 } 05020 if (create_addr(pds.peer, c, &sin, &cai)) { 05021 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 05022 return -1; 05023 } 05024 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) { 05025 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n"); 05026 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05027 return -1; 05028 } 05029 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 05030 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 05031 return -1; 05032 } 05033 if (!pds.username && !ast_strlen_zero(cai.username)) 05034 pds.username = cai.username; 05035 if (!pds.password && !ast_strlen_zero(cai.secret)) 05036 pds.password = cai.secret; 05037 if (!pds.key && !ast_strlen_zero(cai.outkey)) 05038 pds.key = cai.outkey; 05039 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 05040 pds.context = cai.peercontext; 05041 05042 /* Keep track of the context for outgoing calls too */ 05043 ast_copy_string(c->context, cai.context, sizeof(c->context)); 05044 05045 if (pds.port) 05046 sin.sin_port = htons(atoi(pds.port)); 05047 05048 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL; 05049 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL; 05050 05051 /* Now build request */ 05052 memset(&ied, 0, sizeof(ied)); 05053 05054 /* On new call, first IE MUST be IAX version of caller */ 05055 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 05056 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 05057 if (pds.options && strchr(pds.options, 'a')) { 05058 /* Request auto answer */ 05059 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 05060 } 05061 05062 /* WARNING: this breaks down at 190 bits! */ 05063 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 05064 05065 if (l) { 05066 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 05067 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05068 ast_party_id_presentation(&c->connected.id)); 05069 } else if (n) { 05070 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05071 ast_party_id_presentation(&c->connected.id)); 05072 } else { 05073 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 05074 } 05075 05076 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan); 05077 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select); 05078 05079 if (n) 05080 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 05081 if (ast_test_flag64(iaxs[callno], IAX_SENDANI) 05082 && c->connected.ani.number.valid 05083 && c->connected.ani.number.str) { 05084 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str); 05085 } 05086 05087 if (!ast_strlen_zero(c->language)) 05088 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 05089 if (!ast_strlen_zero(c->dialed.number.str)) { 05090 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str); 05091 } 05092 if (c->redirecting.from.number.valid 05093 && !ast_strlen_zero(c->redirecting.from.number.str)) { 05094 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str); 05095 } 05096 05097 if (pds.context) 05098 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 05099 05100 if (pds.username) 05101 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 05102 05103 if (cai.encmethods) 05104 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 05105 05106 ast_mutex_lock(&iaxsl[callno]); 05107 05108 if (!ast_strlen_zero(c->context)) 05109 ast_string_field_set(iaxs[callno], context, c->context); 05110 05111 if (pds.username) 05112 ast_string_field_set(iaxs[callno], username, pds.username); 05113 05114 iaxs[callno]->encmethods = cai.encmethods; 05115 05116 iaxs[callno]->adsi = cai.adsi; 05117 05118 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 05119 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 05120 05121 if (pds.key) 05122 ast_string_field_set(iaxs[callno], outkey, pds.key); 05123 if (pds.password) 05124 ast_string_field_set(iaxs[callno], secret, pds.password); 05125 05126 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats); 05127 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats); 05128 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability); 05129 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability); 05130 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 05131 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 05132 05133 if (iaxs[callno]->maxtime) { 05134 /* Initialize pingtime and auto-congest time */ 05135 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 05136 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 05137 } else if (autokill) { 05138 iaxs[callno]->pingtime = autokill / 2; 05139 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 05140 } 05141 05142 /* Check if there is an OSP token */ 05143 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 05144 if (!ast_strlen_zero(osp_token_ptr)) { 05145 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 05146 osp_block_index = 0; 05147 while (osp_token_length > 0) { 05148 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 05149 osp_buffer[0] = osp_block_index; 05150 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 05151 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 05152 osp_block_index++; 05153 osp_token_ptr += osp_block_length; 05154 osp_token_length -= osp_block_length; 05155 } 05156 } else 05157 ast_log(LOG_WARNING, "OSP token is too long\n"); 05158 } else if (iaxdebug) 05159 ast_debug(1, "OSP token is undefined\n"); 05160 05161 /* send the command using the appropriate socket for this peer */ 05162 iaxs[callno]->sockfd = cai.sockfd; 05163 05164 /* Add remote vars */ 05165 if (variablestore) { 05166 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 05167 ast_debug(1, "Found an IAX variable store on this channel\n"); 05168 AST_LIST_LOCK(variablelist); 05169 AST_LIST_TRAVERSE(variablelist, var, entries) { 05170 char tmp[256]; 05171 int i; 05172 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 05173 /* Automatically divide the value up into sized chunks */ 05174 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 05175 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 05176 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 05177 } 05178 } 05179 AST_LIST_UNLOCK(variablelist); 05180 } 05181 05182 /* Transmit the string in a "NEW" request */ 05183 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 05184 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 05185 05186 ast_mutex_unlock(&iaxsl[callno]); 05187 ast_setstate(c, AST_STATE_RINGING); 05188 05189 return 0; 05190 }
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 13669 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.
13670 { 13671 int res = 0; 13672 struct iax2_dpcache *dp = NULL; 13673 #if 0 13674 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13675 #endif 13676 if ((priority != 1) && (priority != 2)) 13677 return 0; 13678 13679 AST_LIST_LOCK(&dpcache); 13680 if ((dp = find_cache(chan, data, context, exten, priority))) { 13681 if (dp->flags & CACHE_FLAG_CANEXIST) 13682 res = 1; 13683 } else { 13684 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13685 } 13686 AST_LIST_UNLOCK(&dpcache); 13687 13688 return res; 13689 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4657 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().
04658 { 04659 struct timeval t = ast_tvnow(); 04660 struct ast_tm tm; 04661 unsigned int tmp; 04662 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04663 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04664 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04665 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04666 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04667 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04668 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04669 return tmp; 04670 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3372 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().
03373 { 03374 struct chan_iax2_pvt *pvt = NULL; 03375 struct ast_channel *owner = NULL; 03376 03377 retry: 03378 if ((pvt = iaxs[callno])) { 03379 #if 0 03380 /* iax2_destroy_helper gets called from this function later on. When 03381 * called twice, we get the (previously) familiar FRACK! errors in 03382 * devmode, from the scheduler. An alternative to this approach is to 03383 * reset the scheduler entries to -1 when they're deleted in 03384 * iax2_destroy_helper(). That approach was previously decided to be 03385 * "wrong" because "the memory is going to be deallocated anyway. Why 03386 * should we be resetting those values?" */ 03387 iax2_destroy_helper(pvt); 03388 #endif 03389 } 03390 03391 owner = pvt ? pvt->owner : NULL; 03392 03393 if (owner) { 03394 if (ast_channel_trylock(owner)) { 03395 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03396 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03397 goto retry; 03398 } 03399 } 03400 03401 if (!owner) { 03402 iaxs[callno] = NULL; 03403 } 03404 03405 if (pvt) { 03406 if (!owner) { 03407 pvt->owner = NULL; 03408 } else { 03409 /* If there's an owner, prod it to give up */ 03410 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03411 * because we already hold the owner channel lock. */ 03412 ast_queue_hangup(owner); 03413 } 03414 03415 if (pvt->peercallno) { 03416 remove_by_peercallno(pvt); 03417 } 03418 03419 if (pvt->transfercallno) { 03420 remove_by_transfercallno(pvt); 03421 } 03422 03423 if (!owner) { 03424 ao2_ref(pvt, -1); 03425 pvt = NULL; 03426 } 03427 } 03428 03429 if (owner) { 03430 ast_channel_unlock(owner); 03431 } 03432 03433 if (callno & 0x4000) { 03434 update_max_trunk(); 03435 } 03436 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1772 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, DONT_RESCHEDULE, IAX_MAXAUTHREQ, iaxsl, chan_iax2_pvt::initid, chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, iax2_user::name, OBJ_POINTER, chan_iax2_pvt::pingid, sched, user, user_unref(), chan_iax2_pvt::username, and users.
Referenced by iax2_destroy(), iax2_predestroy(), pvt_destructor(), and stop_stuff().
01773 { 01774 /* Decrement AUTHREQ count if needed */ 01775 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) { 01776 struct iax2_user *user; 01777 struct iax2_user tmp_user = { 01778 .name = pvt->username, 01779 }; 01780 01781 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01782 if (user) { 01783 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01784 user_unref(user); 01785 } 01786 01787 ast_clear_flag64(pvt, IAX_MAXAUTHREQ); 01788 } 01789 /* No more pings or lagrq's */ 01790 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]); 01791 pvt->pingid = DONT_RESCHEDULE; 01792 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]); 01793 pvt->lagid = DONT_RESCHEDULE; 01794 ast_sched_thread_del(sched, pvt->autoid); 01795 ast_sched_thread_del(sched, pvt->authid); 01796 ast_sched_thread_del(sched, pvt->initid); 01797 ast_sched_thread_del(sched, pvt->jbid); 01798 ast_sched_thread_del(sched, pvt->keyrotateid); 01799 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 13874 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(), and peer_unref().
13875 { 13876 struct parsed_dial_string pds; 13877 char *tmp = ast_strdupa(data); 13878 struct iax2_peer *p; 13879 int res = AST_DEVICE_INVALID; 13880 13881 memset(&pds, 0, sizeof(pds)); 13882 parse_dial_string(tmp, &pds); 13883 13884 if (ast_strlen_zero(pds.peer)) { 13885 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 13886 return res; 13887 } 13888 13889 ast_debug(3, "Checking device state for device %s\n", pds.peer); 13890 13891 /* SLD: FIXME: second call to find_peer during registration */ 13892 if (!(p = find_peer(pds.peer, 1))) 13893 return res; 13894 13895 res = AST_DEVICE_UNAVAILABLE; 13896 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 13897 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 13898 13899 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) && 13900 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 13901 /* Peer is registered, or have default IP address 13902 and a valid registration */ 13903 if (p->historicms == 0 || p->historicms <= p->maxms) 13904 /* let the core figure out whether it is in use or not */ 13905 res = AST_DEVICE_UNKNOWN; 13906 } 13907 13908 peer_unref(p); 13909 13910 return res; 13911 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 4262 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04263 { 04264 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04265 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 4267 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04268 { 04269 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04270 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11683 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, 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, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, sched, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), network_change_event_sched_cb(), and reload_config().
11684 { 11685 struct iax_ie_data ied; 11686 if (iaxdebug) 11687 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11688 11689 if (reg->dnsmgr && 11690 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) { 11691 /* Maybe the IP has changed, force DNS refresh */ 11692 ast_dnsmgr_refresh(reg->dnsmgr); 11693 } 11694 11695 /* 11696 * if IP has Changed, free allocated call to create a new one with new IP 11697 * call has the pointer to IP and must be updated to the new one 11698 */ 11699 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11700 int callno = reg->callno; 11701 ast_mutex_lock(&iaxsl[callno]); 11702 iax2_destroy(callno); 11703 ast_mutex_unlock(&iaxsl[callno]); 11704 reg->callno = 0; 11705 } 11706 if (!ast_sockaddr_ipv4(®->addr)) { 11707 if (iaxdebug) 11708 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11709 /* Setup the next registration attempt */ 11710 reg->expire = iax2_sched_replace(reg->expire, sched, 11711 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11712 return -1; 11713 } 11714 11715 if (!reg->callno) { 11716 struct sockaddr_in reg_addr; 11717 11718 ast_debug(3, "Allocate call number\n"); 11719 11720 ast_sockaddr_to_sin(®->addr, ®_addr); 11721 11722 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0); 11723 if (reg->callno < 1) { 11724 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11725 return -1; 11726 } else 11727 ast_debug(3, "Registration created on call %d\n", reg->callno); 11728 iaxs[reg->callno]->reg = reg; 11729 ast_mutex_unlock(&iaxsl[reg->callno]); 11730 } 11731 /* Setup the next registration a little early */ 11732 reg->expire = iax2_sched_replace(reg->expire, sched, 11733 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11734 /* Send the request */ 11735 memset(&ied, 0, sizeof(ied)); 11736 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11737 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11738 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11739 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11740 reg->regstate = REG_STATE_REGSENT; 11741 return 0; 11742 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8245 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
08246 { 08247 #ifdef SCHED_MULTITHREADED 08248 if (schedule_action(__iax2_do_register_s, data)) 08249 #endif 08250 __iax2_do_register_s(data); 08251 return 0; 08252 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 9010 of file chan_iax2.c.
References AST_FRAME_IAX, auto_hangup(), chan_iax2_pvt::autoid, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_replace(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iaxs, sched, and send_command().
Referenced by find_cache(), and socket_process().
09011 { 09012 struct iax_ie_data ied; 09013 /* Auto-hangup with 30 seconds of inactivity */ 09014 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 09015 sched, 30000, auto_hangup, (void *)(long)callno); 09016 memset(&ied, 0, sizeof(ied)); 09017 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 09018 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 09019 dp->flags |= CACHE_FLAG_TRANSMITTED; 09020 }
static void * iax2_dup_variable_datastore | ( | void * | ) | [static] |
Definition at line 1338 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(), ast_var_t::entries, and LOG_ERROR.
01339 { 01340 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01341 struct ast_var_t *oldvar, *newvar; 01342 01343 newlist = ast_calloc(sizeof(*newlist), 1); 01344 if (!newlist) { 01345 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01346 return NULL; 01347 } 01348 01349 AST_LIST_HEAD_INIT(newlist); 01350 AST_LIST_LOCK(oldlist); 01351 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01352 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01353 if (newvar) 01354 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01355 else 01356 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01357 } 01358 AST_LIST_UNLOCK(oldlist); 01359 return newlist; 01360 }
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 13715 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().
13716 { 13717 char odata[256]; 13718 char req[256]; 13719 char *ncontext; 13720 struct iax2_dpcache *dp = NULL; 13721 struct ast_app *dial = NULL; 13722 #if 0 13723 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); 13724 #endif 13725 if (priority == 2) { 13726 /* Indicate status, can be overridden in dialplan */ 13727 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13728 if (dialstatus) { 13729 dial = pbx_findapp(dialstatus); 13730 if (dial) 13731 pbx_exec(chan, dial, ""); 13732 } 13733 return -1; 13734 } else if (priority != 1) 13735 return -1; 13736 13737 AST_LIST_LOCK(&dpcache); 13738 if ((dp = find_cache(chan, data, context, exten, priority))) { 13739 if (dp->flags & CACHE_FLAG_EXISTS) { 13740 ast_copy_string(odata, data, sizeof(odata)); 13741 ncontext = strchr(odata, '/'); 13742 if (ncontext) { 13743 *ncontext = '\0'; 13744 ncontext++; 13745 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13746 } else { 13747 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13748 } 13749 ast_verb(3, "Executing Dial('%s')\n", req); 13750 } else { 13751 AST_LIST_UNLOCK(&dpcache); 13752 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13753 return -1; 13754 } 13755 } 13756 AST_LIST_UNLOCK(&dpcache); 13757 13758 if ((dial = pbx_findapp("Dial"))) 13759 return pbx_exec(chan, dial, req); 13760 else 13761 ast_log(LOG_WARNING, "No dial application registered\n"); 13762 13763 return -1; 13764 }
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 13646 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.
13647 { 13648 int res = 0; 13649 struct iax2_dpcache *dp = NULL; 13650 #if 0 13651 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13652 #endif 13653 if ((priority != 1) && (priority != 2)) 13654 return 0; 13655 13656 AST_LIST_LOCK(&dpcache); 13657 if ((dp = find_cache(chan, data, context, exten, priority))) { 13658 if (dp->flags & CACHE_FLAG_EXISTS) 13659 res = 1; 13660 } else { 13661 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13662 } 13663 AST_LIST_UNLOCK(&dpcache); 13664 13665 return res; 13666 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 4289 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.
04290 { 04291 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04292 ast_mutex_lock(&iaxsl[callno]); 04293 if (iaxs[callno]) 04294 iaxs[callno]->owner = newchan; 04295 else 04296 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04297 ast_mutex_unlock(&iaxsl[callno]); 04298 return 0; 04299 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1801 of file chan_iax2.c.
References ast_sched_thread_del, iax_frame_free(), iax_frame::retrans, and sched.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), resend_with_token(), and schedule_delivery().
01802 { 01803 ast_sched_thread_del(sched, fr->retrans); 01804 iax_frame_free(fr); 01805 }
static void iax2_free_variable_datastore | ( | void * | ) | [static] |
Definition at line 1362 of file chan_iax2.c.
References ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and ast_var_t::entries.
01363 { 01364 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01365 struct ast_var_t *oldvar; 01366 01367 AST_LIST_LOCK(oldlist); 01368 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01369 ast_free(oldvar); 01370 } 01371 AST_LIST_UNLOCK(oldlist); 01372 AST_LIST_HEAD_DESTROY(oldlist); 01373 ast_free(oldlist); 01374 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1735 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, iax2_peer::name, peer_unref(), peers, and realtime_peer().
Referenced by __find_callno().
01736 { 01737 struct iax2_peer *peer = NULL; 01738 int res = 0; 01739 struct ao2_iterator i; 01740 01741 i = ao2_iterator_init(peers, 0); 01742 while ((peer = ao2_iterator_next(&i))) { 01743 struct sockaddr_in peer_addr; 01744 01745 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 01746 01747 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01748 (peer_addr.sin_port == sin.sin_port)) { 01749 ast_copy_string(host, peer->name, len); 01750 peer_unref(peer); 01751 res = 1; 01752 break; 01753 } 01754 peer_unref(peer); 01755 } 01756 ao2_iterator_destroy(&i); 01757 01758 if (!peer) { 01759 peer = realtime_peer(NULL, &sin); 01760 if (peer) { 01761 ast_copy_string(host, peer->name, len); 01762 peer_unref(peer); 01763 res = 1; 01764 } 01765 } 01766 01767 return res; 01768 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5656 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, peer_unref(), and peers.
Referenced by check_access().
05657 { 05658 struct iax2_peer *peer; 05659 int res = 0; 05660 struct ao2_iterator i; 05661 05662 i = ao2_iterator_init(peers, 0); 05663 while ((peer = ao2_iterator_next(&i))) { 05664 struct sockaddr_in peer_addr; 05665 05666 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 05667 05668 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05669 (peer_addr.sin_port == sin.sin_port)) { 05670 res = ast_test_flag64(peer, IAX_TRUNK); 05671 peer_unref(peer); 05672 break; 05673 } 05674 peer_unref(peer); 05675 } 05676 ao2_iterator_destroy(&i); 05677 05678 return res; 05679 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5192 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, 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, ast_channel::name, PTR_TO_CALLNO, sched, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.
05193 { 05194 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05195 struct iax_ie_data ied; 05196 int alreadygone; 05197 memset(&ied, 0, sizeof(ied)); 05198 ast_mutex_lock(&iaxsl[callno]); 05199 if (callno && iaxs[callno]) { 05200 ast_debug(1, "We're hanging up %s now...\n", c->name); 05201 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE); 05202 /* Send the hangup unless we have had a transmission error or are already gone */ 05203 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 05204 if (!iaxs[callno]->error && !alreadygone) { 05205 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 05206 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 05207 } 05208 if (!iaxs[callno]) { 05209 ast_mutex_unlock(&iaxsl[callno]); 05210 return 0; 05211 } 05212 } 05213 /* Explicitly predestroy it */ 05214 iax2_predestroy(callno); 05215 /* If we were already gone to begin with, destroy us now */ 05216 if (iaxs[callno] && alreadygone) { 05217 ast_debug(1, "Really destroying %s now...\n", c->name); 05218 iax2_destroy(callno); 05219 } else if (iaxs[callno]) { 05220 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 05221 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05222 iax2_destroy(callno); 05223 } 05224 } 05225 } else if (c->tech_pvt) { 05226 /* If this call no longer exists, but the channel still 05227 * references it we need to set the channel's tech_pvt to null 05228 * to avoid ast_channel_free() trying to free it. 05229 */ 05230 c->tech_pvt = NULL; 05231 } 05232 ast_mutex_unlock(&iaxsl[callno]); 05233 ast_verb(3, "Hungup '%s'\n", c->name); 05234 return 0; 05235 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5592 of file chan_iax2.c.
References AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, IAX_SENDCONNECTEDLINE, iaxs, iaxsl, chan_iax2_pvt::mohinterpret, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
05593 { 05594 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05595 struct chan_iax2_pvt *pvt; 05596 int res = 0; 05597 05598 if (iaxdebug) 05599 ast_debug(1, "Indicating condition %d\n", condition); 05600 05601 ast_mutex_lock(&iaxsl[callno]); 05602 pvt = iaxs[callno]; 05603 05604 if (wait_for_peercallno(pvt)) { 05605 res = -1; 05606 goto done; 05607 } 05608 05609 switch (condition) { 05610 case AST_CONTROL_HOLD: 05611 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05612 ast_moh_start(c, data, pvt->mohinterpret); 05613 goto done; 05614 } 05615 break; 05616 case AST_CONTROL_UNHOLD: 05617 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05618 ast_moh_stop(c); 05619 goto done; 05620 } 05621 break; 05622 case AST_CONTROL_CONNECTED_LINE: 05623 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) 05624 goto done; 05625 break; 05626 } 05627 05628 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05629 05630 done: 05631 ast_mutex_unlock(&iaxsl[callno]); 05632 05633 return res; 05634 }
static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5344 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, md5(), MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, sched, and send_command().
Referenced by iax2_send().
05345 { 05346 int res = 0; 05347 struct chan_iax2_pvt *pvt = (void *) vpvt; 05348 struct MD5Context md5; 05349 char key[17] = ""; 05350 struct iax_ie_data ied = { 05351 .pos = 0, 05352 }; 05353 05354 ast_mutex_lock(&iaxsl[pvt->callno]); 05355 pvt->keyrotateid = 05356 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05357 05358 snprintf(key, sizeof(key), "%lX", ast_random()); 05359 05360 MD5Init(&md5); 05361 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05362 MD5Final((unsigned char *) key, &md5); 05363 05364 IAX_DEBUGDIGEST("Sending", key); 05365 05366 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05367 05368 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05369 05370 build_ecx_key((unsigned char *) key, pvt); 05371 05372 ast_mutex_unlock(&iaxsl[pvt->callno]); 05373 05374 return res; 05375 }
static void iax2_lock_owner | ( | int | callno | ) | [static] |
Definition at line 1258 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().
01259 { 01260 for (;;) { 01261 if (!iaxs[callno] || !iaxs[callno]->owner) { 01262 /* There is no owner lock to get. */ 01263 break; 01264 } 01265 if (!ast_channel_trylock(iaxs[callno]->owner)) { 01266 /* We got the lock */ 01267 break; 01268 } 01269 /* Avoid deadlock by pausing and trying again */ 01270 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01271 } 01272 }
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 13692 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.
13693 { 13694 int res = 0; 13695 struct iax2_dpcache *dp = NULL; 13696 #if 0 13697 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13698 #endif 13699 if ((priority != 1) && (priority != 2)) 13700 return 0; 13701 13702 AST_LIST_LOCK(&dpcache); 13703 if ((dp = find_cache(chan, data, context, exten, priority))) { 13704 if (dp->flags & CACHE_FLAG_MATCHMORE) 13705 res = 1; 13706 } else { 13707 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13708 } 13709 AST_LIST_UNLOCK(&dpcache); 13710 13711 return res; 13712 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11887 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
11888 { 11889 struct iax2_peer *peer = (struct iax2_peer *)data; 11890 peer->pokeexpire = -1; 11891 #ifdef SCHED_MULTITHREADED 11892 if (schedule_action(__iax2_poke_noanswer, data)) 11893 #endif 11894 __iax2_poke_noanswer(data); 11895 peer_unref(peer); 11896 return 0; 11897 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 11908 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, iax2_peer::name, NEW_FORCE, peer_ref(), peer_unref(), chan_iax2_pvt::peerpoke, chan_iax2_pvt::pingtime, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax_ie_data::pos, sched, 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().
11909 { 11910 int callno; 11911 struct sockaddr_in peer_addr; 11912 11913 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) { 11914 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 11915 immediately after clearing things out */ 11916 peer->lastms = 0; 11917 peer->historicms = 0; 11918 peer->pokeexpire = -1; 11919 peer->callno = 0; 11920 return 0; 11921 } 11922 11923 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 11924 11925 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 11926 if ((callno = peer->callno) > 0) { 11927 ast_log(LOG_NOTICE, "Still have a callno...\n"); 11928 ast_mutex_lock(&iaxsl[callno]); 11929 iax2_destroy(callno); 11930 ast_mutex_unlock(&iaxsl[callno]); 11931 } 11932 if (heldcall) 11933 ast_mutex_unlock(&iaxsl[heldcall]); 11934 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0); 11935 if (heldcall) 11936 ast_mutex_lock(&iaxsl[heldcall]); 11937 if (peer->callno < 1) { 11938 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 11939 return -1; 11940 } 11941 11942 /* Speed up retransmission times for this qualify call */ 11943 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 11944 iaxs[peer->callno]->peerpoke = peer; 11945 11946 if (peer->pokeexpire > -1) { 11947 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 11948 peer->pokeexpire = -1; 11949 peer_unref(peer); 11950 } 11951 } 11952 11953 /* Queue up a new task to handle no reply */ 11954 /* If the host is already unreachable then use the unreachable interval instead */ 11955 if (peer->lastms < 0) 11956 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 11957 else 11958 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 11959 11960 if (peer->pokeexpire == -1) 11961 peer_unref(peer); 11962 11963 /* And send the poke */ 11964 ast_mutex_lock(&iaxsl[callno]); 11965 if (iaxs[callno]) { 11966 struct iax_ie_data ied = { 11967 .buf = { 0 }, 11968 .pos = 0, 11969 }; 11970 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 11971 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 11972 } 11973 ast_mutex_unlock(&iaxsl[callno]); 11974 11975 return 0; 11976 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11899 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
11900 { 11901 struct iax2_peer *peer = obj; 11902 11903 iax2_poke_peer(peer, 0); 11904 11905 return 0; 11906 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9047 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
09048 { 09049 struct iax2_peer *peer = (struct iax2_peer *)data; 09050 peer->pokeexpire = -1; 09051 #ifdef SCHED_MULTITHREADED 09052 if (schedule_action(__iax2_poke_peer_s, data)) 09053 #endif 09054 __iax2_poke_peer_s(data); 09055 return 0; 09056 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3349 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().
03350 { 03351 struct ast_channel *c = NULL; 03352 struct chan_iax2_pvt *pvt = iaxs[callno]; 03353 03354 if (!pvt) 03355 return -1; 03356 03357 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) { 03358 iax2_destroy_helper(pvt); 03359 ast_set_flag64(pvt, IAX_ALREADYGONE); 03360 } 03361 03362 if ((c = pvt->owner)) { 03363 c->tech_pvt = NULL; 03364 iax2_queue_hangup(callno); 03365 pvt->owner = NULL; 03366 ast_module_unref(ast_module_info->self); 03367 } 03368 03369 return 0; 03370 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 11544 of file chan_iax2.c.
References ast_atomic_fetchadd_int(), ast_cond_timedwait, ast_mutex_lock, ast_mutex_unlock, ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_process_thread_cleanup(), IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, insert_idle_thread(), signal_condition(), and thread.
Referenced by find_idle_thread(), and start_network_thread().
11545 { 11546 struct iax2_thread *thread = data; 11547 struct timeval wait; 11548 struct timespec ts; 11549 int put_into_idle = 0; 11550 int first_time = 1; 11551 int old_state; 11552 11553 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1); 11554 11555 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); 11556 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11557 11558 for (;;) { 11559 /* Wait for something to signal us to be awake */ 11560 ast_mutex_lock(&thread->lock); 11561 11562 if (thread->stop) { 11563 ast_mutex_unlock(&thread->lock); 11564 break; 11565 } 11566 11567 /* Flag that we're ready to accept signals */ 11568 if (first_time) { 11569 signal_condition(&thread->init_lock, &thread->init_cond); 11570 first_time = 0; 11571 } 11572 11573 /* Put into idle list if applicable */ 11574 if (put_into_idle) { 11575 insert_idle_thread(thread); 11576 } 11577 11578 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11579 struct iax2_thread *t = NULL; 11580 /* Wait to be signalled or time out */ 11581 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11582 ts.tv_sec = wait.tv_sec; 11583 ts.tv_nsec = wait.tv_usec * 1000; 11584 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11585 /* This thread was never put back into the available dynamic 11586 * thread list, so just go away. */ 11587 if (!put_into_idle || thread->stop) { 11588 ast_mutex_unlock(&thread->lock); 11589 break; 11590 } 11591 AST_LIST_LOCK(&dynamic_list); 11592 /* Account for the case where this thread is acquired *right* after a timeout */ 11593 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11594 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11595 AST_LIST_UNLOCK(&dynamic_list); 11596 if (t) { 11597 /* This dynamic thread timed out waiting for a task and was 11598 * not acquired immediately after the timeout, 11599 * so it's time to go away. */ 11600 ast_mutex_unlock(&thread->lock); 11601 break; 11602 } 11603 /* Someone grabbed our thread *right* after we timed out. 11604 * Wait for them to set us up with something to do and signal 11605 * us to continue. */ 11606 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11607 ts.tv_sec = wait.tv_sec; 11608 ts.tv_nsec = wait.tv_usec * 1000; 11609 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11610 ast_mutex_unlock(&thread->lock); 11611 break; 11612 } 11613 } 11614 } else { 11615 ast_cond_wait(&thread->cond, &thread->lock); 11616 } 11617 11618 /* Go back into our respective list */ 11619 put_into_idle = 1; 11620 11621 ast_mutex_unlock(&thread->lock); 11622 11623 if (thread->stop) { 11624 break; 11625 } 11626 11627 if (thread->iostate == IAX_IOSTATE_IDLE) 11628 continue; 11629 11630 /* See what we need to do */ 11631 switch (thread->iostate) { 11632 case IAX_IOSTATE_READY: 11633 thread->actions++; 11634 thread->iostate = IAX_IOSTATE_PROCESSING; 11635 socket_process(thread); 11636 handle_deferred_full_frames(thread); 11637 break; 11638 case IAX_IOSTATE_SCHEDREADY: 11639 thread->actions++; 11640 thread->iostate = IAX_IOSTATE_PROCESSING; 11641 #ifdef SCHED_MULTITHREADED 11642 thread->schedfunc(thread->scheddata); 11643 #endif 11644 default: 11645 break; 11646 } 11647 time(&thread->checktime); 11648 thread->iostate = IAX_IOSTATE_IDLE; 11649 #ifdef DEBUG_SCHED_MULTITHREAD 11650 thread->curfunc[0]='\0'; 11651 #endif 11652 11653 /* The network thread added us to the active_thread list when we were given 11654 * frames to process, Now that we are done, we must remove ourselves from 11655 * the active list, and return to the idle list */ 11656 AST_LIST_LOCK(&active_list); 11657 AST_LIST_REMOVE(&active_list, thread, list); 11658 AST_LIST_UNLOCK(&active_list); 11659 11660 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11661 handle_deferred_full_frames(thread); 11662 } 11663 11664 /*!\note For some reason, idle threads are exiting without being removed 11665 * from an idle list, which is causing memory corruption. Forcibly remove 11666 * it from the list, if it's there. 11667 */ 11668 AST_LIST_LOCK(&idle_list); 11669 AST_LIST_REMOVE(&idle_list, thread, list); 11670 AST_LIST_UNLOCK(&idle_list); 11671 11672 AST_LIST_LOCK(&dynamic_list); 11673 AST_LIST_REMOVE(&dynamic_list, thread, list); 11674 AST_LIST_UNLOCK(&dynamic_list); 11675 11676 /* I am exiting here on my own volition, I need to clean up my own data structures 11677 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11678 */ 11679 pthread_cleanup_pop(1); 11680 return NULL; 11681 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11533 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().
11534 { 11535 struct iax2_thread *thread = data; 11536 ast_mutex_destroy(&thread->lock); 11537 ast_cond_destroy(&thread->cond); 11538 ast_mutex_destroy(&thread->init_lock); 11539 ast_cond_destroy(&thread->init_cond); 11540 ast_free(thread); 11541 ast_atomic_dec_and_test(&iaxactivethreadcount); 11542 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
const char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 11744 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, sched, and send_command().
Referenced by check_provisioning(), handle_cli_iax2_provision(), and iax2_prov_app().
11745 { 11746 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11747 is found for template */ 11748 struct iax_ie_data provdata; 11749 struct iax_ie_data ied; 11750 unsigned int sig; 11751 struct sockaddr_in sin; 11752 int callno; 11753 struct create_addr_info cai; 11754 11755 memset(&cai, 0, sizeof(cai)); 11756 11757 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11758 11759 if (iax_provision_build(&provdata, &sig, template, force)) { 11760 ast_debug(1, "No provisioning found for template '%s'\n", template); 11761 return 0; 11762 } 11763 11764 if (end) { 11765 memcpy(&sin, end, sizeof(sin)); 11766 cai.sockfd = sockfd; 11767 } else if (create_addr(dest, NULL, &sin, &cai)) 11768 return -1; 11769 11770 /* Build the rest of the message */ 11771 memset(&ied, 0, sizeof(ied)); 11772 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11773 11774 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11775 if (!callno) 11776 return -1; 11777 11778 if (iaxs[callno]) { 11779 /* Schedule autodestruct in case they don't ever give us anything back */ 11780 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11781 sched, 15000, auto_hangup, (void *)(long)callno); 11782 ast_set_flag64(iaxs[callno], IAX_PROVISION); 11783 /* Got a call number now, so go ahead and send the provisioning information */ 11784 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11785 } 11786 ast_mutex_unlock(&iaxsl[callno]); 11787 11788 return 1; 11789 }
static int iax2_queryoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int * | datalen | |||
) | [static] |
Definition at line 5321 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.
05322 { 05323 switch (option) { 05324 case AST_OPTION_SECURE_SIGNALING: 05325 case AST_OPTION_SECURE_MEDIA: 05326 { 05327 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05328 ast_mutex_lock(&iaxsl[callno]); 05329 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0; 05330 ast_mutex_unlock(&iaxsl[callno]); 05331 return 0; 05332 } 05333 default: 05334 return -1; 05335 } 05336 }
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 2982 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_control_data(), iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.
Referenced by socket_process().
02984 { 02985 iax2_lock_owner(callno); 02986 if (iaxs[callno] && iaxs[callno]->owner) { 02987 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 02988 ast_channel_unlock(iaxs[callno]->owner); 02989 } 02990 return 0; 02991 }
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 2936 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_frame(), f, iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
02937 { 02938 iax2_lock_owner(callno); 02939 if (iaxs[callno] && iaxs[callno]->owner) { 02940 ast_queue_frame(iaxs[callno]->owner, f); 02941 ast_channel_unlock(iaxs[callno]->owner); 02942 } 02943 return 0; 02944 }
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 2959 of file chan_iax2.c.
References ast_channel_unlock, ast_queue_hangup(), iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.
Referenced by iax2_predestroy().
02960 { 02961 iax2_lock_owner(callno); 02962 if (iaxs[callno] && iaxs[callno]->owner) { 02963 ast_queue_hangup(iaxs[callno]->owner); 02964 ast_channel_unlock(iaxs[callno]->owner); 02965 } 02966 return 0; 02967 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5338 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
05339 { 05340 ast_log(LOG_NOTICE, "I should never be called!\n"); 05341 return &ast_null_frame; 05342 }
static int iax2_register | ( | const char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 8488 of file chan_iax2.c.
References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, secret, and strsep().
Referenced by set_config().
08489 { 08490 char copy[256]; 08491 char *username, *hostname, *secret; 08492 char *porta; 08493 char *stringp=NULL; 08494 08495 if (!value) 08496 return -1; 08497 08498 ast_copy_string(copy, value, sizeof(copy)); 08499 stringp = copy; 08500 username = strsep(&stringp, "@"); 08501 hostname = strsep(&stringp, "@"); 08502 08503 if (!hostname) { 08504 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08505 return -1; 08506 } 08507 08508 stringp = username; 08509 username = strsep(&stringp, ":"); 08510 secret = strsep(&stringp, ":"); 08511 stringp = hostname; 08512 hostname = strsep(&stringp, ":"); 08513 porta = strsep(&stringp, ":"); 08514 08515 if (porta && !atoi(porta)) { 08516 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08517 return -1; 08518 } 08519 08520 return iax2_append_register(hostname, username, secret, porta); 08521 }
static struct ast_channel * iax2_request | ( | const char * | type, | |
format_t | format, | |||
const struct ast_channel * | requestor, | |||
void * | data, | |||
int * | cause | |||
) | [static] |
Definition at line 11988 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(), find_callno_locked(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDANI, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iaxs, iaxsl, ast_channel::linkedid, LOG_WARNING, make_trunk(), chan_iax2_pvt::maxtime, ast_channel::name, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), chan_iax2_pvt::peer, ast_channel::readformat, and ast_channel::writeformat.
11989 { 11990 int callno; 11991 int res; 11992 format_t fmt, native; 11993 struct sockaddr_in sin; 11994 struct ast_channel *c; 11995 struct parsed_dial_string pds; 11996 struct create_addr_info cai; 11997 char *tmpstr; 11998 11999 memset(&pds, 0, sizeof(pds)); 12000 tmpstr = ast_strdupa(data); 12001 parse_dial_string(tmpstr, &pds); 12002 12003 if (ast_strlen_zero(pds.peer)) { 12004 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12005 return NULL; 12006 } 12007 12008 memset(&cai, 0, sizeof(cai)); 12009 cai.capability = iax2_capability; 12010 12011 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12012 12013 /* Populate our address from the given */ 12014 if (create_addr(pds.peer, NULL, &sin, &cai)) { 12015 *cause = AST_CAUSE_UNREGISTERED; 12016 return NULL; 12017 } 12018 12019 if (pds.port) 12020 sin.sin_port = htons(atoi(pds.port)); 12021 12022 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12023 if (callno < 1) { 12024 ast_log(LOG_WARNING, "Unable to create call\n"); 12025 *cause = AST_CAUSE_CONGESTION; 12026 return NULL; 12027 } 12028 12029 /* If this is a trunk, update it now */ 12030 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12031 if (ast_test_flag64(&cai, IAX_TRUNK)) { 12032 int new_callno; 12033 if ((new_callno = make_trunk(callno, 1)) != -1) 12034 callno = new_callno; 12035 } 12036 iaxs[callno]->maxtime = cai.maxtime; 12037 if (cai.found) 12038 ast_string_field_set(iaxs[callno], host, pds.peer); 12039 12040 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL); 12041 12042 ast_mutex_unlock(&iaxsl[callno]); 12043 12044 if (c) { 12045 /* Choose a format we can live with */ 12046 if (c->nativeformats & format) 12047 c->nativeformats &= format; 12048 else { 12049 native = c->nativeformats; 12050 fmt = format; 12051 res = ast_translator_best_choice(&fmt, &native); 12052 if (res < 0) { 12053 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 12054 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 12055 ast_hangup(c); 12056 return NULL; 12057 } 12058 c->nativeformats = native; 12059 } 12060 c->readformat = ast_best_codec(c->nativeformats); 12061 c->writeformat = c->readformat; 12062 } 12063 12064 return c; 12065 }
static int iax2_sched_add | ( | struct ast_sched_thread * | st, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1498 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(), reg_source_db(), sched_delay_remove(), socket_process(), transmit_frame(), and update_registry().
01500 { 01501 return ast_sched_thread_add(st, when, callback, data); 01502 }
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 1490 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().
01492 { 01493 ast_sched_thread_del(st, id); 01494 01495 return ast_sched_thread_add(st, when, callback, data); 01496 }
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 6319 of file chan_iax2.c.
References iax_frame::af, iax_frame::afdatalen, 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, ast_frame::datalen, iax_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::encmethods, encrypt_frame(), f, 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, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, 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, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, iax_frame::transfer, 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().
06320 { 06321 /* Queue a packet for delivery on a given private structure. Use "ts" for 06322 timestamp, or calculate if ts is 0. Send immediately without retransmission 06323 or delayed, with retransmission */ 06324 struct ast_iax2_full_hdr *fh; 06325 struct ast_iax2_mini_hdr *mh; 06326 struct ast_iax2_video_hdr *vh; 06327 struct { 06328 struct iax_frame fr2; 06329 unsigned char buffer[4096]; 06330 } frb; 06331 struct iax_frame *fr; 06332 int res; 06333 int sendmini=0; 06334 unsigned int lastsent; 06335 unsigned int fts; 06336 06337 frb.fr2.afdatalen = sizeof(frb.buffer); 06338 06339 if (!pvt) { 06340 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06341 return -1; 06342 } 06343 06344 lastsent = pvt->lastsent; 06345 06346 /* Calculate actual timestamp */ 06347 fts = calc_timestamp(pvt, ts, f); 06348 06349 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06350 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06351 * increment the "predicted timestamps" for voice, if we're predicting */ 06352 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06353 return 0; 06354 #if 0 06355 ast_log(LOG_NOTICE, 06356 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06357 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06358 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06359 pvt->keyrotateid != -1 ? "" : "no " 06360 ); 06361 #endif 06362 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06363 iax2_key_rotate(pvt); 06364 } 06365 06366 if ((ast_test_flag64(pvt, IAX_TRUNK) || 06367 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06368 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06369 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06370 (f->frametype == AST_FRAME_VOICE) 06371 /* is a voice frame */ && 06372 (f->subclass.codec == pvt->svoiceformat) 06373 /* is the same type */ ) { 06374 /* Force immediate rather than delayed transmission */ 06375 now = 1; 06376 /* Mark that mini-style frame is appropriate */ 06377 sendmini = 1; 06378 } 06379 if ( f->frametype == AST_FRAME_VIDEO ) { 06380 /* 06381 * If the lower 15 bits of the timestamp roll over, or if 06382 * the video format changed then send a full frame. 06383 * Otherwise send a mini video frame 06384 */ 06385 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06386 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat) 06387 ) { 06388 now = 1; 06389 sendmini = 1; 06390 } else { 06391 now = 0; 06392 sendmini = 0; 06393 } 06394 pvt->lastvsent = fts; 06395 } 06396 if (f->frametype == AST_FRAME_IAX) { 06397 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06398 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX; 06399 if (!pvt->first_iax_message) { 06400 pvt->first_iax_message = pvt->last_iax_message; 06401 } 06402 } 06403 /* Allocate an iax_frame */ 06404 if (now) { 06405 fr = &frb.fr2; 06406 } else 06407 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)); 06408 if (!fr) { 06409 ast_log(LOG_WARNING, "Out of memory\n"); 06410 return -1; 06411 } 06412 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06413 iax_frame_wrap(fr, f); 06414 06415 fr->ts = fts; 06416 fr->callno = pvt->callno; 06417 fr->transfer = transfer; 06418 fr->final = final; 06419 fr->encmethods = 0; 06420 if (!sendmini) { 06421 /* We need a full frame */ 06422 if (seqno > -1) 06423 fr->oseqno = seqno; 06424 else 06425 fr->oseqno = pvt->oseqno++; 06426 fr->iseqno = pvt->iseqno; 06427 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06428 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06429 fh->ts = htonl(fr->ts); 06430 fh->oseqno = fr->oseqno; 06431 if (transfer) { 06432 fh->iseqno = 0; 06433 } else 06434 fh->iseqno = fr->iseqno; 06435 /* Keep track of the last thing we've acknowledged */ 06436 if (!transfer) 06437 pvt->aseqno = fr->iseqno; 06438 fh->type = fr->af.frametype & 0xFF; 06439 06440 if (fr->af.frametype == AST_FRAME_VIDEO) { 06441 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6); 06442 } else if (fr->af.frametype == AST_FRAME_VOICE) { 06443 fh->csub = compress_subclass(fr->af.subclass.codec); 06444 } else { 06445 fh->csub = compress_subclass(fr->af.subclass.integer); 06446 } 06447 06448 if (transfer) { 06449 fr->dcallno = pvt->transfercallno; 06450 } else 06451 fr->dcallno = pvt->peercallno; 06452 fh->dcallno = htons(fr->dcallno); 06453 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06454 fr->data = fh; 06455 fr->retries = 0; 06456 /* Retry after 2x the ping time has passed */ 06457 fr->retrytime = pvt->pingtime * 2; 06458 if (fr->retrytime < MIN_RETRY_TIME) 06459 fr->retrytime = MIN_RETRY_TIME; 06460 if (fr->retrytime > MAX_RETRY_TIME) 06461 fr->retrytime = MAX_RETRY_TIME; 06462 /* Acks' don't get retried */ 06463 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK)) 06464 fr->retries = -1; 06465 else if (f->frametype == AST_FRAME_VOICE) 06466 pvt->svoiceformat = f->subclass.codec; 06467 else if (f->frametype == AST_FRAME_VIDEO) 06468 pvt->svideoformat = f->subclass.codec & ~0x1LL; 06469 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06470 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06471 if (fr->transfer) 06472 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06473 else 06474 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06475 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06476 fr->encmethods = pvt->encmethods; 06477 fr->ecx = pvt->ecx; 06478 fr->mydcx = pvt->mydcx; 06479 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06480 } else 06481 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06482 } 06483 06484 if (now) { 06485 res = send_packet(fr); 06486 } else 06487 res = iax2_transmit(fr); 06488 } else { 06489 if (ast_test_flag64(pvt, IAX_TRUNK)) { 06490 iax2_trunk_queue(pvt, fr); 06491 res = 0; 06492 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06493 /* Video frame have no sequence number */ 06494 fr->oseqno = -1; 06495 fr->iseqno = -1; 06496 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06497 vh->zeros = 0; 06498 vh->callno = htons(0x8000 | fr->callno); 06499 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0)); 06500 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06501 fr->data = vh; 06502 fr->retries = -1; 06503 res = send_packet(fr); 06504 } else { 06505 /* Mini-frames have no sequence number */ 06506 fr->oseqno = -1; 06507 fr->iseqno = -1; 06508 /* Mini frame will do */ 06509 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06510 mh->callno = htons(fr->callno); 06511 mh->ts = htons(fr->ts & 0xFFFF); 06512 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06513 fr->data = mh; 06514 fr->retries = -1; 06515 if (pvt->transferring == TRANSFER_MEDIAPASS) 06516 fr->transfer = 1; 06517 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06518 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06519 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06520 } else 06521 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06522 } 06523 res = send_packet(fr); 06524 } 06525 } 06526 return res; 06527 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4284 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04285 { 04286 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04287 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 4279 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.
04280 { 04281 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1); 04282 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 4272 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04273 { 04274 04275 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04276 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04277 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 5259 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_FLAG_REQUEST, AST_OPTION_FORMAT_READ, AST_OPTION_FORMAT_WRITE, AST_OPTION_MAKE_COMPATIBLE, AST_OPTION_OPRMODE, AST_OPTION_RXGAIN, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_TXGAIN, ast_set_flag64, errno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
05260 { 05261 struct ast_option_header *h; 05262 int res; 05263 05264 switch (option) { 05265 case AST_OPTION_TXGAIN: 05266 case AST_OPTION_RXGAIN: 05267 /* these two cannot be sent, because they require a result */ 05268 errno = ENOSYS; 05269 return -1; 05270 case AST_OPTION_FORMAT_READ: 05271 case AST_OPTION_FORMAT_WRITE: 05272 case AST_OPTION_MAKE_COMPATIBLE: 05273 return -1; 05274 case AST_OPTION_OPRMODE: 05275 errno = EINVAL; 05276 return -1; 05277 case AST_OPTION_SECURE_SIGNALING: 05278 case AST_OPTION_SECURE_MEDIA: 05279 { 05280 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05281 ast_mutex_lock(&iaxsl[callno]); 05282 if ((*(int *) data)) { 05283 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05284 } else { 05285 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05286 } 05287 ast_mutex_unlock(&iaxsl[callno]); 05288 return 0; 05289 } 05290 default: 05291 { 05292 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05293 struct chan_iax2_pvt *pvt; 05294 05295 ast_mutex_lock(&iaxsl[callno]); 05296 pvt = iaxs[callno]; 05297 05298 if (wait_for_peercallno(pvt)) { 05299 ast_mutex_unlock(&iaxsl[callno]); 05300 return -1; 05301 } 05302 05303 ast_mutex_unlock(&iaxsl[callno]); 05304 05305 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05306 return -1; 05307 } 05308 05309 h->flag = AST_OPTION_FLAG_REQUEST; 05310 h->option = htons(option); 05311 memcpy(h->data, data, datalen); 05312 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05313 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05314 datalen + sizeof(*h), -1); 05315 ast_free(h); 05316 return res; 05317 } 05318 } 05319 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 5377 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag64, 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, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
05378 { 05379 int res; 05380 struct iax_ie_data ied0; 05381 struct iax_ie_data ied1; 05382 unsigned int transferid = (unsigned int)ast_random(); 05383 05384 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05385 ast_debug(1, "transfers are not supported for encrypted calls at this time"); 05386 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER); 05387 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER); 05388 return 0; 05389 } 05390 05391 memset(&ied0, 0, sizeof(ied0)); 05392 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05393 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05394 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05395 05396 memset(&ied1, 0, sizeof(ied1)); 05397 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05398 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05399 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05400 05401 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05402 if (res) 05403 return -1; 05404 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05405 if (res) 05406 return -1; 05407 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05408 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05409 return 0; 05410 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 5636 of file chan_iax2.c.
References AST_CONTROL_TRANSFER, ast_copy_string(), ast_debug, AST_FRAME_IAX, ast_queue_control_data(), AST_TRANSFER_SUCCESS, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, ast_channel::name, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05637 { 05638 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05639 struct iax_ie_data ied = { "", }; 05640 char tmp[256], *context; 05641 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 05642 ast_copy_string(tmp, dest, sizeof(tmp)); 05643 context = strchr(tmp, '@'); 05644 if (context) { 05645 *context = '\0'; 05646 context++; 05647 } 05648 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05649 if (context) 05650 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05651 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05652 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message)); 05653 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05654 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4255 of file chan_iax2.c.
References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().
Referenced by iax2_send().
04256 { 04257 fr->sentyet = 0; 04258 04259 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr); 04260 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 9101 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
09102 { 09103 /* Drop when trunk is about 5 seconds idle */ 09104 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 09105 return 1; 09106 return 0; 09107 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 6056 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, DEFAULT_TRUNKDATA, f, find_tpeer(), globalflags, 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, 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().
06057 { 06058 struct ast_frame *f; 06059 struct iax2_trunk_peer *tpeer; 06060 void *tmp, *ptr; 06061 struct timeval now; 06062 int res; 06063 struct ast_iax2_meta_trunk_entry *met; 06064 struct ast_iax2_meta_trunk_mini *mtm; 06065 06066 f = &fr->af; 06067 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 06068 if (tpeer) { 06069 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 06070 /* Need to reallocate space */ 06071 if (tpeer->trunkdataalloc < trunkmaxsize) { 06072 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 06073 ast_mutex_unlock(&tpeer->lock); 06074 return -1; 06075 } 06076 06077 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 06078 tpeer->trunkdata = tmp; 06079 ast_debug(1, "Expanded trunk '%s:%d' to %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), tpeer->trunkdataalloc); 06080 } else { 06081 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)); 06082 ast_mutex_unlock(&tpeer->lock); 06083 return -1; 06084 } 06085 } 06086 06087 /* Append to meta frame */ 06088 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 06089 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) { 06090 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06091 mtm->len = htons(f->datalen); 06092 mtm->mini.callno = htons(pvt->callno); 06093 mtm->mini.ts = htons(0xffff & fr->ts); 06094 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06095 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 06096 } else { 06097 met = (struct ast_iax2_meta_trunk_entry *)ptr; 06098 /* Store call number and length in meta header */ 06099 met->callno = htons(pvt->callno); 06100 met->len = htons(f->datalen); 06101 /* Advance pointers/decrease length past trunk entry header */ 06102 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06103 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 06104 } 06105 /* Copy actual trunk data */ 06106 memcpy(ptr, f->data.ptr, f->datalen); 06107 tpeer->trunkdatalen += f->datalen; 06108 06109 tpeer->calls++; 06110 06111 /* track the largest mtu we actually have sent */ 06112 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 06113 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 06114 06115 /* if we have enough for a full MTU, ship it now without waiting */ 06116 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 06117 now = ast_tvnow(); 06118 res = send_trunk(tpeer, &now); 06119 trunk_untimed ++; 06120 } 06121 06122 ast_mutex_unlock(&tpeer->lock); 06123 } 06124 return 0; 06125 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 9022 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().
09023 { 09024 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 09025 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 7401 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, f, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, iaxs, iaxsl, PTR_TO_CALLNO, state, and ast_channel::tech_pvt.
07402 { 07403 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07404 int res = -1; 07405 ast_mutex_lock(&iaxsl[callno]); 07406 if (iaxs[callno]) { 07407 /* If there's an outstanding error, return failure now */ 07408 if (!iaxs[callno]->error) { 07409 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) 07410 res = 0; 07411 /* Don't waste bandwidth sending null frames */ 07412 else if (f->frametype == AST_FRAME_NULL) 07413 res = 0; 07414 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH)) 07415 res = 0; 07416 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07417 res = 0; 07418 else 07419 /* Simple, just queue for transmission */ 07420 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07421 } else { 07422 ast_debug(1, "Write error: %s\n", strerror(errno)); 07423 } 07424 } 07425 /* If it's already gone, just return */ 07426 ast_mutex_unlock(&iaxsl[callno]); 07427 return res; 07428 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 3141 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::devname, iax_firmware::fwh, iax2_trunk_peer::list, and ast_iax2_firmware_header::version.
Referenced by update_registry().
03142 { 03143 int res = 0; 03144 struct iax_firmware *cur = NULL; 03145 03146 if (ast_strlen_zero(dev)) 03147 return 0; 03148 03149 AST_LIST_LOCK(&firmwares); 03150 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03151 if (!strcmp(dev, (char *)cur->fwh->devname)) { 03152 res = ntohs(cur->fwh->version); 03153 break; 03154 } 03155 } 03156 AST_LIST_UNLOCK(&firmwares); 03157 03158 return res; 03159 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 1115 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
01116 { 01117 if (iaxdebug) 01118 ast_verbose("%s", data); 01119 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 1121 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
01122 { 01123 ast_log(LOG_WARNING, "%s", data); 01124 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 3161 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, ast_iax2_firmware_header::devname, iax_firmware::fwh, iax_ie_append(), iax_ie_append_int(), iax_ie_append_raw(), IAX_IE_FWBLOCKDATA, IAX_IE_FWBLOCKDESC, and iax2_trunk_peer::list.
Referenced by socket_process().
03162 { 03163 int res = -1; 03164 unsigned int bs = desc & 0xff; 03165 unsigned int start = (desc >> 8) & 0xffffff; 03166 unsigned int bytes; 03167 struct iax_firmware *cur; 03168 03169 if (ast_strlen_zero((char *)dev) || !bs) 03170 return -1; 03171 03172 start *= bs; 03173 03174 AST_LIST_LOCK(&firmwares); 03175 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03176 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 03177 continue; 03178 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 03179 if (start < ntohl(cur->fwh->datalen)) { 03180 bytes = ntohl(cur->fwh->datalen) - start; 03181 if (bytes > bs) 03182 bytes = bs; 03183 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 03184 } else { 03185 bytes = 0; 03186 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 03187 } 03188 if (bytes == bs) 03189 res = 0; 03190 else 03191 res = 1; 03192 break; 03193 } 03194 AST_LIST_UNLOCK(&firmwares); 03195 03196 return res; 03197 }
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 1098 of file chan_iax2.c.
References debugaddr, f, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), and socket_process().
01099 { 01100 if (iaxdebug || 01101 (sin && debugaddr.sin_addr.s_addr && 01102 (!ntohs(debugaddr.sin_port) || 01103 debugaddr.sin_port == sin->sin_port) && 01104 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 01105 if (iaxdebug) { 01106 iax_showframe(f, fhi, rx, sin, datalen); 01107 } else { 01108 iaxdebug = 1; 01109 iax_showframe(f, fhi, rx, sin, datalen); 01110 iaxdebug = 0; 01111 } 01112 } 01113 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2, | |||
const char * | parkexten | |||
) | [static] |
Definition at line 9264 of file chan_iax2.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_channel::context, ast_channel::exten, iax_park_thread(), ast_channel::linkedid, LOG_WARNING, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
09265 { 09266 struct iax_dual *d; 09267 struct ast_channel *chan1m, *chan2m; 09268 pthread_t th; 09269 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 09270 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name); 09271 if (chan2m && chan1m) { 09272 /* Make formats okay */ 09273 chan1m->readformat = chan1->readformat; 09274 chan1m->writeformat = chan1->writeformat; 09275 ast_channel_masquerade(chan1m, chan1); 09276 /* Setup the extensions and such */ 09277 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 09278 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 09279 chan1m->priority = chan1->priority; 09280 09281 /* We make a clone of the peer channel too, so we can play 09282 back the announcement */ 09283 /* Make formats okay */ 09284 chan2m->readformat = chan2->readformat; 09285 chan2m->writeformat = chan2->writeformat; 09286 ast_channel_masquerade(chan2m, chan2); 09287 /* Setup the extensions and such */ 09288 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 09289 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 09290 chan2m->priority = chan2->priority; 09291 if (ast_do_masquerade(chan2m)) { 09292 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 09293 ast_hangup(chan2m); 09294 return -1; 09295 } 09296 } else { 09297 if (chan1m) 09298 ast_hangup(chan1m); 09299 if (chan2m) 09300 ast_hangup(chan2m); 09301 return -1; 09302 } 09303 if ((d = ast_calloc(1, sizeof(*d)))) { 09304 d->chan1 = chan1m; 09305 d->chan2 = chan2m; 09306 d->parkexten = parkexten; 09307 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) { 09308 return 0; 09309 } 09310 ast_free(d); 09311 } 09312 return -1; 09313 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 9244 of file chan_iax2.c.
References ast_free, ast_frfree, ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, ext, f, LOG_NOTICE, and iax_dual::parkexten.
Referenced by iax_park().
09245 { 09246 struct ast_channel *chan1, *chan2; 09247 struct iax_dual *d; 09248 struct ast_frame *f; 09249 int ext; 09250 int res; 09251 d = stuff; 09252 chan1 = d->chan1; 09253 chan2 = d->chan2; 09254 ast_free(d); 09255 f = ast_read(chan1); 09256 if (f) 09257 ast_frfree(f); 09258 res = ast_park_call(chan1, chan2, 0, d->parkexten, &ext); 09259 ast_hangup(chan2); 09260 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 09261 return NULL; 09262 }
Definition at line 1955 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().
01956 { 01957 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01958 if (new) { 01959 size_t afdatalen = new->afdatalen; 01960 memcpy(new, fr, sizeof(*new)); 01961 iax_frame_wrap(new, &fr->af); 01962 new->afdatalen = afdatalen; 01963 new->data = NULL; 01964 new->datalen = 0; 01965 new->direction = DIRECTION_INGRESS; 01966 new->retrans = -1; 01967 } 01968 return new; 01969 }
static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1380 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_THREAD_TYPE_DYNAMIC, iax2_trunk_peer::list, and thread.
Referenced by iax2_process_thread().
01381 { 01382 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01383 AST_LIST_LOCK(&dynamic_list); 01384 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01385 AST_LIST_UNLOCK(&dynamic_list); 01386 } else { 01387 AST_LIST_LOCK(&idle_list); 01388 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01389 AST_LIST_UNLOCK(&idle_list); 01390 } 01391 01392 return; 01393 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1150 of file chan_iax2.c.
References args, and ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01151 { 01152 va_list args; 01153 char buf[1024]; 01154 01155 va_start(args, fmt); 01156 vsnprintf(buf, sizeof(buf), fmt, args); 01157 va_end(args); 01158 01159 ast_verbose("%s", buf); 01160 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1126 of file chan_iax2.c.
References args, ast_log(), and LOG_ERROR.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01127 { 01128 va_list args; 01129 char buf[1024]; 01130 01131 va_start(args, fmt); 01132 vsnprintf(buf, sizeof(buf), fmt, args); 01133 va_end(args); 01134 01135 ast_log(LOG_ERROR, "%s", buf); 01136 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1138 of file chan_iax2.c.
References args, ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01139 { 01140 va_list args; 01141 char buf[1024]; 01142 01143 va_start(args, fmt); 01144 vsnprintf(buf, sizeof(buf), fmt, args); 01145 va_end(args); 01146 01147 ast_log(LOG_WARNING, "%s", buf); 01148 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 14575 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, iax2_registry::entry, 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, 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(), netsock, network_change_event_subscribe(), outsock, papp, peer_set_sock_cb(), peers, reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched, SENTINEL, set_config(), start_network_thread(), and timer.
14576 { 14577 static const char config[] = "iax.conf"; 14578 int x = 0; 14579 struct iax2_registry *reg = NULL; 14580 14581 if (load_objects()) { 14582 return AST_MODULE_LOAD_FAILURE; 14583 } 14584 14585 memset(iaxs, 0, sizeof(iaxs)); 14586 14587 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14588 ast_mutex_init(&iaxsl[x]); 14589 } 14590 14591 if (!(sched = ast_sched_thread_create())) { 14592 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 14593 return AST_MODULE_LOAD_FAILURE; 14594 } 14595 14596 if (!(io = io_context_create())) { 14597 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 14598 sched = ast_sched_thread_destroy(sched); 14599 return AST_MODULE_LOAD_FAILURE; 14600 } 14601 14602 if (!(netsock = ast_netsock_list_alloc())) { 14603 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 14604 io_context_destroy(io); 14605 sched = ast_sched_thread_destroy(sched); 14606 return AST_MODULE_LOAD_FAILURE; 14607 } 14608 ast_netsock_init(netsock); 14609 14610 outsock = ast_netsock_list_alloc(); 14611 if (!outsock) { 14612 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 14613 io_context_destroy(io); 14614 sched = ast_sched_thread_destroy(sched); 14615 return AST_MODULE_LOAD_FAILURE; 14616 } 14617 ast_netsock_init(outsock); 14618 14619 randomcalltokendata = ast_random(); 14620 14621 iax_set_output(iax_debug_output); 14622 iax_set_error(iax_error_output); 14623 jb_setoutput(jb_error_output, jb_warning_output, NULL); 14624 14625 if ((timer = ast_timer_open())) { 14626 ast_timer_set_rate(timer, trunkfreq); 14627 } 14628 14629 if (set_config(config, 0) == -1) { 14630 if (timer) { 14631 ast_timer_close(timer); 14632 } 14633 return AST_MODULE_LOAD_DECLINE; 14634 } 14635 14636 #ifdef TEST_FRAMEWORK 14637 AST_TEST_REGISTER(test_iax2_peers_get); 14638 AST_TEST_REGISTER(test_iax2_users_get); 14639 #endif 14640 14641 /* Register AstData providers */ 14642 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers)); 14643 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14644 14645 ast_register_application_xml(papp, iax2_prov_app); 14646 14647 ast_custom_function_register(&iaxpeer_function); 14648 ast_custom_function_register(&iaxvar_function); 14649 14650 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers); 14651 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list); 14652 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats); 14653 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry); 14654 14655 if (ast_channel_register(&iax2_tech)) { 14656 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 14657 __unload_module(); 14658 return AST_MODULE_LOAD_FAILURE; 14659 } 14660 14661 if (ast_register_switch(&iax2_switch)) { 14662 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 14663 } 14664 14665 if (start_network_thread()) { 14666 ast_log(LOG_ERROR, "Unable to start network thread\n"); 14667 __unload_module(); 14668 return AST_MODULE_LOAD_FAILURE; 14669 } else { 14670 ast_verb(2, "IAX Ready and Listening\n"); 14671 } 14672 14673 AST_LIST_LOCK(®istrations); 14674 AST_LIST_TRAVERSE(®istrations, reg, entry) 14675 iax2_do_register(reg); 14676 AST_LIST_UNLOCK(®istrations); 14677 14678 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 14679 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 14680 14681 14682 reload_firmware(0); 14683 iax_provision_reload(0); 14684 14685 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 14686 14687 network_change_event_subscribe(); 14688 14689 return AST_MODULE_LOAD_SUCCESS; 14690 }
static int load_objects | ( | void | ) | [static] |
Definition at line 14334 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(), callno_limits, calltoken_ignores, 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(), peercnts, peers, pvt_cmp_cb(), pvt_hash_cb(), TPS_REF_DEFAULT, transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), user_hash_cb(), and users.
Referenced by load_module().
14335 { 14336 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 14337 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 14338 14339 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 14340 goto container_fail; 14341 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 14342 goto container_fail; 14343 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 14344 goto container_fail; 14345 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 14346 goto container_fail; 14347 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 14348 goto container_fail; 14349 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14350 goto container_fail; 14351 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14352 goto container_fail; 14353 } else if (create_callno_pools()) { 14354 goto container_fail; 14355 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) { 14356 goto container_fail; 14357 } 14358 14359 return 0; 14360 14361 container_fail: 14362 if (peers) { 14363 ao2_ref(peers, -1); 14364 } 14365 if (users) { 14366 ao2_ref(users, -1); 14367 } 14368 if (iax_peercallno_pvts) { 14369 ao2_ref(iax_peercallno_pvts, -1); 14370 } 14371 if (iax_transfercallno_pvts) { 14372 ao2_ref(iax_transfercallno_pvts, -1); 14373 } 14374 if (peercnts) { 14375 ao2_ref(peercnts, -1); 14376 } 14377 if (callno_limits) { 14378 ao2_ref(callno_limits, -1); 14379 } 14380 if (calltoken_ignores) { 14381 ao2_ref(calltoken_ignores, -1); 14382 } 14383 if (callno_pool) { 14384 ao2_ref(callno_pool, -1); 14385 } 14386 if (callno_pool_trunk) { 14387 ao2_ref(callno_pool_trunk, -1); 14388 } 14389 return AST_MODULE_LOAD_FAILURE; 14390 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5412 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
05413 { 05414 ast_mutex_lock(&iaxsl[callno0]); 05415 while (ast_mutex_trylock(&iaxsl[callno1])) { 05416 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05417 } 05418 }
static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9385 of file chan_iax2.c.
References ast_debug, ast_mutex_lock, ast_mutex_unlock, ast_test_flag64, jb_info::current, iax_rr::delay, iax_rr::dropped, 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(), iax_rr::jitter, jb_info::jitter, iax_rr::losscnt, iax_rr::losspct, jb_info::losspct, manager_event, jb_info::min, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::pingtime, and chan_iax2_pvt::remote_rr.
Referenced by socket_process().
09386 { 09387 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09388 jb_info jbinfo; 09389 09390 ast_mutex_lock(&iaxsl[callno]); 09391 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 09392 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) { 09393 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09394 localjitter = jbinfo.jitter; 09395 localdelay = jbinfo.current - jbinfo.min; 09396 locallost = jbinfo.frames_lost; 09397 locallosspct = jbinfo.losspct/1000; 09398 localdropped = jbinfo.frames_dropped; 09399 localooo = jbinfo.frames_ooo; 09400 localpackets = jbinfo.frames_in; 09401 } 09402 ast_debug(3, "JB STATS:%s ping=%d ljitterms=%d ljbdelayms=%d ltotlost=%d lrecentlosspct=%d ldropped=%d looo=%d lrecvd=%d rjitterms=%d rjbdelayms=%d rtotlost=%d rrecentlosspct=%d rdropped=%d rooo=%d rrecvd=%d\n", 09403 iaxs[callno]->owner->name, 09404 iaxs[callno]->pingtime, 09405 localjitter, 09406 localdelay, 09407 locallost, 09408 locallosspct, 09409 localdropped, 09410 localooo, 09411 localpackets, 09412 iaxs[callno]->remote_rr.jitter, 09413 iaxs[callno]->remote_rr.delay, 09414 iaxs[callno]->remote_rr.losscnt, 09415 iaxs[callno]->remote_rr.losspct/1000, 09416 iaxs[callno]->remote_rr.dropped, 09417 iaxs[callno]->remote_rr.ooo, 09418 iaxs[callno]->remote_rr.packets); 09419 manager_event(EVENT_FLAG_REPORTING, "JitterBufStats", "Owner: %s\r\nPing: %d\r\nLocalJitter: %d\r\nLocalJBDelay: %d\r\nLocalTotalLost: %d\r\nLocalLossPercent: %d\r\nLocalDropped: %d\r\nLocalooo: %d\r\nLocalReceived: %d\r\nRemoteJitter: %d\r\nRemoteJBDelay: %d\r\nRemoteTotalLost: %d\r\nRemoteLossPercent: %d\r\nRemoteDropped: %d\r\nRemoteooo: %d\r\nRemoteReceived: %d\r\n", 09420 iaxs[callno]->owner->name, 09421 iaxs[callno]->pingtime, 09422 localjitter, 09423 localdelay, 09424 locallost, 09425 locallosspct, 09426 localdropped, 09427 localooo, 09428 localpackets, 09429 iaxs[callno]->remote_rr.jitter, 09430 iaxs[callno]->remote_rr.delay, 09431 iaxs[callno]->remote_rr.losscnt, 09432 iaxs[callno]->remote_rr.losspct/1000, 09433 iaxs[callno]->remote_rr.dropped, 09434 iaxs[callno]->remote_rr.ooo, 09435 iaxs[callno]->remote_rr.packets); 09436 } 09437 ast_mutex_unlock(&iaxsl[callno]); 09438 }
static int make_trunk | ( | unsigned short | callno, | |
int | locked | |||
) | [static] |
Definition at line 2035 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(), sched, send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), update_max_trunk(), and callno_entry::validated.
Referenced by iax2_request(), and socket_process().
02036 { 02037 int x; 02038 int res= 0; 02039 struct callno_entry *callno_entry; 02040 if (iaxs[callno]->oseqno) { 02041 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 02042 return -1; 02043 } 02044 if (callno & TRUNK_CALL_START) { 02045 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 02046 return -1; 02047 } 02048 02049 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 02050 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 02051 return -1; 02052 } 02053 02054 x = callno_entry->callno; 02055 ast_mutex_lock(&iaxsl[x]); 02056 02057 /*! 02058 * \note We delete these before switching the slot, because if 02059 * they fire in the meantime, they will generate a warning. 02060 */ 02061 ast_sched_thread_del(sched, iaxs[callno]->pingid); 02062 ast_sched_thread_del(sched, iaxs[callno]->lagid); 02063 iaxs[callno]->lagid = iaxs[callno]->pingid = -1; 02064 iaxs[x] = iaxs[callno]; 02065 iaxs[x]->callno = x; 02066 02067 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 02068 * before assigning the new one */ 02069 if (iaxs[x]->callno_entry) { 02070 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 02071 } 02072 iaxs[x]->callno_entry = callno_entry; 02073 02074 iaxs[callno] = NULL; 02075 /* Update the two timers that should have been started */ 02076 iaxs[x]->pingid = iax2_sched_add(sched, 02077 ping_time * 1000, send_ping, (void *)(long)x); 02078 iaxs[x]->lagid = iax2_sched_add(sched, 02079 lagrq_time * 1000, send_lagrq, (void *)(long)x); 02080 02081 if (locked) 02082 ast_mutex_unlock(&iaxsl[callno]); 02083 res = x; 02084 if (!locked) 02085 ast_mutex_unlock(&iaxsl[x]); 02086 02087 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 02088 /* We move this call from a non-trunked to a trunked call */ 02089 update_max_trunk(); 02090 update_max_nontrunk(); 02091 return res; 02092 }
static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 6902 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
06903 { 06904 ast_cli_netstats(s, -1, 0); 06905 astman_append(s, "\r\n"); 06906 return RESULT_SUCCESS; 06907 }
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 6965 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, iax2_peer::name, peer_status(), peer_unref(), peers, RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by load_module().
06966 { 06967 struct iax2_peer *peer = NULL; 06968 int peer_count = 0; 06969 char nm[20]; 06970 char status[20]; 06971 const char *id = astman_get_header(m,"ActionID"); 06972 char idtext[256] = ""; 06973 struct ast_str *encmethods = ast_str_alloca(256); 06974 struct ao2_iterator i; 06975 06976 if (!ast_strlen_zero(id)) 06977 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06978 06979 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 06980 06981 06982 i = ao2_iterator_init(peers, 0); 06983 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) { 06984 encmethods_to_str(peer->encmethods, encmethods); 06985 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 06986 if (!ast_strlen_zero(peer->username)) { 06987 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 06988 } else { 06989 astman_append(s, "ObjectName: %s\r\n", peer->name); 06990 } 06991 astman_append(s, "ChanObjectType: peer\r\n"); 06992 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr)); 06993 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06994 astman_append(s, "Mask: %s\r\n", nm); 06995 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr)); 06996 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 06997 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 06998 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 06999 peer_status(peer, status, sizeof(status)); 07000 astman_append(s, "Status: %s\r\n\r\n", status); 07001 peer_count++; 07002 } 07003 ao2_iterator_destroy(&i); 07004 07005 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 07006 return RESULT_SUCCESS; 07007 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
callback to display iax peers in manager
Definition at line 6941 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().
06942 { 06943 static const char * const a[] = { "iax2", "show", "peers" }; 06944 const char *id = astman_get_header(m,"ActionID"); 06945 char idtext[256] = ""; 06946 int total = 0; 06947 06948 if (!ast_strlen_zero(id)) 06949 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06950 06951 astman_send_listack(s, m, "Peer status list will follow", "start"); 06952 /* List the peers in separate manager events */ 06953 __iax2_show_peers(-1, &total, s, 3, a); 06954 /* Send final confirmation */ 06955 astman_append(s, 06956 "Event: PeerlistComplete\r\n" 06957 "EventList: Complete\r\n" 06958 "ListItems: %d\r\n" 06959 "%s" 06960 "\r\n", total, idtext); 06961 return 0; 06962 }
static int manager_iax2_show_registry | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 7073 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::entry, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.
Referenced by load_module().
07074 { 07075 const char *id = astman_get_header(m, "ActionID"); 07076 struct iax2_registry *reg = NULL; 07077 char idtext[256] = ""; 07078 char host[80] = ""; 07079 char perceived[80] = ""; 07080 int total = 0; 07081 07082 if (!ast_strlen_zero(id)) 07083 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07084 07085 astman_send_listack(s, m, "Registrations will follow", "start"); 07086 07087 AST_LIST_LOCK(®istrations); 07088 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07089 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07090 07091 if (reg->us.sin_addr.s_addr) { 07092 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07093 } else { 07094 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07095 } 07096 07097 astman_append(s, 07098 "Event: RegistryEntry\r\n" 07099 "%s" 07100 "Host: %s\r\n" 07101 "DNSmanager: %s\r\n" 07102 "Username: %s\r\n" 07103 "Perceived: %s\r\n" 07104 "Refresh: %d\r\n" 07105 "State: %s\r\n" 07106 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 07107 reg->refresh, regstate2str(reg->regstate)); 07108 07109 total++; 07110 } 07111 AST_LIST_UNLOCK(®istrations); 07112 07113 astman_append(s, 07114 "Event: RegistrationsComplete\r\n" 07115 "EventList: Complete\r\n" 07116 "ListItems: %d\r\n" 07117 "%s" 07118 "\r\n", total, idtext); 07119 07120 return 0; 07121 }
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 1984 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __find_callno(), 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(), and transfercallno_pvt_cmp_cb().
01985 { 01986 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01987 (cur->addr.sin_port == sin->sin_port)) { 01988 /* This is the main host */ 01989 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01990 (check_dcallno ? dcallno == cur->callno : 1) ) { 01991 /* That's us. Be sure we keep track of the peer call number */ 01992 return 1; 01993 } 01994 } 01995 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01996 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01997 /* We're transferring */ 01998 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01999 return 1; 02000 } 02001 return 0; 02002 }
static void memcpy_decrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_decrypt_key * | dcx | |||
) | [static] |
Definition at line 6155 of file chan_iax2.c.
References ast_aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
06156 { 06157 #if 0 06158 /* Debug with "fake encryption" */ 06159 int x; 06160 if (len % 16) 06161 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06162 for (x=0;x<len;x++) 06163 dst[x] = src[x] ^ 0xff; 06164 #else 06165 unsigned char lastblock[16] = { 0 }; 06166 int x; 06167 while(len > 0) { 06168 ast_aes_decrypt(src, dst, dcx); 06169 for (x=0;x<16;x++) 06170 dst[x] ^= lastblock[x]; 06171 memcpy(lastblock, src, sizeof(lastblock)); 06172 dst += 16; 06173 src += 16; 06174 len -= 16; 06175 } 06176 #endif 06177 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_encrypt_key * | ecx | |||
) | [static] |
Definition at line 6179 of file chan_iax2.c.
References ast_aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
06180 { 06181 #if 0 06182 /* Debug with "fake encryption" */ 06183 int x; 06184 if (len % 16) 06185 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06186 for (x=0;x<len;x++) 06187 dst[x] = src[x] ^ 0xff; 06188 #else 06189 unsigned char curblock[16] = { 0 }; 06190 int x; 06191 while(len > 0) { 06192 for (x=0;x<16;x++) 06193 curblock[x] ^= src[x]; 06194 ast_aes_encrypt(curblock, dst, ecx); 06195 memcpy(curblock, dst, sizeof(curblock)); 06196 dst += 16; 06197 src += 16; 06198 len -= 16; 06199 } 06200 #endif 06201 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 7745 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().
07746 { 07747 /* Select exactly one common encryption if there are any */ 07748 p->encmethods &= enc; 07749 if (p->encmethods) { 07750 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07751 p->keyrotateid = -2; 07752 } 07753 if (p->encmethods & IAX_ENCRYPT_AES128) 07754 p->encmethods = IAX_ENCRYPT_AES128; 07755 else 07756 p->encmethods = 0; 07757 } 07758 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 1274 of file chan_iax2.c.
01275 { 01276 /* The MWI subscriptions exist just so the core knows we care about those 01277 * mailboxes. However, we just grab the events out of the cache when it 01278 * is time to send MWI, since it is only sent with a REGACK. */ 01279 }
static void network_change_event_cb | ( | const struct ast_event * | , | |
void * | ||||
) | [static] |
Definition at line 1312 of file chan_iax2.c.
References ast_debug, iax2_sched_add(), network_change_event_sched_cb(), and sched.
Referenced by network_change_event_subscribe().
01313 { 01314 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n"); 01315 if (network_change_event_sched_id == -1) { 01316 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 01317 } 01318 01319 }
static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 1299 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_registry::entry, and iax2_do_register().
Referenced by network_change_event_cb().
01300 { 01301 struct iax2_registry *reg; 01302 network_change_event_sched_id = -1; 01303 AST_LIST_LOCK(®istrations); 01304 AST_LIST_TRAVERSE(®istrations, reg, entry) { 01305 iax2_do_register(reg); 01306 } 01307 AST_LIST_UNLOCK(®istrations); 01308 01309 return 0; 01310 }
static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 1281 of file chan_iax2.c.
References AST_EVENT_IE_END, AST_EVENT_NETWORK_CHANGE, ast_event_subscribe(), network_change_event_cb(), and network_change_event_subscription.
Referenced by load_module(), and set_config().
01282 { 01283 if (!network_change_event_subscription) { 01284 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 01285 network_change_event_cb, 01286 "SIP Network Change ", 01287 NULL, 01288 AST_EVENT_IE_END); 01289 } 01290 }
static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 1292 of file chan_iax2.c.
References ast_event_unsubscribe(), and network_change_event_subscription.
Referenced by __unload_module(), set_config(), and unload_module().
01293 { 01294 if (network_change_event_subscription) { 01295 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 01296 } 01297 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 12067 of file chan_iax2.c.
References ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), ast_timer_fd(), io, timer, and timing_read().
Referenced by start_network_thread().
12068 { 12069 if (timer) { 12070 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 12071 } 12072 12073 for (;;) { 12074 pthread_testcancel(); 12075 /* Wake up once a second just in case SIGURG was sent while 12076 * we weren't in poll(), to make sure we don't hang when trying 12077 * to unload. */ 12078 ast_io_wait(io, 1000); 12079 } 12080 12081 return NULL; 12082 }
static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
const char * | host | |||
) | [static] |
Definition at line 1913 of file chan_iax2.c.
References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, exten, jb_new(), jb_setconf(), jb_conf::max_contig_interp, jb_conf::max_jitterbuf, prefs, pvt_destructor(), jb_conf::resync_threshold, and jb_conf::target_extra.
Referenced by __find_callno().
01914 { 01915 struct chan_iax2_pvt *tmp; 01916 jb_conf jbconf; 01917 01918 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01919 return NULL; 01920 } 01921 01922 if (ast_string_field_init(tmp, 32)) { 01923 ao2_ref(tmp, -1); 01924 tmp = NULL; 01925 return NULL; 01926 } 01927 01928 tmp->prefs = prefs; 01929 tmp->pingid = -1; 01930 tmp->lagid = -1; 01931 tmp->autoid = -1; 01932 tmp->authid = -1; 01933 tmp->initid = -1; 01934 tmp->keyrotateid = -1; 01935 01936 ast_string_field_set(tmp,exten, "s"); 01937 ast_string_field_set(tmp,host, host); 01938 01939 tmp->jb = jb_new(); 01940 tmp->jbid = -1; 01941 jbconf.max_jitterbuf = maxjitterbuffer; 01942 jbconf.resync_threshold = resyncthreshold; 01943 jbconf.max_contig_interp = maxjitterinterps; 01944 jbconf.target_extra = jittertargetextra; 01945 jb_setconf(tmp->jb,&jbconf); 01946 01947 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 01948 01949 tmp->hold_signaling = 1; 01950 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 01951 01952 return tmp; 01953 }
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 |
The dial string format is: [username[:password]@]peer[:port][/exten[@context]][/options]
Definition at line 4944 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, strsep(), and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
04945 { 04946 if (ast_strlen_zero(data)) 04947 return; 04948 04949 pds->peer = strsep(&data, "/"); 04950 pds->exten = strsep(&data, "/"); 04951 pds->options = data; 04952 04953 if (pds->exten) { 04954 data = pds->exten; 04955 pds->exten = strsep(&data, "@"); 04956 pds->context = data; 04957 } 04958 04959 if (strchr(pds->peer, '@')) { 04960 data = pds->peer; 04961 pds->username = strsep(&data, "@"); 04962 pds->peer = data; 04963 } 04964 04965 if (pds->username) { 04966 data = pds->username; 04967 pds->username = strsep(&data, ":"); 04968 pds->password = data; 04969 } 04970 04971 data = pds->peer; 04972 pds->peer = strsep(&data, ":"); 04973 pds->port = data; 04974 04975 /* check for a key name wrapped in [] in the secret position, if found, 04976 move it to the key field instead 04977 */ 04978 if (pds->password && (pds->password[0] == '[')) { 04979 pds->key = ast_strip_quoted(pds->password, "[", "]"); 04980 pds->password = NULL; 04981 } 04982 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1656 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and iax2_peer::name.
Referenced by load_module(), and load_objects().
01657 { 01658 struct iax2_peer *peer = obj, *peer2 = arg; 01659 01660 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01661 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12811 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
12812 { 12813 struct iax2_peer *peer = obj; 12814 12815 ast_set_flag64(peer, IAX_DELME); 12816 12817 return 0; 12818 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 12243 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().
12244 { 12245 struct iax2_peer *peer = obj; 12246 int callno = peer->callno; 12247 12248 ast_free_ha(peer->ha); 12249 12250 if (callno > 0) { 12251 ast_mutex_lock(&iaxsl[callno]); 12252 iax2_destroy(callno); 12253 ast_mutex_unlock(&iaxsl[callno]); 12254 } 12255 12256 register_peer_exten(peer, 0); 12257 12258 if (peer->dnsmgr) 12259 ast_dnsmgr_release(peer->dnsmgr); 12260 12261 if (peer->mwi_event_sub) 12262 ast_event_unsubscribe(peer->mwi_event_sub); 12263 12264 ast_string_field_free_memory(peer); 12265 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1646 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_module(), and load_objects().
01647 { 01648 const struct iax2_peer *peer = obj; 01649 01650 return ast_str_hash(peer->name); 01651 }
Definition at line 1703 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(), reg_source_db(), socket_process(), and update_registry().
01704 { 01705 ao2_ref(peer, +1); 01706 return peer; 01707 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14288 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
14289 { 14290 struct iax2_peer *peer = obj; 14291 14292 if (peer->sockfd < 0) 14293 peer->sockfd = defaultsockfd; 14294 14295 return 0; 14296 }
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 12169 of file chan_iax2.c.
References 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, io, LOG_WARNING, iax2_peer::name, netsock, outsock, qos, socket_read(), iax2_peer::sockfd, and strsep().
Referenced by build_peer().
12170 { 12171 struct sockaddr_in sin; 12172 struct ast_sockaddr sin_tmp; 12173 int nonlocal = 1; 12174 int port = IAX_DEFAULT_PORTNO; 12175 int sockfd = defaultsockfd; 12176 char *tmp; 12177 char *addr; 12178 char *portstr; 12179 12180 if (!(tmp = ast_strdupa(srcaddr))) 12181 return -1; 12182 12183 addr = strsep(&tmp, ":"); 12184 portstr = tmp; 12185 12186 if (portstr) { 12187 port = atoi(portstr); 12188 if (port < 1) 12189 port = IAX_DEFAULT_PORTNO; 12190 } 12191 12192 if (!ast_get_ip(&sin_tmp, addr)) { 12193 struct ast_netsock *sock; 12194 int res; 12195 12196 ast_sockaddr_to_sin(&sin_tmp, &sin); 12197 sin.sin_port = 0; 12198 sin.sin_family = AF_INET; 12199 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 12200 if (res == 0) { 12201 /* ip address valid. */ 12202 sin.sin_port = htons(port); 12203 if (!(sock = ast_netsock_find(netsock, &sin))) 12204 sock = ast_netsock_find(outsock, &sin); 12205 if (sock) { 12206 sockfd = ast_netsock_sockfd(sock); 12207 nonlocal = 0; 12208 } else { 12209 unsigned int orig_saddr = sin.sin_addr.s_addr; 12210 /* INADDR_ANY matches anyway! */ 12211 sin.sin_addr.s_addr = INADDR_ANY; 12212 if (ast_netsock_find(netsock, &sin)) { 12213 sin.sin_addr.s_addr = orig_saddr; 12214 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 12215 if (sock) { 12216 sockfd = ast_netsock_sockfd(sock); 12217 ast_netsock_unref(sock); 12218 nonlocal = 0; 12219 } else { 12220 nonlocal = 2; 12221 } 12222 } 12223 } 12224 } 12225 } 12226 12227 peer->sockfd = sockfd; 12228 12229 if (nonlocal == 1) { 12230 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 12231 srcaddr, peer->name); 12232 return -1; 12233 } else if (nonlocal == 2) { 12234 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 12235 srcaddr, peer->name); 12236 return -1; 12237 } else { 12238 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 12239 return 0; 12240 } 12241 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3702 of file chan_iax2.c.
References ast_copy_string(), iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), _sip_show_peer(), _sip_show_peers(), function_iaxpeer(), function_sippeer(), handle_cli_iax2_show_peer(), manager_iax2_show_peer_list(), and peers_data_provider_get().
03703 { 03704 int res = 0; 03705 if (peer->maxms) { 03706 if (peer->lastms < 0) { 03707 ast_copy_string(status, "UNREACHABLE", statuslen); 03708 } else if (peer->lastms > peer->maxms) { 03709 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03710 res = 1; 03711 } else if (peer->lastms) { 03712 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03713 res = 1; 03714 } else { 03715 ast_copy_string(status, "UNKNOWN", statuslen); 03716 } 03717 } else { 03718 ast_copy_string(status, "Unmonitored", statuslen); 03719 res = -1; 03720 } 03721 return res; 03722 }
Definition at line 1709 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(), reg_source_db(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().
01710 { 01711 ao2_ref(peer, -1); 01712 return NULL; 01713 }
static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2332 of file chan_iax2.c.
References peercnt::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_debug, ast_inet_ntoa(), ast_log(), LOG_ERROR, OBJ_POINTER, peercnts, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
02333 { 02334 struct peercnt *peercnt; 02335 unsigned long addr = sin->sin_addr.s_addr; 02336 int res = 0; 02337 struct peercnt tmp = { 02338 .addr = addr, 02339 }; 02340 02341 /* Reasoning for peercnts container lock: Two identical ip addresses 02342 * could be added by different threads at the "same time". Without the container 02343 * lock, both threads could alloc space for the same object and attempt 02344 * to link to table. With the lock, one would create the object and link 02345 * to table while the other would find the already created peercnt object 02346 * rather than creating a new one. */ 02347 ao2_lock(peercnts); 02348 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02349 ao2_lock(peercnt); 02350 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02351 ao2_lock(peercnt); 02352 /* create and set defaults */ 02353 peercnt->addr = addr; 02354 set_peercnt_limit(peercnt); 02355 /* guarantees it does not go away after unlocking table 02356 * ao2_find automatically adds this */ 02357 ao2_link(peercnts, peercnt); 02358 } else { 02359 ao2_unlock(peercnts); 02360 return -1; 02361 } 02362 02363 /* check to see if the address has hit its callno limit. If not increment cur. */ 02364 if (peercnt->limit > peercnt->cur) { 02365 peercnt->cur++; 02366 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02367 } else { /* max num call numbers for this peer has been reached! */ 02368 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02369 res = -1; 02370 } 02371 02372 /* clean up locks and ref count */ 02373 ao2_unlock(peercnt); 02374 ao2_unlock(peercnts); 02375 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02376 02377 return res; 02378 }
static int peercnt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2162 of file chan_iax2.c.
References peercnt::addr, CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
02163 { 02164 struct peercnt *peercnt1 = obj, *peercnt2 = arg; 02165 return (peercnt1->addr == peercnt2->addr) ? CMP_MATCH | CMP_STOP : 0; 02166 }
static int peercnt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2156 of file chan_iax2.c.
References peercnt::addr.
Referenced by load_objects().
static void peercnt_modify | ( | unsigned char | reg, | |
uint16_t | limit, | |||
struct ast_sockaddr * | sockaddr | |||
) | [static] |
Definition at line 2299 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), ast_sockaddr_to_sin, peercnt::limit, OBJ_POINTER, peercnts, peercnt::reg, and set_peercnt_limit().
Referenced by __expire_registry(), build_peer(), and update_registry().
02300 { 02301 /* this function turns off and on custom callno limits set by peer registration */ 02302 struct peercnt *peercnt; 02303 struct peercnt tmp = { 02304 .addr = 0, 02305 }; 02306 struct sockaddr_in sin; 02307 02308 ast_sockaddr_to_sin(sockaddr, &sin); 02309 02310 tmp.addr = sin.sin_addr.s_addr; 02311 02312 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02313 peercnt->reg = reg; 02314 if (limit) { 02315 peercnt->limit = limit; 02316 } else { 02317 set_peercnt_limit(peercnt); 02318 } 02319 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin.sin_addr), peercnt->limit, peercnt->reg); 02320 ao2_ref(peercnt, -1); /* decrement ref from find */ 02321 } 02322 }
static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2384 of file chan_iax2.c.
References peercnt::addr, ao2_lock, ao2_unlink, ao2_unlock, ast_debug, ast_inet_ntoa(), peercnt::cur, and peercnts.
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
02385 { 02386 struct sockaddr_in sin = { 02387 .sin_addr.s_addr = peercnt->addr, 02388 }; 02389 02390 if (peercnt) { 02391 /* Container locked here since peercnt may be unlinked from list. If left unlocked, 02392 * peercnt_add could try and grab this entry from the table and modify it at the 02393 * "same time" this thread attemps to unlink it.*/ 02394 ao2_lock(peercnts); 02395 peercnt->cur--; 02396 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02397 /* if this was the last connection from the peer remove it from table */ 02398 if (peercnt->cur == 0) { 02399 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02400 } 02401 ao2_unlock(peercnts); 02402 } 02403 }
static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2423 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, OBJ_POINTER, peercnt_remove(), and peercnts.
Referenced by __find_callno(), and complete_transfer().
02424 { 02425 struct peercnt *peercnt; 02426 struct peercnt tmp = { 02427 .addr = sin->sin_addr.s_addr, 02428 }; 02429 02430 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02431 peercnt_remove(peercnt); 02432 ao2_ref(peercnt, -1); /* decrement ref from find */ 02433 } 02434 return 0; 02435 }
static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2409 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02410 { 02411 struct peercnt *peercnt = (struct peercnt *) obj; 02412 02413 peercnt_remove(peercnt); 02414 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02415 02416 return 0; 02417 }
static int peers_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 14422 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(), peers, and status.
14424 { 14425 struct ast_data *data_peer; 14426 struct iax2_peer *peer; 14427 struct ao2_iterator i; 14428 char status[20]; 14429 struct ast_str *encmethods = ast_str_alloca(256); 14430 14431 i = ao2_iterator_init(peers, 0); 14432 while ((peer = ao2_iterator_next(&i))) { 14433 data_peer = ast_data_add_node(data_root, "peer"); 14434 if (!data_peer) { 14435 peer_unref(peer); 14436 continue; 14437 } 14438 14439 ast_data_add_structure(iax2_peer, data_peer, peer); 14440 14441 ast_data_add_codecs(data_peer, "codecs", peer->capability); 14442 14443 peer_status(peer, status, sizeof(status)); 14444 ast_data_add_str(data_peer, "status", status); 14445 14446 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr)); 14447 14448 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask)); 14449 14450 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr)); 14451 14452 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK)); 14453 14454 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC)); 14455 14456 encmethods_to_str(peer->encmethods, encmethods); 14457 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no"); 14458 14459 peer_unref(peer); 14460 14461 if (!ast_data_search_match(search, data_peer)) { 14462 ast_data_remove_node(data_root, data_peer); 14463 } 14464 } 14465 ao2_iterator_destroy(&i); 14466 14467 return 0; 14468 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 13377 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, iax2_poke_peer(), peer_unref(), and peers.
Referenced by reload_config().
13378 { 13379 struct ao2_iterator i; 13380 struct iax2_peer *peer; 13381 13382 i = ao2_iterator_init(peers, 0); 13383 while ((peer = ao2_iterator_next(&i))) { 13384 iax2_poke_peer(peer, 0); 13385 peer_unref(peer); 13386 } 13387 ao2_iterator_destroy(&i); 13388 }
static int prune_addr_range_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2288 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02289 { 02290 struct addr_range *addr_range = obj; 02291 02292 return addr_range->delme ? CMP_MATCH : 0; 02293 }
static void prune_peers | ( | void | ) | [static] |
Definition at line 12874 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), peers, and unlink_peer().
12875 { 12876 struct iax2_peer *peer; 12877 struct ao2_iterator i; 12878 12879 i = ao2_iterator_init(peers, 0); 12880 while ((peer = ao2_iterator_next(&i))) { 12881 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 12882 unlink_peer(peer); 12883 } 12884 peer_unref(peer); 12885 } 12886 ao2_iterator_destroy(&i); 12887 }
static void prune_users | ( | void | ) | [static] |
Definition at line 12858 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_test_flag64, IAX_DELME, IAX_RTCACHEFRIENDS, user, user_unref(), and users.
Referenced by handle_cli_iax2_prune_realtime(), and reload_config().
12859 { 12860 struct iax2_user *user; 12861 struct ao2_iterator i; 12862 12863 i = ao2_iterator_init(users, 0); 12864 while ((user = ao2_iterator_next(&i))) { 12865 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 12866 ao2_unlink(users, user); 12867 } 12868 user_unref(user); 12869 } 12870 ao2_iterator_destroy(&i); 12871 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14305 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
14306 { 14307 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14308 14309 /* The frames_received field is used to hold whether we're matching 14310 * against a full frame or not ... */ 14311 14312 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 14313 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14314 }
static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1866 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, frame_queue, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, iaxsl, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, iax2_trunk_peer::list, iax2_trunk_peer::next, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, sched_delay_remove(), chan_iax2_pvt::signaling_queue, and chan_iax2_pvt::vars.
01867 { 01868 struct chan_iax2_pvt *pvt = obj; 01869 struct iax_frame *cur = NULL; 01870 struct signaling_queue_entry *s = NULL; 01871 01872 ast_mutex_lock(&iaxsl[pvt->callno]); 01873 01874 iax2_destroy_helper(pvt); 01875 01876 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01877 pvt->callno_entry = NULL; 01878 01879 /* Already gone */ 01880 ast_set_flag64(pvt, IAX_ALREADYGONE); 01881 01882 AST_LIST_TRAVERSE(&frame_queue[pvt->callno], cur, list) { 01883 /* Cancel any pending transmissions */ 01884 cur->retries = -1; 01885 } 01886 01887 ast_mutex_unlock(&iaxsl[pvt->callno]); 01888 01889 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01890 free_signaling_queue_entry(s); 01891 } 01892 01893 if (pvt->reg) { 01894 pvt->reg->callno = 0; 01895 } 01896 01897 if (!pvt->owner) { 01898 jb_frame frame; 01899 if (pvt->vars) { 01900 ast_variables_destroy(pvt->vars); 01901 pvt->vars = NULL; 01902 } 01903 01904 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01905 iax2_frame_free(frame.data); 01906 } 01907 01908 jb_destroy(pvt->jb); 01909 ast_string_field_free_memory(pvt); 01910 } 01911 }
static int pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14298 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
14299 { 14300 const struct chan_iax2_pvt *pvt = obj; 14301 14302 return pvt->peercallno; 14303 }
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 1842 of file chan_iax2.c.
References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_trunk_peer::next, and chan_iax2_pvt::signaling_queue.
Referenced by __send_command().
01843 { 01844 struct signaling_queue_entry *new; 01845 01846 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01847 return 1; /* do not queue this frame */ 01848 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01849 return -1; /* out of memory */ 01850 } 01851 01852 memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */ 01853 01854 if (new->f.datalen) { /* if there is data in this frame copy it over as well */ 01855 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) { 01856 free_signaling_queue_entry(new); 01857 return -1; 01858 } 01859 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr)); 01860 } 01861 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next); 01862 01863 return 0; 01864 }
static int raw_hangup | ( | struct sockaddr_in * | sin, | |
unsigned short | src, | |||
unsigned short | dst, | |||
int | sockfd | |||
) | [static] |
Definition at line 7726 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().
07727 { 07728 struct ast_iax2_full_hdr fh; 07729 fh.scallno = htons(src | IAX_FLAG_FULL); 07730 fh.dcallno = htons(dst); 07731 fh.ts = 0; 07732 fh.oseqno = 0; 07733 fh.iseqno = 0; 07734 fh.type = AST_FRAME_IAX; 07735 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07736 iax_outputframe(NULL, &fh, 0, sin, 0); 07737 #if 0 07738 if (option_debug) 07739 #endif 07740 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07741 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07742 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07743 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4305 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
04306 { 04307 struct ast_variable *var = NULL; 04308 struct ast_variable *tmp; 04309 struct iax2_peer *peer=NULL; 04310 time_t regseconds = 0, nowtime; 04311 int dynamic=0; 04312 04313 if (peername) { 04314 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04315 if (!var && sin) 04316 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04317 } else if (sin) { 04318 char porta[25]; 04319 sprintf(porta, "%d", ntohs(sin->sin_port)); 04320 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04321 if (var) { 04322 /* We'll need the peer name in order to build the structure! */ 04323 for (tmp = var; tmp; tmp = tmp->next) { 04324 if (!strcasecmp(tmp->name, "name")) 04325 peername = tmp->value; 04326 } 04327 } 04328 } 04329 if (!var && peername) { /* Last ditch effort */ 04330 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04331 /*!\note 04332 * If this one loaded something, then we need to ensure that the host 04333 * field matched. The only reason why we can't have this as a criteria 04334 * is because we only have the IP address and the host field might be 04335 * set as a name (and the reverse PTR might not match). 04336 */ 04337 if (var && sin) { 04338 for (tmp = var; tmp; tmp = tmp->next) { 04339 if (!strcasecmp(tmp->name, "host")) { 04340 struct ast_hostent ahp; 04341 struct hostent *hp; 04342 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04343 /* No match */ 04344 ast_variables_destroy(var); 04345 var = NULL; 04346 } 04347 break; 04348 } 04349 } 04350 } 04351 } 04352 if (!var) 04353 return NULL; 04354 04355 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04356 04357 if (!peer) { 04358 ast_variables_destroy(var); 04359 return NULL; 04360 } 04361 04362 for (tmp = var; tmp; tmp = tmp->next) { 04363 /* Make sure it's not a user only... */ 04364 if (!strcasecmp(tmp->name, "type")) { 04365 if (strcasecmp(tmp->value, "friend") && 04366 strcasecmp(tmp->value, "peer")) { 04367 /* Whoops, we weren't supposed to exist! */ 04368 peer = peer_unref(peer); 04369 break; 04370 } 04371 } else if (!strcasecmp(tmp->name, "regseconds")) { 04372 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04373 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04374 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE); 04375 } else if (!strcasecmp(tmp->name, "port")) { 04376 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value)); 04377 } else if (!strcasecmp(tmp->name, "host")) { 04378 if (!strcasecmp(tmp->value, "dynamic")) 04379 dynamic = 1; 04380 } 04381 } 04382 04383 ast_variables_destroy(var); 04384 04385 if (!peer) 04386 return NULL; 04387 04388 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04389 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04390 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) { 04391 if (peer->expire > -1) { 04392 if (!ast_sched_thread_del(sched, peer->expire)) { 04393 peer->expire = -1; 04394 peer_unref(peer); 04395 } 04396 } 04397 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04398 if (peer->expire == -1) 04399 peer_unref(peer); 04400 } 04401 ao2_link(peers, peer); 04402 if (ast_test_flag64(peer, IAX_DYNAMIC)) 04403 reg_source_db(peer); 04404 } else { 04405 ast_set_flag64(peer, IAX_TEMPONLY); 04406 } 04407 04408 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04409 time(&nowtime); 04410 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04411 memset(&peer->addr, 0, sizeof(peer->addr)); 04412 realtime_update_peer(peer->name, &peer->addr, 0); 04413 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04414 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04415 } 04416 else { 04417 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04418 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04419 } 04420 } 04421 04422 return peer; 04423 }
static void realtime_update_peer | ( | const char * | peername, | |
struct ast_sockaddr * | sockaddr, | |||
time_t | regtime | |||
) | [static] |
Definition at line 4496 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(), globalflags, IAX_RTSAVE_SYSNAME, and SENTINEL.
Referenced by __expire_registry(), update_peer(), and update_registry().
04497 { 04498 char port[10]; 04499 char regseconds[20]; 04500 const char *sysname = ast_config_AST_SYSTEM_NAME; 04501 char *syslabel = NULL; 04502 04503 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04504 sysname = NULL; 04505 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME)) 04506 syslabel = "regserver"; 04507 04508 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04509 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr)); 04510 ast_update_realtime("iaxpeers", "name", peername, 04511 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 04512 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */ 04513 }
static struct iax2_user * realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4425 of file chan_iax2.c.
References ahp, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
04426 { 04427 struct ast_variable *var; 04428 struct ast_variable *tmp; 04429 struct iax2_user *user=NULL; 04430 04431 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04432 if (!var) 04433 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04434 if (!var && sin) { 04435 char porta[6]; 04436 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04437 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04438 if (!var) 04439 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04440 } 04441 if (!var) { /* Last ditch effort */ 04442 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04443 /*!\note 04444 * If this one loaded something, then we need to ensure that the host 04445 * field matched. The only reason why we can't have this as a criteria 04446 * is because we only have the IP address and the host field might be 04447 * set as a name (and the reverse PTR might not match). 04448 */ 04449 if (var) { 04450 for (tmp = var; tmp; tmp = tmp->next) { 04451 if (!strcasecmp(tmp->name, "host")) { 04452 struct ast_hostent ahp; 04453 struct hostent *hp; 04454 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04455 /* No match */ 04456 ast_variables_destroy(var); 04457 var = NULL; 04458 } 04459 break; 04460 } 04461 } 04462 } 04463 } 04464 if (!var) 04465 return NULL; 04466 04467 tmp = var; 04468 while(tmp) { 04469 /* Make sure it's not a peer only... */ 04470 if (!strcasecmp(tmp->name, "type")) { 04471 if (strcasecmp(tmp->value, "friend") && 04472 strcasecmp(tmp->value, "user")) { 04473 return NULL; 04474 } 04475 } 04476 tmp = tmp->next; 04477 } 04478 04479 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)); 04480 04481 ast_variables_destroy(var); 04482 04483 if (!user) 04484 return NULL; 04485 04486 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04487 ast_set_flag64(user, IAX_RTCACHEFRIENDS); 04488 ao2_link(users, user); 04489 } else { 04490 ast_set_flag64(user, IAX_TEMPONLY); 04491 } 04492 04493 return user; 04494 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8605 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, 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, iax2_peer::name, PARSE_PORT_REQUIRE, peer_ref(), peer_unref(), register_peer_exten(), and sched.
Referenced by build_peer(), set_config(), and temp_peer().
08606 { 08607 char data[80]; 08608 char *expiry; 08609 08610 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) { 08611 return; 08612 } 08613 08614 expiry = strrchr(data, ':'); 08615 if (!expiry) { 08616 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data); 08617 } 08618 *expiry++ = '\0'; 08619 08620 if (ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) { 08621 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data); 08622 return; 08623 } 08624 08625 p->expiry = atoi(expiry); 08626 08627 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name, 08628 ast_sockaddr_stringify(&p->addr), p->expiry); 08629 08630 iax2_poke_peer(p, 0); 08631 if (p->expire > -1) { 08632 if (!ast_sched_thread_del(sched, p->expire)) { 08633 p->expire = -1; 08634 peer_unref(p); 08635 } 08636 } 08637 08638 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08639 08640 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08641 if (p->expire == -1) { 08642 peer_unref(p); 08643 } 08644 08645 if (iax2_regfunk) { 08646 iax2_regfunk(p->name, 1); 08647 } 08648 08649 register_peer_exten(p, 1); 08650 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 8524 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, iax2_peer::name, iax2_peer::regexten, S_OR, and strsep().
Referenced by __expire_registry(), expire_register(), handle_response_peerpoke(), parse_register_contact(), peer_destructor(), reg_source_db(), sip_destroy_peer(), sip_poke_noanswer(), and update_registry().
08525 { 08526 char multi[256]; 08527 char *stringp, *ext; 08528 if (!ast_strlen_zero(regcontext)) { 08529 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08530 stringp = multi; 08531 while((ext = strsep(&stringp, "&"))) { 08532 if (onoff) { 08533 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08534 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08535 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08536 } else 08537 ast_context_remove_extension(regcontext, ext, 1, NULL); 08538 } 08539 } 08540 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 7900 of file chan_iax2.c.
References ast_apply_ha(), ast_check_signature(), ast_clear_flag, ast_copy_string(), 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, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iaxs, iaxsl, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, md5(), iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, iax_ies::refresh, iax_ies::rsa_result, iax2_peer::secret, secret, state, strsep(), and iax_ies::username.
Referenced by handle_request_register(), and socket_process().
07901 { 07902 char requeststr[256] = ""; 07903 char peer[256] = ""; 07904 char md5secret[256] = ""; 07905 char rsasecret[256] = ""; 07906 char secret[256] = ""; 07907 struct iax2_peer *p = NULL; 07908 struct ast_key *key; 07909 char *keyn; 07910 int x; 07911 int expire = 0; 07912 int res = -1; 07913 struct ast_sockaddr addr; 07914 07915 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07916 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 07917 if (ies->username) 07918 ast_copy_string(peer, ies->username, sizeof(peer)); 07919 if (ies->password) 07920 ast_copy_string(secret, ies->password, sizeof(secret)); 07921 if (ies->md5_result) 07922 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07923 if (ies->rsa_result) 07924 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07925 if (ies->refresh) 07926 expire = ies->refresh; 07927 07928 if (ast_strlen_zero(peer)) { 07929 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 07930 return -1; 07931 } 07932 07933 /* SLD: first call to lookup peer during registration */ 07934 ast_mutex_unlock(&iaxsl[callno]); 07935 p = find_peer(peer, 1); 07936 ast_mutex_lock(&iaxsl[callno]); 07937 if (!p || !iaxs[callno]) { 07938 if (iaxs[callno]) { 07939 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 07940 /* Anything, as long as it's non-blank */ 07941 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07942 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 07943 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 07944 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 07945 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 07946 * to be plaintext, indicating it is an authmethod used by other peers on the system. 07947 * 07948 * If none of these cases exist, res will be returned as 0 without authentication indicating 07949 * an AUTHREQ needs to be sent out. */ 07950 07951 if (ast_strlen_zero(iaxs[callno]->challenge) && 07952 !(!ast_strlen_zero(secret) && plaintext)) { 07953 /* by setting res to 0, an REGAUTH will be sent */ 07954 res = 0; 07955 } 07956 } 07957 if (authdebug && !p) 07958 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07959 goto return_unref; 07960 } 07961 07962 if (!ast_test_flag64(p, IAX_DYNAMIC)) { 07963 if (authdebug) 07964 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07965 goto return_unref; 07966 } 07967 07968 ast_sockaddr_from_sin(&addr, sin); 07969 if (!ast_apply_ha(p->ha, &addr)) { 07970 if (authdebug) 07971 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 07972 goto return_unref; 07973 } 07974 ast_string_field_set(iaxs[callno], secret, p->secret); 07975 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 07976 /* Check secret against what we have on file */ 07977 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 07978 if (!ast_strlen_zero(p->inkeys)) { 07979 char tmpkeys[256]; 07980 char *stringp=NULL; 07981 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 07982 stringp=tmpkeys; 07983 keyn = strsep(&stringp, ":"); 07984 while(keyn) { 07985 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07986 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 07987 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07988 break; 07989 } else if (!key) 07990 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 07991 keyn = strsep(&stringp, ":"); 07992 } 07993 if (!keyn) { 07994 if (authdebug) 07995 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 07996 goto return_unref; 07997 } 07998 } else { 07999 if (authdebug) 08000 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 08001 goto return_unref; 08002 } 08003 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08004 struct MD5Context md5; 08005 unsigned char digest[16]; 08006 char *tmppw, *stringp; 08007 08008 tmppw = ast_strdupa(p->secret); 08009 stringp = tmppw; 08010 while((tmppw = strsep(&stringp, ";"))) { 08011 MD5Init(&md5); 08012 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 08013 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08014 MD5Final(digest, &md5); 08015 for (x=0;x<16;x++) 08016 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 08017 if (!strcasecmp(requeststr, md5secret)) 08018 break; 08019 } 08020 if (tmppw) { 08021 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08022 } else { 08023 if (authdebug) 08024 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 08025 goto return_unref; 08026 } 08027 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 08028 /* They've provided a plain text password and we support that */ 08029 if (strcmp(secret, p->secret)) { 08030 if (authdebug) 08031 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08032 goto return_unref; 08033 } else 08034 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08035 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 08036 /* if challenge has been sent, but no challenge response if given, reject. */ 08037 goto return_unref; 08038 } 08039 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08040 08041 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 08042 res = 0; 08043 08044 return_unref: 08045 if (iaxs[callno]) { 08046 ast_string_field_set(iaxs[callno], peer, peer); 08047 08048 /* Choose lowest expiry number */ 08049 if (expire && (expire < iaxs[callno]->expiry)) { 08050 iaxs[callno]->expiry = expire; 08051 } 08052 } 08053 08054 if (p) { 08055 peer_unref(p); 08056 } 08057 return res; 08058 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8826 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, 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(), and send_command().
Referenced by socket_process().
08827 { 08828 struct iax_ie_data ied; 08829 struct iax2_peer *p; 08830 char challenge[10]; 08831 const char *peer_name; 08832 int sentauthmethod; 08833 08834 peer_name = ast_strdupa(iaxs[callno]->peer); 08835 08836 /* SLD: third call to find_peer in registration */ 08837 ast_mutex_unlock(&iaxsl[callno]); 08838 if ((p = find_peer(peer_name, 1))) { 08839 last_authmethod = p->authmethods; 08840 } 08841 08842 ast_mutex_lock(&iaxsl[callno]); 08843 if (!iaxs[callno]) 08844 goto return_unref; 08845 08846 memset(&ied, 0, sizeof(ied)); 08847 /* The selection of which delayed reject is sent may leak information, 08848 * if it sets a static response. For example, if a host is known to only 08849 * use MD5 authentication, then an RSA response would indicate that the 08850 * peer does not exist, and vice-versa. 08851 * Therefore, we use whatever the last peer used (which may vary over the 08852 * course of a server, which should leak minimal information). */ 08853 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08854 if (!p) { 08855 iaxs[callno]->authmethods = sentauthmethod; 08856 } 08857 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08858 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08859 /* Build the challenge */ 08860 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08861 ast_string_field_set(iaxs[callno], challenge, challenge); 08862 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08863 } 08864 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08865 08866 return_unref: 08867 if (p) { 08868 peer_unref(p); 08869 } 08870 08871 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08872 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8874 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_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, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.
Referenced by socket_process().
08875 { 08876 struct iax2_registry *reg; 08877 /* Start pessimistic */ 08878 struct iax_ie_data ied; 08879 char peer[256] = ""; 08880 char challenge[256] = ""; 08881 int res; 08882 int authmethods = 0; 08883 if (ies->authmethods) 08884 authmethods = ies->authmethods; 08885 if (ies->username) 08886 ast_copy_string(peer, ies->username, sizeof(peer)); 08887 if (ies->challenge) 08888 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 08889 memset(&ied, 0, sizeof(ied)); 08890 reg = iaxs[callno]->reg; 08891 if (reg) { 08892 struct sockaddr_in reg_addr; 08893 08894 ast_sockaddr_to_sin(®->addr, ®_addr); 08895 08896 if (inaddrcmp(®_addr, sin)) { 08897 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08898 return -1; 08899 } 08900 if (ast_strlen_zero(reg->secret)) { 08901 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 08902 reg->regstate = REG_STATE_NOAUTH; 08903 return -1; 08904 } 08905 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08906 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08907 if (reg->secret[0] == '[') { 08908 char tmpkey[256]; 08909 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 08910 tmpkey[strlen(tmpkey) - 1] = '\0'; 08911 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 08912 } else 08913 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 08914 if (!res) { 08915 reg->regstate = REG_STATE_AUTHSENT; 08916 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 08917 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08918 } else 08919 return -1; 08920 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 08921 } else 08922 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 08923 return -1; 08924 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 7010 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_cli_iax2_show_registry(), handle_response_register(), manager_iax2_show_registry(), manager_show_registry(), sip_reg_timeout(), and sip_show_registry().
07011 { 07012 switch(regstate) { 07013 case REG_STATE_UNREGISTERED: 07014 return "Unregistered"; 07015 case REG_STATE_REGSENT: 07016 return "Request Sent"; 07017 case REG_STATE_AUTHSENT: 07018 return "Auth. Sent"; 07019 case REG_STATE_REGISTERED: 07020 return "Registered"; 07021 case REG_STATE_REJECTED: 07022 return "Rejected"; 07023 case REG_STATE_TIMEOUT: 07024 return "Timeout"; 07025 case REG_STATE_NOAUTH: 07026 return "No Authentication"; 07027 default: 07028 return "Unknown"; 07029 } 07030 }
static int reload | ( | void | ) | [static] |
Definition at line 13438 of file chan_iax2.c.
References reload_config().
13439 { 13440 return reload_config(); 13441 }
static int reload_config | ( | void | ) | [static] |
Definition at line 13389 of file chan_iax2.c.
References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), callno_limits, calltoken_ignores, config, debugaddr, iax2_registry::entry, iax2_do_register(), iax_provision_reload(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, peercnts, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), reload_firmware(), set_config(), and set_peercnt_limit_all_cb().
13390 { 13391 static const char config[] = "iax.conf"; 13392 struct iax2_registry *reg; 13393 13394 if (set_config(config, 1) > 0) { 13395 prune_peers(); 13396 prune_users(); 13397 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13398 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13399 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 13400 trunk_timed = trunk_untimed = 0; 13401 trunk_nmaxmtu = trunk_maxmtu = 0; 13402 memset(&debugaddr, '\0', sizeof(debugaddr)); 13403 13404 AST_LIST_LOCK(®istrations); 13405 AST_LIST_TRAVERSE(®istrations, reg, entry) 13406 iax2_do_register(reg); 13407 AST_LIST_UNLOCK(®istrations); 13408 13409 /* Qualify hosts, too */ 13410 poke_all_peers(); 13411 } 13412 13413 reload_firmware(0); 13414 iax_provision_reload(1); 13415 ast_unload_realtime("iaxpeers"); 13416 13417 return 0; 13418 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 3200 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, iax_firmware::dead, destroy_firmware(), errno, iax2_trunk_peer::list, LOG_WARNING, and try_firmware().
Referenced by __unload_module(), load_module(), and reload_config().
03201 { 03202 struct iax_firmware *cur = NULL; 03203 DIR *fwd; 03204 struct dirent *de; 03205 char dir[256], fn[256]; 03206 03207 AST_LIST_LOCK(&firmwares); 03208 03209 /* Mark all as dead */ 03210 AST_LIST_TRAVERSE(&firmwares, cur, list) 03211 cur->dead = 1; 03212 03213 /* Now that we have marked them dead... load new ones */ 03214 if (!unload) { 03215 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 03216 fwd = opendir(dir); 03217 if (fwd) { 03218 while((de = readdir(fwd))) { 03219 if (de->d_name[0] != '.') { 03220 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 03221 if (!try_firmware(fn)) { 03222 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 03223 } 03224 } 03225 } 03226 closedir(fwd); 03227 } else 03228 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 03229 } 03230 03231 /* Clean up leftovers */ 03232 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 03233 if (!cur->dead) 03234 continue; 03235 AST_LIST_REMOVE_CURRENT(list); 03236 destroy_firmware(cur); 03237 } 03238 AST_LIST_TRAVERSE_SAFE_END; 03239 03240 AST_LIST_UNLOCK(&firmwares); 03241 }
static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2123 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().
02124 { 02125 if (!pvt->peercallno) { 02126 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02127 return; 02128 } 02129 02130 ao2_unlink(iax_peercallno_pvts, pvt); 02131 }
static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2104 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().
02105 { 02106 if (!pvt->transfercallno) { 02107 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02108 return; 02109 } 02110 02111 ao2_unlink(iax_transfercallno_pvts, pvt); 02112 }
static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2632 of file chan_iax2.c.
References ao2_link, ao2_lock, ao2_ref, ao2_unlock, ast_log(), callno_entry::callno, LOG_ERROR, TRUNK_CALL_START, and callno_entry::validated.
Referenced by __find_callno(), make_trunk(), and sched_delay_remove().
02633 { 02634 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02635 02636 /* the callno_pool container is locked here primarily to ensure thread 02637 * safety of the total_nonval_callno_used check and decrement */ 02638 ao2_lock(callno_pool); 02639 02640 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02641 total_nonval_callno_used--; 02642 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02643 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02644 } 02645 02646 if (callno_entry->callno < TRUNK_CALL_START) { 02647 ao2_link(callno_pool, callno_entry); 02648 } else { 02649 ao2_link(callno_pool_trunk, callno_entry); 02650 } 02651 ao2_ref(callno_entry, -1); /* only container ref remains */ 02652 02653 ao2_unlock(callno_pool); 02654 return 0; 02655 }
static void requirecalltoken_mark_auto | ( | const char * | name, | |
int | subclass | |||
) | [static] |
Definition at line 4801 of file chan_iax2.c.
References ast_strlen_zero(), CALLTOKEN_AUTO, iax2_peer::calltoken_required, CALLTOKEN_YES, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), user, and user_unref().
Referenced by handle_call_token().
04802 { 04803 struct iax2_user *user = NULL; 04804 struct iax2_peer *peer = NULL; 04805 04806 if (ast_strlen_zero(name)) { 04807 return; /* no username given */ 04808 } 04809 04810 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04811 user->calltoken_required = CALLTOKEN_YES; 04812 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04813 peer->calltoken_required = CALLTOKEN_YES; 04814 } 04815 04816 if (peer) { 04817 peer_unref(peer); 04818 } 04819 if (user) { 04820 user_unref(user); 04821 } 04822 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4719 of file chan_iax2.c.
References chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_REMOVE, iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, f, frame_queue, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, iaxs, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, and send_command().
Referenced by socket_process().
04720 { 04721 struct chan_iax2_pvt *pvt = iaxs[callno]; 04722 int frametype = f->af.frametype; 04723 int subclass = f->af.subclass.integer; 04724 struct { 04725 struct ast_iax2_full_hdr fh; 04726 struct iax_ie_data ied; 04727 } data = { 04728 .ied.buf = { 0 }, 04729 .ied.pos = 0, 04730 }; 04731 /* total len - header len gives us the frame's IE len */ 04732 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04733 04734 if (!pvt) { 04735 return; /* this should not be possible if called from socket_process() */ 04736 } 04737 04738 /* 04739 * Check to make sure last frame sent is valid for call token resend 04740 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04741 * 2. Frame should _NOT_ already have a destination callno 04742 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04743 * 4. Pvt must have a calltoken_ie_len which represents the number of 04744 * bytes at the end of the frame used for the previous calltoken ie. 04745 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04746 * 6. Total length of f->data must be _LESS_ than size of our data struct 04747 * because f->data must be able to fit within data. 04748 */ 04749 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04750 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04751 (f->datalen > sizeof(data))) { 04752 04753 return; /* ignore resend, token was not valid for the dialog */ 04754 } 04755 04756 /* token is valid 04757 * 1. Copy frame data over 04758 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04759 * NOTE: Having the ie always be last is not protocol specified, 04760 * it is only an implementation choice. Since we only expect the ie to 04761 * be last for frames we have sent, this can no way be affected by 04762 * another end point. 04763 * 3. Remove frame from queue 04764 * 4. Free old frame 04765 * 5. Clear previous seqnos 04766 * 6. Resend with CALLTOKEN ie. 04767 */ 04768 04769 /* ---1.--- */ 04770 memcpy(&data, f->data, f->datalen); 04771 data.ied.pos = ie_data_pos; 04772 04773 /* ---2.--- */ 04774 /* move to the beginning of the calltoken ie so we can write over it */ 04775 data.ied.pos -= pvt->calltoken_ie_len; 04776 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04777 04778 /* make sure to update token length incase it ever has to be stripped off again */ 04779 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04780 04781 /* ---3.--- */ 04782 AST_LIST_REMOVE(&frame_queue[callno], f, list); 04783 04784 /* ---4.--- */ 04785 iax2_frame_free(f); 04786 04787 /* ---5.--- */ 04788 pvt->oseqno = 0; 04789 pvt->rseqno = 0; 04790 pvt->iseqno = 0; 04791 pvt->aseqno = 0; 04792 if (pvt->peercallno) { 04793 remove_by_peercallno(pvt); 04794 pvt->peercallno = 0; 04795 } 04796 04797 /* ---6.--- */ 04798 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04799 }
Definition at line 9355 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().
09356 { 09357 int i; 09358 unsigned int length, offset = 0; 09359 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09360 09361 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09362 length = ies->ospblocklength[i]; 09363 if (length != 0) { 09364 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09365 /* OSP token block length wrong, clear buffer */ 09366 offset = 0; 09367 break; 09368 } else { 09369 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09370 offset += length; 09371 } 09372 } else { 09373 break; 09374 } 09375 } 09376 *(full_osptoken + offset) = '\0'; 09377 if (strlen(full_osptoken) != offset) { 09378 /* OSP token length wrong, clear buffer */ 09379 *full_osptoken = '\0'; 09380 } 09381 09382 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09383 }
Definition at line 9344 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, iaxs, iax_rr::jitter, iax_rr::losscnt, iax_rr::losspct, iax_rr::ooo, iax_rr::packets, chan_iax2_pvt::remote_rr, 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().
09345 { 09346 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09347 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09348 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09349 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09350 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09351 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09352 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09353 }
static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
struct callno_entry * | callno_entry | |||
) | [static] |
Definition at line 2704 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), iax2_sched_add(), MIN_REUSE_TIME, OBJ_POINTER, peercnt_remove_cb(), peercnts, replace_callno(), and sched.
Referenced by pvt_destructor().
02705 { 02706 int i; 02707 struct peercnt *peercnt; 02708 struct peercnt tmp = { 02709 .addr = sin->sin_addr.s_addr, 02710 }; 02711 02712 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02713 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02714 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02715 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02716 if (i == -1) { 02717 ao2_ref(peercnt, -1); 02718 } 02719 } 02720 02721 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02722 }
static int schedule_delivery | ( | struct iax_frame * | fr, | |
int | updatehistory, | |||
int | fromtrunk, | |||
unsigned int * | tsout | |||
) | [static] |
IMPORTANT NOTE!!! Any time this function is used, even if iaxs[callno] was valid before calling it, it may no longer be valid after calling it.
Definition at line 4133 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::delivery, ast_frame::frametype, iax2_frame_free(), iax2_lock_owner(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, iaxs, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, sched, ast_frame::subclass, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process(), and socket_process_meta().
04134 { 04135 int type, len; 04136 int ret; 04137 int needfree = 0; 04138 struct ast_channel *owner = NULL; 04139 struct ast_channel *bridge = NULL; 04140 04141 /* Attempt to recover wrapped timestamps */ 04142 unwrap_timestamp(fr); 04143 04144 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 04145 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 04146 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 04147 else { 04148 #if 0 04149 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 04150 #endif 04151 fr->af.delivery = ast_tv(0,0); 04152 } 04153 04154 type = JB_TYPE_CONTROL; 04155 len = 0; 04156 04157 if(fr->af.frametype == AST_FRAME_VOICE) { 04158 type = JB_TYPE_VOICE; 04159 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000); 04160 } else if(fr->af.frametype == AST_FRAME_CNG) { 04161 type = JB_TYPE_SILENCE; 04162 } 04163 04164 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04165 if (tsout) 04166 *tsout = fr->ts; 04167 __do_deliver(fr); 04168 return -1; 04169 } 04170 04171 iax2_lock_owner(fr->callno); 04172 if (!iaxs[fr->callno]) { 04173 /* The call dissappeared so discard this frame that we could not send. */ 04174 iax2_frame_free(fr); 04175 return -1; 04176 } 04177 if ((owner = iaxs[fr->callno]->owner)) 04178 bridge = ast_bridged_channel(owner); 04179 04180 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04181 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04182 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04183 jb_frame frame; 04184 04185 ast_channel_unlock(owner); 04186 04187 /* deliver any frames in the jb */ 04188 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04189 __do_deliver(frame.data); 04190 /* __do_deliver() can make the call disappear */ 04191 if (!iaxs[fr->callno]) 04192 return -1; 04193 } 04194 04195 jb_reset(iaxs[fr->callno]->jb); 04196 04197 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid); 04198 04199 /* deliver this frame now */ 04200 if (tsout) 04201 *tsout = fr->ts; 04202 __do_deliver(fr); 04203 return -1; 04204 } 04205 if (owner) { 04206 ast_channel_unlock(owner); 04207 } 04208 04209 /* insert into jitterbuffer */ 04210 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04211 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04212 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04213 if (ret == JB_DROP) { 04214 needfree++; 04215 } else if (ret == JB_SCHED) { 04216 update_jbsched(iaxs[fr->callno]); 04217 } 04218 if (tsout) 04219 *tsout = fr->ts; 04220 if (needfree) { 04221 /* Free our iax frame */ 04222 iax2_frame_free(fr); 04223 return -1; 04224 } 04225 return 0; 04226 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1807 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().
01808 { 01809 unsigned short callno = PTR_TO_CALLNO(vid); 01810 ast_mutex_lock(&iaxsl[callno]); 01811 if (iaxs[callno]) { 01812 if (option_debug) { 01813 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01814 } 01815 iax2_destroy(callno); 01816 } 01817 ast_mutex_unlock(&iaxsl[callno]); 01818 return 0; 01819 }
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 4683 of file chan_iax2.c.
References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), f, and iax_ie_data::pos.
Referenced by handle_call_token(), and socket_process().
04686 { 04687 struct { 04688 struct ast_iax2_full_hdr f; 04689 struct iax_ie_data ied; 04690 } data; 04691 size_t size = sizeof(struct ast_iax2_full_hdr); 04692 04693 if (ied) { 04694 size += ied->pos; 04695 memcpy(&data.ied, ied->buf, ied->pos); 04696 } 04697 04698 data.f.scallno = htons(0x8000 | callno); 04699 data.f.dcallno = htons(dcallno); 04700 data.f.ts = htonl(ts); 04701 data.f.iseqno = seqno; 04702 data.f.oseqno = 0; 04703 data.f.type = AST_FRAME_IAX; 04704 data.f.csub = compress_subclass(command); 04705 04706 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04707 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7449 of file chan_iax2.c.
References __send_command().
Referenced by __attempt_transmit(), __send_lagrq(), __send_ping(), authenticate_reply(), authenticate_request(), cache_get_callno_locked(), dp_lookup(), iax2_call(), iax2_do_register(), iax2_dprequest(), iax2_indicate(), iax2_key_rotate(), iax2_poke_peer(), iax2_provision(), iax2_start_transfer(), registry_authrequest(), registry_rerequest(), resend_with_token(), send_command_locked(), and socket_process().
07450 { 07451 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07452 }
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 7468 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().
07469 { 07470 int call_num = i->callno; 07471 /* It is assumed that the callno has already been locked */ 07472 iax2_predestroy(i->callno); 07473 if (!iaxs[call_num]) 07474 return -1; 07475 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07476 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7478 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07479 { 07480 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07481 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7454 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().
07455 { 07456 int res; 07457 ast_mutex_lock(&iaxsl[callno]); 07458 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07459 ast_mutex_unlock(&iaxsl[callno]); 07460 return res; 07461 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 7483 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07484 { 07485 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07486 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1593 of file chan_iax2.c.
References __send_lagrq(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::lagid, and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01594 { 01595 int callno = (long) data; 01596 ast_mutex_lock(&iaxsl[callno]); 01597 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) { 01598 iaxs[callno]->lagid = -1; 01599 } 01600 ast_mutex_unlock(&iaxsl[callno]); 01601 01602 #ifdef SCHED_MULTITHREADED 01603 if (schedule_action(__send_lagrq, data)) 01604 #endif 01605 __send_lagrq(data); 01606 return 0; 01607 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3313 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_debug, ast_inet_ntoa(), errno, f, handle_error(), iax_showframe(), iaxs, chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, and chan_iax2_pvt::transfer.
Referenced by __attempt_transmit(), iax2_send(), transmit_frame(), and vnak_retransmit().
03314 { 03315 int res; 03316 int callno = f->callno; 03317 03318 /* Don't send if there was an error, but return error instead */ 03319 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03320 return -1; 03321 03322 /* Called with iaxsl held */ 03323 if (iaxdebug) 03324 ast_debug(3, "Sending %d on %d/%d to %s:%d\n", f->ts, callno, iaxs[callno]->peercallno, ast_inet_ntoa(iaxs[callno]->addr.sin_addr), ntohs(iaxs[callno]->addr.sin_port)); 03325 03326 if (f->transfer) { 03327 if (iaxdebug) 03328 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03329 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03330 } else { 03331 if (iaxdebug) 03332 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03333 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03334 } 03335 if (res < 0) { 03336 if (iaxdebug) 03337 ast_debug(1, "Received error: %s\n", strerror(errno)); 03338 handle_error(); 03339 } else 03340 res = 0; 03341 03342 return res; 03343 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1526 of file chan_iax2.c.
References __send_ping(), ast_mutex_lock, ast_mutex_unlock, iax2_thread::callno, DONT_RESCHEDULE, iaxs, iaxsl, chan_iax2_pvt::pingid, and schedule_action.
Referenced by __find_callno(), __send_ping(), do_monitor(), init_phone_step2(), and make_trunk().
01527 { 01528 int callno = (long) data; 01529 ast_mutex_lock(&iaxsl[callno]); 01530 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) { 01531 iaxs[callno]->pingid = -1; 01532 } 01533 ast_mutex_unlock(&iaxsl[callno]); 01534 01535 #ifdef SCHED_MULTITHREADED 01536 if (schedule_action(__send_ping, data)) 01537 #endif 01538 __send_ping(data); 01539 01540 return 0; 01541 }
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 1829 of file chan_iax2.c.
References AST_LIST_REMOVE_HEAD, signaling_queue_entry::f, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, iax2_send(), iax2_trunk_peer::next, and chan_iax2_pvt::signaling_queue.
Referenced by socket_process().
01830 { 01831 struct signaling_queue_entry *s = NULL; 01832 01833 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01834 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01835 free_signaling_queue_entry(s); 01836 } 01837 pvt->hold_signaling = 0; 01838 }
static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [static] |
Definition at line 9058 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, globalflags, 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().
09059 { 09060 int res = 0; 09061 struct iax_frame *fr; 09062 struct ast_iax2_meta_hdr *meta; 09063 struct ast_iax2_meta_trunk_hdr *mth; 09064 int calls = 0; 09065 09066 /* Point to frame */ 09067 fr = (struct iax_frame *)tpeer->trunkdata; 09068 /* Point to meta data */ 09069 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 09070 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 09071 if (tpeer->trunkdatalen) { 09072 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 09073 meta->zeros = 0; 09074 meta->metacmd = IAX_META_TRUNK; 09075 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) 09076 meta->cmddata = IAX_META_TRUNK_MINI; 09077 else 09078 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 09079 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 09080 /* And the rest of the ast_iax2 header */ 09081 fr->direction = DIRECTION_OUTGRESS; 09082 fr->retrans = -1; 09083 fr->transfer = 0; 09084 /* Any appropriate call will do */ 09085 fr->data = fr->afdata; 09086 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 09087 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 09088 calls = tpeer->calls; 09089 #if 0 09090 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)); 09091 #endif 09092 /* Reset transmit trunk side data */ 09093 tpeer->trunkdatalen = 0; 09094 tpeer->calls = 0; 09095 } 09096 if (res < 0) 09097 return res; 09098 return calls; 09099 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 12906 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_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), globalflags, 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, io, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, netsock, network_change_event_subscribe(), network_change_event_unsubscribe(), ast_variable::next, outsock, peer_unref(), peers, prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user, user_unref(), users, and ast_variable::value.
Referenced by load_module(), reload(), and reload_config().
12907 { 12908 struct ast_config *cfg, *ucfg; 12909 format_t capability = iax2_capability; 12910 struct ast_variable *v; 12911 char *cat; 12912 const char *utype; 12913 const char *tosval; 12914 int format; 12915 int portno = IAX_DEFAULT_PORTNO; 12916 int x; 12917 int mtuv; 12918 int subscribe_network_change = 1; 12919 struct iax2_user *user; 12920 struct iax2_peer *peer; 12921 struct ast_netsock *ns; 12922 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 12923 #if 0 12924 static unsigned short int last_port=0; 12925 #endif 12926 12927 cfg = ast_config_load(config_file, config_flags); 12928 12929 if (!cfg) { 12930 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 12931 return -1; 12932 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 12933 ucfg = ast_config_load("users.conf", config_flags); 12934 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 12935 return 0; 12936 /* Otherwise we need to reread both files */ 12937 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12938 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 12939 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 12940 ast_config_destroy(ucfg); 12941 return 0; 12942 } 12943 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 12944 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 12945 return 0; 12946 } else { /* iax.conf changed, gotta reread users.conf, too */ 12947 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12948 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 12949 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 12950 ast_config_destroy(cfg); 12951 return 0; 12952 } 12953 } 12954 12955 if (reload) { 12956 set_config_destroy(); 12957 } 12958 12959 /* Reset global codec prefs */ 12960 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 12961 12962 /* Reset Global Flags */ 12963 memset(&globalflags, 0, sizeof(globalflags)); 12964 ast_set_flag64(&globalflags, IAX_RTUPDATE); 12965 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 12966 12967 #ifdef SO_NO_CHECK 12968 nochecksums = 0; 12969 #endif 12970 /* Reset default parking lot */ 12971 default_parkinglot[0] = '\0'; 12972 12973 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12974 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12975 global_max_trunk_mtu = MAX_TRUNK_MTU; 12976 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 12977 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 12978 12979 maxauthreq = 3; 12980 12981 srvlookup = 0; 12982 12983 v = ast_variable_browse(cfg, "general"); 12984 12985 /* Seed initial tos value */ 12986 tosval = ast_variable_retrieve(cfg, "general", "tos"); 12987 if (tosval) { 12988 if (ast_str2tos(tosval, &qos.tos)) 12989 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 12990 } 12991 /* Seed initial cos value */ 12992 tosval = ast_variable_retrieve(cfg, "general", "cos"); 12993 if (tosval) { 12994 if (ast_str2cos(tosval, &qos.cos)) 12995 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 12996 } 12997 while(v) { 12998 if (!strcasecmp(v->name, "bindport")){ 12999 if (reload) 13000 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 13001 else 13002 portno = atoi(v->value); 13003 } else if (!strcasecmp(v->name, "pingtime")) 13004 ping_time = atoi(v->value); 13005 else if (!strcasecmp(v->name, "iaxthreadcount")) { 13006 if (reload) { 13007 if (atoi(v->value) != iaxthreadcount) 13008 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 13009 } else { 13010 iaxthreadcount = atoi(v->value); 13011 if (iaxthreadcount < 1) { 13012 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 13013 iaxthreadcount = 1; 13014 } else if (iaxthreadcount > 256) { 13015 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 13016 iaxthreadcount = 256; 13017 } 13018 } 13019 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 13020 if (reload) { 13021 AST_LIST_LOCK(&dynamic_list); 13022 iaxmaxthreadcount = atoi(v->value); 13023 AST_LIST_UNLOCK(&dynamic_list); 13024 } else { 13025 iaxmaxthreadcount = atoi(v->value); 13026 if (iaxmaxthreadcount < 0) { 13027 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 13028 iaxmaxthreadcount = 0; 13029 } else if (iaxmaxthreadcount > 256) { 13030 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 13031 iaxmaxthreadcount = 256; 13032 } 13033 } 13034 } else if (!strcasecmp(v->name, "nochecksums")) { 13035 #ifdef SO_NO_CHECK 13036 if (ast_true(v->value)) 13037 nochecksums = 1; 13038 else 13039 nochecksums = 0; 13040 #else 13041 if (ast_true(v->value)) 13042 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 13043 #endif 13044 } 13045 else if (!strcasecmp(v->name, "maxjitterbuffer")) 13046 maxjitterbuffer = atoi(v->value); 13047 else if (!strcasecmp(v->name, "resyncthreshold")) 13048 resyncthreshold = atoi(v->value); 13049 else if (!strcasecmp(v->name, "maxjitterinterps")) 13050 maxjitterinterps = atoi(v->value); 13051 else if (!strcasecmp(v->name, "jittertargetextra")) 13052 jittertargetextra = atoi(v->value); 13053 else if (!strcasecmp(v->name, "lagrqtime")) 13054 lagrq_time = atoi(v->value); 13055 else if (!strcasecmp(v->name, "maxregexpire")) 13056 max_reg_expire = atoi(v->value); 13057 else if (!strcasecmp(v->name, "minregexpire")) 13058 min_reg_expire = atoi(v->value); 13059 else if (!strcasecmp(v->name, "bindaddr")) { 13060 if (reload) { 13061 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 13062 } else { 13063 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 13064 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 13065 } else { 13066 if (strchr(v->value, ':')) 13067 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 13068 else 13069 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 13070 if (defaultsockfd < 0) 13071 defaultsockfd = ast_netsock_sockfd(ns); 13072 ast_netsock_unref(ns); 13073 } 13074 } 13075 } else if (!strcasecmp(v->name, "authdebug")) { 13076 authdebug = ast_true(v->value); 13077 } else if (!strcasecmp(v->name, "encryption")) { 13078 iax2_encryption |= get_encrypt_methods(v->value); 13079 if (!iax2_encryption) { 13080 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13081 } 13082 } else if (!strcasecmp(v->name, "forceencryption")) { 13083 if (ast_false(v->value)) { 13084 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13085 } else { 13086 iax2_encryption |= get_encrypt_methods(v->value); 13087 if (iax2_encryption) { 13088 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13089 } 13090 } 13091 } else if (!strcasecmp(v->name, "transfer")) { 13092 if (!strcasecmp(v->value, "mediaonly")) { 13093 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13094 } else if (ast_true(v->value)) { 13095 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13096 } else 13097 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13098 } else if (!strcasecmp(v->name, "codecpriority")) { 13099 if(!strcasecmp(v->value, "caller")) 13100 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST); 13101 else if(!strcasecmp(v->value, "disabled")) 13102 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13103 else if(!strcasecmp(v->value, "reqonly")) { 13104 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP); 13105 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13106 } 13107 } else if (!strcasecmp(v->name, "jitterbuffer")) 13108 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 13109 else if (!strcasecmp(v->name, "forcejitterbuffer")) 13110 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 13111 else if (!strcasecmp(v->name, "delayreject")) 13112 delayreject = ast_true(v->value); 13113 else if (!strcasecmp(v->name, "allowfwdownload")) 13114 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 13115 else if (!strcasecmp(v->name, "rtcachefriends")) 13116 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 13117 else if (!strcasecmp(v->name, "rtignoreregexpire")) 13118 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 13119 else if (!strcasecmp(v->name, "rtupdate")) 13120 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE); 13121 else if (!strcasecmp(v->name, "rtsavesysname")) 13122 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME); 13123 else if (!strcasecmp(v->name, "trunktimestamps")) 13124 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 13125 else if (!strcasecmp(v->name, "rtautoclear")) { 13126 int i = atoi(v->value); 13127 if(i > 0) 13128 global_rtautoclear = i; 13129 else 13130 i = 0; 13131 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 13132 } else if (!strcasecmp(v->name, "trunkfreq")) { 13133 trunkfreq = atoi(v->value); 13134 if (trunkfreq < 10) 13135 trunkfreq = 10; 13136 } else if (!strcasecmp(v->name, "trunkmtu")) { 13137 mtuv = atoi(v->value); 13138 if (mtuv == 0 ) 13139 global_max_trunk_mtu = 0; 13140 else if (mtuv >= 172 && mtuv < 4000) 13141 global_max_trunk_mtu = mtuv; 13142 else 13143 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 13144 mtuv, v->lineno); 13145 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 13146 trunkmaxsize = atoi(v->value); 13147 if (trunkmaxsize == 0) 13148 trunkmaxsize = MAX_TRUNKDATA; 13149 } else if (!strcasecmp(v->name, "autokill")) { 13150 if (sscanf(v->value, "%30d", &x) == 1) { 13151 if (x >= 0) 13152 autokill = x; 13153 else 13154 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 13155 } else if (ast_true(v->value)) { 13156 autokill = DEFAULT_MAXMS; 13157 } else { 13158 autokill = 0; 13159 } 13160 } else if (!strcasecmp(v->name, "bandwidth")) { 13161 if (!strcasecmp(v->value, "low")) { 13162 capability = IAX_CAPABILITY_LOWBANDWIDTH; 13163 } else if (!strcasecmp(v->value, "medium")) { 13164 capability = IAX_CAPABILITY_MEDBANDWIDTH; 13165 } else if (!strcasecmp(v->value, "high")) { 13166 capability = IAX_CAPABILITY_FULLBANDWIDTH; 13167 } else 13168 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 13169 } else if (!strcasecmp(v->name, "allow")) { 13170 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 13171 } else if (!strcasecmp(v->name, "disallow")) { 13172 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 13173 } else if (!strcasecmp(v->name, "register")) { 13174 iax2_register(v->value, v->lineno); 13175 } else if (!strcasecmp(v->name, "iaxcompat")) { 13176 iaxcompat = ast_true(v->value); 13177 } else if (!strcasecmp(v->name, "regcontext")) { 13178 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 13179 /* Create context if it doesn't exist already */ 13180 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 13181 } else if (!strcasecmp(v->name, "tos")) { 13182 if (ast_str2tos(v->value, &qos.tos)) 13183 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 13184 } else if (!strcasecmp(v->name, "cos")) { 13185 if (ast_str2cos(v->value, &qos.cos)) 13186 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 13187 } else if (!strcasecmp(v->name, "parkinglot")) { 13188 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 13189 } else if (!strcasecmp(v->name, "accountcode")) { 13190 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 13191 } else if (!strcasecmp(v->name, "mohinterpret")) { 13192 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 13193 } else if (!strcasecmp(v->name, "mohsuggest")) { 13194 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 13195 } else if (!strcasecmp(v->name, "amaflags")) { 13196 format = ast_cdr_amaflags2int(v->value); 13197 if (format < 0) { 13198 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13199 } else { 13200 amaflags = format; 13201 } 13202 } else if (!strcasecmp(v->name, "language")) { 13203 ast_copy_string(language, v->value, sizeof(language)); 13204 } else if (!strcasecmp(v->name, "maxauthreq")) { 13205 maxauthreq = atoi(v->value); 13206 if (maxauthreq < 0) 13207 maxauthreq = 0; 13208 } else if (!strcasecmp(v->name, "adsi")) { 13209 adsi = ast_true(v->value); 13210 } else if (!strcasecmp(v->name, "srvlookup")) { 13211 srvlookup = ast_true(v->value); 13212 } else if (!strcasecmp(v->name, "connectedline")) { 13213 if (ast_true(v->value)) { 13214 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13215 } else if (!strcasecmp(v->value, "send")) { 13216 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13217 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13218 } else if (!strcasecmp(v->value, "receive")) { 13219 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13220 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13221 } else { 13222 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13223 } 13224 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 13225 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 13226 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 13227 } 13228 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 13229 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 13230 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); 13231 } 13232 } else if (!strcasecmp(v->name, "calltokenoptional")) { 13233 if (add_calltoken_ignore(v->value)) { 13234 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 13235 } 13236 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 13237 if (ast_true(v->value)) { 13238 subscribe_network_change = 1; 13239 } else if (ast_false(v->value)) { 13240 subscribe_network_change = 0; 13241 } else { 13242 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 13243 } 13244 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 13245 if (ast_true(v->value)) { 13246 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13247 } else if (ast_false(v->value)) { 13248 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID); 13249 } else { 13250 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 13251 } 13252 }/*else if (strcasecmp(v->name,"type")) */ 13253 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13254 v = v->next; 13255 } 13256 13257 if (subscribe_network_change) { 13258 network_change_event_subscribe(); 13259 } else { 13260 network_change_event_unsubscribe(); 13261 } 13262 13263 if (defaultsockfd < 0) { 13264 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 13265 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 13266 } else { 13267 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 13268 defaultsockfd = ast_netsock_sockfd(ns); 13269 ast_netsock_unref(ns); 13270 } 13271 } 13272 if (reload) { 13273 ast_netsock_release(outsock); 13274 outsock = ast_netsock_list_alloc(); 13275 if (!outsock) { 13276 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13277 return -1; 13278 } 13279 ast_netsock_init(outsock); 13280 } 13281 13282 if (min_reg_expire > max_reg_expire) { 13283 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 13284 min_reg_expire, max_reg_expire, max_reg_expire); 13285 min_reg_expire = max_reg_expire; 13286 } 13287 iax2_capability = capability; 13288 13289 if (ucfg) { 13290 struct ast_variable *gen; 13291 int genhasiax; 13292 int genregisteriax; 13293 const char *hasiax, *registeriax; 13294 13295 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 13296 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 13297 gen = ast_variable_browse(ucfg, "general"); 13298 cat = ast_category_browse(ucfg, NULL); 13299 while (cat) { 13300 if (strcasecmp(cat, "general")) { 13301 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 13302 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 13303 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 13304 /* Start with general parameters, then specific parameters, user and peer */ 13305 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 13306 if (user) { 13307 ao2_link(users, user); 13308 user = user_unref(user); 13309 } 13310 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 13311 if (peer) { 13312 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13313 reg_source_db(peer); 13314 ao2_link(peers, peer); 13315 peer = peer_unref(peer); 13316 } 13317 } 13318 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 13319 char tmp[256]; 13320 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 13321 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 13322 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 13323 if (!host) 13324 host = ast_variable_retrieve(ucfg, "general", "host"); 13325 if (!username) 13326 username = ast_variable_retrieve(ucfg, "general", "username"); 13327 if (!secret) 13328 secret = ast_variable_retrieve(ucfg, "general", "secret"); 13329 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 13330 if (!ast_strlen_zero(secret)) 13331 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 13332 else 13333 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 13334 iax2_register(tmp, 0); 13335 } 13336 } 13337 } 13338 cat = ast_category_browse(ucfg, cat); 13339 } 13340 ast_config_destroy(ucfg); 13341 } 13342 13343 cat = ast_category_browse(cfg, NULL); 13344 while(cat) { 13345 if (strcasecmp(cat, "general")) { 13346 utype = ast_variable_retrieve(cfg, cat, "type"); 13347 if (!strcasecmp(cat, "callnumberlimits")) { 13348 build_callno_limits(ast_variable_browse(cfg, cat)); 13349 } else if (utype) { 13350 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 13351 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 13352 if (user) { 13353 ao2_link(users, user); 13354 user = user_unref(user); 13355 } 13356 } 13357 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 13358 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 13359 if (peer) { 13360 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13361 reg_source_db(peer); 13362 ao2_link(peers, peer); 13363 peer = peer_unref(peer); 13364 } 13365 } else if (strcasecmp(utype, "user")) { 13366 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 13367 } 13368 } else 13369 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 13370 } 13371 cat = ast_category_browse(cfg, cat); 13372 } 13373 ast_config_destroy(cfg); 13374 return 1; 13375 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 12889 of file chan_iax2.c.
References addr_range_delme_cb(), ao2_callback, ast_clear_flag64, callno_limits, calltoken_ignores, delete_users(), globalflags, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RECVCONNECTEDLINE, IAX_SENDCONNECTEDLINE, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, MAX_TRUNKDATA, and OBJ_NODATA.
Referenced by set_config().
12890 { 12891 strcpy(accountcode, ""); 12892 strcpy(language, ""); 12893 strcpy(mohinterpret, "default"); 12894 strcpy(mohsuggest, ""); 12895 trunkmaxsize = MAX_TRUNKDATA; 12896 amaflags = 0; 12897 delayreject = 0; 12898 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | 12899 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12900 delete_users(); 12901 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 12902 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 12903 }
static void set_hangup_source_and_cause | ( | int | callno, | |
unsigned char | causecode | |||
) | [static] |
Definition at line 9780 of file chan_iax2.c.
References ast_channel_unlock, ast_set_hangupsource(), ast_channel::hangupcause, iax2_lock_owner(), iaxs, and chan_iax2_pvt::owner.
Referenced by socket_process().
09781 { 09782 iax2_lock_owner(callno); 09783 if (iaxs[callno] && iaxs[callno]->owner) { 09784 if (causecode) { 09785 iaxs[callno]->owner->hangupcause = causecode; 09786 } 09787 ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0); 09788 ast_channel_unlock(iaxs[callno]->owner); 09789 } 09790 }
static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2248 of file chan_iax2.c.
References peercnt::addr, addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), callno_limits, addr_range::limit, peercnt::limit, and peercnt::reg.
Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().
02249 { 02250 uint16_t limit = global_maxcallno; 02251 struct addr_range *addr_range; 02252 struct sockaddr_in sin = { 02253 .sin_addr.s_addr = peercnt->addr, 02254 }; 02255 02256 02257 if (peercnt->reg && peercnt->limit) { 02258 return; /* this peercnt has a custom limit set by a registration */ 02259 } 02260 02261 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02262 limit = addr_range->limit; 02263 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02264 ao2_ref(addr_range, -1); 02265 } 02266 02267 peercnt->limit = limit; 02268 }
static int set_peercnt_limit_all_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 2274 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02275 { 02276 struct peercnt *peercnt = obj; 02277 02278 set_peercnt_limit(peercnt); 02279 ast_debug(1, "Reset limits for peercnts table\n"); 02280 02281 return 0; 02282 }
static void signal_condition | ( | ast_mutex_t * | lock, | |
ast_cond_t * | cond | |||
) | [static] |
Definition at line 1047 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().
01048 { 01049 ast_mutex_lock(lock); 01050 ast_cond_signal(cond); 01051 ast_mutex_unlock(lock); 01052 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 9792 of file chan_iax2.c.
References ast_aes_set_decrypt_key(), 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_unlock, ast_clear_flag, ast_clear_flag64, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_exists_extension(), AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_IAX, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_free, ast_getformatname(), ast_getformatname_multiple(), ast_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_event, ast_mutex_lock, ast_mutex_unlock, ast_parking_ext_valid(), ast_party_connected_line_free(), ast_party_connected_line_init(), ast_party_id_presentation(), ast_sched_thread_del, ast_set_callerid(), ast_set_flag, ast_set_flag64, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_test_flag64, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, calc_timestamp(), iax_ies::called_number, chan_iax2_pvt::calling_pres, iax_ies::callno, iax2_peer::callno, iax2_dpcache::callno, chan_iax2_pvt::callno, iax_ies::calltoken, iax_ies::calltokendata, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), cid_name, cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), connected, construct_rr(), ast_channel::context, context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, decrypt_frame(), iax_ies::devicetype, dp_lookup(), iax_ies::encmethods, ast_var_t::entries, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, f, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, frame_queue, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, globalflags, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_lock_owner(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), iax2_variable_datastore_info, iax2_vnak(), IAX_ALLOWFWDOWNLOAD, IAX_ALREADYGONE, IAX_AUTH_MD5, IAX_CALLENCRYPTED, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_COMMAND_ACCEPT, IAX_COMMAND_ACK, IAX_COMMAND_AUTHREP, IAX_COMMAND_AUTHREQ, IAX_COMMAND_CALLTOKEN, IAX_COMMAND_DIAL, IAX_COMMAND_DPREP, IAX_COMMAND_DPREQ, IAX_COMMAND_FWDATA, IAX_COMMAND_FWDOWNL, IAX_COMMAND_HANGUP, IAX_COMMAND_INVAL, IAX_COMMAND_LAGRP, IAX_COMMAND_LAGRQ, IAX_COMMAND_NEW, IAX_COMMAND_PING, IAX_COMMAND_POKE, IAX_COMMAND_PONG, IAX_COMMAND_QUELCH, IAX_COMMAND_REGACK, IAX_COMMAND_REGAUTH, IAX_COMMAND_REGREJ, IAX_COMMAND_REGREL, IAX_COMMAND_REGREQ, IAX_COMMAND_REJECT, IAX_COMMAND_RTKEY, IAX_COMMAND_TRANSFER, IAX_COMMAND_TXACC, IAX_COMMAND_TXCNT, IAX_COMMAND_TXMEDIA, IAX_COMMAND_TXREADY, IAX_COMMAND_TXREJ, IAX_COMMAND_TXREL, IAX_COMMAND_TXREQ, IAX_COMMAND_UNQUELCH, IAX_COMMAND_UNSUPPORT, IAX_COMMAND_VNAK, IAX_DEBUGDIGEST, IAX_DELAYPBXSTART, IAX_ENCRYPTED, iax_firmware_append(), IAX_FLAG_FULL, IAX_FLAG_RETRANS, IAX_FORCE_ENCRYPT, iax_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), iax_ie_append_versioned_uint64(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_FORMAT2, IAX_IE_IAX_UNKNOWN, IAX_IMMEDIATE, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_RECVCONNECTEDLINE, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), iaxs, iaxsl, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, iax_ies::musiconhold, iax2_peer::name, ast_channel::name, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, iax_frame::oseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, iax_ies::provver, iax_ies::provverpres, raw_hangup(), iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rseqno, S_COR, S_OR, save_osptoken(), save_rr(), sched, 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(), stop_stuff(), store_by_peercallno(), thread, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, uncompress_subclass(), update_registry(), iax_ies::username, 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().
09793 { 09794 struct sockaddr_in sin; 09795 int res; 09796 int updatehistory=1; 09797 int new = NEW_PREVENT; 09798 int dcallno = 0; 09799 char decrypted = 0; 09800 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09801 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09802 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09803 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09804 struct iax_frame *fr; 09805 struct iax_frame *cur; 09806 struct ast_frame f = { 0, }; 09807 struct ast_channel *c = NULL; 09808 struct iax2_dpcache *dp; 09809 struct iax2_peer *peer; 09810 struct iax_ies ies; 09811 struct iax_ie_data ied0, ied1; 09812 format_t format; 09813 int fd; 09814 int exists; 09815 int minivid = 0; 09816 char empty[32]=""; /* Safety measure */ 09817 struct iax_frame *duped_fr; 09818 char host_pref_buf[128]; 09819 char caller_pref_buf[128]; 09820 struct ast_codec_pref pref; 09821 char *using_prefs = "mine"; 09822 09823 /* allocate an iax_frame with 4096 bytes of data buffer */ 09824 fr = alloca(sizeof(*fr) + 4096); 09825 memset(fr, 0, sizeof(*fr)); 09826 fr->afdatalen = 4096; /* From alloca() above */ 09827 09828 /* Copy frequently used parameters to the stack */ 09829 res = thread->buf_len; 09830 fd = thread->iofd; 09831 memcpy(&sin, &thread->iosin, sizeof(sin)); 09832 09833 if (res < sizeof(*mh)) { 09834 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09835 return 1; 09836 } 09837 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09838 if (res < sizeof(*vh)) { 09839 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)); 09840 return 1; 09841 } 09842 09843 /* This is a video frame, get call number */ 09844 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 09845 minivid = 1; 09846 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 09847 return socket_process_meta(res, meta, &sin, fd, fr); 09848 09849 #ifdef DEBUG_SUPPORT 09850 if (res >= sizeof(*fh)) 09851 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 09852 #endif 09853 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09854 if (res < sizeof(*fh)) { 09855 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)); 09856 return 1; 09857 } 09858 09859 /* Get the destination call number */ 09860 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 09861 09862 09863 /* check to make sure this full frame isn't encrypted before we attempt 09864 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 09865 * callno is not found here, that just means one hasn't been allocated for 09866 * this connection yet. */ 09867 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 09868 ast_mutex_lock(&iaxsl[fr->callno]); 09869 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { 09870 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09871 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09872 ast_mutex_unlock(&iaxsl[fr->callno]); 09873 return 1; 09874 } 09875 decrypted = 1; 09876 } 09877 ast_mutex_unlock(&iaxsl[fr->callno]); 09878 } 09879 09880 /* Retrieve the type and subclass */ 09881 f.frametype = fh->type; 09882 if (f.frametype == AST_FRAME_VIDEO) { 09883 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 09884 } else if (f.frametype == AST_FRAME_VOICE) { 09885 f.subclass.codec = uncompress_subclass(fh->csub); 09886 } else { 09887 f.subclass.integer = uncompress_subclass(fh->csub); 09888 } 09889 09890 /* Deal with POKE/PONG without allocating a callno */ 09891 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) { 09892 /* Reply back with a PONG, but don't care about the result. */ 09893 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09894 return 1; 09895 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) { 09896 /* Ignore */ 09897 return 1; 09898 } 09899 09900 f.datalen = res - sizeof(*fh); 09901 if (f.datalen) { 09902 if (f.frametype == AST_FRAME_IAX) { 09903 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 09904 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 09905 ast_variables_destroy(ies.vars); 09906 return 1; 09907 } 09908 f.data.ptr = NULL; 09909 f.datalen = 0; 09910 } else { 09911 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 09912 memset(&ies, 0, sizeof(ies)); 09913 } 09914 } else { 09915 if (f.frametype == AST_FRAME_IAX) 09916 f.data.ptr = NULL; 09917 else 09918 f.data.ptr = empty; 09919 memset(&ies, 0, sizeof(ies)); 09920 } 09921 09922 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) { 09923 /* only set NEW_ALLOW if calltoken checks out */ 09924 if (handle_call_token(fh, &ies, &sin, fd)) { 09925 ast_variables_destroy(ies.vars); 09926 return 1; 09927 } 09928 09929 if (ies.calltoken && ies.calltokendata) { 09930 /* if we've gotten this far, and the calltoken ie data exists, 09931 * then calltoken validation _MUST_ have taken place. If calltoken 09932 * data is provided, it is always validated reguardless of any 09933 * calltokenoptional or requirecalltoken options */ 09934 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 09935 } else { 09936 new = NEW_ALLOW; 09937 } 09938 } 09939 } else { 09940 /* Don't know anything about it yet */ 09941 f.frametype = AST_FRAME_NULL; 09942 f.subclass.integer = 0; 09943 memset(&ies, 0, sizeof(ies)); 09944 } 09945 09946 if (!fr->callno) { 09947 int check_dcallno = 0; 09948 09949 /* 09950 * We enforce accurate destination call numbers for ACKs. This forces the other 09951 * end to know the destination call number before call setup can complete. 09952 * 09953 * Discussed in the following thread: 09954 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 09955 */ 09956 09957 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) { 09958 check_dcallno = 1; 09959 } 09960 09961 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 09962 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) { 09963 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09964 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) { 09965 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09966 } 09967 ast_variables_destroy(ies.vars); 09968 return 1; 09969 } 09970 } 09971 09972 if (fr->callno > 0) 09973 ast_mutex_lock(&iaxsl[fr->callno]); 09974 09975 if (!fr->callno || !iaxs[fr->callno]) { 09976 /* A call arrived for a nonexistent destination. Unless it's an "inval" 09977 frame, reply with an inval */ 09978 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09979 /* We can only raw hangup control frames */ 09980 if (((f.subclass.integer != IAX_COMMAND_INVAL) && 09981 (f.subclass.integer != IAX_COMMAND_TXCNT) && 09982 (f.subclass.integer != IAX_COMMAND_TXACC) && 09983 (f.subclass.integer != IAX_COMMAND_FWDOWNL))|| 09984 (f.frametype != AST_FRAME_IAX)) 09985 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 09986 fd); 09987 } 09988 if (fr->callno > 0) 09989 ast_mutex_unlock(&iaxsl[fr->callno]); 09990 ast_variables_destroy(ies.vars); 09991 return 1; 09992 } 09993 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 09994 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09995 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09996 ast_variables_destroy(ies.vars); 09997 ast_mutex_unlock(&iaxsl[fr->callno]); 09998 return 1; 09999 } 10000 decrypted = 1; 10001 } 10002 10003 #ifdef DEBUG_SUPPORT 10004 if (decrypted) { 10005 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 10006 } 10007 #endif 10008 10009 10010 /* count this frame */ 10011 iaxs[fr->callno]->frames_received++; 10012 10013 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 10014 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */ 10015 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */ 10016 unsigned short new_peercallno; 10017 10018 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 10019 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 10020 if (iaxs[fr->callno]->peercallno) { 10021 remove_by_peercallno(iaxs[fr->callno]); 10022 } 10023 iaxs[fr->callno]->peercallno = new_peercallno; 10024 store_by_peercallno(iaxs[fr->callno]); 10025 } 10026 } 10027 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10028 if (iaxdebug) 10029 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer); 10030 /* Check if it's out of order (and not an ACK or INVAL) */ 10031 fr->oseqno = fh->oseqno; 10032 fr->iseqno = fh->iseqno; 10033 fr->ts = ntohl(fh->ts); 10034 #ifdef IAXTESTS 10035 if (test_resync) { 10036 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 10037 fr->ts += test_resync; 10038 } 10039 #endif /* IAXTESTS */ 10040 #if 0 10041 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 10042 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 10043 (f.subclass == IAX_COMMAND_NEW || 10044 f.subclass == IAX_COMMAND_AUTHREQ || 10045 f.subclass == IAX_COMMAND_ACCEPT || 10046 f.subclass == IAX_COMMAND_REJECT)) ) ) 10047 #endif 10048 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 10049 updatehistory = 0; 10050 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 10051 (iaxs[fr->callno]->iseqno || 10052 ((f.subclass.integer != IAX_COMMAND_TXCNT) && 10053 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10054 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10055 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10056 (f.subclass.integer != IAX_COMMAND_TXACC)) || 10057 (f.frametype != AST_FRAME_IAX))) { 10058 if ( 10059 ((f.subclass.integer != IAX_COMMAND_ACK) && 10060 (f.subclass.integer != IAX_COMMAND_INVAL) && 10061 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10062 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10063 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10064 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10065 (f.subclass.integer != IAX_COMMAND_TXACC) && 10066 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10067 (f.frametype != AST_FRAME_IAX)) { 10068 /* If it's not an ACK packet, it's out of order. */ 10069 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 10070 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer); 10071 /* Check to see if we need to request retransmission, 10072 * and take sequence number wraparound into account */ 10073 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 10074 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 10075 if ((f.frametype != AST_FRAME_IAX) || 10076 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) { 10077 ast_debug(1, "Acking anyway\n"); 10078 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 10079 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 10080 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10081 } 10082 } else { 10083 /* Send a VNAK requesting retransmission */ 10084 iax2_vnak(fr->callno); 10085 } 10086 ast_variables_destroy(ies.vars); 10087 ast_mutex_unlock(&iaxsl[fr->callno]); 10088 return 1; 10089 } 10090 } else { 10091 /* Increment unless it's an ACK or VNAK */ 10092 if (((f.subclass.integer != IAX_COMMAND_ACK) && 10093 (f.subclass.integer != IAX_COMMAND_INVAL) && 10094 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10095 (f.subclass.integer != IAX_COMMAND_TXACC) && 10096 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10097 (f.frametype != AST_FRAME_IAX)) 10098 iaxs[fr->callno]->iseqno++; 10099 } 10100 /* Ensure text frames are NULL-terminated */ 10101 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 10102 if (res < thread->buf_size) 10103 thread->buf[res++] = '\0'; 10104 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 10105 thread->buf[res - 1] = '\0'; 10106 } 10107 10108 /* Handle implicit ACKing unless this is an INVAL, and only if this is 10109 from the real peer, not the transfer peer */ 10110 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10111 ((f.subclass.integer != IAX_COMMAND_INVAL) || 10112 (f.frametype != AST_FRAME_IAX))) { 10113 unsigned char x; 10114 int call_to_destroy; 10115 /* First we have to qualify that the ACKed value is within our window */ 10116 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 10117 x = fr->iseqno; 10118 else 10119 x = iaxs[fr->callno]->oseqno; 10120 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 10121 /* The acknowledgement is within our window. Time to acknowledge everything 10122 that it says to */ 10123 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 10124 /* Ack the packet with the given timestamp */ 10125 if (iaxdebug) 10126 ast_debug(1, "Cancelling transmission of packet %d\n", x); 10127 call_to_destroy = 0; 10128 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10129 /* If it's our call, and our timestamp, mark -1 retries */ 10130 if (x == cur->oseqno) { 10131 cur->retries = -1; 10132 /* Destroy call if this is the end */ 10133 if (cur->final) 10134 call_to_destroy = fr->callno; 10135 } 10136 } 10137 if (call_to_destroy) { 10138 if (iaxdebug) 10139 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 10140 ast_mutex_lock(&iaxsl[call_to_destroy]); 10141 iax2_destroy(call_to_destroy); 10142 ast_mutex_unlock(&iaxsl[call_to_destroy]); 10143 } 10144 } 10145 /* Note how much we've received acknowledgement for */ 10146 if (iaxs[fr->callno]) 10147 iaxs[fr->callno]->rseqno = fr->iseqno; 10148 else { 10149 /* Stop processing now */ 10150 ast_variables_destroy(ies.vars); 10151 ast_mutex_unlock(&iaxsl[fr->callno]); 10152 return 1; 10153 } 10154 } else { 10155 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 10156 } 10157 } 10158 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10159 ((f.frametype != AST_FRAME_IAX) || 10160 ((f.subclass.integer != IAX_COMMAND_TXACC) && 10161 (f.subclass.integer != IAX_COMMAND_TXCNT)))) { 10162 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 10163 ast_variables_destroy(ies.vars); 10164 ast_mutex_unlock(&iaxsl[fr->callno]); 10165 return 1; 10166 } 10167 10168 /* when we receive the first full frame for a new incoming channel, 10169 it is safe to start the PBX on the channel because we have now 10170 completed a 3-way handshake with the peer */ 10171 if ((f.frametype == AST_FRAME_VOICE) || 10172 (f.frametype == AST_FRAME_VIDEO) || 10173 (f.frametype == AST_FRAME_IAX)) { 10174 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 10175 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10176 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) { 10177 ast_variables_destroy(ies.vars); 10178 ast_mutex_unlock(&iaxsl[fr->callno]); 10179 return 1; 10180 } 10181 } 10182 10183 if (ies.vars) { 10184 struct ast_datastore *variablestore = NULL; 10185 struct ast_variable *var, *prev = NULL; 10186 AST_LIST_HEAD(, ast_var_t) *varlist; 10187 10188 iax2_lock_owner(fr->callno); 10189 if (!iaxs[fr->callno]) { 10190 ast_variables_destroy(ies.vars); 10191 ast_mutex_unlock(&iaxsl[fr->callno]); 10192 return 1; 10193 } 10194 if ((c = iaxs[fr->callno]->owner)) { 10195 varlist = ast_calloc(1, sizeof(*varlist)); 10196 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10197 10198 if (variablestore && varlist) { 10199 variablestore->data = varlist; 10200 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10201 AST_LIST_HEAD_INIT(varlist); 10202 ast_debug(1, "I can haz IAX vars?\n"); 10203 for (var = ies.vars; var; var = var->next) { 10204 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10205 if (prev) { 10206 ast_free(prev); 10207 } 10208 prev = var; 10209 if (!newvar) { 10210 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10211 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10212 } else { 10213 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10214 } 10215 } 10216 if (prev) { 10217 ast_free(prev); 10218 } 10219 ies.vars = NULL; 10220 ast_channel_datastore_add(c, variablestore); 10221 } else { 10222 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10223 if (variablestore) { 10224 ast_datastore_free(variablestore); 10225 } 10226 if (varlist) { 10227 ast_free(varlist); 10228 } 10229 } 10230 ast_channel_unlock(c); 10231 } else { 10232 /* No channel yet, so transfer the variables directly over to the pvt, 10233 * for later inheritance. */ 10234 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 10235 for (var = ies.vars; var && var->next; var = var->next); 10236 if (var) { 10237 var->next = iaxs[fr->callno]->iaxvars; 10238 iaxs[fr->callno]->iaxvars = ies.vars; 10239 ies.vars = NULL; 10240 } 10241 } 10242 } 10243 10244 if (ies.vars) { 10245 ast_debug(1, "I have IAX variables, but they were not processed\n"); 10246 } 10247 } 10248 10249 /* once we receive our first IAX Full Frame that is not CallToken related, send all 10250 * queued signaling frames that were being held. */ 10251 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 10252 send_signaling(iaxs[fr->callno]); 10253 } 10254 10255 if (f.frametype == AST_FRAME_VOICE) { 10256 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) { 10257 iaxs[fr->callno]->voiceformat = f.subclass.codec; 10258 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec)); 10259 if (iaxs[fr->callno]->owner) { 10260 iax2_lock_owner(fr->callno); 10261 if (iaxs[fr->callno]) { 10262 if (iaxs[fr->callno]->owner) { 10263 format_t orignative; 10264 10265 orignative = iaxs[fr->callno]->owner->nativeformats; 10266 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec; 10267 if (iaxs[fr->callno]->owner->readformat) 10268 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10269 iaxs[fr->callno]->owner->nativeformats = orignative; 10270 ast_channel_unlock(iaxs[fr->callno]->owner); 10271 } 10272 } else { 10273 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 10274 /* Free remote variables (if any) */ 10275 if (ies.vars) { 10276 ast_variables_destroy(ies.vars); 10277 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 10278 ies.vars = NULL; 10279 } 10280 ast_mutex_unlock(&iaxsl[fr->callno]); 10281 return 1; 10282 } 10283 } 10284 } 10285 } 10286 if (f.frametype == AST_FRAME_VIDEO) { 10287 if (f.subclass.codec != iaxs[fr->callno]->videoformat) { 10288 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL)); 10289 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL; 10290 } 10291 } 10292 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 10293 if (f.subclass.integer == AST_CONTROL_BUSY) { 10294 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 10295 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) { 10296 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 10297 } 10298 } 10299 if (f.frametype == AST_FRAME_IAX) { 10300 ast_sched_thread_del(sched, iaxs[fr->callno]->initid); 10301 /* Handle the IAX pseudo frame itself */ 10302 if (iaxdebug) 10303 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer); 10304 10305 /* Update last ts unless the frame's timestamp originated with us. */ 10306 if (iaxs[fr->callno]->last < fr->ts && 10307 f.subclass.integer != IAX_COMMAND_ACK && 10308 f.subclass.integer != IAX_COMMAND_PONG && 10309 f.subclass.integer != IAX_COMMAND_LAGRP) { 10310 iaxs[fr->callno]->last = fr->ts; 10311 if (iaxdebug) 10312 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10313 } 10314 iaxs[fr->callno]->last_iax_message = f.subclass.integer; 10315 if (!iaxs[fr->callno]->first_iax_message) { 10316 iaxs[fr->callno]->first_iax_message = f.subclass.integer; 10317 } 10318 switch(f.subclass.integer) { 10319 case IAX_COMMAND_ACK: 10320 /* Do nothing */ 10321 break; 10322 case IAX_COMMAND_QUELCH: 10323 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10324 /* Generate Manager Hold event, if necessary*/ 10325 if (iaxs[fr->callno]->owner) { 10326 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10327 "Status: On\r\n" 10328 "Channel: %s\r\n" 10329 "Uniqueid: %s\r\n", 10330 iaxs[fr->callno]->owner->name, 10331 iaxs[fr->callno]->owner->uniqueid); 10332 } 10333 10334 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH); 10335 if (ies.musiconhold) { 10336 iax2_lock_owner(fr->callno); 10337 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 10338 break; 10339 } 10340 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10341 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 10342 10343 /* 10344 * We already hold the owner lock so we do not 10345 * need to check iaxs[fr->callno] after it returns. 10346 */ 10347 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 10348 S_OR(moh_suggest, NULL), 10349 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 10350 } 10351 ast_channel_unlock(iaxs[fr->callno]->owner); 10352 } 10353 } 10354 break; 10355 case IAX_COMMAND_UNQUELCH: 10356 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10357 iax2_lock_owner(fr->callno); 10358 if (!iaxs[fr->callno]) { 10359 break; 10360 } 10361 /* Generate Manager Unhold event, if necessary */ 10362 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { 10363 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10364 "Status: Off\r\n" 10365 "Channel: %s\r\n" 10366 "Uniqueid: %s\r\n", 10367 iaxs[fr->callno]->owner->name, 10368 iaxs[fr->callno]->owner->uniqueid); 10369 } 10370 10371 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH); 10372 if (!iaxs[fr->callno]->owner) { 10373 break; 10374 } 10375 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10376 /* 10377 * We already hold the owner lock so we do not 10378 * need to check iaxs[fr->callno] after it returns. 10379 */ 10380 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10381 } 10382 ast_channel_unlock(iaxs[fr->callno]->owner); 10383 } 10384 break; 10385 case IAX_COMMAND_TXACC: 10386 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10387 /* Ack the packet with the given timestamp */ 10388 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10389 /* Cancel any outstanding txcnt's */ 10390 if (cur->transfer) { 10391 cur->retries = -1; 10392 } 10393 } 10394 memset(&ied1, 0, sizeof(ied1)); 10395 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10396 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10397 iaxs[fr->callno]->transferring = TRANSFER_READY; 10398 } 10399 break; 10400 case IAX_COMMAND_NEW: 10401 /* Ignore if it's already up */ 10402 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10403 break; 10404 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10405 ast_mutex_unlock(&iaxsl[fr->callno]); 10406 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10407 ast_mutex_lock(&iaxsl[fr->callno]); 10408 if (!iaxs[fr->callno]) { 10409 break; 10410 } 10411 } 10412 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10413 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) { 10414 int new_callno; 10415 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10416 fr->callno = new_callno; 10417 } 10418 /* For security, always ack immediately */ 10419 if (delayreject) 10420 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10421 if (check_access(fr->callno, &sin, &ies)) { 10422 /* They're not allowed on */ 10423 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10424 if (authdebug) 10425 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); 10426 break; 10427 } 10428 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10429 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10430 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10431 break; 10432 } 10433 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10434 const char *context, *exten, *cid_num; 10435 10436 context = ast_strdupa(iaxs[fr->callno]->context); 10437 exten = ast_strdupa(iaxs[fr->callno]->exten); 10438 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10439 10440 /* This might re-enter the IAX code and need the lock */ 10441 ast_mutex_unlock(&iaxsl[fr->callno]); 10442 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10443 ast_mutex_lock(&iaxsl[fr->callno]); 10444 10445 if (!iaxs[fr->callno]) { 10446 break; 10447 } 10448 } else 10449 exists = 0; 10450 /* Get OSP token if it does exist */ 10451 save_osptoken(fr, &ies); 10452 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10453 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10454 memset(&ied0, 0, sizeof(ied0)); 10455 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10456 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10457 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10458 if (!iaxs[fr->callno]) { 10459 break; 10460 } 10461 if (authdebug) 10462 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); 10463 } else { 10464 /* Select an appropriate format */ 10465 10466 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10467 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10468 using_prefs = "reqonly"; 10469 } else { 10470 using_prefs = "disabled"; 10471 } 10472 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10473 memset(&pref, 0, sizeof(pref)); 10474 strcpy(caller_pref_buf, "disabled"); 10475 strcpy(host_pref_buf, "disabled"); 10476 } else { 10477 using_prefs = "mine"; 10478 /* If the information elements are in here... use them */ 10479 if (ies.codec_prefs) 10480 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10481 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10482 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10483 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10484 pref = iaxs[fr->callno]->rprefs; 10485 using_prefs = "caller"; 10486 } else { 10487 pref = iaxs[fr->callno]->prefs; 10488 } 10489 } else 10490 pref = iaxs[fr->callno]->prefs; 10491 10492 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10493 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10494 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10495 } 10496 if (!format) { 10497 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10498 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10499 if (!format) { 10500 memset(&ied0, 0, sizeof(ied0)); 10501 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10502 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10503 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10504 if (!iaxs[fr->callno]) { 10505 break; 10506 } 10507 if (authdebug) { 10508 char tmp[256], tmp2[256], tmp3[256]; 10509 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10510 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 10511 ast_inet_ntoa(sin.sin_addr), 10512 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10513 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10514 } else { 10515 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10516 ast_inet_ntoa(sin.sin_addr), 10517 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10518 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10519 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10520 } 10521 } 10522 } else { 10523 /* Pick one... */ 10524 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10525 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10526 format = 0; 10527 } else { 10528 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10529 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10530 memset(&pref, 0, sizeof(pref)); 10531 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10532 strcpy(caller_pref_buf,"disabled"); 10533 strcpy(host_pref_buf,"disabled"); 10534 } else { 10535 using_prefs = "mine"; 10536 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10537 /* Do the opposite of what we tried above. */ 10538 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10539 pref = iaxs[fr->callno]->prefs; 10540 } else { 10541 pref = iaxs[fr->callno]->rprefs; 10542 using_prefs = "caller"; 10543 } 10544 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10545 } else /* if no codec_prefs IE do it the old way */ 10546 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10547 } 10548 } 10549 10550 if (!format) { 10551 char tmp[256], tmp2[256], tmp3[256]; 10552 memset(&ied0, 0, sizeof(ied0)); 10553 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10554 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10555 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 10556 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10557 if (!iaxs[fr->callno]) { 10558 break; 10559 } 10560 if (authdebug) { 10561 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10562 ast_inet_ntoa(sin.sin_addr), 10563 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10564 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10565 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10566 } 10567 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10568 break; 10569 } 10570 } 10571 } 10572 if (format) { 10573 /* No authentication required, let them in */ 10574 memset(&ied1, 0, sizeof(ied1)); 10575 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10576 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 10577 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10578 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10579 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10580 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10581 "%srequested format = %s,\n" 10582 "%srequested prefs = %s,\n" 10583 "%sactual format = %s,\n" 10584 "%shost prefs = %s,\n" 10585 "%spriority = %s\n", 10586 ast_inet_ntoa(sin.sin_addr), 10587 VERBOSE_PREFIX_4, 10588 ast_getformatname(iaxs[fr->callno]->peerformat), 10589 VERBOSE_PREFIX_4, 10590 caller_pref_buf, 10591 VERBOSE_PREFIX_4, 10592 ast_getformatname(format), 10593 VERBOSE_PREFIX_4, 10594 host_pref_buf, 10595 VERBOSE_PREFIX_4, 10596 using_prefs); 10597 10598 iaxs[fr->callno]->chosenformat = format; 10599 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10600 } else { 10601 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10602 /* If this is a TBD call, we're ready but now what... */ 10603 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10604 } 10605 } 10606 } 10607 break; 10608 } 10609 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10610 merge_encryption(iaxs[fr->callno],ies.encmethods); 10611 else 10612 iaxs[fr->callno]->encmethods = 0; 10613 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10614 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10615 break; 10616 case IAX_COMMAND_DPREQ: 10617 /* Request status in the dialplan */ 10618 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10619 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10620 if (iaxcompat) { 10621 /* Spawn a thread for the lookup */ 10622 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10623 } else { 10624 /* Just look it up */ 10625 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10626 } 10627 } 10628 break; 10629 case IAX_COMMAND_HANGUP: 10630 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10631 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10632 /* Set hangup cause according to remote and hangupsource */ 10633 if (iaxs[fr->callno]->owner) { 10634 set_hangup_source_and_cause(fr->callno, ies.causecode); 10635 if (!iaxs[fr->callno]) { 10636 break; 10637 } 10638 } 10639 10640 /* Send ack immediately, before we destroy */ 10641 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10642 iax2_destroy(fr->callno); 10643 break; 10644 case IAX_COMMAND_REJECT: 10645 /* Set hangup cause according to remote and hangup source */ 10646 if (iaxs[fr->callno]->owner) { 10647 set_hangup_source_and_cause(fr->callno, ies.causecode); 10648 if (!iaxs[fr->callno]) { 10649 break; 10650 } 10651 } 10652 10653 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10654 if (iaxs[fr->callno]->owner && authdebug) 10655 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10656 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10657 ies.cause ? ies.cause : "<Unknown>"); 10658 ast_debug(1, "Immediately destroying %d, having received reject\n", 10659 fr->callno); 10660 } 10661 /* Send ack immediately, before we destroy */ 10662 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10663 fr->ts, NULL, 0, fr->iseqno); 10664 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) 10665 iaxs[fr->callno]->error = EPERM; 10666 iax2_destroy(fr->callno); 10667 break; 10668 case IAX_COMMAND_TRANSFER: 10669 { 10670 struct ast_channel *bridged_chan; 10671 struct ast_channel *owner; 10672 10673 iax2_lock_owner(fr->callno); 10674 if (!iaxs[fr->callno]) { 10675 /* Initiating call went away before we could transfer. */ 10676 break; 10677 } 10678 owner = iaxs[fr->callno]->owner; 10679 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 10680 if (bridged_chan && ies.called_number) { 10681 ast_mutex_unlock(&iaxsl[fr->callno]); 10682 10683 /* Set BLINDTRANSFER channel variables */ 10684 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name); 10685 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name); 10686 10687 if (ast_parking_ext_valid(ies.called_number, c, iaxs[fr->callno]->context)) { 10688 ast_debug(1, "Parking call '%s'\n", bridged_chan->name); 10689 if (iax_park(bridged_chan, owner, ies.called_number)) { 10690 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 10691 bridged_chan->name); 10692 } 10693 ast_mutex_lock(&iaxsl[fr->callno]); 10694 } else { 10695 ast_mutex_lock(&iaxsl[fr->callno]); 10696 10697 if (iaxs[fr->callno]) { 10698 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, 10699 ies.called_number, 1)) { 10700 ast_log(LOG_WARNING, 10701 "Async goto of '%s' to '%s@%s' failed\n", 10702 bridged_chan->name, ies.called_number, 10703 iaxs[fr->callno]->context); 10704 } else { 10705 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", 10706 bridged_chan->name, ies.called_number, 10707 iaxs[fr->callno]->context); 10708 } 10709 } else { 10710 /* Initiating call went away before we could transfer. */ 10711 } 10712 } 10713 } else { 10714 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10715 } 10716 if (owner) { 10717 ast_channel_unlock(owner); 10718 } 10719 10720 break; 10721 } 10722 case IAX_COMMAND_ACCEPT: 10723 /* Ignore if call is already up or needs authentication or is a TBD */ 10724 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10725 break; 10726 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10727 /* Send ack immediately, before we destroy */ 10728 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10729 iax2_destroy(fr->callno); 10730 break; 10731 } 10732 if (ies.format) { 10733 iaxs[fr->callno]->peerformat = ies.format; 10734 } else { 10735 if (iaxs[fr->callno]->owner) 10736 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10737 else 10738 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10739 } 10740 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)); 10741 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10742 memset(&ied0, 0, sizeof(ied0)); 10743 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10744 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10745 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10746 if (!iaxs[fr->callno]) { 10747 break; 10748 } 10749 if (authdebug) { 10750 char tmp1[256], tmp2[256]; 10751 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n", 10752 ast_inet_ntoa(sin.sin_addr), 10753 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10754 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10755 } 10756 } else { 10757 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10758 iax2_lock_owner(fr->callno); 10759 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10760 /* Switch us to use a compatible format */ 10761 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 10762 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 10763 10764 /* Setup read/write formats properly. */ 10765 if (iaxs[fr->callno]->owner->writeformat) 10766 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 10767 if (iaxs[fr->callno]->owner->readformat) 10768 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10769 ast_channel_unlock(iaxs[fr->callno]->owner); 10770 } 10771 } 10772 if (iaxs[fr->callno]) { 10773 AST_LIST_LOCK(&dpcache); 10774 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10775 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10776 iax2_dprequest(dp, fr->callno); 10777 AST_LIST_UNLOCK(&dpcache); 10778 } 10779 break; 10780 case IAX_COMMAND_POKE: 10781 /* Send back a pong packet with the original timestamp */ 10782 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10783 break; 10784 case IAX_COMMAND_PING: 10785 { 10786 struct iax_ie_data pingied; 10787 construct_rr(iaxs[fr->callno], &pingied); 10788 /* Send back a pong packet with the original timestamp */ 10789 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10790 } 10791 break; 10792 case IAX_COMMAND_PONG: 10793 /* Calculate ping time */ 10794 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10795 /* save RR info */ 10796 save_rr(fr, &ies); 10797 10798 /* Good time to write jb stats for this call */ 10799 log_jitterstats(fr->callno); 10800 10801 if (iaxs[fr->callno]->peerpoke) { 10802 peer = iaxs[fr->callno]->peerpoke; 10803 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10804 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10805 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10806 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Reachable\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 10807 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */ 10808 } 10809 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10810 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10811 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10812 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Lagged\r\nTime: %d\r\n", peer->name, iaxs[fr->callno]->pingtime); 10813 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 10814 } 10815 } 10816 peer->lastms = iaxs[fr->callno]->pingtime; 10817 if (peer->smoothing && (peer->lastms > -1)) 10818 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10819 else if (peer->smoothing && peer->lastms < 0) 10820 peer->historicms = (0 + peer->historicms) / 2; 10821 else 10822 peer->historicms = iaxs[fr->callno]->pingtime; 10823 10824 /* Remove scheduled iax2_poke_noanswer */ 10825 if (peer->pokeexpire > -1) { 10826 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 10827 peer_unref(peer); 10828 peer->pokeexpire = -1; 10829 } 10830 } 10831 /* Schedule the next cycle */ 10832 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 10833 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10834 else 10835 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 10836 if (peer->pokeexpire == -1) 10837 peer_unref(peer); 10838 /* and finally send the ack */ 10839 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10840 /* And wrap up the qualify call */ 10841 iax2_destroy(fr->callno); 10842 peer->callno = 0; 10843 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 10844 } 10845 break; 10846 case IAX_COMMAND_LAGRQ: 10847 case IAX_COMMAND_LAGRP: 10848 f.src = "LAGRQ"; 10849 f.mallocd = 0; 10850 f.offset = 0; 10851 f.samples = 0; 10852 iax_frame_wrap(fr, &f); 10853 if (f.subclass.integer == IAX_COMMAND_LAGRQ) { 10854 /* Received a LAGRQ - echo back a LAGRP */ 10855 fr->af.subclass.integer = IAX_COMMAND_LAGRP; 10856 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 10857 } else { 10858 /* Received LAGRP in response to our LAGRQ */ 10859 unsigned int ts; 10860 /* This is a reply we've been given, actually measure the difference */ 10861 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 10862 iaxs[fr->callno]->lag = ts - fr->ts; 10863 if (iaxdebug) 10864 ast_debug(1, "Peer %s lag measured as %dms\n", 10865 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 10866 } 10867 break; 10868 case IAX_COMMAND_AUTHREQ: 10869 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10870 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>"); 10871 break; 10872 } 10873 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 10874 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 10875 .subclass.integer = AST_CONTROL_HANGUP, 10876 }; 10877 ast_log(LOG_WARNING, 10878 "I don't know how to authenticate %s to %s\n", 10879 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 10880 iax2_queue_frame(fr->callno, &hangup_fr); 10881 } 10882 break; 10883 case IAX_COMMAND_AUTHREP: 10884 /* For security, always ack immediately */ 10885 if (delayreject) 10886 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10887 /* Ignore once we've started */ 10888 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10889 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>"); 10890 break; 10891 } 10892 if (authenticate_verify(iaxs[fr->callno], &ies)) { 10893 if (authdebug) 10894 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); 10895 memset(&ied0, 0, sizeof(ied0)); 10896 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10897 break; 10898 } 10899 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10900 /* This might re-enter the IAX code and need the lock */ 10901 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 10902 } else 10903 exists = 0; 10904 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10905 if (authdebug) 10906 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); 10907 memset(&ied0, 0, sizeof(ied0)); 10908 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10909 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10910 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10911 if (!iaxs[fr->callno]) { 10912 break; 10913 } 10914 } else { 10915 /* Select an appropriate format */ 10916 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10917 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10918 using_prefs = "reqonly"; 10919 } else { 10920 using_prefs = "disabled"; 10921 } 10922 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10923 memset(&pref, 0, sizeof(pref)); 10924 strcpy(caller_pref_buf, "disabled"); 10925 strcpy(host_pref_buf, "disabled"); 10926 } else { 10927 using_prefs = "mine"; 10928 if (ies.codec_prefs) 10929 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10930 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10931 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10932 pref = iaxs[fr->callno]->rprefs; 10933 using_prefs = "caller"; 10934 } else { 10935 pref = iaxs[fr->callno]->prefs; 10936 } 10937 } else /* if no codec_prefs IE do it the old way */ 10938 pref = iaxs[fr->callno]->prefs; 10939 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10940 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10941 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10942 } 10943 if (!format) { 10944 char tmp1[256], tmp2[256], tmp3[256]; 10945 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10946 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n", 10947 ast_getformatname(iaxs[fr->callno]->peerformat), 10948 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability)); 10949 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10950 } 10951 if (!format) { 10952 if (authdebug) { 10953 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10954 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr), 10955 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10956 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10957 } else { 10958 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10959 ast_inet_ntoa(sin.sin_addr), 10960 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10961 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10962 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10963 } 10964 } 10965 memset(&ied0, 0, sizeof(ied0)); 10966 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10967 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10968 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10969 if (!iaxs[fr->callno]) { 10970 break; 10971 } 10972 } else { 10973 /* Pick one... */ 10974 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10975 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10976 format = 0; 10977 } else { 10978 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10979 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10980 memset(&pref, 0, sizeof(pref)); 10981 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 10982 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10983 strcpy(caller_pref_buf,"disabled"); 10984 strcpy(host_pref_buf,"disabled"); 10985 } else { 10986 using_prefs = "mine"; 10987 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10988 /* Do the opposite of what we tried above. */ 10989 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10990 pref = iaxs[fr->callno]->prefs; 10991 } else { 10992 pref = iaxs[fr->callno]->rprefs; 10993 using_prefs = "caller"; 10994 } 10995 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10996 } else /* if no codec_prefs IE do it the old way */ 10997 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10998 } 10999 } 11000 if (!format) { 11001 char tmp1[256], tmp2[256], tmp3[256]; 11002 ast_log(LOG_ERROR, "No best format in %s???\n", 11003 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 11004 if (authdebug) { 11005 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11006 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%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 } else { 11011 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11012 ast_inet_ntoa(sin.sin_addr), 11013 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11014 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11015 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11016 } 11017 } 11018 memset(&ied0, 0, sizeof(ied0)); 11019 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11020 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11021 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11022 if (!iaxs[fr->callno]) { 11023 break; 11024 } 11025 } 11026 } 11027 } 11028 if (format) { 11029 /* Authentication received */ 11030 memset(&ied1, 0, sizeof(ied1)); 11031 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 11032 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 11033 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 11034 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 11035 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11036 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 11037 "%srequested format = %s,\n" 11038 "%srequested prefs = %s,\n" 11039 "%sactual format = %s,\n" 11040 "%shost prefs = %s,\n" 11041 "%spriority = %s\n", 11042 ast_inet_ntoa(sin.sin_addr), 11043 VERBOSE_PREFIX_4, 11044 ast_getformatname(iaxs[fr->callno]->peerformat), 11045 VERBOSE_PREFIX_4, 11046 caller_pref_buf, 11047 VERBOSE_PREFIX_4, 11048 ast_getformatname(format), 11049 VERBOSE_PREFIX_4, 11050 host_pref_buf, 11051 VERBOSE_PREFIX_4, 11052 using_prefs); 11053 11054 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11055 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL))) 11056 iax2_destroy(fr->callno); 11057 else if (ies.vars) { 11058 struct ast_datastore *variablestore; 11059 struct ast_variable *var, *prev = NULL; 11060 AST_LIST_HEAD(, ast_var_t) *varlist; 11061 varlist = ast_calloc(1, sizeof(*varlist)); 11062 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11063 if (variablestore && varlist) { 11064 variablestore->data = varlist; 11065 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11066 AST_LIST_HEAD_INIT(varlist); 11067 ast_debug(1, "I can haz IAX vars? w00t\n"); 11068 for (var = ies.vars; var; var = var->next) { 11069 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11070 if (prev) 11071 ast_free(prev); 11072 prev = var; 11073 if (!newvar) { 11074 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11075 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11076 } else { 11077 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11078 } 11079 } 11080 if (prev) 11081 ast_free(prev); 11082 ies.vars = NULL; 11083 ast_channel_datastore_add(c, variablestore); 11084 } else { 11085 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11086 if (variablestore) 11087 ast_datastore_free(variablestore); 11088 if (varlist) 11089 ast_free(varlist); 11090 } 11091 } 11092 } else { 11093 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11094 /* If this is a TBD call, we're ready but now what... */ 11095 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 11096 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) { 11097 goto immediatedial; 11098 } 11099 } 11100 } 11101 } 11102 break; 11103 case IAX_COMMAND_DIAL: 11104 immediatedial: 11105 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 11106 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11107 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 11108 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 11109 if (authdebug) 11110 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); 11111 memset(&ied0, 0, sizeof(ied0)); 11112 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11113 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11114 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11115 if (!iaxs[fr->callno]) { 11116 break; 11117 } 11118 } else { 11119 char tmp[256]; 11120 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11121 ast_verb(3, "Accepting DIAL from %s, formats = %s\n", 11122 ast_inet_ntoa(sin.sin_addr), 11123 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat)); 11124 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11125 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 11126 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL))) 11127 iax2_destroy(fr->callno); 11128 else if (ies.vars) { 11129 struct ast_datastore *variablestore; 11130 struct ast_variable *var, *prev = NULL; 11131 AST_LIST_HEAD(, ast_var_t) *varlist; 11132 varlist = ast_calloc(1, sizeof(*varlist)); 11133 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11134 ast_debug(1, "I can haz IAX vars? w00t\n"); 11135 if (variablestore && varlist) { 11136 variablestore->data = varlist; 11137 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11138 AST_LIST_HEAD_INIT(varlist); 11139 for (var = ies.vars; var; var = var->next) { 11140 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11141 if (prev) 11142 ast_free(prev); 11143 prev = var; 11144 if (!newvar) { 11145 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11146 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11147 } else { 11148 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11149 } 11150 } 11151 if (prev) 11152 ast_free(prev); 11153 ies.vars = NULL; 11154 ast_channel_datastore_add(c, variablestore); 11155 } else { 11156 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11157 if (variablestore) 11158 ast_datastore_free(variablestore); 11159 if (varlist) 11160 ast_free(varlist); 11161 } 11162 } 11163 } 11164 } 11165 break; 11166 case IAX_COMMAND_INVAL: 11167 iaxs[fr->callno]->error = ENOTCONN; 11168 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 11169 iax2_destroy(fr->callno); 11170 ast_debug(1, "Destroying call %d\n", fr->callno); 11171 break; 11172 case IAX_COMMAND_VNAK: 11173 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 11174 /* Force retransmission */ 11175 vnak_retransmit(fr->callno, fr->iseqno); 11176 break; 11177 case IAX_COMMAND_REGREQ: 11178 case IAX_COMMAND_REGREL: 11179 /* For security, always ack immediately */ 11180 if (delayreject) 11181 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11182 if (register_verify(fr->callno, &sin, &ies)) { 11183 if (!iaxs[fr->callno]) { 11184 break; 11185 } 11186 /* Send delayed failure */ 11187 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 11188 break; 11189 } 11190 if (!iaxs[fr->callno]) { 11191 break; 11192 } 11193 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 11194 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 11195 11196 if (f.subclass.integer == IAX_COMMAND_REGREL) { 11197 memset(&sin, 0, sizeof(sin)); 11198 sin.sin_family = AF_INET; 11199 } 11200 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) { 11201 ast_log(LOG_WARNING, "Registry error\n"); 11202 } 11203 if (!iaxs[fr->callno]) { 11204 break; 11205 } 11206 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 11207 ast_mutex_unlock(&iaxsl[fr->callno]); 11208 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 11209 ast_mutex_lock(&iaxsl[fr->callno]); 11210 } 11211 break; 11212 } 11213 registry_authrequest(fr->callno); 11214 break; 11215 case IAX_COMMAND_REGACK: 11216 if (iax2_ack_registry(&ies, &sin, fr->callno)) 11217 ast_log(LOG_WARNING, "Registration failure\n"); 11218 /* Send ack immediately, before we destroy */ 11219 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11220 iax2_destroy(fr->callno); 11221 break; 11222 case IAX_COMMAND_REGREJ: 11223 if (iaxs[fr->callno]->reg) { 11224 if (authdebug) { 11225 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)); 11226 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>"); 11227 } 11228 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 11229 } 11230 /* Send ack immediately, before we destroy */ 11231 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11232 iax2_destroy(fr->callno); 11233 break; 11234 case IAX_COMMAND_REGAUTH: 11235 /* Authentication request */ 11236 if (registry_rerequest(&ies, fr->callno, &sin)) { 11237 memset(&ied0, 0, sizeof(ied0)); 11238 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 11239 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 11240 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11241 } 11242 break; 11243 case IAX_COMMAND_TXREJ: 11244 iaxs[fr->callno]->transferring = 0; 11245 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11246 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 11247 if (iaxs[fr->callno]->bridgecallno) { 11248 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 11249 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 11250 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 11251 } 11252 } 11253 break; 11254 case IAX_COMMAND_TXREADY: 11255 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 11256 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 11257 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 11258 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 11259 else 11260 iaxs[fr->callno]->transferring = TRANSFER_READY; 11261 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11262 if (iaxs[fr->callno]->bridgecallno) { 11263 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 11264 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 11265 /* They're both ready, now release them. */ 11266 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 11267 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11268 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11269 11270 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 11271 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 11272 11273 memset(&ied0, 0, sizeof(ied0)); 11274 memset(&ied1, 0, sizeof(ied1)); 11275 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11276 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11277 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 11278 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 11279 } else { 11280 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11281 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11282 11283 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 11284 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 11285 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 11286 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 11287 11288 /* Stop doing lag & ping requests */ 11289 stop_stuff(fr->callno); 11290 stop_stuff(iaxs[fr->callno]->bridgecallno); 11291 11292 memset(&ied0, 0, sizeof(ied0)); 11293 memset(&ied1, 0, sizeof(ied1)); 11294 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11295 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11296 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 11297 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 11298 } 11299 11300 } 11301 } 11302 } 11303 break; 11304 case IAX_COMMAND_TXREQ: 11305 try_transfer(iaxs[fr->callno], &ies); 11306 break; 11307 case IAX_COMMAND_TXCNT: 11308 if (iaxs[fr->callno]->transferring) 11309 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 11310 break; 11311 case IAX_COMMAND_TXREL: 11312 /* Send ack immediately, rather than waiting until we've changed addresses */ 11313 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11314 complete_transfer(fr->callno, &ies); 11315 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 11316 break; 11317 case IAX_COMMAND_TXMEDIA: 11318 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 11319 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 11320 /* Cancel any outstanding frames and start anew */ 11321 if (cur->transfer) { 11322 cur->retries = -1; 11323 } 11324 } 11325 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 11326 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 11327 } 11328 break; 11329 case IAX_COMMAND_RTKEY: 11330 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 11331 ast_log(LOG_WARNING, 11332 "we've been told to rotate our encryption key, " 11333 "but this isn't an encrypted call. bad things will happen.\n" 11334 ); 11335 break; 11336 } 11337 11338 IAX_DEBUGDIGEST("Receiving", ies.challenge); 11339 11340 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 11341 break; 11342 case IAX_COMMAND_DPREP: 11343 complete_dpreply(iaxs[fr->callno], &ies); 11344 break; 11345 case IAX_COMMAND_UNSUPPORT: 11346 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 11347 break; 11348 case IAX_COMMAND_FWDOWNL: 11349 /* Firmware download */ 11350 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 11351 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 11352 break; 11353 } 11354 memset(&ied0, 0, sizeof(ied0)); 11355 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 11356 if (res < 0) 11357 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11358 else if (res > 0) 11359 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11360 else 11361 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11362 break; 11363 case IAX_COMMAND_CALLTOKEN: 11364 { 11365 struct iax_frame *cur; 11366 /* find last sent frame */ 11367 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) { 11368 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 11369 } 11370 break; 11371 } 11372 default: 11373 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno); 11374 memset(&ied0, 0, sizeof(ied0)); 11375 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer); 11376 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11377 } 11378 /* Free remote variables (if any) */ 11379 if (ies.vars) { 11380 ast_variables_destroy(ies.vars); 11381 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11382 ies.vars = NULL; 11383 } 11384 11385 /* Don't actually pass these frames along */ 11386 if ((f.subclass.integer != IAX_COMMAND_ACK) && 11387 (f.subclass.integer != IAX_COMMAND_TXCNT) && 11388 (f.subclass.integer != IAX_COMMAND_TXACC) && 11389 (f.subclass.integer != IAX_COMMAND_INVAL) && 11390 (f.subclass.integer != IAX_COMMAND_VNAK)) { 11391 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11392 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11393 } 11394 ast_mutex_unlock(&iaxsl[fr->callno]); 11395 return 1; 11396 } 11397 /* Unless this is an ACK or INVAL frame, ack it */ 11398 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11399 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11400 } else if (minivid) { 11401 f.frametype = AST_FRAME_VIDEO; 11402 if (iaxs[fr->callno]->videoformat > 0) 11403 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0); 11404 else { 11405 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11406 iax2_vnak(fr->callno); 11407 ast_variables_destroy(ies.vars); 11408 ast_mutex_unlock(&iaxsl[fr->callno]); 11409 return 1; 11410 } 11411 f.datalen = res - sizeof(*vh); 11412 if (f.datalen) 11413 f.data.ptr = thread->buf + sizeof(*vh); 11414 else 11415 f.data.ptr = NULL; 11416 #ifdef IAXTESTS 11417 if (test_resync) { 11418 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11419 } else 11420 #endif /* IAXTESTS */ 11421 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11422 } else { 11423 /* A mini frame */ 11424 f.frametype = AST_FRAME_VOICE; 11425 if (iaxs[fr->callno]->voiceformat > 0) 11426 f.subclass.codec = iaxs[fr->callno]->voiceformat; 11427 else { 11428 ast_debug(1, "Received mini frame before first full voice frame\n"); 11429 iax2_vnak(fr->callno); 11430 ast_variables_destroy(ies.vars); 11431 ast_mutex_unlock(&iaxsl[fr->callno]); 11432 return 1; 11433 } 11434 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11435 if (f.datalen < 0) { 11436 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11437 ast_variables_destroy(ies.vars); 11438 ast_mutex_unlock(&iaxsl[fr->callno]); 11439 return 1; 11440 } 11441 if (f.datalen) 11442 f.data.ptr = thread->buf + sizeof(*mh); 11443 else 11444 f.data.ptr = NULL; 11445 #ifdef IAXTESTS 11446 if (test_resync) { 11447 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11448 } else 11449 #endif /* IAXTESTS */ 11450 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11451 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11452 } 11453 /* Don't pass any packets until we're started */ 11454 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11455 ast_variables_destroy(ies.vars); 11456 ast_mutex_unlock(&iaxsl[fr->callno]); 11457 return 1; 11458 } 11459 /* Don't allow connected line updates unless we are configured to */ 11460 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) { 11461 struct ast_party_connected_line connected; 11462 11463 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) { 11464 ast_variables_destroy(ies.vars); 11465 ast_mutex_unlock(&iaxsl[fr->callno]); 11466 return 1; 11467 } 11468 11469 /* Initialize defaults */ 11470 ast_party_connected_line_init(&connected); 11471 connected.id.number.presentation = iaxs[fr->callno]->calling_pres; 11472 connected.id.name.presentation = iaxs[fr->callno]->calling_pres; 11473 11474 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) { 11475 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str); 11476 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str); 11477 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id); 11478 11479 if (iaxs[fr->callno]->owner) { 11480 ast_set_callerid(iaxs[fr->callno]->owner, 11481 S_COR(connected.id.number.valid, connected.id.number.str, ""), 11482 S_COR(connected.id.name.valid, connected.id.name.str, ""), 11483 NULL); 11484 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation; 11485 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation; 11486 } 11487 } 11488 ast_party_connected_line_free(&connected); 11489 } 11490 /* Common things */ 11491 f.src = "IAX2"; 11492 f.mallocd = 0; 11493 f.offset = 0; 11494 f.len = 0; 11495 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11496 f.samples = ast_codec_get_samples(&f); 11497 /* We need to byteswap incoming slinear samples from network byte order */ 11498 if (f.subclass.codec == AST_FORMAT_SLINEAR) 11499 ast_frame_byteswap_be(&f); 11500 } else 11501 f.samples = 0; 11502 iax_frame_wrap(fr, &f); 11503 11504 /* If this is our most recent packet, use it as our basis for timestamping */ 11505 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11506 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11507 fr->outoforder = 0; 11508 } else { 11509 if (iaxdebug && iaxs[fr->callno]) 11510 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass.integer, fr->ts, iaxs[fr->callno]->last); 11511 fr->outoforder = -1; 11512 } 11513 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11514 duped_fr = iaxfrdup2(fr); 11515 if (duped_fr) { 11516 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11517 } 11518 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11519 iaxs[fr->callno]->last = fr->ts; 11520 #if 1 11521 if (iaxdebug) 11522 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 11523 #endif 11524 } 11525 11526 /* Always run again */ 11527 ast_variables_destroy(ies.vars); 11528 ast_mutex_unlock(&iaxsl[fr->callno]); 11529 return 1; 11530 }
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 9582 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_mini_hdr::callno, f, find_callno_locked(), find_tpeer(), fix_peerts(), 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_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, iax_frame::outoforder, iax2_trunk_peer::rxtrunktime, schedule_delivery(), iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
09584 { 09585 unsigned char metatype; 09586 struct ast_iax2_meta_trunk_mini *mtm; 09587 struct ast_iax2_meta_trunk_hdr *mth; 09588 struct ast_iax2_meta_trunk_entry *mte; 09589 struct iax2_trunk_peer *tpeer; 09590 unsigned int ts; 09591 void *ptr; 09592 struct timeval rxtrunktime; 09593 struct ast_frame f = { 0, }; 09594 09595 if (packet_len < sizeof(*meta)) { 09596 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09597 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09598 return 1; 09599 } 09600 09601 if (meta->metacmd != IAX_META_TRUNK) 09602 return 1; 09603 09604 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09605 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09606 (int) (sizeof(*meta) + sizeof(*mth))); 09607 return 1; 09608 } 09609 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09610 ts = ntohl(mth->ts); 09611 metatype = meta->cmddata; 09612 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09613 ptr = mth->data; 09614 tpeer = find_tpeer(sin, sockfd); 09615 if (!tpeer) { 09616 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09617 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09618 return 1; 09619 } 09620 tpeer->trunkact = ast_tvnow(); 09621 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09622 tpeer->rxtrunktime = tpeer->trunkact; 09623 rxtrunktime = tpeer->rxtrunktime; 09624 ast_mutex_unlock(&tpeer->lock); 09625 while (packet_len >= sizeof(*mte)) { 09626 /* Process channels */ 09627 unsigned short callno, trunked_ts, len; 09628 09629 if (metatype == IAX_META_TRUNK_MINI) { 09630 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09631 ptr += sizeof(*mtm); 09632 packet_len -= sizeof(*mtm); 09633 len = ntohs(mtm->len); 09634 callno = ntohs(mtm->mini.callno); 09635 trunked_ts = ntohs(mtm->mini.ts); 09636 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09637 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09638 ptr += sizeof(*mte); 09639 packet_len -= sizeof(*mte); 09640 len = ntohs(mte->len); 09641 callno = ntohs(mte->callno); 09642 trunked_ts = 0; 09643 } else { 09644 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09645 break; 09646 } 09647 /* Stop if we don't have enough data */ 09648 if (len > packet_len) 09649 break; 09650 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09651 if (!fr->callno) 09652 continue; 09653 09654 /* If it's a valid call, deliver the contents. If not, we 09655 drop it, since we don't have a scallno to use for an INVAL */ 09656 /* Process as a mini frame */ 09657 memset(&f, 0, sizeof(f)); 09658 f.frametype = AST_FRAME_VOICE; 09659 if (!iaxs[fr->callno]) { 09660 /* drop it */ 09661 } else if (iaxs[fr->callno]->voiceformat == 0) { 09662 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09663 iax2_vnak(fr->callno); 09664 } else { 09665 f.subclass.codec = iaxs[fr->callno]->voiceformat; 09666 f.datalen = len; 09667 if (f.datalen >= 0) { 09668 if (f.datalen) 09669 f.data.ptr = ptr; 09670 else 09671 f.data.ptr = NULL; 09672 if (trunked_ts) 09673 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09674 else 09675 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09676 /* Don't pass any packets until we're started */ 09677 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09678 struct iax_frame *duped_fr; 09679 09680 /* Common things */ 09681 f.src = "IAX2"; 09682 f.mallocd = 0; 09683 f.offset = 0; 09684 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09685 f.samples = ast_codec_get_samples(&f); 09686 else 09687 f.samples = 0; 09688 fr->outoforder = 0; 09689 iax_frame_wrap(fr, &f); 09690 duped_fr = iaxfrdup2(fr); 09691 if (duped_fr) 09692 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09693 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09694 iaxs[fr->callno]->last = fr->ts; 09695 } 09696 } else { 09697 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09698 } 09699 } 09700 ast_mutex_unlock(&iaxsl[fr->callno]); 09701 ptr += len; 09702 packet_len -= len; 09703 } 09704 09705 return 1; 09706 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9503 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(), iax2_thread::callno, 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(), iax2_thread::list, LOG_WARNING, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, thread, and ast_iax2_full_hdr::type.
Referenced by network_thread(), peer_set_srcaddr(), and set_config().
09504 { 09505 struct iax2_thread *thread; 09506 socklen_t len; 09507 time_t t; 09508 static time_t last_errtime = 0; 09509 struct ast_iax2_full_hdr *fh; 09510 09511 if (!(thread = find_idle_thread())) { 09512 time(&t); 09513 if (t != last_errtime) 09514 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09515 last_errtime = t; 09516 usleep(1); 09517 return 1; 09518 } 09519 09520 len = sizeof(thread->iosin); 09521 thread->iofd = fd; 09522 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09523 thread->buf_size = sizeof(thread->readbuf); 09524 thread->buf = thread->readbuf; 09525 if (thread->buf_len < 0) { 09526 if (errno != ECONNREFUSED && errno != EAGAIN) 09527 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09528 handle_error(); 09529 thread->iostate = IAX_IOSTATE_IDLE; 09530 signal_condition(&thread->lock, &thread->cond); 09531 return 1; 09532 } 09533 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09534 thread->iostate = IAX_IOSTATE_IDLE; 09535 signal_condition(&thread->lock, &thread->cond); 09536 return 1; 09537 } 09538 09539 /* Determine if this frame is a full frame; if so, and any thread is currently 09540 processing a full frame for the same callno from this peer, then drop this 09541 frame (and the peer will retransmit it) */ 09542 fh = (struct ast_iax2_full_hdr *) thread->buf; 09543 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09544 struct iax2_thread *cur = NULL; 09545 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09546 09547 AST_LIST_LOCK(&active_list); 09548 AST_LIST_TRAVERSE(&active_list, cur, list) { 09549 if ((cur->ffinfo.callno == callno) && 09550 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09551 break; 09552 } 09553 if (cur) { 09554 /* we found another thread processing a full frame for this call, 09555 so queue it up for processing later. */ 09556 defer_full_frame(thread, cur); 09557 AST_LIST_UNLOCK(&active_list); 09558 thread->iostate = IAX_IOSTATE_IDLE; 09559 signal_condition(&thread->lock, &thread->cond); 09560 return 1; 09561 } else { 09562 /* this thread is going to process this frame, so mark it */ 09563 thread->ffinfo.callno = callno; 09564 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09565 thread->ffinfo.type = fh->type; 09566 thread->ffinfo.csub = fh->csub; 09567 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09568 } 09569 AST_LIST_UNLOCK(&active_list); 09570 } 09571 09572 /* Mark as ready and send on its way */ 09573 thread->iostate = IAX_IOSTATE_READY; 09574 #ifdef DEBUG_SCHED_MULTITHREAD 09575 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09576 #endif 09577 signal_condition(&thread->lock, &thread->cond); 09578 09579 return 1; 09580 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 9220 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
09221 { 09222 pthread_t newthread; 09223 struct dpreq_data *dpr; 09224 09225 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 09226 return; 09227 09228 dpr->callno = callno; 09229 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 09230 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 09231 if (callerid) 09232 dpr->callerid = ast_strdup(callerid); 09233 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 09234 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 09235 } 09236 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 12084 of file chan_iax2.c.
References ast_calloc, ast_cond_destroy, ast_cond_init, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_destroy, ast_mutex_init, ast_pthread_create_background, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::list, LOG_WARNING, and thread.
Referenced by load_module().
12085 { 12086 struct iax2_thread *thread; 12087 int threadcount = 0; 12088 int x; 12089 for (x = 0; x < iaxthreadcount; x++) { 12090 thread = ast_calloc(1, sizeof(*thread)); 12091 if (thread) { 12092 thread->type = IAX_THREAD_TYPE_POOL; 12093 thread->threadnum = ++threadcount; 12094 ast_mutex_init(&thread->lock); 12095 ast_cond_init(&thread->cond, NULL); 12096 ast_mutex_init(&thread->init_lock); 12097 ast_cond_init(&thread->init_cond, NULL); 12098 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 12099 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 12100 ast_mutex_destroy(&thread->lock); 12101 ast_cond_destroy(&thread->cond); 12102 ast_mutex_destroy(&thread->init_lock); 12103 ast_cond_destroy(&thread->init_cond); 12104 ast_free(thread); 12105 thread = NULL; 12106 continue; 12107 } 12108 AST_LIST_LOCK(&idle_list); 12109 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 12110 AST_LIST_UNLOCK(&idle_list); 12111 } 12112 } 12113 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 12114 ast_verb(2, "%d helper threads started\n", threadcount); 12115 return 0; 12116 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 8926 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
08927 { 08928 iax2_destroy_helper(iaxs[callno]); 08929 }
static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2113 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().
02114 { 02115 if (!pvt->peercallno) { 02116 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 02117 return; 02118 } 02119 02120 ao2_link(iax_peercallno_pvts, pvt); 02121 }
static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 2094 of file chan_iax2.c.
References ao2_link, ast_log(), iax_transfercallno_pvts, LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
02095 { 02096 if (!pvt->transfercallno) { 02097 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 02098 return; 02099 } 02100 02101 ao2_link(iax_transfercallno_pvts, pvt); 02102 }
static int timing_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9109 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_mutex_destroy, ast_mutex_lock, ast_mutex_unlock, ast_timer_ack(), ast_tvnow(), ast_verbose, iax2_trunk_expired(), iax2_trunk_peer::lock, send_trunk(), timer, totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
09110 { 09111 int res, processed = 0, totalcalls = 0; 09112 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 09113 struct timeval now = ast_tvnow(); 09114 09115 if (iaxtrunkdebug) 09116 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 09117 09118 if (timer) { 09119 ast_timer_ack(timer, 1); 09120 } 09121 09122 /* For each peer that supports trunking... */ 09123 AST_LIST_LOCK(&tpeers); 09124 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 09125 processed++; 09126 res = 0; 09127 ast_mutex_lock(&tpeer->lock); 09128 /* We can drop a single tpeer per pass. That makes all this logic 09129 substantially easier */ 09130 if (!drop && iax2_trunk_expired(tpeer, &now)) { 09131 /* Take it out of the list, but don't free it yet, because it 09132 could be in use */ 09133 AST_LIST_REMOVE_CURRENT(list); 09134 drop = tpeer; 09135 } else { 09136 res = send_trunk(tpeer, &now); 09137 trunk_timed++; 09138 if (iaxtrunkdebug) 09139 ast_verbose(" - Trunk peer (%s:%d) has %d call chunk%s in transit, %d bytes backloged and has hit a high water mark of %d bytes\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port), res, (res != 1) ? "s" : "", tpeer->trunkdatalen, tpeer->trunkdataalloc); 09140 } 09141 totalcalls += res; 09142 res = 0; 09143 ast_mutex_unlock(&tpeer->lock); 09144 } 09145 AST_LIST_TRAVERSE_SAFE_END; 09146 AST_LIST_UNLOCK(&tpeers); 09147 09148 if (drop) { 09149 ast_mutex_lock(&drop->lock); 09150 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 09151 because by the time they could get tpeerlock, we've already grabbed it */ 09152 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 09153 if (drop->trunkdata) { 09154 ast_free(drop->trunkdata); 09155 drop->trunkdata = NULL; 09156 } 09157 ast_mutex_unlock(&drop->lock); 09158 ast_mutex_destroy(&drop->lock); 09159 ast_free(drop); 09160 09161 } 09162 09163 if (iaxtrunkdebug) 09164 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 09165 iaxtrunkdebug = 0; 09166 09167 return 1; 09168 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14323 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
14324 { 14325 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14326 14327 /* The frames_received field is used to hold whether we're matching 14328 * against a full frame or not ... */ 14329 14330 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 14331 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14332 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14316 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
14317 { 14318 const struct chan_iax2_pvt *pvt = obj; 14319 14320 return pvt->transfercallno; 14321 }
static int transmit_frame | ( | void * | data | ) | [static] |
Definition at line 4228 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, ast_mutex_lock, ast_mutex_unlock, attempt_transmit(), iax_frame::callno, frame_queue, iax2_sched_add(), iax_frame_free(), iaxs, iaxsl, iax2_trunk_peer::list, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, sched, send_packet(), and iax_frame::sentyet.
Referenced by iax2_transmit().
04229 { 04230 struct iax_frame *fr = data; 04231 04232 ast_mutex_lock(&iaxsl[fr->callno]); 04233 04234 fr->sentyet = 1; 04235 04236 if (iaxs[fr->callno]) { 04237 send_packet(fr); 04238 } 04239 04240 if (fr->retries < 0) { 04241 ast_mutex_unlock(&iaxsl[fr->callno]); 04242 /* No retransmit requested */ 04243 iax_frame_free(fr); 04244 } else { 04245 /* We need reliable delivery. Schedule a retransmission */ 04246 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list); 04247 fr->retries++; 04248 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr); 04249 ast_mutex_unlock(&iaxsl[fr->callno]); 04250 } 04251 04252 return 0; 04253 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 3300 of file chan_iax2.c.
References ast_debug, errno, f, and handle_error().
Referenced by send_trunk().
03301 { 03302 int res; 03303 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03304 sizeof(*sin)); 03305 if (res < 0) { 03306 ast_debug(1, "Received error: %s\n", strerror(errno)); 03307 handle_error(); 03308 } else 03309 res = 0; 03310 return res; 03311 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 3002 of file chan_iax2.c.
References ast_calloc, AST_FILE_MODE, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_strlen_zero(), ast_iax2_firmware_header::chksum, ast_iax2_firmware_header::data, ast_iax2_firmware_header::datalen, iax_firmware::dead, ast_iax2_firmware_header::devname, errno, iax_firmware::fd, iax_firmware::fwh, IAX_FIRMWARE_MAGIC, last, iax2_trunk_peer::list, LOG_WARNING, md5(), MD5Final(), MD5Init(), MD5Update(), and ast_iax2_firmware_header::version.
Referenced by reload_firmware().
03003 { 03004 struct stat stbuf; 03005 struct iax_firmware *cur = NULL; 03006 int ifd, fd, res, len, chunk; 03007 struct ast_iax2_firmware_header *fwh, fwh2; 03008 struct MD5Context md5; 03009 unsigned char sum[16], buf[1024]; 03010 char *s2, *last; 03011 03012 if (!(s2 = alloca(strlen(s) + 100))) { 03013 ast_log(LOG_WARNING, "Alloca failed!\n"); 03014 return -1; 03015 } 03016 03017 last = strrchr(s, '/'); 03018 if (last) 03019 last++; 03020 else 03021 last = s; 03022 03023 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 03024 03025 if ((res = stat(s, &stbuf) < 0)) { 03026 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 03027 return -1; 03028 } 03029 03030 /* Make sure it's not a directory */ 03031 if (S_ISDIR(stbuf.st_mode)) 03032 return -1; 03033 ifd = open(s, O_RDONLY); 03034 if (ifd < 0) { 03035 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 03036 return -1; 03037 } 03038 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 03039 if (fd < 0) { 03040 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 03041 close(ifd); 03042 return -1; 03043 } 03044 /* Unlink our newly created file */ 03045 unlink(s2); 03046 03047 /* Now copy the firmware into it */ 03048 len = stbuf.st_size; 03049 while(len) { 03050 chunk = len; 03051 if (chunk > sizeof(buf)) 03052 chunk = sizeof(buf); 03053 res = read(ifd, buf, chunk); 03054 if (res != chunk) { 03055 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03056 close(ifd); 03057 close(fd); 03058 return -1; 03059 } 03060 res = write(fd, buf, chunk); 03061 if (res != chunk) { 03062 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03063 close(ifd); 03064 close(fd); 03065 return -1; 03066 } 03067 len -= chunk; 03068 } 03069 close(ifd); 03070 /* Return to the beginning */ 03071 lseek(fd, 0, SEEK_SET); 03072 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 03073 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 03074 close(fd); 03075 return -1; 03076 } 03077 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 03078 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 03079 close(fd); 03080 return -1; 03081 } 03082 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 03083 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 03084 close(fd); 03085 return -1; 03086 } 03087 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 03088 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 03089 close(fd); 03090 return -1; 03091 } 03092 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 03093 if (fwh == MAP_FAILED) { 03094 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 03095 close(fd); 03096 return -1; 03097 } 03098 MD5Init(&md5); 03099 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 03100 MD5Final(sum, &md5); 03101 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 03102 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 03103 munmap((void*)fwh, stbuf.st_size); 03104 close(fd); 03105 return -1; 03106 } 03107 03108 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03109 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 03110 /* Found a candidate */ 03111 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 03112 /* The version we have on loaded is older, load this one instead */ 03113 break; 03114 /* This version is no newer than what we have. Don't worry about it. 03115 We'll consider it a proper load anyhow though */ 03116 munmap((void*)fwh, stbuf.st_size); 03117 close(fd); 03118 return 0; 03119 } 03120 } 03121 03122 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 03123 cur->fd = -1; 03124 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 03125 } 03126 03127 if (cur) { 03128 if (cur->fwh) 03129 munmap((void*)cur->fwh, cur->mmaplen); 03130 if (cur->fd > -1) 03131 close(cur->fd); 03132 cur->fwh = fwh; 03133 cur->fd = fd; 03134 cur->mmaplen = stbuf.st_size; 03135 cur->dead = 0; 03136 } 03137 03138 return 0; 03139 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8254 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, inet_aton(), LOG_WARNING, 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().
08255 { 08256 int newcall = 0; 08257 char newip[256]; 08258 struct iax_ie_data ied; 08259 struct sockaddr_in new; 08260 08261 08262 memset(&ied, 0, sizeof(ied)); 08263 if (ies->apparent_addr) 08264 memmove(&new, ies->apparent_addr, sizeof(new)); 08265 if (ies->callno) 08266 newcall = ies->callno; 08267 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 08268 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08269 return -1; 08270 } 08271 pvt->transfercallno = newcall; 08272 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 08273 inet_aton(newip, &pvt->transfer.sin_addr); 08274 pvt->transfer.sin_family = AF_INET; 08275 pvt->transferid = ies->transferid; 08276 /* only store by transfercallno if this is a new transfer, 08277 * just in case we get a duplicate TXREQ */ 08278 if (pvt->transferring == TRANSFER_NONE) { 08279 store_by_transfercallno(pvt); 08280 } 08281 pvt->transferring = TRANSFER_BEGIN; 08282 08283 if (ies->transferid) 08284 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 08285 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 08286 return 0; 08287 }
static format_t uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1629 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01630 { 01631 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01632 if (csub & IAX_FLAG_SC_LOG) { 01633 /* special case for 'compressed' -1 */ 01634 if (csub == 0xff) 01635 return -1; 01636 else 01637 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01638 } 01639 else 01640 return csub; 01641 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8543 of file chan_iax2.c.
References ao2_unlink, ast_sched_thread_del, iax2_peer::expire, peer_unref(), peers, iax2_peer::pokeexpire, and sched.
Referenced by __expire_registry(), build_peer(), and prune_peers().
08544 { 08545 if (peer->expire > -1) { 08546 if (!ast_sched_thread_del(sched, peer->expire)) { 08547 peer->expire = -1; 08548 peer_unref(peer); 08549 } 08550 } 08551 08552 if (peer->pokeexpire > -1) { 08553 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 08554 peer->pokeexpire = -1; 08555 peer_unref(peer); 08556 } 08557 } 08558 08559 ao2_unlink(peers, peer); 08560 }
static int unload_module | ( | void | ) | [static] |
Definition at line 14281 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
14282 { 14283 ast_custom_function_unregister(&iaxpeer_function); 14284 ast_custom_function_unregister(&iaxvar_function); 14285 return __unload_module(); 14286 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5420 of file chan_iax2.c.
References ast_mutex_unlock, and iaxsl.
Referenced by iax2_bridge().
05421 { 05422 ast_mutex_unlock(&iaxsl[callno1]); 05423 ast_mutex_unlock(&iaxsl[callno0]); 05424 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3990 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().
03991 { 03992 /* Video mini frames only encode the lower 15 bits of the session 03993 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 03994 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 03995 const int lower_mask = (1 << ts_shift) - 1; 03996 const int upper_mask = ~lower_mask; 03997 const int last_upper = iaxs[fr->callno]->last & upper_mask; 03998 03999 if ( (fr->ts & upper_mask) == last_upper ) { 04000 const int x = fr->ts - iaxs[fr->callno]->last; 04001 const int threshold = (ts_shift == 15) ? 25000 : 50000; 04002 04003 if (x < -threshold) { 04004 /* Sudden big jump backwards in timestamp: 04005 What likely happened here is that miniframe timestamp has circled but we haven't 04006 gotten the update from the main packet. We'll just pretend that we did, and 04007 update the timestamp appropriately. */ 04008 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 04009 if (iaxdebug) 04010 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 04011 } else if (x > threshold) { 04012 /* Sudden apparent big jump forwards in timestamp: 04013 What's likely happened is this is an old miniframe belonging to the previous 04014 top 15 or 16-bit timestamp that has turned up out of order. 04015 Adjust the timestamp appropriately. */ 04016 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 04017 if (iaxdebug) 04018 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 04019 } 04020 } 04021 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4025 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, chan_iax2_pvt::rxcore, and sched.
Referenced by __get_from_jb(), and schedule_delivery().
04026 { 04027 int when; 04028 04029 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 04030 04031 when = jb_next(pvt->jb) - when; 04032 04033 if (when <= 0) { 04034 /* XXX should really just empty until when > 0.. */ 04035 when = 1; 04036 } 04037 04038 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 04039 CALLNO_TO_PTR(pvt->callno)); 04040 }
static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 2021 of file chan_iax2.c.
References ast_debug, iaxs, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
02022 { 02023 int max = 1; 02024 int x; 02025 /* XXX Prolly don't need locks here XXX */ 02026 for (x=1;x<TRUNK_CALL_START - 1; x++) { 02027 if (iaxs[x]) 02028 max = x + 1; 02029 } 02030 maxnontrunkcall = max; 02031 if (iaxdebug) 02032 ast_debug(1, "New max nontrunk callno is %d\n", max); 02033 }
static void update_max_trunk | ( | void | ) | [static] |
Definition at line 2004 of file chan_iax2.c.
References ARRAY_LEN, ast_debug, iaxs, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
02005 { 02006 int max = TRUNK_CALL_START; 02007 int x; 02008 02009 /* XXX Prolly don't need locks here XXX */ 02010 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 02011 if (iaxs[x]) { 02012 max = x + 1; 02013 } 02014 } 02015 02016 maxtrunkcall = max; 02017 if (iaxdebug) 02018 ast_debug(1, "New max trunk callno is %d\n", max); 02019 }
static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3438 of file chan_iax2.c.
References build_rand_pad(), ast_iax2_full_hdr::dcallno, decode_frame(), encrypt_frame(), f, IAX_FLAG_RETRANS, iaxs, ast_iax2_full_hdr::iseqno, and chan_iax2_pvt::iseqno.
Referenced by __attempt_transmit().
03439 { 03440 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03441 struct ast_iax2_full_hdr *fh = f->data; 03442 struct ast_frame af; 03443 03444 /* if frame is encrypted. decrypt before updating it. */ 03445 if (f->encmethods) { 03446 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03447 } 03448 /* Mark this as a retransmission */ 03449 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03450 /* Update iseqno */ 03451 f->iseqno = iaxs[f->callno]->iseqno; 03452 fh->iseqno = f->iseqno; 03453 03454 /* Now re-encrypt the frame */ 03455 if (f->encmethods) { 03456 /* since this is a retransmit frame, create a new random padding 03457 * before re-encrypting. */ 03458 build_rand_pad(f->semirand, sizeof(f->semirand)); 03459 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03460 } 03461 return 0; 03462 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 8658 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_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, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), globalflags, 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, iax2_peer::mailbox, manager_event, iax2_peer::maxcallno, iax2_peer::name, peer_ref(), peer_unref(), peercnt_modify(), iax_ie_data::pos, realtime_update_peer(), register_peer_exten(), sched, send_command_final(), iax2_peer::sockfd, state, strsep(), version, and iax2_peer::zonetag.
Referenced by socket_process().
08659 { 08660 /* Called from IAX thread only, with proper iaxsl lock */ 08661 struct iax_ie_data ied = { 08662 .pos = 0, 08663 }; 08664 struct iax2_peer *p; 08665 int msgcount; 08666 char data[80]; 08667 int version; 08668 const char *peer_name; 08669 int res = -1; 08670 struct ast_sockaddr sockaddr; 08671 08672 ast_sockaddr_from_sin(&sockaddr, sin); 08673 08674 peer_name = ast_strdupa(iaxs[callno]->peer); 08675 08676 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08677 ast_mutex_unlock(&iaxsl[callno]); 08678 if (!(p = find_peer(peer_name, 1))) { 08679 ast_mutex_lock(&iaxsl[callno]); 08680 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08681 return -1; 08682 } 08683 ast_mutex_lock(&iaxsl[callno]); 08684 if (!iaxs[callno]) 08685 goto return_unref; 08686 08687 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08688 if (sin->sin_addr.s_addr) { 08689 time_t nowtime; 08690 time(&nowtime); 08691 realtime_update_peer(peer_name, &sockaddr, nowtime); 08692 } else { 08693 realtime_update_peer(peer_name, &sockaddr, 0); 08694 } 08695 } 08696 08697 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) { 08698 if (iax2_regfunk) { 08699 iax2_regfunk(p->name, 1); 08700 } 08701 08702 /* modify entry in peercnts table as _not_ registered */ 08703 peercnt_modify(0, 0, &p->addr); 08704 08705 /* Stash the IP address from which they registered */ 08706 ast_sockaddr_from_sin(&p->addr, sin); 08707 08708 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08709 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08710 ast_db_put("IAX/Registry", p->name, data); 08711 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08712 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08713 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08714 register_peer_exten(p, 1); 08715 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08716 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) { 08717 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08718 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08719 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08720 register_peer_exten(p, 0); 08721 ast_db_del("IAX/Registry", p->name); 08722 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */ 08723 } 08724 /* Update the host */ 08725 /* Verify that the host is really there */ 08726 iax2_poke_peer(p, callno); 08727 } 08728 08729 /* modify entry in peercnts table as registered */ 08730 if (p->maxcallno) { 08731 peercnt_modify(1, p->maxcallno, &p->addr); 08732 } 08733 08734 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08735 if (!iaxs[callno]) { 08736 res = -1; 08737 goto return_unref; 08738 } 08739 08740 /* Store socket fd */ 08741 p->sockfd = fd; 08742 /* Setup the expiry */ 08743 if (p->expire > -1) { 08744 if (!ast_sched_thread_del(sched, p->expire)) { 08745 p->expire = -1; 08746 peer_unref(p); 08747 } 08748 } 08749 /* treat an unspecified refresh interval as the minimum */ 08750 if (!refresh) 08751 refresh = min_reg_expire; 08752 if (refresh > max_reg_expire) { 08753 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08754 p->name, max_reg_expire, refresh); 08755 p->expiry = max_reg_expire; 08756 } else if (refresh < min_reg_expire) { 08757 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08758 p->name, min_reg_expire, refresh); 08759 p->expiry = min_reg_expire; 08760 } else { 08761 p->expiry = refresh; 08762 } 08763 if (p->expiry && sin->sin_addr.s_addr) { 08764 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08765 if (p->expire == -1) 08766 peer_unref(p); 08767 } 08768 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08769 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08770 if (sin->sin_addr.s_addr) { 08771 struct sockaddr_in peer_addr; 08772 08773 ast_sockaddr_to_sin(&p->addr, &peer_addr); 08774 08775 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08776 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr); 08777 if (!ast_strlen_zero(p->mailbox)) { 08778 struct ast_event *event; 08779 int new, old; 08780 char *mailbox, *context; 08781 08782 context = mailbox = ast_strdupa(p->mailbox); 08783 strsep(&context, "@"); 08784 if (ast_strlen_zero(context)) 08785 context = "default"; 08786 08787 event = ast_event_get_cached(AST_EVENT_MWI, 08788 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08789 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08790 AST_EVENT_IE_END); 08791 if (event) { 08792 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08793 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08794 ast_event_destroy(event); 08795 } else { /* Fall back on checking the mailbox directly */ 08796 ast_app_inboxcount(p->mailbox, &new, &old); 08797 } 08798 08799 if (new > 255) { 08800 new = 255; 08801 } 08802 if (old > 255) { 08803 old = 255; 08804 } 08805 msgcount = (old << 8) | new; 08806 08807 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08808 } 08809 if (ast_test_flag64(p, IAX_HASCALLERID)) { 08810 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08811 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08812 } 08813 } 08814 version = iax_check_version(devtype); 08815 if (version) 08816 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08817 08818 res = 0; 08819 08820 return_unref: 08821 peer_unref(p); 08822 08823 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08824 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1676 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and user.
Referenced by load_objects().
01677 { 01678 struct iax2_user *user = obj, *user2 = arg; 01679 01680 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01681 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12820 of file chan_iax2.c.
References ast_set_flag64, IAX_DELME, and user.
Referenced by delete_users().
12821 { 12822 struct iax2_user *user = obj; 12823 12824 ast_set_flag64(user, IAX_DELME); 12825 12826 return 0; 12827 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12545 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), free_context(), and user.
Referenced by build_user().
12546 { 12547 struct iax2_user *user = obj; 12548 12549 ast_free_ha(user->ha); 12550 free_context(user->contexts); 12551 if(user->vars) { 12552 ast_variables_destroy(user->vars); 12553 user->vars = NULL; 12554 } 12555 ast_string_field_free_memory(user); 12556 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1666 of file chan_iax2.c.
References ast_str_hash(), and user.
Referenced by load_objects().
01667 { 01668 const struct iax2_user *user = obj; 01669 01670 return ast_str_hash(user->name); 01671 }
Definition at line 1729 of file chan_iax2.c.
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().
static int users_data_provider_get | ( | const struct ast_data_search * | search, | |
struct ast_data * | data_root | |||
) | [static] |
Definition at line 14486 of file chan_iax2.c.
References 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, DEFAULT_CONTEXT, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, user, user_unref(), and users.
14488 { 14489 struct ast_data *data_user, *data_authmethods, *data_enum_node; 14490 struct iax2_user *user; 14491 struct ao2_iterator i; 14492 char auth[90]; 14493 char *pstr = ""; 14494 14495 i = ao2_iterator_init(users, 0); 14496 while ((user = ao2_iterator_next(&i))) { 14497 data_user = ast_data_add_node(data_root, "user"); 14498 if (!data_user) { 14499 user_unref(user); 14500 continue; 14501 } 14502 14503 ast_data_add_structure(iax2_user, data_user, user); 14504 14505 ast_data_add_codecs(data_user, "codecs", user->capability); 14506 14507 if (!ast_strlen_zero(user->secret)) { 14508 ast_copy_string(auth, user->secret, sizeof(auth)); 14509 } else if (!ast_strlen_zero(user->inkeys)) { 14510 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys); 14511 } else { 14512 ast_copy_string(auth, "no secret", sizeof(auth)); 14513 } 14514 ast_data_add_password(data_user, "secret", auth); 14515 14516 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT); 14517 14518 /* authmethods */ 14519 data_authmethods = ast_data_add_node(data_user, "authmethods"); 14520 if (!data_authmethods) { 14521 ast_data_remove_node(data_root, data_user); 14522 continue; 14523 } 14524 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA); 14525 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5); 14526 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT); 14527 14528 /* amaflags */ 14529 data_enum_node = ast_data_add_node(data_user, "amaflags"); 14530 if (!data_enum_node) { 14531 ast_data_remove_node(data_root, data_user); 14532 continue; 14533 } 14534 ast_data_add_int(data_enum_node, "value", user->amaflags); 14535 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags)); 14536 14537 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0); 14538 14539 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) { 14540 pstr = "REQ only"; 14541 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) { 14542 pstr = "disabled"; 14543 } else { 14544 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host"; 14545 } 14546 ast_data_add_str(data_user, "codec-preferences", pstr); 14547 14548 user_unref(user); 14549 14550 if (!ast_data_search_match(search, data_user)) { 14551 ast_data_remove_node(data_root, data_user); 14552 } 14553 } 14554 ao2_iterator_destroy(&i); 14555 14556 return 0; 14557 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 9027 of file chan_iax2.c.
References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::list, and send_packet().
Referenced by socket_process().
09028 { 09029 struct iax_frame *f; 09030 09031 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) { 09032 /* Send a copy immediately */ 09033 if (((unsigned char) (f->oseqno - last) < 128) && 09034 (f->retries >= 0)) { 09035 send_packet(f); 09036 } 09037 } 09038 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5240 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().
05241 { 05242 unsigned short callno = pvt->callno; 05243 05244 if (!pvt->peercallno) { 05245 /* We don't know the remote side's call number, yet. :( */ 05246 int count = 10; 05247 while (count-- && pvt && !pvt->peercallno) { 05248 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05249 pvt = iaxs[callno]; 05250 } 05251 if (!pvt->peercallno) { 05252 return -1; 05253 } 05254 } 05255 05256 return 0; 05257 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Inter Asterisk eXchange (Ver 2)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "8586c2a7d357cb591cc3a6607a8f62d1" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } [static] |
Definition at line 14698 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 378 of file chan_iax2.c.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), 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(), do_forward(), findmeexec(), func_channel_write_real(), gtalk_new(), jingle_new(), local_call(), mgcp_new(), sip_new(), skinny_new(), and tds_log().
int adsi = 0 [static] |
Definition at line 382 of file chan_iax2.c.
int amaflags = 0 [static] |
Definition at line 381 of file chan_iax2.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 14698 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 289 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 290 of file chan_iax2.c.
struct ao2_container* callno_limits [static] |
Table containing custom callno limit rules for a range of ip addresses.
Definition at line 889 of file chan_iax2.c.
Referenced by __unload_module(), build_callno_limits(), load_objects(), reload_config(), set_config_destroy(), and set_peercnt_limit().
struct ao2_container* callno_pool [static] |
table of available call numbers
Definition at line 844 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 849 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 847 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 892 of file chan_iax2.c.
Referenced by __unload_module(), add_calltoken_ignore(), calltoken_required(), load_objects(), reload_config(), and set_config_destroy().
struct ast_cli_entry cli_iax2[] [static] |
unsigned int cos |
Definition at line 300 of file chan_iax2.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1096 of file chan_iax2.c.
Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), reload_config(), sip_debug_test_addr(), sip_do_debug(), sip_do_debug_ip(), and sip_do_debug_peer().
uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static] |
Definition at line 894 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 896 of file chan_iax2.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Definition at line 267 of file chan_iax2.c.
Referenced by load_config(), park_exec_full(), park_space_reserve(), and sip_alloc().
int defaultsockfd = -1 [static] |
Definition at line 312 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 383 of file chan_iax2.c.
Definition at line 860 of file chan_iax2.c.
struct { ... } frame_queue[IAX_MAX_CALLS + 1] [static] |
a list of frames that may need to be retransmitted
Contents protected by the iaxsl[] locks
Referenced by __attempt_transmit(), complete_transfer(), handle_cli_iax2_show_stats(), pvt_destructor(), resend_with_token(), socket_process(), transmit_frame(), and vnak_retransmit().
int global_max_trunk_mtu [static] |
Maximum MTU, 0 if not used
Definition at line 262 of file chan_iax2.c.
uint16_t global_maxcallno [static] |
Definition at line 898 of file chan_iax2.c.
uint16_t global_maxcallno_nonval [static] |
Total num of call numbers allowed to be allocated without calltoken validation
Definition at line 901 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 434 of file chan_iax2.c.
struct ast_flags64 globalflags = { 0 } [static] |
Definition at line 386 of file chan_iax2.c.
format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 364 of file chan_iax2.c.
struct ast_data_entry iax2_data_providers[] [static] |
Initial value:
{ AST_DATA_ENTRY("asterisk/channel/iax2/peers", &peers_data_provider), AST_DATA_ENTRY("asterisk/channel/iax2/users", &users_data_provider), }
Definition at line 14569 of file chan_iax2.c.
Referenced by load_module().
int iax2_encryption = 0 [static] |
Definition at line 384 of file chan_iax2.c.
int(*) iax2_regfunk(const char *username, int onoff) = NULL [static] |
Definition at line 314 of file chan_iax2.c.
Referenced by __expire_registry(), reg_source_db(), and update_registry().
struct ast_switch iax2_switch [static] |
struct ast_channel_tech iax2_tech [static] |
Definition at line 1214 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] |
Initial value:
{ .type = "IAX2_VARIABLE", .duplicate = iax2_dup_variable_datastore, .destroy = iax2_free_variable_datastore, }
Definition at line 1332 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 1073 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 1089 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 633 of file chan_iax2.c.
Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 291 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 366 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 294 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 296 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
int iaxdynamicthreadnum = 0 [static] |
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
struct ast_custom_function iaxpeer_function [static] |
Initial value:
{ .name = "IAXPEER", .read = function_iaxpeer, }
Definition at line 13833 of file chan_iax2.c.
Referenced by load_module(), and unload_module().
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS+1] [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 1062 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_max_nontrunk(), update_max_trunk(), 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 1082 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(), socket_process(), socket_process_meta(), transmit_frame(), unlock_both(), update_registry(), and wait_for_peercallno().
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 629 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 368 of file chan_iax2.c.
struct ast_custom_function iaxvar_function [static] |
Initial value:
{ .name = "IAXVAR", .read = acf_iaxvar_read, .write = acf_iaxvar_write, }
Definition at line 9774 of file chan_iax2.c.
Referenced by load_module(), and unload_module().
struct io_context* io [static] |
Definition at line 359 of file chan_iax2.c.
int jittertargetextra = 40 [static] |
Definition at line 282 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 278 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 269 of file chan_iax2.c.
Definition at line 860 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 292 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 866 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 304 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 276 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 275 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 279 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 281 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 1163 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 1162 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 303 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 379 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 380 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 310 of file chan_iax2.c.
Referenced by __unload_module(), ast_netsock_destroy(), load_module(), peer_set_srcaddr(), and set_config().
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 388 of file chan_iax2.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 273 of file chan_iax2.c.
Referenced by network_change_event_cb(), and network_change_event_sched_cb().
struct ast_event_sub* network_change_event_subscription [static] |
subscription id for network change events
Definition at line 272 of file chan_iax2.c.
Referenced by network_change_event_subscribe(), and network_change_event_unsubscribe().
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 311 of file chan_iax2.c.
Referenced by __unload_module(), load_module(), peer_set_srcaddr(), and set_config().
char* papp = "IAX2Provision" [static] |
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 886 of file chan_iax2.c.
Referenced by __unload_module(), handle_cli_iax2_show_callno_limits(), load_objects(), peercnt_add(), peercnt_modify(), peercnt_remove(), peercnt_remove_by_addr(), reload_config(), and sched_delay_remove().
struct ao2_container* peers [static] |
Definition at line 880 of file chan_iax2.c.
Referenced by __iax2_show_peers(), __unload_module(), authenticate_reply(), build_peer(), complete_iax2_peers(), complete_iax2_unregister(), delete_users(), find_peer(), handle_cli_iax2_unregister(), iax2_getpeername(), iax2_getpeertrunk(), load_module(), load_objects(), manager_iax2_show_peer_list(), peers_data_provider_get(), poke_all_peers(), prune_peers(), set_config(), and unlink_peer().
struct ast_data_handler peers_data_provider [static] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = peers_data_provider_get }
Definition at line 14559 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 277 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 253 of file chan_iax2.c.
Referenced by ast_best_codec(), ast_rtp_codecs_packetization_set(), build_peer(), build_user(), check_access(), create_addr(), gtalk_create_member(), gtalk_load_config(), jingle_create_member(), jingle_load_config(), new_iax(), set_config(), set_local_capabilities(), and set_peer_capabilities().
struct { ... } qos [static] |
Referenced by config_load(), config_parse_variables(), peer_set_srcaddr(), reload_config(), set_config(), and start_rtp().
int randomcalltokendata [static] |
Definition at line 864 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 270 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 280 of file chan_iax2.c.
struct ast_sched_thread* sched [static] |
Definition at line 360 of file chan_iax2.c.
int srvlookup = 0 [static] |
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 255 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 370 of file chan_iax2.c.
Definition at line 308 of file chan_iax2.c.
Referenced by __unload_module(), build_peer(), build_user(), check_timer(), find_timer(), kqueue_timer_hash(), kqueue_timer_open(), load_module(), network_thread(), 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(), read_pipe(), run_timer(), softmix_bridge_create(), softmix_bridge_thread(), timer_destroy(), timerfd_timer_hash(), timerfd_timer_open(), timing_read(), timing_test(), and write_byte().
unsigned int tos |
Definition at line 299 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 903 of file chan_iax2.c.
struct ast_taskprocessor* transmit_processor [static] |
Definition at line 862 of file chan_iax2.c.
int trunk_maxmtu [static] |
Definition at line 263 of file chan_iax2.c.
int trunk_nmaxmtu [static] |
Trunk MTU statistics
Definition at line 263 of file chan_iax2.c.
int trunk_timed [static] |
Definition at line 263 of file chan_iax2.c.
int trunk_untimed [static] |
Definition at line 263 of file chan_iax2.c.
int trunkfreq = 20 [static] |
Definition at line 286 of file chan_iax2.c.
int trunkmaxsize = MAX_TRUNKDATA [static] |
Definition at line 287 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 883 of file chan_iax2.c.
Referenced by __unload_module(), authenticate_request(), authenticate_verify(), build_user(), check_access(), delete_users(), find_user(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), load_module(), load_objects(), pp_each_user_helper(), prune_users(), set_config(), unload_module(), and users_data_provider_get().
struct ast_data_handler users_data_provider [static] |
Initial value:
{ .version = AST_DATA_HANDLER_VERSION, .get = users_data_provider_get }
Definition at line 14564 of file chan_iax2.c.