#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 *park_exten, const char *park_context) |
static void * | iax_park_thread (void *stuff) |
static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
static void | insert_idle_thread (struct iax2_thread *thread) |
static void | jb_debug_output (const char *fmt,...) |
static void | jb_error_output (const char *fmt,...) |
static void | jb_warning_output (const char *fmt,...) |
static int | load_module (void) |
Load IAX2 module, load configuraiton ---. | |
static int | load_objects (void) |
static void | lock_both (unsigned short callno0, unsigned short callno1) |
static void | log_jitterstats (unsigned short callno) |
static int | make_trunk (unsigned short callno, int locked) |
static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
static int | manager_iax2_show_peer_list (struct mansession *s, const struct message *m) |
callback to display iax peers in manager format | |
static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
callback to display iax peers in manager | |
static int | manager_iax2_show_registry (struct mansession *s, const struct message *m) |
static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno) |
static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx) |
static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx) |
static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
static void | network_change_event_cb (const struct ast_event *, void *) |
static int | network_change_event_sched_cb (const void *data) |
static void | network_change_event_subscribe (void) |
static void | network_change_event_unsubscribe (void) |
static void * | network_thread (void *ignore) |
static struct chan_iax2_pvt * | new_iax (struct sockaddr_in *sin, const char *host) |
static void | parse_dial_string (char *data, struct parsed_dial_string *pds) |
Parses an IAX dial string into its component parts. | |
static int | peer_cmp_cb (void *obj, void *arg, int flags) |
static int | peer_delme_cb (void *obj, void *arg, int flags) |
static void | peer_destructor (void *obj) |
static int | peer_hash_cb (const void *obj, const int flags) |
static struct iax2_peer * | peer_ref (struct iax2_peer *peer) |
static int | peer_set_sock_cb (void *obj, void *arg, int flags) |
static int | peer_set_srcaddr (struct iax2_peer *peer, const char *srcaddr) |
Parse the "sourceaddress" value, lookup in netsock list and set peer's sockfd. Defaults to defaultsockfd if not found. | |
static int | peer_status (struct iax2_peer *peer, char *status, int statuslen) |
peer_status: Report Peer status in character string | |
static struct iax2_peer * | peer_unref (struct iax2_peer *peer) |
static int | peercnt_add (struct sockaddr_in *sin) |
static int | peercnt_cmp_cb (void *obj, void *arg, int flags) |
static int | peercnt_hash_cb (const void *obj, const int flags) |
static void | peercnt_modify (unsigned char reg, uint16_t limit, struct ast_sockaddr *sockaddr) |
static void | peercnt_remove (struct peercnt *peercnt) |
static int | peercnt_remove_by_addr (struct sockaddr_in *sin) |
static int | peercnt_remove_cb (const void *obj) |
static int | peers_data_provider_get (const struct ast_data_search *search, struct ast_data *data_root) |
static void | poke_all_peers (void) |
static int | prune_addr_range_cb (void *obj, void *arg, int flags) |
static void | prune_peers (void) |
static void | prune_users (void) |
static int | pvt_cmp_cb (void *obj, void *arg, int flags) |
static void | pvt_destructor (void *obj) |
static int | pvt_hash_cb (const void *obj, const int flags) |
static int | queue_signalling (struct chan_iax2_pvt *pvt, struct ast_frame *f) |
All frames other than that of type AST_FRAME_IAX must be held until we have received a destination call number. | |
static int | raw_hangup (struct sockaddr_in *sin, unsigned short src, unsigned short dst, int sockfd) |
static struct iax2_peer * | realtime_peer (const char *peername, struct sockaddr_in *sin) |
static void | realtime_update_peer (const char *peername, struct ast_sockaddr *sockaddr, time_t regtime) |
static struct iax2_user * | realtime_user (const char *username, struct sockaddr_in *sin) |
static void | reg_source_db (struct iax2_peer *p) |
static void | register_peer_exten (struct iax2_peer *peer, int onoff) |
static int | register_verify (int callno, struct sockaddr_in *sin, struct iax_ies *ies) |
Verify inbound registration. | |
static int | registry_authrequest (int callno) |
static int | registry_rerequest (struct iax_ies *ies, int callno, struct sockaddr_in *sin) |
static char * | regstate2str (int regstate) |
static int | reload (void) |
static int | reload_config (void) |
static void | reload_firmware (int unload) |
static void | remove_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | remove_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | replace_callno (const void *obj) |
static void | requirecalltoken_mark_auto (const char *name, int subclass) |
static void | resend_with_token (int callno, struct iax_frame *f, const char *newtoken) |
static void | save_osptoken (struct iax_frame *fr, struct iax_ies *ies) |
static void | save_rr (struct iax_frame *fr, struct iax_ies *ies) |
static void | sched_delay_remove (struct sockaddr_in *sin, struct callno_entry *callno_entry) |
static int | schedule_delivery (struct iax_frame *fr, int updatehistory, int fromtrunk, unsigned int *tsout) |
static int | scheduled_destroy (const void *vid) |
static int | send_apathetic_reply (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int command, int ts, unsigned char seqno, int sockfd, struct iax_ie_data *ied) |
static int | send_command (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_final (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_immediate (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_locked (unsigned short callno, char, int, unsigned int, const unsigned char *, int, int) |
static int | send_command_transfer (struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int) |
static int | send_lagrq (const void *data) |
static int | send_packet (struct iax_frame *f) |
static int | send_ping (const void *data) |
static void | send_signaling (struct chan_iax2_pvt *pvt) |
This function must be called once we are sure the other side has given us a call number. All signaling is held here until that point. | |
static int | send_trunk (struct iax2_trunk_peer *tpeer, struct timeval *now) |
static int | set_config (const char *config_file, int reload) |
Load configuration. | |
static void | set_config_destroy (void) |
static void | set_hangup_source_and_cause (int callno, unsigned char causecode) |
static void | set_peercnt_limit (struct peercnt *peercnt) |
static int | set_peercnt_limit_all_cb (void *obj, void *arg, int flags) |
static void | signal_condition (ast_mutex_t *lock, ast_cond_t *cond) |
static int | socket_process (struct iax2_thread *thread) |
static int | socket_process_meta (int packet_len, struct ast_iax2_meta_hdr *meta, struct sockaddr_in *sin, int sockfd, struct iax_frame *fr) |
static int | socket_read (int *id, int fd, short events, void *cbdata) |
static void | spawn_dp_lookup (int callno, const char *context, const char *callednum, const char *callerid) |
static int | start_network_thread (void) |
static void | stop_stuff (int callno) |
static void | store_by_peercallno (struct chan_iax2_pvt *pvt) |
static void | store_by_transfercallno (struct chan_iax2_pvt *pvt) |
static int | timing_read (int *id, int fd, short events, void *cbdata) |
static int | transfercallno_pvt_cmp_cb (void *obj, void *arg, int flags) |
static int | transfercallno_pvt_hash_cb (const void *obj, const int flags) |
static int | transmit_frame (void *data) |
static int | transmit_trunk (struct iax_frame *f, struct sockaddr_in *sin, int sockfd) |
static int | try_firmware (char *s) |
static int | try_transfer (struct chan_iax2_pvt *pvt, struct iax_ies *ies) |
static format_t | uncompress_subclass (unsigned char csub) |
static void | unlink_peer (struct iax2_peer *peer) |
static int | unload_module (void) |
static void | unlock_both (unsigned short callno0, unsigned short callno1) |
static void | unwrap_timestamp (struct iax_frame *fr) |
static void | update_jbsched (struct chan_iax2_pvt *pvt) |
static 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 = "88eaa8f5c1bd988bedd71113385e0886" , .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 239 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 14473 of file chan_iax2.c.
#define DATA_EXPORT_IAX2_USER | ( | MEMBER | ) |
Definition at line 14550 of file chan_iax2.c.
#define DEBUG_SCHED_MULTITHREAD |
Definition at line 231 of file chan_iax2.c.
#define DEBUG_SUPPORT |
Definition at line 247 of file chan_iax2.c.
#define DEFAULT_CONTEXT "default" |
Definition at line 266 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), reload_config(), and users_data_provider_get().
#define DEFAULT_DROP 3 |
Definition at line 245 of file chan_iax2.c.
#define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 341 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 242 of file chan_iax2.c.
#define DEFAULT_MAXMS 2000 |
Definition at line 339 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 241 of file chan_iax2.c.
#define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 620 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
#define DONT_RESCHEDULE -2 |
Definition at line 363 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 252 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 429 of file chan_iax2.c.
Referenced by set_config(), and socket_process().
#define IAX_ALREADYGONE (uint64_t)(1 << 9) |
Already disconnected
Definition at line 412 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 344 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 318 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 330 of file chan_iax2.c.
Referenced by set_config().
#define IAX_CAPABILITY_LOWFREE |
Value:
Definition at line 335 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 419 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 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_USER_FIRST (uint64_t)(1 << 14) |
are we willing to let the other guy choose the codec?
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_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 428 of file chan_iax2.c.
Referenced by socket_process().
#define IAX_DELME (uint64_t)(1 << 1) |
Needs to be deleted
Definition at line 404 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 409 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 415 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 433 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 423 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 403 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 430 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 416 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 427 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 407 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 413 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 414 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 432 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 422 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 420 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 424 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 411 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 421 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 410 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 431 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 434 of file chan_iax2.c.
Referenced by check_access(), and set_config().
#define IAX_TEMPONLY (uint64_t)(1 << 2) |
Temporary (realtime)
Definition at line 405 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 426 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 406 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 425 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 408 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 628 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 617 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 879 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 622 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 261 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 285 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 244 of file chan_iax2.c.
#define MIN_JITTER_BUFFER 10 |
Definition at line 618 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 238 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 227 of file chan_iax2.c.
#define schedule_action | ( | func, | |||
data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1485 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 1094 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 625 of file chan_iax2.c.
anonymous enum |
Definition at line 939 of file chan_iax2.c.
00939 { 00940 /*! Extension exists */ 00941 CACHE_FLAG_EXISTS = (1 << 0), 00942 /*! Extension is nonexistent */ 00943 CACHE_FLAG_NONEXISTENT = (1 << 1), 00944 /*! Extension can exist */ 00945 CACHE_FLAG_CANEXIST = (1 << 2), 00946 /*! Waiting to hear back response */ 00947 CACHE_FLAG_PENDING = (1 << 3), 00948 /*! Timed out */ 00949 CACHE_FLAG_TIMEOUT = (1 << 4), 00950 /*! Request transmitted */ 00951 CACHE_FLAG_TRANSMITTED = (1 << 5), 00952 /*! Timeout */ 00953 CACHE_FLAG_UNKNOWN = (1 << 6), 00954 /*! Matchmore */ 00955 CACHE_FLAG_MATCHMORE = (1 << 7), 00956 };
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 442 of file chan_iax2.c.
00442 { 00443 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00444 CALLTOKEN_DEFAULT = 0, 00445 /*! \brief Require call token validation. */ 00446 CALLTOKEN_YES = 1, 00447 /*! \brief Require call token validation after a successful registration 00448 * using call token validation occurs. */ 00449 CALLTOKEN_AUTO = 2, 00450 /*! \brief Do not require call token validation. */ 00451 CALLTOKEN_NO = 3, 00452 };
enum iax2_state |
Definition at line 391 of file chan_iax2.c.
00391 { 00392 IAX_STATE_STARTED = (1 << 0), 00393 IAX_STATE_AUTHENTICATED = (1 << 1), 00394 IAX_STATE_TBD = (1 << 2), 00395 };
enum iax2_thread_iostate |
Definition at line 980 of file chan_iax2.c.
00980 { 00981 IAX_IOSTATE_IDLE, 00982 IAX_IOSTATE_READY, 00983 IAX_IOSTATE_PROCESSING, 00984 IAX_IOSTATE_SCHEDREADY, 00985 };
enum iax2_thread_type |
Definition at line 987 of file chan_iax2.c.
00987 { 00988 IAX_THREAD_TYPE_POOL, 00989 IAX_THREAD_TYPE_DYNAMIC, 00990 };
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 573 of file chan_iax2.c.
00573 { 00574 REG_STATE_UNREGISTERED = 0, 00575 REG_STATE_REGSENT, 00576 REG_STATE_AUTHSENT, 00577 REG_STATE_REGISTERED, 00578 REG_STATE_REJECTED, 00579 REG_STATE_TIMEOUT, 00580 REG_STATE_NOAUTH 00581 };
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 583 of file chan_iax2.c.
00583 { 00584 TRANSFER_NONE = 0, 00585 TRANSFER_BEGIN, 00586 TRANSFER_READY, 00587 TRANSFER_RELEASED, 00588 TRANSFER_PASSTHROUGH, 00589 TRANSFER_MBEGIN, 00590 TRANSFER_MREADY, 00591 TRANSFER_MRELEASED, 00592 TRANSFER_MPASSTHROUGH, 00593 TRANSFER_MEDIA, 00594 TRANSFER_MEDIAPASS 00595 };
static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3466 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().
03467 { 03468 /* Attempt to transmit the frame to the remote peer... 03469 Called without iaxsl held. */ 03470 struct iax_frame *f = (struct iax_frame *)data; 03471 int freeme = 0; 03472 int callno = f->callno; 03473 /* Make sure this call is still active */ 03474 if (callno) 03475 ast_mutex_lock(&iaxsl[callno]); 03476 if (callno && iaxs[callno]) { 03477 if ((f->retries < 0) /* Already ACK'd */ || 03478 (f->retries >= max_retries) /* Too many attempts */) { 03479 /* Record an error if we've transmitted too many times */ 03480 if (f->retries >= max_retries) { 03481 if (f->transfer) { 03482 /* Transfer timeout */ 03483 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03484 } else if (f->final) { 03485 iax2_destroy(callno); 03486 } else { 03487 if (iaxs[callno]->owner) 03488 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); 03489 iaxs[callno]->error = ETIMEDOUT; 03490 if (iaxs[callno]->owner) { 03491 struct ast_frame fr = { AST_FRAME_CONTROL, { AST_CONTROL_HANGUP }, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03492 /* Hangup the fd */ 03493 iax2_queue_frame(callno, &fr); /* XXX */ 03494 /* Remember, owner could disappear */ 03495 if (iaxs[callno] && iaxs[callno]->owner) 03496 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03497 } else { 03498 if (iaxs[callno]->reg) { 03499 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03500 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03501 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03502 } 03503 iax2_destroy(callno); 03504 } 03505 } 03506 03507 } 03508 freeme = 1; 03509 } else { 03510 /* Update it if it needs it */ 03511 update_packet(f); 03512 /* Attempt transmission */ 03513 send_packet(f); 03514 f->retries++; 03515 /* Try again later after 10 times as long */ 03516 f->retrytime *= 10; 03517 if (f->retrytime > MAX_RETRY_TIME) 03518 f->retrytime = MAX_RETRY_TIME; 03519 /* Transfer messages max out at one second */ 03520 if (f->transfer && (f->retrytime > 1000)) 03521 f->retrytime = 1000; 03522 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03523 } 03524 } else { 03525 /* Make sure it gets freed */ 03526 f->retries = -1; 03527 freeme = 1; 03528 } 03529 03530 if (freeme) { 03531 /* Don't attempt delivery, just remove it from the queue */ 03532 AST_LIST_REMOVE(&frame_queue[callno], f, list); 03533 ast_mutex_unlock(&iaxsl[callno]); 03534 f->retrans = -1; /* this is safe because this is the scheduled function */ 03535 /* Free the IAX frame */ 03536 iax2_frame_free(f); 03537 } else if (callno) { 03538 ast_mutex_unlock(&iaxsl[callno]); 03539 } 03540 }
static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 8953 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().
08954 { 08955 /* Called from IAX thread only, without iaxs lock */ 08956 int callno = (int)(long)(nothing); 08957 struct iax_ie_data ied; 08958 ast_mutex_lock(&iaxsl[callno]); 08959 if (iaxs[callno]) { 08960 memset(&ied, 0, sizeof(ied)); 08961 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 08962 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 08963 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 08964 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 08965 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 08966 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08967 } 08968 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 08969 } 08970 ast_mutex_unlock(&iaxsl[callno]); 08971 }
static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4638 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().
04639 { 04640 int callno = PTR_TO_CALLNO(nothing); 04641 struct ast_frame f = { AST_FRAME_CONTROL, { AST_CONTROL_CONGESTION } }; 04642 ast_mutex_lock(&iaxsl[callno]); 04643 if (iaxs[callno]) { 04644 iaxs[callno]->initid = -1; 04645 iax2_queue_frame(callno, &f); 04646 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04647 } 04648 ast_mutex_unlock(&iaxsl[callno]); 04649 }
static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 9002 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().
09003 { 09004 /* Called from IAX thread only, without iaxs lock */ 09005 int callno = (int)(long)(nothing); 09006 struct iax_ie_data ied; 09007 ast_mutex_lock(&iaxsl[callno]); 09008 if (iaxs[callno]) { 09009 memset(&ied, 0, sizeof(ied)); 09010 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 09011 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 09012 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 09013 } 09014 ast_mutex_unlock(&iaxsl[callno]); 09015 }
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 3252 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().
03253 { 03254 /* Just deliver the packet by using queueing. This is called by 03255 the IAX thread with the iaxsl lock held. */ 03256 struct iax_frame *fr = data; 03257 fr->retrans = -1; 03258 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03259 if (iaxs[fr->callno] && !ast_test_flag64(iaxs[fr->callno], IAX_ALREADYGONE)) 03260 iax2_queue_frame(fr->callno, &fr->af); 03261 /* Free our iax frame */ 03262 iax2_frame_free(fr); 03263 /* And don't run again */ 03264 return 0; 03265 }
static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8580 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().
08581 { 08582 struct iax2_peer *peer = (struct iax2_peer *) data; 08583 08584 if (!peer) 08585 return; 08586 if (peer->expire == -1) { 08587 /* Removed already (possibly through CLI), ignore */ 08588 return; 08589 } 08590 08591 peer->expire = -1; 08592 08593 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08594 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08595 realtime_update_peer(peer->name, &peer->addr, 0); 08596 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08597 /* modify entry in peercnts table as _not_ registered */ 08598 peercnt_modify(0, 0, &peer->addr); 08599 /* Reset the address */ 08600 memset(&peer->addr, 0, sizeof(peer->addr)); 08601 /* Reset expiry value */ 08602 peer->expiry = min_reg_expire; 08603 if (!ast_test_flag64(peer, IAX_TEMPONLY)) 08604 ast_db_del("IAX/Registry", peer->name); 08605 register_peer_exten(peer, 0); 08606 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 08607 if (iax2_regfunk) 08608 iax2_regfunk(peer->name, 0); 08609 08610 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) 08611 unlink_peer(peer); 08612 08613 peer_unref(peer); 08614 }
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 2755 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().
02756 { 02757 int res = 0; 02758 int x; 02759 /* this call is calltoken validated as long as it is either NEW_FORCE 02760 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02761 int validated = (new > NEW_ALLOW) ? 1 : 0; 02762 char host[80]; 02763 02764 if (new <= NEW_ALLOW) { 02765 if (callno) { 02766 struct chan_iax2_pvt *pvt; 02767 struct chan_iax2_pvt tmp_pvt = { 02768 .callno = dcallno, 02769 .peercallno = callno, 02770 .transfercallno = callno, 02771 /* hack!! */ 02772 .frames_received = check_dcallno, 02773 }; 02774 02775 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02776 /* this works for finding normal call numbers not involving transfering */ 02777 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02778 if (return_locked) { 02779 ast_mutex_lock(&iaxsl[pvt->callno]); 02780 } 02781 res = pvt->callno; 02782 ao2_ref(pvt, -1); 02783 pvt = NULL; 02784 return res; 02785 } 02786 /* this searches for transfer call numbers that might not get caught otherwise */ 02787 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02788 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02789 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02790 if (return_locked) { 02791 ast_mutex_lock(&iaxsl[pvt->callno]); 02792 } 02793 res = pvt->callno; 02794 ao2_ref(pvt, -1); 02795 pvt = NULL; 02796 return res; 02797 } 02798 } 02799 /* This will occur on the first response to a message that we initiated, 02800 * such as a PING. */ 02801 if (dcallno) { 02802 ast_mutex_lock(&iaxsl[dcallno]); 02803 } 02804 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02805 iaxs[dcallno]->peercallno = callno; 02806 res = dcallno; 02807 store_by_peercallno(iaxs[dcallno]); 02808 if (!res || !return_locked) { 02809 ast_mutex_unlock(&iaxsl[dcallno]); 02810 } 02811 return res; 02812 } 02813 if (dcallno) { 02814 ast_mutex_unlock(&iaxsl[dcallno]); 02815 } 02816 #ifdef IAX_OLD_FIND 02817 /* If we get here, we SHOULD NOT find a call structure for this 02818 callno; if we do, it means that there is a call structure that 02819 has a peer callno but did NOT get entered into the hash table, 02820 which is bad. 02821 02822 If we find a call structure using this old, slow method, output a log 02823 message so we'll know about it. After a few months of leaving this in 02824 place, if we don't hear about people seeing these messages, we can 02825 remove this code for good. 02826 */ 02827 02828 for (x = 1; !res && x < maxnontrunkcall; x++) { 02829 ast_mutex_lock(&iaxsl[x]); 02830 if (iaxs[x]) { 02831 /* Look for an exact match */ 02832 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02833 res = x; 02834 } 02835 } 02836 if (!res || !return_locked) 02837 ast_mutex_unlock(&iaxsl[x]); 02838 } 02839 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02840 ast_mutex_lock(&iaxsl[x]); 02841 if (iaxs[x]) { 02842 /* Look for an exact match */ 02843 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02844 res = x; 02845 } 02846 } 02847 if (!res || !return_locked) 02848 ast_mutex_unlock(&iaxsl[x]); 02849 } 02850 #endif 02851 } 02852 if (!res && (new >= NEW_ALLOW)) { 02853 struct callno_entry *callno_entry; 02854 /* It may seem odd that we look through the peer list for a name for 02855 * this *incoming* call. Well, it is weird. However, users don't 02856 * have an IP address/port number that we can match against. So, 02857 * this is just checking for a peer that has that IP/port and 02858 * assuming that we have a user of the same name. This isn't always 02859 * correct, but it will be changed if needed after authentication. */ 02860 if (!iax2_getpeername(*sin, host, sizeof(host))) 02861 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02862 02863 if (peercnt_add(sin)) { 02864 /* This address has hit its callnumber limit. When the limit 02865 * is reached, the connection is not added to the peercnts table.*/ 02866 return 0; 02867 } 02868 02869 if (!(callno_entry = get_unused_callno(0, validated))) { 02870 /* since we ran out of space, remove the peercnt 02871 * entry we added earlier */ 02872 peercnt_remove_by_addr(sin); 02873 ast_log(LOG_WARNING, "No more space\n"); 02874 return 0; 02875 } 02876 x = callno_entry->callno; 02877 ast_mutex_lock(&iaxsl[x]); 02878 02879 iaxs[x] = new_iax(sin, host); 02880 update_max_nontrunk(); 02881 if (iaxs[x]) { 02882 if (iaxdebug) 02883 ast_debug(1, "Creating new call structure %d\n", x); 02884 iaxs[x]->callno_entry = callno_entry; 02885 iaxs[x]->sockfd = sockfd; 02886 iaxs[x]->addr.sin_port = sin->sin_port; 02887 iaxs[x]->addr.sin_family = sin->sin_family; 02888 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02889 iaxs[x]->peercallno = callno; 02890 iaxs[x]->callno = x; 02891 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02892 iaxs[x]->expiry = min_reg_expire; 02893 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02894 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02895 iaxs[x]->amaflags = amaflags; 02896 ast_copy_flags64(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 02897 ast_string_field_set(iaxs[x], accountcode, accountcode); 02898 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02899 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02900 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02901 02902 if (iaxs[x]->peercallno) { 02903 store_by_peercallno(iaxs[x]); 02904 } 02905 } else { 02906 ast_log(LOG_WARNING, "Out of resources\n"); 02907 ast_mutex_unlock(&iaxsl[x]); 02908 replace_callno(callno_entry); 02909 return 0; 02910 } 02911 if (!return_locked) 02912 ast_mutex_unlock(&iaxsl[x]); 02913 res = x; 02914 } 02915 return res; 02916 }
static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4043 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().
04044 { 04045 int callno = PTR_TO_CALLNO(p); 04046 struct chan_iax2_pvt *pvt = NULL; 04047 struct iax_frame *fr; 04048 jb_frame frame; 04049 int ret; 04050 long ms; 04051 long next; 04052 struct timeval now = ast_tvnow(); 04053 04054 /* Make sure we have a valid private structure before going on */ 04055 ast_mutex_lock(&iaxsl[callno]); 04056 pvt = iaxs[callno]; 04057 if (!pvt) { 04058 /* No go! */ 04059 ast_mutex_unlock(&iaxsl[callno]); 04060 return; 04061 } 04062 04063 pvt->jbid = -1; 04064 04065 /* round up a millisecond since ast_sched_runq does; */ 04066 /* prevents us from spinning while waiting for our now */ 04067 /* to catch up with runq's now */ 04068 now.tv_usec += 1000; 04069 04070 ms = ast_tvdiff_ms(now, pvt->rxcore); 04071 04072 if(ms >= (next = jb_next(pvt->jb))) { 04073 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 04074 switch(ret) { 04075 case JB_OK: 04076 fr = frame.data; 04077 __do_deliver(fr); 04078 /* __do_deliver() can cause the call to disappear */ 04079 pvt = iaxs[callno]; 04080 break; 04081 case JB_INTERP: 04082 { 04083 struct ast_frame af = { 0, }; 04084 04085 /* create an interpolation frame */ 04086 af.frametype = AST_FRAME_VOICE; 04087 af.subclass.codec = pvt->voiceformat; 04088 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 04089 af.src = "IAX2 JB interpolation"; 04090 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 04091 af.offset = AST_FRIENDLY_OFFSET; 04092 04093 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 04094 * which we'd need to malloc, and then it would free it. That seems like a drag */ 04095 if (!ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) { 04096 iax2_queue_frame(callno, &af); 04097 /* iax2_queue_frame() could cause the call to disappear */ 04098 pvt = iaxs[callno]; 04099 } 04100 } 04101 break; 04102 case JB_DROP: 04103 iax2_frame_free(frame.data); 04104 break; 04105 case JB_NOFRAME: 04106 case JB_EMPTY: 04107 /* do nothing */ 04108 break; 04109 default: 04110 /* shouldn't happen */ 04111 break; 04112 } 04113 } 04114 if (pvt) 04115 update_jbsched(pvt); 04116 ast_mutex_unlock(&iaxsl[callno]); 04117 }
static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8250 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
08251 { 08252 struct iax2_registry *reg = (struct iax2_registry *)data; 08253 reg->expire = -1; 08254 iax2_do_register(reg); 08255 }
static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11941 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().
11942 { 11943 struct iax2_peer *peer = (struct iax2_peer *)data; 11944 int callno; 11945 11946 if (peer->lastms > -1) { 11947 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 11948 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 11949 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 11950 } 11951 if ((callno = peer->callno) > 0) { 11952 ast_mutex_lock(&iaxsl[callno]); 11953 iax2_destroy(callno); 11954 ast_mutex_unlock(&iaxsl[callno]); 11955 } 11956 peer->callno = 0; 11957 peer->lastms = -1; 11958 /* Try again quickly */ 11959 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11960 if (peer->pokeexpire == -1) 11961 peer_unref(peer); 11962 }
static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9062 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
09063 { 09064 struct iax2_peer *peer = (struct iax2_peer *)data; 09065 iax2_poke_peer(peer, 0); 09066 peer_unref(peer); 09067 }
static int __iax2_show_peers | ( | int | fd, | |
int * | total, | |||
struct mansession * | s, | |||
const int | argc, | |||
const char *const | argv[] | |||
) | [static] |
Definition at line 6616 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().
06617 { 06618 regex_t regexbuf; 06619 int havepattern = 0; 06620 int total_peers = 0; 06621 int online_peers = 0; 06622 int offline_peers = 0; 06623 int unmonitored_peers = 0; 06624 struct ao2_iterator i; 06625 06626 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s\n" 06627 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s\n" 06628 06629 struct iax2_peer *peer = NULL; 06630 char name[256]; 06631 struct ast_str *encmethods = ast_str_alloca(256); 06632 int registeredonly=0; 06633 char idtext[256] = ""; 06634 switch (argc) { 06635 case 6: 06636 if (!strcasecmp(argv[3], "registered")) 06637 registeredonly = 1; 06638 else 06639 return RESULT_SHOWUSAGE; 06640 if (!strcasecmp(argv[4], "like")) { 06641 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06642 return RESULT_SHOWUSAGE; 06643 havepattern = 1; 06644 } else 06645 return RESULT_SHOWUSAGE; 06646 break; 06647 case 5: 06648 if (!strcasecmp(argv[3], "like")) { 06649 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06650 return RESULT_SHOWUSAGE; 06651 havepattern = 1; 06652 } else 06653 return RESULT_SHOWUSAGE; 06654 break; 06655 case 4: 06656 if (!strcasecmp(argv[3], "registered")) 06657 registeredonly = 1; 06658 else 06659 return RESULT_SHOWUSAGE; 06660 break; 06661 case 3: 06662 break; 06663 default: 06664 return RESULT_SHOWUSAGE; 06665 } 06666 06667 06668 if (!s) 06669 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status"); 06670 06671 i = ao2_iterator_init(peers, 0); 06672 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 06673 char nm[20]; 06674 char status[20]; 06675 int retstatus; 06676 struct sockaddr_in peer_addr; 06677 06678 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 06679 06680 if (registeredonly && !peer_addr.sin_addr.s_addr) { 06681 continue; 06682 } 06683 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) { 06684 continue; 06685 } 06686 06687 if (!ast_strlen_zero(peer->username)) 06688 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06689 else 06690 ast_copy_string(name, peer->name, sizeof(name)); 06691 06692 encmethods_to_str(peer->encmethods, encmethods); 06693 retstatus = peer_status(peer, status, sizeof(status)); 06694 if (retstatus > 0) 06695 online_peers++; 06696 else if (!retstatus) 06697 offline_peers++; 06698 else 06699 unmonitored_peers++; 06700 06701 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06702 06703 if (s) { 06704 astman_append(s, 06705 "Event: PeerEntry\r\n%s" 06706 "Channeltype: IAX2\r\n" 06707 "ObjectName: %s\r\n" 06708 "ChanObjectType: peer\r\n" 06709 "IPaddress: %s\r\n" 06710 "IPport: %d\r\n" 06711 "Dynamic: %s\r\n" 06712 "Trunk: %s\r\n" 06713 "Encryption: %s\r\n" 06714 "Status: %s\r\n\r\n", 06715 idtext, 06716 name, 06717 ast_sockaddr_stringify_addr(&peer->addr), 06718 ast_sockaddr_port(&peer->addr), 06719 ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no", 06720 ast_test_flag64(peer, IAX_TRUNK) ? "yes" : "no", 06721 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06722 status); 06723 } else { 06724 ast_cli(fd, FORMAT, name, 06725 ast_sockaddr_stringify_addr(&peer->addr), 06726 ast_test_flag64(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06727 nm, 06728 ast_sockaddr_port(&peer->addr), 06729 ast_test_flag64(peer, IAX_TRUNK) ? "(T)" : " ", 06730 peer->encmethods ? "(E)" : " ", 06731 status); 06732 } 06733 total_peers++; 06734 } 06735 ao2_iterator_destroy(&i); 06736 06737 if (!s) 06738 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]\n", 06739 total_peers, online_peers, offline_peers, unmonitored_peers); 06740 06741 if (havepattern) 06742 regfree(®exbuf); 06743 06744 if (total) 06745 *total = total_peers; 06746 06747 return RESULT_SUCCESS; 06748 #undef FORMAT 06749 #undef FORMAT2 06750 }
static void __reg_module | ( | void | ) | [static] |
Definition at line 14775 of file chan_iax2.c.
static int __schedule_action | ( | void(*)(const void *data) | func, | |
const void * | data, | |||
const char * | funcname | |||
) | [static] |
Definition at line 1460 of file chan_iax2.c.
References ast_copy_string(), ast_debug, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, signal_condition(), and thread.
01461 { 01462 struct iax2_thread *thread = NULL; 01463 static time_t lasterror; 01464 static time_t t; 01465 01466 thread = find_idle_thread(); 01467 01468 if (thread != NULL) { 01469 thread->schedfunc = func; 01470 thread->scheddata = data; 01471 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01472 #ifdef DEBUG_SCHED_MULTITHREAD 01473 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01474 #endif 01475 signal_condition(&thread->lock, &thread->cond); 01476 return 0; 01477 } 01478 time(&t); 01479 if (t != lasterror) 01480 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01481 lasterror = t; 01482 01483 return -1; 01484 }
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 7442 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().
07444 { 07445 struct ast_frame f = { 0, }; 07446 int res = 0; 07447 07448 f.frametype = type; 07449 f.subclass.integer = command; 07450 f.datalen = datalen; 07451 f.src = __FUNCTION__; 07452 f.data.ptr = (void *) data; 07453 07454 if ((res = queue_signalling(i, &f)) <= 0) { 07455 return res; 07456 } 07457 07458 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07459 }
static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1571 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().
01572 { 01573 int callno = (long) data; 01574 01575 ast_mutex_lock(&iaxsl[callno]); 01576 01577 if (iaxs[callno]) { 01578 if (iaxs[callno]->peercallno) { 01579 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01580 if (iaxs[callno]->lagid != DONT_RESCHEDULE) { 01581 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01582 } 01583 } 01584 } else { 01585 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01586 } 01587 01588 ast_mutex_unlock(&iaxsl[callno]); 01589 }
static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1504 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().
01505 { 01506 int callno = (long) data; 01507 01508 ast_mutex_lock(&iaxsl[callno]); 01509 01510 if (iaxs[callno]) { 01511 if (iaxs[callno]->peercallno) { 01512 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01513 if (iaxs[callno]->pingid != DONT_RESCHEDULE) { 01514 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01515 } 01516 } 01517 } else { 01518 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01519 } 01520 01521 ast_mutex_unlock(&iaxsl[callno]); 01522 }
static int __unload_module | ( | void | ) | [static] |
Definition at line 14278 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.
14279 { 14280 struct ast_context *con; 14281 int x; 14282 14283 network_change_event_unsubscribe(); 14284 14285 ast_manager_unregister("IAXpeers"); 14286 ast_manager_unregister("IAXpeerlist"); 14287 ast_manager_unregister("IAXnetstats"); 14288 ast_manager_unregister("IAXregistry"); 14289 ast_unregister_application(papp); 14290 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14291 ast_unregister_switch(&iax2_switch); 14292 ast_channel_unregister(&iax2_tech); 14293 14294 if (netthreadid != AST_PTHREADT_NULL) { 14295 pthread_cancel(netthreadid); 14296 pthread_kill(netthreadid, SIGURG); 14297 pthread_join(netthreadid, NULL); 14298 } 14299 14300 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14301 if (iaxs[x]) { 14302 iax2_destroy(x); 14303 } 14304 } 14305 14306 /* Call for all threads to halt */ 14307 cleanup_thread_list(&idle_list); 14308 cleanup_thread_list(&active_list); 14309 cleanup_thread_list(&dynamic_list); 14310 14311 ast_netsock_release(netsock); 14312 ast_netsock_release(outsock); 14313 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 14314 if (iaxs[x]) { 14315 iax2_destroy(x); 14316 } 14317 } 14318 ast_manager_unregister( "IAXpeers" ); 14319 ast_manager_unregister( "IAXpeerlist" ); 14320 ast_manager_unregister( "IAXnetstats" ); 14321 ast_manager_unregister( "IAXregistry" ); 14322 ast_unregister_application(papp); 14323 #ifdef TEST_FRAMEWORK 14324 AST_TEST_UNREGISTER(test_iax2_peers_get); 14325 AST_TEST_UNREGISTER(test_iax2_users_get); 14326 #endif 14327 ast_data_unregister(NULL); 14328 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14329 ast_unregister_switch(&iax2_switch); 14330 ast_channel_unregister(&iax2_tech); 14331 delete_users(); 14332 iax_provision_unload(); 14333 reload_firmware(1); 14334 14335 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14336 ast_mutex_destroy(&iaxsl[x]); 14337 } 14338 14339 ao2_ref(peers, -1); 14340 ao2_ref(users, -1); 14341 ao2_ref(iax_peercallno_pvts, -1); 14342 ao2_ref(iax_transfercallno_pvts, -1); 14343 ao2_ref(peercnts, -1); 14344 ao2_ref(callno_limits, -1); 14345 ao2_ref(calltoken_ignores, -1); 14346 ao2_ref(callno_pool, -1); 14347 ao2_ref(callno_pool_trunk, -1); 14348 if (timer) { 14349 ast_timer_close(timer); 14350 } 14351 transmit_processor = ast_taskprocessor_unreference(transmit_processor); 14352 sched = ast_sched_thread_destroy(sched); 14353 14354 con = ast_context_find(regcontext); 14355 if (con) 14356 ast_context_destroy(con, "IAX2"); 14357 ast_unload_realtime("iaxpeers"); 14358 return 0; 14359 }
static void __unreg_module | ( | void | ) | [static] |
Definition at line 14775 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 13918 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.
13919 { 13920 struct chan_iax2_pvt *pvt; 13921 unsigned int callno; 13922 int res = 0; 13923 13924 if (!chan || chan->tech != &iax2_tech) { 13925 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13926 return -1; 13927 } 13928 13929 callno = PTR_TO_CALLNO(chan->tech_pvt); 13930 ast_mutex_lock(&iaxsl[callno]); 13931 if (!(pvt = iaxs[callno])) { 13932 ast_mutex_unlock(&iaxsl[callno]); 13933 return -1; 13934 } 13935 13936 if (!strcasecmp(args, "osptoken")) { 13937 ast_copy_string(buf, pvt->osptoken, buflen); 13938 } else if (!strcasecmp(args, "peerip")) { 13939 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 13940 } else if (!strcasecmp(args, "peername")) { 13941 ast_copy_string(buf, pvt->username, buflen); 13942 } else if (!strcasecmp(args, "secure_signaling") || !strcasecmp(args, "secure_media")) { 13943 snprintf(buf, buflen, "%s", IAX_CALLENCRYPTED(pvt) ? "1" : ""); 13944 } else { 13945 res = -1; 13946 } 13947 13948 ast_mutex_unlock(&iaxsl[callno]); 13949 13950 return res; 13951 }
static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 9777 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.
09778 { 09779 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09780 AST_LIST_HEAD(, ast_var_t) *varlist; 09781 struct ast_var_t *var; 09782 09783 if (!variablestore) { 09784 *buf = '\0'; 09785 return 0; 09786 } 09787 varlist = variablestore->data; 09788 09789 AST_LIST_LOCK(varlist); 09790 AST_LIST_TRAVERSE(varlist, var, entries) { 09791 if (strcmp(var->name, data) == 0) { 09792 ast_copy_string(buf, var->value, len); 09793 break; 09794 } 09795 } 09796 AST_LIST_UNLOCK(varlist); 09797 return 0; 09798 }
static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
const char * | value | |||
) | [static] |
Definition at line 9800 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.
09801 { 09802 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09803 AST_LIST_HEAD(, ast_var_t) *varlist; 09804 struct ast_var_t *var; 09805 09806 if (!variablestore) { 09807 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09808 if (!variablestore) { 09809 ast_log(LOG_ERROR, "Memory allocation error\n"); 09810 return -1; 09811 } 09812 varlist = ast_calloc(1, sizeof(*varlist)); 09813 if (!varlist) { 09814 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09815 return -1; 09816 } 09817 09818 AST_LIST_HEAD_INIT(varlist); 09819 variablestore->data = varlist; 09820 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09821 ast_channel_datastore_add(chan, variablestore); 09822 } else 09823 varlist = variablestore->data; 09824 09825 AST_LIST_LOCK(varlist); 09826 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09827 if (strcmp(var->name, data) == 0) { 09828 AST_LIST_REMOVE_CURRENT(entries); 09829 ast_var_delete(var); 09830 break; 09831 } 09832 } 09833 AST_LIST_TRAVERSE_SAFE_END; 09834 var = ast_var_assign(data, value); 09835 if (var) 09836 AST_LIST_INSERT_TAIL(varlist, var, entries); 09837 else 09838 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09839 AST_LIST_UNLOCK(varlist); 09840 return 0; 09841 }
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 4712 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().
04713 { 04714 /* first make sure their are two empty bytes left in ied->buf */ 04715 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04716 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04717 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04718 pvt->calltoken_ie_len = 2; 04719 } 04720 }
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 7500 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
07501 { 07502 while(con) { 07503 if (!strcmp(con->context, context) || !strcmp(con->context, "*")) 07504 return -1; 07505 con = con->next; 07506 } 07507 return 0; 07508 }
static int ast_cli_netstats | ( | struct mansession * | s, | |
int | fd, | |||
int | limit_fmt | |||
) | [static] |
Definition at line 7201 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().
07202 { 07203 int x; 07204 int numchans = 0; 07205 char first_message[10] = { 0, }; 07206 char last_message[10] = { 0, }; 07207 #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" 07208 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 07209 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07210 ast_mutex_lock(&iaxsl[x]); 07211 if (iaxs[x]) { 07212 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 07213 jb_info jbinfo; 07214 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07215 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07216 07217 if(ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07218 jb_getinfo(iaxs[x]->jb, &jbinfo); 07219 localjitter = jbinfo.jitter; 07220 localdelay = jbinfo.current - jbinfo.min; 07221 locallost = jbinfo.frames_lost; 07222 locallosspct = jbinfo.losspct/1000; 07223 localdropped = jbinfo.frames_dropped; 07224 localooo = jbinfo.frames_ooo; 07225 } else { 07226 localjitter = -1; 07227 localdelay = 0; 07228 locallost = -1; 07229 locallosspct = -1; 07230 localdropped = 0; 07231 localooo = -1; 07232 } 07233 if (s) 07234 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07235 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07236 iaxs[x]->pingtime, 07237 localjitter, 07238 localdelay, 07239 locallost, 07240 locallosspct, 07241 localdropped, 07242 localooo, 07243 iaxs[x]->frames_received/1000, 07244 iaxs[x]->remote_rr.jitter, 07245 iaxs[x]->remote_rr.delay, 07246 iaxs[x]->remote_rr.losscnt, 07247 iaxs[x]->remote_rr.losspct, 07248 iaxs[x]->remote_rr.dropped, 07249 iaxs[x]->remote_rr.ooo, 07250 iaxs[x]->remote_rr.packets/1000, 07251 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07252 first_message, 07253 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07254 last_message); 07255 else 07256 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 07257 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07258 iaxs[x]->pingtime, 07259 localjitter, 07260 localdelay, 07261 locallost, 07262 locallosspct, 07263 localdropped, 07264 localooo, 07265 iaxs[x]->frames_received/1000, 07266 iaxs[x]->remote_rr.jitter, 07267 iaxs[x]->remote_rr.delay, 07268 iaxs[x]->remote_rr.losscnt, 07269 iaxs[x]->remote_rr.losspct, 07270 iaxs[x]->remote_rr.dropped, 07271 iaxs[x]->remote_rr.ooo, 07272 iaxs[x]->remote_rr.packets/1000, 07273 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07274 first_message, 07275 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07276 last_message); 07277 numchans++; 07278 } 07279 ast_mutex_unlock(&iaxsl[x]); 07280 } 07281 07282 return numchans; 07283 }
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 5695 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().
05696 { 05697 struct ast_channel *tmp; 05698 struct chan_iax2_pvt *i; 05699 struct ast_variable *v = NULL; 05700 05701 if (!(i = iaxs[callno])) { 05702 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05703 return NULL; 05704 } 05705 05706 /* Don't hold call lock */ 05707 ast_mutex_unlock(&iaxsl[callno]); 05708 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); 05709 ast_mutex_lock(&iaxsl[callno]); 05710 if (i != iaxs[callno]) { 05711 if (tmp) { 05712 /* unlock and relock iaxsl[callno] to preserve locking order */ 05713 ast_mutex_unlock(&iaxsl[callno]); 05714 tmp = ast_channel_release(tmp); 05715 ast_mutex_lock(&iaxsl[callno]); 05716 } 05717 return NULL; 05718 } 05719 iax2_ami_channelupdate(i); 05720 if (!tmp) 05721 return NULL; 05722 tmp->tech = &iax2_tech; 05723 /* We can support any format by default, until we get restricted */ 05724 tmp->nativeformats = capability; 05725 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05726 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05727 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05728 05729 if (!ast_strlen_zero(i->parkinglot)) 05730 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05731 /* Don't use ast_set_callerid() here because it will 05732 * generate a NewCallerID event before the NewChannel event */ 05733 if (!ast_strlen_zero(i->ani)) { 05734 tmp->caller.ani.number.valid = 1; 05735 tmp->caller.ani.number.str = ast_strdup(i->ani); 05736 } else if (!ast_strlen_zero(i->cid_num)) { 05737 tmp->caller.ani.number.valid = 1; 05738 tmp->caller.ani.number.str = ast_strdup(i->cid_num); 05739 } 05740 tmp->dialed.number.str = ast_strdup(i->dnid); 05741 if (!ast_strlen_zero(i->rdnis)) { 05742 tmp->redirecting.from.number.valid = 1; 05743 tmp->redirecting.from.number.str = ast_strdup(i->rdnis); 05744 } 05745 tmp->caller.id.name.presentation = i->calling_pres; 05746 tmp->caller.id.number.presentation = i->calling_pres; 05747 tmp->caller.id.number.plan = i->calling_ton; 05748 tmp->dialed.transit_network_select = i->calling_tns; 05749 if (!ast_strlen_zero(i->language)) 05750 ast_string_field_set(tmp, language, i->language); 05751 if (!ast_strlen_zero(i->accountcode)) 05752 ast_string_field_set(tmp, accountcode, i->accountcode); 05753 if (i->amaflags) 05754 tmp->amaflags = i->amaflags; 05755 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05756 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05757 if (i->adsi) 05758 tmp->adsicpe = i->peeradsicpe; 05759 else 05760 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05761 i->owner = tmp; 05762 i->capability = capability; 05763 05764 /* Set inherited variables */ 05765 if (i->vars) { 05766 for (v = i->vars ; v ; v = v->next) 05767 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05768 } 05769 if (i->iaxvars) { 05770 struct ast_datastore *variablestore; 05771 struct ast_variable *var, *prev = NULL; 05772 AST_LIST_HEAD(, ast_var_t) *varlist; 05773 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05774 varlist = ast_calloc(1, sizeof(*varlist)); 05775 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05776 if (variablestore && varlist) { 05777 variablestore->data = varlist; 05778 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05779 AST_LIST_HEAD_INIT(varlist); 05780 for (var = i->iaxvars; var; var = var->next) { 05781 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05782 if (prev) 05783 ast_free(prev); 05784 prev = var; 05785 if (!newvar) { 05786 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05787 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05788 } else { 05789 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05790 } 05791 } 05792 if (prev) 05793 ast_free(prev); 05794 i->iaxvars = NULL; 05795 ast_channel_datastore_add(i->owner, variablestore); 05796 } else { 05797 if (variablestore) { 05798 ast_datastore_free(variablestore); 05799 } 05800 if (varlist) { 05801 ast_free(varlist); 05802 } 05803 } 05804 } 05805 05806 if (state != AST_STATE_DOWN) { 05807 if (ast_pbx_start(tmp)) { 05808 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05809 ast_hangup(tmp); 05810 i->owner = NULL; 05811 return NULL; 05812 } 05813 } 05814 05815 ast_module_ref(ast_module_info->self); 05816 return tmp; 05817 }
static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3542 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and transmit_frame().
03543 { 03544 #ifdef SCHED_MULTITHREADED 03545 if (schedule_action(__attempt_transmit, data)) 03546 #endif 03547 __attempt_transmit(data); 03548 return 0; 03549 }
static int auth_fail | ( | int | callno, | |
int | failcode | |||
) | [static] |
Definition at line 8987 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().
08988 { 08989 /* Schedule sending the authentication failure in one second, to prevent 08990 guessing */ 08991 if (iaxs[callno]) { 08992 iaxs[callno]->authfail = failcode; 08993 if (delayreject) { 08994 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 08995 sched, 1000, auth_reject, (void *)(long)callno); 08996 } else 08997 auth_reject((void *)(long)callno); 08998 } 08999 return 0; 09000 }
static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 8973 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().
08974 { 08975 int callno = (int)(long)(data); 08976 ast_mutex_lock(&iaxsl[callno]); 08977 if (iaxs[callno]) 08978 iaxs[callno]->authid = -1; 08979 ast_mutex_unlock(&iaxsl[callno]); 08980 #ifdef SCHED_MULTITHREADED 08981 if (schedule_action(__auth_reject, data)) 08982 #endif 08983 __auth_reject(data); 08984 return 0; 08985 }
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 8072 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().
08073 { 08074 int res = -1; 08075 int x; 08076 if (!ast_strlen_zero(keyn)) { 08077 if (!(authmethods & IAX_AUTH_RSA)) { 08078 if (ast_strlen_zero(secret)) 08079 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)); 08080 } else if (ast_strlen_zero(challenge)) { 08081 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 08082 } else { 08083 char sig[256]; 08084 struct ast_key *key; 08085 key = ast_key_get(keyn, AST_KEY_PRIVATE); 08086 if (!key) { 08087 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 08088 } else { 08089 if (ast_sign(key, (char*)challenge, sig)) { 08090 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 08091 res = -1; 08092 } else { 08093 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 08094 res = 0; 08095 } 08096 } 08097 } 08098 } 08099 /* Fall back */ 08100 if (res && !ast_strlen_zero(secret)) { 08101 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 08102 struct MD5Context md5; 08103 unsigned char digest[16]; 08104 char digres[128]; 08105 MD5Init(&md5); 08106 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 08107 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 08108 MD5Final(digest, &md5); 08109 /* If they support md5, authenticate with it. */ 08110 for (x=0;x<16;x++) 08111 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 08112 if (pvt) { 08113 build_encryption_keys(digest, pvt); 08114 } 08115 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 08116 res = 0; 08117 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 08118 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 08119 res = 0; 08120 } else 08121 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 08122 } 08123 return res; 08124 }
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 8130 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().
08131 { 08132 struct iax2_peer *peer = NULL; 08133 /* Start pessimistic */ 08134 int res = -1; 08135 int authmethods = 0; 08136 struct iax_ie_data ied; 08137 uint16_t callno = p->callno; 08138 08139 memset(&ied, 0, sizeof(ied)); 08140 08141 if (ies->username) 08142 ast_string_field_set(p, username, ies->username); 08143 if (ies->challenge) 08144 ast_string_field_set(p, challenge, ies->challenge); 08145 if (ies->authmethods) 08146 authmethods = ies->authmethods; 08147 if (authmethods & IAX_AUTH_MD5) 08148 merge_encryption(p, ies->encmethods); 08149 else 08150 p->encmethods = 0; 08151 08152 /* Check for override RSA authentication first */ 08153 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 08154 /* Normal password authentication */ 08155 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 08156 } else { 08157 struct ao2_iterator i = ao2_iterator_init(peers, 0); 08158 while ((peer = ao2_iterator_next(&i))) { 08159 struct sockaddr_in peer_addr; 08160 08161 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 08162 08163 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 08164 /* No peer specified at our end, or this is the peer */ 08165 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 08166 /* No username specified in peer rule, or this is the right username */ 08167 && (!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))) 08168 /* No specified host, or this is our host */ 08169 ) { 08170 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 08171 if (!res) { 08172 peer_unref(peer); 08173 break; 08174 } 08175 } 08176 peer_unref(peer); 08177 } 08178 ao2_iterator_destroy(&i); 08179 if (!peer) { 08180 /* We checked our list and didn't find one. It's unlikely, but possible, 08181 that we're trying to authenticate *to* a realtime peer */ 08182 const char *peer_name = ast_strdupa(p->peer); 08183 ast_mutex_unlock(&iaxsl[callno]); 08184 if ((peer = realtime_peer(peer_name, NULL))) { 08185 ast_mutex_lock(&iaxsl[callno]); 08186 if (!(p = iaxs[callno])) { 08187 peer_unref(peer); 08188 return -1; 08189 } 08190 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 08191 peer_unref(peer); 08192 } 08193 if (!peer) { 08194 ast_mutex_lock(&iaxsl[callno]); 08195 if (!(p = iaxs[callno])) 08196 return -1; 08197 } 08198 } 08199 } 08200 08201 if (ies->encmethods) { 08202 ast_set_flag64(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 08203 } else if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 08204 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set"); 08205 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 08206 } 08207 if (!res) { 08208 struct ast_datastore *variablestore; 08209 struct ast_variable *var, *prev = NULL; 08210 AST_LIST_HEAD(, ast_var_t) *varlist; 08211 varlist = ast_calloc(1, sizeof(*varlist)); 08212 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 08213 if (variablestore && varlist && p->owner) { 08214 variablestore->data = varlist; 08215 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 08216 AST_LIST_HEAD_INIT(varlist); 08217 for (var = ies->vars; var; var = var->next) { 08218 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 08219 if (prev) 08220 ast_free(prev); 08221 prev = var; 08222 if (!newvar) { 08223 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 08224 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08225 } else { 08226 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 08227 } 08228 } 08229 if (prev) 08230 ast_free(prev); 08231 ies->vars = NULL; 08232 ast_channel_datastore_add(p->owner, variablestore); 08233 } else { 08234 if (p->owner) 08235 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 08236 if (variablestore) 08237 ast_datastore_free(variablestore); 08238 if (varlist) 08239 ast_free(varlist); 08240 } 08241 } 08242 08243 if (!res) 08244 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 08245 return res; 08246 }
static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7778 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().
07779 { 07780 struct iax_ie_data ied; 07781 int res = -1, authreq_restrict = 0; 07782 char challenge[10]; 07783 struct chan_iax2_pvt *p = iaxs[call_num]; 07784 07785 memset(&ied, 0, sizeof(ied)); 07786 07787 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07788 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07789 struct iax2_user *user, tmp_user = { 07790 .name = p->username, 07791 }; 07792 07793 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07794 if (user) { 07795 if (user->curauthreq == user->maxauthreq) 07796 authreq_restrict = 1; 07797 else 07798 user->curauthreq++; 07799 user = user_unref(user); 07800 } 07801 } 07802 07803 /* If the AUTHREQ limit test failed, send back an error */ 07804 if (authreq_restrict) { 07805 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07806 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07807 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07808 return 0; 07809 } 07810 07811 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07812 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07813 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07814 ast_string_field_set(p, challenge, challenge); 07815 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07816 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07817 } 07818 if (p->encmethods) 07819 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07820 07821 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07822 07823 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07824 07825 if (p->encmethods) 07826 ast_set_flag64(p, IAX_ENCRYPTED); 07827 07828 return res; 07829 }
static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 7831 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().
07832 { 07833 char requeststr[256]; 07834 char md5secret[256] = ""; 07835 char secret[256] = ""; 07836 char rsasecret[256] = ""; 07837 int res = -1; 07838 int x; 07839 struct iax2_user *user, tmp_user = { 07840 .name = p->username, 07841 }; 07842 07843 if (p->authrej) { 07844 return res; 07845 } 07846 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07847 if (user) { 07848 if (ast_test_flag64(p, IAX_MAXAUTHREQ)) { 07849 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07850 ast_clear_flag64(p, IAX_MAXAUTHREQ); 07851 } 07852 ast_string_field_set(p, host, user->name); 07853 user = user_unref(user); 07854 } 07855 if (ast_test_flag64(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 07856 ast_log(LOG_NOTICE, "Call Terminated, Incoming call is unencrypted while force encrypt is enabled."); 07857 return res; 07858 } 07859 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07860 return res; 07861 if (ies->password) 07862 ast_copy_string(secret, ies->password, sizeof(secret)); 07863 if (ies->md5_result) 07864 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07865 if (ies->rsa_result) 07866 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07867 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07868 struct ast_key *key; 07869 char *keyn; 07870 char tmpkey[256]; 07871 char *stringp=NULL; 07872 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07873 stringp=tmpkey; 07874 keyn = strsep(&stringp, ":"); 07875 while(keyn) { 07876 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07877 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07878 res = 0; 07879 break; 07880 } else if (!key) 07881 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07882 keyn = strsep(&stringp, ":"); 07883 } 07884 } else if (p->authmethods & IAX_AUTH_MD5) { 07885 struct MD5Context md5; 07886 unsigned char digest[16]; 07887 char *tmppw, *stringp; 07888 07889 tmppw = ast_strdupa(p->secret); 07890 stringp = tmppw; 07891 while((tmppw = strsep(&stringp, ";"))) { 07892 MD5Init(&md5); 07893 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07894 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07895 MD5Final(digest, &md5); 07896 /* If they support md5, authenticate with it. */ 07897 for (x=0;x<16;x++) 07898 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07899 if (!strcasecmp(requeststr, md5secret)) { 07900 res = 0; 07901 break; 07902 } 07903 } 07904 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07905 if (!strcmp(secret, p->secret)) 07906 res = 0; 07907 } 07908 return res; 07909 }
static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4651 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call(), sip_call(), and sip_show_sched().
04652 { 04653 #ifdef SCHED_MULTITHREADED 04654 if (schedule_action(__auto_congest, data)) 04655 #endif 04656 __auto_congest(data); 04657 return 0; 04658 }
static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 9017 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().
09018 { 09019 int callno = (int)(long)(data); 09020 ast_mutex_lock(&iaxsl[callno]); 09021 if (iaxs[callno]) { 09022 iaxs[callno]->autoid = -1; 09023 } 09024 ast_mutex_unlock(&iaxsl[callno]); 09025 #ifdef SCHED_MULTITHREADED 09026 if (schedule_action(__auto_hangup, data)) 09027 #endif 09028 __auto_hangup(data); 09029 return 0; 09030 }
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 12195 of file chan_iax2.c.
References ast_calloc, and ast_copy_string().
Referenced by build_user().
12196 { 12197 struct iax2_context *con; 12198 12199 if ((con = ast_calloc(1, sizeof(*con)))) 12200 ast_copy_string(con->context, context, sizeof(con->context)); 12201 12202 return con; 12203 }
static void build_ecx_key | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6159 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().
06160 { 06161 /* it is required to hold the corresponding decrypt key to our encrypt key 06162 * in the pvt struct because queued frames occasionally need to be decrypted and 06163 * re-encrypted when updated for a retransmission */ 06164 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 06165 ast_aes_set_encrypt_key(digest, &pvt->ecx); 06166 ast_aes_set_decrypt_key(digest, &pvt->mydcx); 06167 }
static void build_encryption_keys | ( | const unsigned char * | digest, | |
struct chan_iax2_pvt * | pvt | |||
) | [static] |
Definition at line 6153 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().
06154 { 06155 build_ecx_key(digest, pvt); 06156 ast_aes_set_decrypt_key(digest, &pvt->dcx); 06157 }
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 12346 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, ast_sockaddr::ss, strsep(), timer, unlink_peer(), ast_variable::value, and zonetag.
12347 { 12348 struct iax2_peer *peer = NULL; 12349 struct ast_ha *oldha = NULL; 12350 int maskfound = 0; 12351 int found = 0; 12352 int firstpass = 1; 12353 struct iax2_peer tmp_peer = { 12354 .name = name, 12355 }; 12356 12357 if (!temponly) { 12358 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 12359 if (peer && !ast_test_flag64(peer, IAX_DELME)) 12360 firstpass = 0; 12361 } 12362 12363 if (peer) { 12364 found++; 12365 if (firstpass) { 12366 oldha = peer->ha; 12367 peer->ha = NULL; 12368 } 12369 unlink_peer(peer); 12370 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 12371 peer->expire = -1; 12372 peer->pokeexpire = -1; 12373 peer->sockfd = defaultsockfd; 12374 peer->addr.ss.ss_family = AF_INET; 12375 if (ast_string_field_init(peer, 32)) 12376 peer = peer_unref(peer); 12377 } 12378 12379 if (peer) { 12380 if (firstpass) { 12381 ast_copy_flags64(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 12382 peer->encmethods = iax2_encryption; 12383 peer->adsi = adsi; 12384 ast_string_field_set(peer,secret,""); 12385 if (!found) { 12386 ast_string_field_set(peer, name, name); 12387 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12388 peer->expiry = min_reg_expire; 12389 } 12390 peer->prefs = prefs; 12391 peer->capability = iax2_capability; 12392 peer->smoothing = 0; 12393 peer->pokefreqok = DEFAULT_FREQ_OK; 12394 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 12395 peer->maxcallno = 0; 12396 peercnt_modify(0, 0, &peer->addr); 12397 peer->calltoken_required = CALLTOKEN_DEFAULT; 12398 ast_string_field_set(peer,context,""); 12399 ast_string_field_set(peer,peercontext,""); 12400 ast_clear_flag64(peer, IAX_HASCALLERID); 12401 ast_string_field_set(peer, cid_name, ""); 12402 ast_string_field_set(peer, cid_num, ""); 12403 ast_string_field_set(peer, mohinterpret, mohinterpret); 12404 ast_string_field_set(peer, mohsuggest, mohsuggest); 12405 } 12406 12407 if (!v) { 12408 v = alt; 12409 alt = NULL; 12410 } 12411 while(v) { 12412 if (!strcasecmp(v->name, "secret")) { 12413 ast_string_field_set(peer, secret, v->value); 12414 } else if (!strcasecmp(v->name, "mailbox")) { 12415 ast_string_field_set(peer, mailbox, v->value); 12416 } else if (!strcasecmp(v->name, "hasvoicemail")) { 12417 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 12418 ast_string_field_set(peer, mailbox, name); 12419 } 12420 } else if (!strcasecmp(v->name, "mohinterpret")) { 12421 ast_string_field_set(peer, mohinterpret, v->value); 12422 } else if (!strcasecmp(v->name, "mohsuggest")) { 12423 ast_string_field_set(peer, mohsuggest, v->value); 12424 } else if (!strcasecmp(v->name, "dbsecret")) { 12425 ast_string_field_set(peer, dbsecret, v->value); 12426 } else if (!strcasecmp(v->name, "trunk")) { 12427 ast_set2_flag64(peer, ast_true(v->value), IAX_TRUNK); 12428 if (ast_test_flag64(peer, IAX_TRUNK) && !timer) { 12429 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 12430 ast_clear_flag64(peer, IAX_TRUNK); 12431 } 12432 } else if (!strcasecmp(v->name, "auth")) { 12433 peer->authmethods = get_auth_methods(v->value); 12434 } else if (!strcasecmp(v->name, "encryption")) { 12435 peer->encmethods |= get_encrypt_methods(v->value); 12436 if (!peer->encmethods) { 12437 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12438 } 12439 } else if (!strcasecmp(v->name, "forceencryption")) { 12440 if (ast_false(v->value)) { 12441 ast_clear_flag64(peer, IAX_FORCE_ENCRYPT); 12442 } else { 12443 peer->encmethods |= get_encrypt_methods(v->value); 12444 if (peer->encmethods) { 12445 ast_set_flag64(peer, IAX_FORCE_ENCRYPT); 12446 } 12447 } 12448 } else if (!strcasecmp(v->name, "transfer")) { 12449 if (!strcasecmp(v->value, "mediaonly")) { 12450 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12451 } else if (ast_true(v->value)) { 12452 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12453 } else 12454 ast_set_flags_to64(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12455 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12456 ast_set2_flag64(peer, ast_true(v->value), IAX_USEJITTERBUF); 12457 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12458 ast_set2_flag64(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 12459 } else if (!strcasecmp(v->name, "host")) { 12460 if (!strcasecmp(v->value, "dynamic")) { 12461 /* They'll register with us */ 12462 ast_set_flag64(peer, IAX_DYNAMIC); 12463 if (!found) { 12464 /* Initialize stuff iff we're not found, otherwise 12465 we keep going with what we had */ 12466 if (ast_sockaddr_port(&peer->addr)) { 12467 peer->defaddr.sin_port = htons(ast_sockaddr_port(&peer->addr)); 12468 } 12469 ast_sockaddr_setnull(&peer->addr); 12470 } 12471 } else { 12472 /* Non-dynamic. Make sure we become that way if we're not */ 12473 ast_sched_thread_del(sched, peer->expire); 12474 ast_clear_flag64(peer, IAX_DYNAMIC); 12475 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12476 return peer_unref(peer); 12477 if (!ast_sockaddr_port(&peer->addr)) { 12478 ast_sockaddr_set_port(&peer->addr, IAX_DEFAULT_PORTNO); 12479 } 12480 } 12481 if (!maskfound) 12482 inet_aton("255.255.255.255", &peer->mask); 12483 } else if (!strcasecmp(v->name, "defaultip")) { 12484 struct ast_sockaddr peer_defaddr_tmp; 12485 12486 peer_defaddr_tmp.ss.ss_family = AF_INET; 12487 if (ast_get_ip(&peer_defaddr_tmp, v->value)) { 12488 return peer_unref(peer); 12489 } 12490 ast_sockaddr_to_sin(&peer_defaddr_tmp, 12491 &peer->defaddr); 12492 } else if (!strcasecmp(v->name, "sourceaddress")) { 12493 peer_set_srcaddr(peer, v->value); 12494 } else if (!strcasecmp(v->name, "permit") || 12495 !strcasecmp(v->name, "deny")) { 12496 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12497 } else if (!strcasecmp(v->name, "mask")) { 12498 maskfound++; 12499 inet_aton(v->value, &peer->mask); 12500 } else if (!strcasecmp(v->name, "context")) { 12501 ast_string_field_set(peer, context, v->value); 12502 } else if (!strcasecmp(v->name, "regexten")) { 12503 ast_string_field_set(peer, regexten, v->value); 12504 } else if (!strcasecmp(v->name, "peercontext")) { 12505 ast_string_field_set(peer, peercontext, v->value); 12506 } else if (!strcasecmp(v->name, "port")) { 12507 if (ast_test_flag64(peer, IAX_DYNAMIC)) { 12508 peer->defaddr.sin_port = htons(atoi(v->value)); 12509 } else { 12510 ast_sockaddr_set_port(&peer->addr, atoi(v->value)); 12511 } 12512 } else if (!strcasecmp(v->name, "username")) { 12513 ast_string_field_set(peer, username, v->value); 12514 } else if (!strcasecmp(v->name, "allow")) { 12515 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12516 } else if (!strcasecmp(v->name, "disallow")) { 12517 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12518 } else if (!strcasecmp(v->name, "callerid")) { 12519 if (!ast_strlen_zero(v->value)) { 12520 char name2[80]; 12521 char num2[80]; 12522 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12523 ast_string_field_set(peer, cid_name, name2); 12524 ast_string_field_set(peer, cid_num, num2); 12525 } else { 12526 ast_string_field_set(peer, cid_name, ""); 12527 ast_string_field_set(peer, cid_num, ""); 12528 } 12529 ast_set_flag64(peer, IAX_HASCALLERID); 12530 } else if (!strcasecmp(v->name, "fullname")) { 12531 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12532 ast_set_flag64(peer, IAX_HASCALLERID); 12533 } else if (!strcasecmp(v->name, "cid_number")) { 12534 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12535 ast_set_flag64(peer, IAX_HASCALLERID); 12536 } else if (!strcasecmp(v->name, "sendani")) { 12537 ast_set2_flag64(peer, ast_true(v->value), IAX_SENDANI); 12538 } else if (!strcasecmp(v->name, "inkeys")) { 12539 ast_string_field_set(peer, inkeys, v->value); 12540 } else if (!strcasecmp(v->name, "outkey")) { 12541 ast_string_field_set(peer, outkey, v->value); 12542 } else if (!strcasecmp(v->name, "qualify")) { 12543 if (!strcasecmp(v->value, "no")) { 12544 peer->maxms = 0; 12545 } else if (!strcasecmp(v->value, "yes")) { 12546 peer->maxms = DEFAULT_MAXMS; 12547 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12548 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); 12549 peer->maxms = 0; 12550 } 12551 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12552 peer->smoothing = ast_true(v->value); 12553 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12554 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12555 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); 12556 } 12557 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12558 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12559 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); 12560 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 12561 } else if (!strcasecmp(v->name, "timezone")) { 12562 ast_string_field_set(peer, zonetag, v->value); 12563 } else if (!strcasecmp(v->name, "adsi")) { 12564 peer->adsi = ast_true(v->value); 12565 } else if (!strcasecmp(v->name, "connectedline")) { 12566 if (ast_true(v->value)) { 12567 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12568 } else if (!strcasecmp(v->value, "send")) { 12569 ast_clear_flag64(peer, IAX_RECVCONNECTEDLINE); 12570 ast_set_flag64(peer, IAX_SENDCONNECTEDLINE); 12571 } else if (!strcasecmp(v->value, "receive")) { 12572 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE); 12573 ast_set_flag64(peer, IAX_RECVCONNECTEDLINE); 12574 } else { 12575 ast_clear_flag64(peer, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12576 } 12577 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12578 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12579 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12580 } else { 12581 peercnt_modify(1, peer->maxcallno, &peer->addr); 12582 } 12583 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12584 /* default is required unless in optional ip list */ 12585 if (ast_false(v->value)) { 12586 peer->calltoken_required = CALLTOKEN_NO; 12587 } else if (!strcasecmp(v->value, "auto")) { 12588 peer->calltoken_required = CALLTOKEN_AUTO; 12589 } else if (ast_true(v->value)) { 12590 peer->calltoken_required = CALLTOKEN_YES; 12591 } else { 12592 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12593 } 12594 } /* else if (strcasecmp(v->name,"type")) */ 12595 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12596 v = v->next; 12597 if (!v) { 12598 v = alt; 12599 alt = NULL; 12600 } 12601 } 12602 if (!peer->authmethods) 12603 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12604 ast_clear_flag64(peer, IAX_DELME); 12605 } 12606 12607 if (oldha) 12608 ast_free_ha(oldha); 12609 12610 if (!ast_strlen_zero(peer->mailbox)) { 12611 char *mailbox, *context; 12612 context = mailbox = ast_strdupa(peer->mailbox); 12613 strsep(&context, "@"); 12614 if (ast_strlen_zero(context)) 12615 context = "default"; 12616 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, "IAX MWI subscription", NULL, 12617 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12618 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12619 AST_EVENT_IE_END); 12620 } 12621 12622 return peer; 12623 }
static void build_rand_pad | ( | unsigned char * | buf, | |
ssize_t | len | |||
) | [static] |
Definition at line 6143 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
06144 { 06145 long tmp; 06146 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 06147 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 06148 buf += sizeof(tmp); 06149 len -= sizeof(tmp); 06150 } 06151 }
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 12639 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.
12640 { 12641 struct iax2_user *user = NULL; 12642 struct iax2_context *con, *conl = NULL; 12643 struct ast_ha *oldha = NULL; 12644 struct iax2_context *oldcon = NULL; 12645 int format; 12646 int firstpass=1; 12647 int oldcurauthreq = 0; 12648 char *varname = NULL, *varval = NULL; 12649 struct ast_variable *tmpvar = NULL; 12650 struct iax2_user tmp_user = { 12651 .name = name, 12652 }; 12653 12654 if (!temponly) { 12655 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12656 if (user && !ast_test_flag64(user, IAX_DELME)) 12657 firstpass = 0; 12658 } 12659 12660 if (user) { 12661 if (firstpass) { 12662 oldcurauthreq = user->curauthreq; 12663 oldha = user->ha; 12664 oldcon = user->contexts; 12665 user->ha = NULL; 12666 user->contexts = NULL; 12667 } 12668 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12669 ao2_unlink(users, user); 12670 } else { 12671 user = ao2_alloc(sizeof(*user), user_destructor); 12672 } 12673 12674 if (user) { 12675 if (firstpass) { 12676 ast_string_field_free_memory(user); 12677 memset(user, 0, sizeof(struct iax2_user)); 12678 if (ast_string_field_init(user, 32)) { 12679 user = user_unref(user); 12680 goto cleanup; 12681 } 12682 user->maxauthreq = maxauthreq; 12683 user->curauthreq = oldcurauthreq; 12684 user->prefs = prefs; 12685 user->capability = iax2_capability; 12686 user->encmethods = iax2_encryption; 12687 user->adsi = adsi; 12688 user->calltoken_required = CALLTOKEN_DEFAULT; 12689 ast_string_field_set(user, name, name); 12690 ast_string_field_set(user, language, language); 12691 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); 12692 ast_clear_flag64(user, IAX_HASCALLERID); 12693 ast_string_field_set(user, cid_name, ""); 12694 ast_string_field_set(user, cid_num, ""); 12695 ast_string_field_set(user, accountcode, accountcode); 12696 ast_string_field_set(user, mohinterpret, mohinterpret); 12697 ast_string_field_set(user, mohsuggest, mohsuggest); 12698 } 12699 if (!v) { 12700 v = alt; 12701 alt = NULL; 12702 } 12703 while(v) { 12704 if (!strcasecmp(v->name, "context")) { 12705 con = build_context(v->value); 12706 if (con) { 12707 if (conl) 12708 conl->next = con; 12709 else 12710 user->contexts = con; 12711 conl = con; 12712 } 12713 } else if (!strcasecmp(v->name, "permit") || 12714 !strcasecmp(v->name, "deny")) { 12715 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12716 } else if (!strcasecmp(v->name, "setvar")) { 12717 varname = ast_strdupa(v->value); 12718 if (varname && (varval = strchr(varname,'='))) { 12719 *varval = '\0'; 12720 varval++; 12721 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12722 tmpvar->next = user->vars; 12723 user->vars = tmpvar; 12724 } 12725 } 12726 } else if (!strcasecmp(v->name, "allow")) { 12727 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12728 } else if (!strcasecmp(v->name, "disallow")) { 12729 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12730 } else if (!strcasecmp(v->name, "trunk")) { 12731 ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK); 12732 if (ast_test_flag64(user, IAX_TRUNK) && !timer) { 12733 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12734 ast_clear_flag64(user, IAX_TRUNK); 12735 } 12736 } else if (!strcasecmp(v->name, "auth")) { 12737 user->authmethods = get_auth_methods(v->value); 12738 } else if (!strcasecmp(v->name, "encryption")) { 12739 user->encmethods |= get_encrypt_methods(v->value); 12740 if (!user->encmethods) { 12741 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12742 } 12743 } else if (!strcasecmp(v->name, "forceencryption")) { 12744 if (ast_false(v->value)) { 12745 ast_clear_flag64(user, IAX_FORCE_ENCRYPT); 12746 } else { 12747 user->encmethods |= get_encrypt_methods(v->value); 12748 if (user->encmethods) { 12749 ast_set_flag64(user, IAX_FORCE_ENCRYPT); 12750 } 12751 } 12752 } else if (!strcasecmp(v->name, "transfer")) { 12753 if (!strcasecmp(v->value, "mediaonly")) { 12754 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12755 } else if (ast_true(v->value)) { 12756 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12757 } else 12758 ast_set_flags_to64(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12759 } else if (!strcasecmp(v->name, "codecpriority")) { 12760 if(!strcasecmp(v->value, "caller")) 12761 ast_set_flag64(user, IAX_CODEC_USER_FIRST); 12762 else if(!strcasecmp(v->value, "disabled")) 12763 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12764 else if(!strcasecmp(v->value, "reqonly")) { 12765 ast_set_flag64(user, IAX_CODEC_NOCAP); 12766 ast_set_flag64(user, IAX_CODEC_NOPREFS); 12767 } 12768 } else if (!strcasecmp(v->name, "immediate")) { 12769 ast_set2_flag64(user, ast_true(v->value), IAX_IMMEDIATE); 12770 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12771 ast_set2_flag64(user, ast_true(v->value), IAX_USEJITTERBUF); 12772 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12773 ast_set2_flag64(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12774 } else if (!strcasecmp(v->name, "dbsecret")) { 12775 ast_string_field_set(user, dbsecret, v->value); 12776 } else if (!strcasecmp(v->name, "secret")) { 12777 if (!ast_strlen_zero(user->secret)) { 12778 char *old = ast_strdupa(user->secret); 12779 12780 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12781 } else 12782 ast_string_field_set(user, secret, v->value); 12783 } else if (!strcasecmp(v->name, "callerid")) { 12784 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12785 char name2[80]; 12786 char num2[80]; 12787 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12788 ast_string_field_set(user, cid_name, name2); 12789 ast_string_field_set(user, cid_num, num2); 12790 ast_set_flag64(user, IAX_HASCALLERID); 12791 } else { 12792 ast_clear_flag64(user, IAX_HASCALLERID); 12793 ast_string_field_set(user, cid_name, ""); 12794 ast_string_field_set(user, cid_num, ""); 12795 } 12796 } else if (!strcasecmp(v->name, "fullname")) { 12797 if (!ast_strlen_zero(v->value)) { 12798 ast_string_field_set(user, cid_name, v->value); 12799 ast_set_flag64(user, IAX_HASCALLERID); 12800 } else { 12801 ast_string_field_set(user, cid_name, ""); 12802 if (ast_strlen_zero(user->cid_num)) 12803 ast_clear_flag64(user, IAX_HASCALLERID); 12804 } 12805 } else if (!strcasecmp(v->name, "cid_number")) { 12806 if (!ast_strlen_zero(v->value)) { 12807 ast_string_field_set(user, cid_num, v->value); 12808 ast_set_flag64(user, IAX_HASCALLERID); 12809 } else { 12810 ast_string_field_set(user, cid_num, ""); 12811 if (ast_strlen_zero(user->cid_name)) 12812 ast_clear_flag64(user, IAX_HASCALLERID); 12813 } 12814 } else if (!strcasecmp(v->name, "accountcode")) { 12815 ast_string_field_set(user, accountcode, v->value); 12816 } else if (!strcasecmp(v->name, "mohinterpret")) { 12817 ast_string_field_set(user, mohinterpret, v->value); 12818 } else if (!strcasecmp(v->name, "mohsuggest")) { 12819 ast_string_field_set(user, mohsuggest, v->value); 12820 } else if (!strcasecmp(v->name, "parkinglot")) { 12821 ast_string_field_set(user, parkinglot, v->value); 12822 } else if (!strcasecmp(v->name, "language")) { 12823 ast_string_field_set(user, language, v->value); 12824 } else if (!strcasecmp(v->name, "amaflags")) { 12825 format = ast_cdr_amaflags2int(v->value); 12826 if (format < 0) { 12827 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12828 } else { 12829 user->amaflags = format; 12830 } 12831 } else if (!strcasecmp(v->name, "inkeys")) { 12832 ast_string_field_set(user, inkeys, v->value); 12833 } else if (!strcasecmp(v->name, "maxauthreq")) { 12834 user->maxauthreq = atoi(v->value); 12835 if (user->maxauthreq < 0) 12836 user->maxauthreq = 0; 12837 } else if (!strcasecmp(v->name, "adsi")) { 12838 user->adsi = ast_true(v->value); 12839 } else if (!strcasecmp(v->name, "connectedline")) { 12840 if (ast_true(v->value)) { 12841 ast_set_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12842 } else if (!strcasecmp(v->value, "send")) { 12843 ast_clear_flag64(user, IAX_RECVCONNECTEDLINE); 12844 ast_set_flag64(user, IAX_SENDCONNECTEDLINE); 12845 } else if (!strcasecmp(v->value, "receive")) { 12846 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE); 12847 ast_set_flag64(user, IAX_RECVCONNECTEDLINE); 12848 } else { 12849 ast_clear_flag64(user, IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12850 } 12851 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12852 /* default is required unless in optional ip list */ 12853 if (ast_false(v->value)) { 12854 user->calltoken_required = CALLTOKEN_NO; 12855 } else if (!strcasecmp(v->value, "auto")) { 12856 user->calltoken_required = CALLTOKEN_AUTO; 12857 } else if (ast_true(v->value)) { 12858 user->calltoken_required = CALLTOKEN_YES; 12859 } else { 12860 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12861 } 12862 } /* else if (strcasecmp(v->name,"type")) */ 12863 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12864 v = v->next; 12865 if (!v) { 12866 v = alt; 12867 alt = NULL; 12868 } 12869 } 12870 if (!user->authmethods) { 12871 if (!ast_strlen_zero(user->secret)) { 12872 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12873 if (!ast_strlen_zero(user->inkeys)) 12874 user->authmethods |= IAX_AUTH_RSA; 12875 } else if (!ast_strlen_zero(user->inkeys)) { 12876 user->authmethods = IAX_AUTH_RSA; 12877 } else { 12878 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12879 } 12880 } 12881 ast_clear_flag64(user, IAX_DELME); 12882 } 12883 cleanup: 12884 if (oldha) 12885 ast_free_ha(oldha); 12886 if (oldcon) 12887 free_context(oldcon); 12888 return user; 12889 }
static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13523 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().
13524 { 13525 struct sockaddr_in sin; 13526 int x; 13527 int callno; 13528 struct iax_ie_data ied; 13529 struct create_addr_info cai; 13530 struct parsed_dial_string pds; 13531 char *tmpstr; 13532 13533 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13534 /* Look for an *exact match* call. Once a call is negotiated, it can only 13535 look up entries for a single context */ 13536 if (!ast_mutex_trylock(&iaxsl[x])) { 13537 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13538 return x; 13539 ast_mutex_unlock(&iaxsl[x]); 13540 } 13541 } 13542 13543 /* No match found, we need to create a new one */ 13544 13545 memset(&cai, 0, sizeof(cai)); 13546 memset(&ied, 0, sizeof(ied)); 13547 memset(&pds, 0, sizeof(pds)); 13548 13549 tmpstr = ast_strdupa(data); 13550 parse_dial_string(tmpstr, &pds); 13551 13552 if (ast_strlen_zero(pds.peer)) { 13553 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13554 return -1; 13555 } 13556 13557 /* Populate our address from the given */ 13558 if (create_addr(pds.peer, NULL, &sin, &cai)) 13559 return -1; 13560 13561 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13562 pds.peer, pds.username, pds.password, pds.context); 13563 13564 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13565 if (callno < 1) { 13566 ast_log(LOG_WARNING, "Unable to create call\n"); 13567 return -1; 13568 } 13569 13570 ast_string_field_set(iaxs[callno], dproot, data); 13571 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13572 13573 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13574 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13575 /* the string format is slightly different from a standard dial string, 13576 because the context appears in the 'exten' position 13577 */ 13578 if (pds.exten) 13579 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13580 if (pds.username) 13581 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13582 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13583 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13584 /* Keep password handy */ 13585 if (pds.password) 13586 ast_string_field_set(iaxs[callno], secret, pds.password); 13587 if (pds.key) 13588 ast_string_field_set(iaxs[callno], outkey, pds.key); 13589 /* Start the call going */ 13590 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13591 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13592 13593 return callno; 13594 }
static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | offset | |||
) | [static] |
Definition at line 5996 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().
05997 { 05998 /* Returns where in "receive time" we are. That is, how many ms 05999 since we received (or would have received) the frame with timestamp 0 */ 06000 int ms; 06001 #ifdef IAXTESTS 06002 int jit; 06003 #endif /* IAXTESTS */ 06004 /* Setup rxcore if necessary */ 06005 if (ast_tvzero(p->rxcore)) { 06006 p->rxcore = ast_tvnow(); 06007 if (iaxdebug) 06008 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 06009 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 06010 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 06011 #if 1 06012 if (iaxdebug) 06013 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 06014 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 06015 #endif 06016 } 06017 06018 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 06019 #ifdef IAXTESTS 06020 if (test_jit) { 06021 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 06022 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 06023 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 06024 jit = -jit; 06025 ms += jit; 06026 } 06027 } 06028 if (test_late) { 06029 ms += test_late; 06030 test_late = 0; 06031 } 06032 #endif /* IAXTESTS */ 06033 return ms; 06034 }
static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
unsigned int | ts, | |||
struct ast_frame * | f | |||
) | [static] |
Definition at line 5863 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().
05864 { 05865 int ms; 05866 int voice = 0; 05867 int genuine = 0; 05868 int adjust; 05869 int rate = ast_format_rate(f->subclass.codec) / 1000; 05870 struct timeval *delivery = NULL; 05871 05872 05873 /* What sort of frame do we have?: voice is self-explanatory 05874 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05875 non-genuine frames are CONTROL frames [ringing etc], DTMF 05876 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05877 the others need a timestamp slaved to the voice frames so that they go in sequence 05878 */ 05879 if (f) { 05880 if (f->frametype == AST_FRAME_VOICE) { 05881 voice = 1; 05882 delivery = &f->delivery; 05883 } else if (f->frametype == AST_FRAME_IAX) { 05884 genuine = 1; 05885 } else if (f->frametype == AST_FRAME_CNG) { 05886 p->notsilenttx = 0; 05887 } 05888 } 05889 if (ast_tvzero(p->offset)) { 05890 p->offset = ast_tvnow(); 05891 /* Round to nearest 20ms for nice looking traces */ 05892 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05893 } 05894 /* If the timestamp is specified, just send it as is */ 05895 if (ts) 05896 return ts; 05897 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05898 if (delivery && !ast_tvzero(*delivery)) { 05899 ms = ast_tvdiff_ms(*delivery, p->offset); 05900 if (ms < 0) { 05901 ms = 0; 05902 } 05903 if (iaxdebug) 05904 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05905 } else { 05906 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05907 if (ms < 0) 05908 ms = 0; 05909 if (voice) { 05910 /* On a voice frame, use predicted values if appropriate */ 05911 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05912 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05913 /* AN EXPLANATION: 05914 When we send voice, we usually send "calculated" timestamps worked out 05915 on the basis of the number of samples sent. When we send other frames, 05916 we usually send timestamps worked out from the real clock. 05917 The problem is that they can tend to drift out of step because the 05918 source channel's clock and our clock may not be exactly at the same rate. 05919 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05920 for this call. Moving it adjusts timestamps for non-voice frames. 05921 We make the adjustment in the style of a moving average. Each time we 05922 adjust p->offset by 10% of the difference between our clock-derived 05923 timestamp and the predicted timestamp. That's why you see "10000" 05924 below even though IAX2 timestamps are in milliseconds. 05925 The use of a moving average avoids offset moving too radically. 05926 Generally, "adjust" roams back and forth around 0, with offset hardly 05927 changing at all. But if a consistent different starts to develop it 05928 will be eliminated over the course of 10 frames (200-300msecs) 05929 */ 05930 adjust = (ms - p->nextpred); 05931 if (adjust < 0) 05932 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05933 else if (adjust > 0) 05934 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05935 05936 if (!p->nextpred) { 05937 p->nextpred = ms; /*f->samples / rate;*/ 05938 if (p->nextpred <= p->lastsent) 05939 p->nextpred = p->lastsent + 3; 05940 } 05941 ms = p->nextpred; 05942 } else { 05943 /* in this case, just use the actual 05944 * time, since we're either way off 05945 * (shouldn't happen), or we're ending a 05946 * silent period -- and seed the next 05947 * predicted time. Also, round ms to the 05948 * next multiple of frame size (so our 05949 * silent periods are multiples of 05950 * frame size too) */ 05951 05952 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05953 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05954 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05955 05956 if (f->samples >= rate) /* check to make sure we don't core dump */ 05957 { 05958 int diff = ms % (f->samples / rate); 05959 if (diff) 05960 ms += f->samples/rate - diff; 05961 } 05962 05963 p->nextpred = ms; 05964 p->notsilenttx = 1; 05965 } 05966 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05967 /* 05968 * IAX2 draft 03 says that timestamps MUST be in order. 05969 * It does not say anything about several frames having the same timestamp 05970 * When transporting video, we can have a frame that spans multiple iax packets 05971 * (so called slices), so it would make sense to use the same timestamp for all of 05972 * them 05973 * We do want to make sure that frames don't go backwards though 05974 */ 05975 if ( (unsigned int)ms < p->lastsent ) 05976 ms = p->lastsent; 05977 } else { 05978 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05979 it's a genuine frame */ 05980 if (genuine) { 05981 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05982 if (ms <= p->lastsent) 05983 ms = p->lastsent + 3; 05984 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05985 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05986 ms = p->lastsent + 3; 05987 } 05988 } 05989 } 05990 p->lastsent = ms; 05991 if (voice) 05992 p->nextpred = p->nextpred + f->samples / rate; 05993 return ms; 05994 }
static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
int | sampms, | |||
struct timeval * | now | |||
) | [static] |
Definition at line 5819 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().
05820 { 05821 unsigned long int mssincetx; /* unsigned to handle overflows */ 05822 long int ms, pred; 05823 05824 tpeer->trunkact = *now; 05825 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05826 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05827 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05828 tpeer->txtrunktime = *now; 05829 tpeer->lastsent = 999999; 05830 } 05831 /* Update last transmit time now */ 05832 tpeer->lasttxtime = *now; 05833 05834 /* Calculate ms offset */ 05835 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05836 /* Predict from last value */ 05837 pred = tpeer->lastsent + sampms; 05838 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05839 ms = pred; 05840 05841 /* We never send the same timestamp twice, so fudge a little if we must */ 05842 if (ms == tpeer->lastsent) 05843 ms = tpeer->lastsent + 1; 05844 tpeer->lastsent = ms; 05845 return ms; 05846 }
static int callno_hash | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 2658 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02659 { 02660 return abs(ast_random()); 02661 }
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 7511 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().
07512 { 07513 /* Start pessimistic */ 07514 int res = -1; 07515 int version = 2; 07516 struct iax2_user *user = NULL, *best = NULL; 07517 int bestscore = 0; 07518 int gotcapability = 0; 07519 struct ast_variable *v = NULL, *tmpvar = NULL; 07520 struct ao2_iterator i; 07521 struct ast_sockaddr addr; 07522 07523 if (!iaxs[callno]) 07524 return res; 07525 if (ies->called_number) 07526 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07527 if (ies->calling_number) { 07528 if (ast_test_flag64(&globalflags, IAX_SHRINKCALLERID)) { 07529 ast_shrink_phone_number(ies->calling_number); 07530 } 07531 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07532 } 07533 if (ies->calling_name) 07534 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07535 if (ies->calling_ani) 07536 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07537 if (ies->dnid) 07538 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07539 if (ies->rdnis) 07540 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07541 if (ies->called_context) 07542 ast_string_field_set(iaxs[callno], context, ies->called_context); 07543 if (ies->language) 07544 ast_string_field_set(iaxs[callno], language, ies->language); 07545 if (ies->username) 07546 ast_string_field_set(iaxs[callno], username, ies->username); 07547 if (ies->calling_ton > -1) 07548 iaxs[callno]->calling_ton = ies->calling_ton; 07549 if (ies->calling_tns > -1) 07550 iaxs[callno]->calling_tns = ies->calling_tns; 07551 if (ies->calling_pres > -1) 07552 iaxs[callno]->calling_pres = ies->calling_pres; 07553 if (ies->format) 07554 iaxs[callno]->peerformat = ies->format; 07555 if (ies->adsicpe) 07556 iaxs[callno]->peeradsicpe = ies->adsicpe; 07557 if (ies->capability) { 07558 gotcapability = 1; 07559 iaxs[callno]->peercapability = ies->capability; 07560 } 07561 if (ies->version) 07562 version = ies->version; 07563 07564 /* Use provided preferences until told otherwise for actual preferences */ 07565 if (ies->codec_prefs) { 07566 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07567 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07568 } 07569 07570 if (!gotcapability) 07571 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07572 if (version > IAX_PROTO_VERSION) { 07573 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07574 ast_inet_ntoa(sin->sin_addr), version); 07575 return res; 07576 } 07577 /* Search the userlist for a compatible entry, and fill in the rest */ 07578 ast_sockaddr_from_sin(&addr, sin); 07579 i = ao2_iterator_init(users, 0); 07580 while ((user = ao2_iterator_next(&i))) { 07581 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07582 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07583 && ast_apply_ha(user->ha, &addr) /* Access is permitted from this IP */ 07584 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07585 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07586 if (!ast_strlen_zero(iaxs[callno]->username)) { 07587 /* Exact match, stop right now. */ 07588 if (best) 07589 user_unref(best); 07590 best = user; 07591 break; 07592 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07593 /* No required authentication */ 07594 if (user->ha) { 07595 /* There was host authentication and we passed, bonus! */ 07596 if (bestscore < 4) { 07597 bestscore = 4; 07598 if (best) 07599 user_unref(best); 07600 best = user; 07601 continue; 07602 } 07603 } else { 07604 /* No host access, but no secret, either, not bad */ 07605 if (bestscore < 3) { 07606 bestscore = 3; 07607 if (best) 07608 user_unref(best); 07609 best = user; 07610 continue; 07611 } 07612 } 07613 } else { 07614 if (user->ha) { 07615 /* Authentication, but host access too, eh, it's something.. */ 07616 if (bestscore < 2) { 07617 bestscore = 2; 07618 if (best) 07619 user_unref(best); 07620 best = user; 07621 continue; 07622 } 07623 } else { 07624 /* Authentication and no host access... This is our baseline */ 07625 if (bestscore < 1) { 07626 bestscore = 1; 07627 if (best) 07628 user_unref(best); 07629 best = user; 07630 continue; 07631 } 07632 } 07633 } 07634 } 07635 user_unref(user); 07636 } 07637 ao2_iterator_destroy(&i); 07638 user = best; 07639 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07640 user = realtime_user(iaxs[callno]->username, sin); 07641 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07642 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 07643 user = user_unref(user); 07644 } 07645 } 07646 if (user) { 07647 /* We found our match (use the first) */ 07648 /* copy vars */ 07649 for (v = user->vars ; v ; v = v->next) { 07650 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07651 tmpvar->next = iaxs[callno]->vars; 07652 iaxs[callno]->vars = tmpvar; 07653 } 07654 } 07655 /* If a max AUTHREQ restriction is in place, activate it */ 07656 if (user->maxauthreq > 0) 07657 ast_set_flag64(iaxs[callno], IAX_MAXAUTHREQ); 07658 iaxs[callno]->prefs = user->prefs; 07659 ast_copy_flags64(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07660 iaxs[callno]->encmethods = user->encmethods; 07661 /* Store the requested username if not specified */ 07662 if (ast_strlen_zero(iaxs[callno]->username)) 07663 ast_string_field_set(iaxs[callno], username, user->name); 07664 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07665 ast_copy_flags64(iaxs[callno], user, IAX_TRUNK); 07666 iaxs[callno]->capability = user->capability; 07667 /* And use the default context */ 07668 if (ast_strlen_zero(iaxs[callno]->context)) { 07669 if (user->contexts) 07670 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07671 else 07672 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07673 } 07674 /* And any input keys */ 07675 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07676 /* And the permitted authentication methods */ 07677 iaxs[callno]->authmethods = user->authmethods; 07678 iaxs[callno]->adsi = user->adsi; 07679 /* If the user has callerid, override the remote caller id. */ 07680 if (ast_test_flag64(user, IAX_HASCALLERID)) { 07681 iaxs[callno]->calling_tns = 0; 07682 iaxs[callno]->calling_ton = 0; 07683 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07684 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07685 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07686 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07687 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07688 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07689 } /* else user is allowed to set their own CID settings */ 07690 if (!ast_strlen_zero(user->accountcode)) 07691 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07692 if (!ast_strlen_zero(user->mohinterpret)) 07693 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07694 if (!ast_strlen_zero(user->mohsuggest)) 07695 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07696 if (!ast_strlen_zero(user->parkinglot)) 07697 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07698 if (user->amaflags) 07699 iaxs[callno]->amaflags = user->amaflags; 07700 if (!ast_strlen_zero(user->language)) 07701 ast_string_field_set(iaxs[callno], language, user->language); 07702 ast_copy_flags64(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 07703 /* Keep this check last */ 07704 if (!ast_strlen_zero(user->dbsecret)) { 07705 char *family, *key=NULL; 07706 char buf[80]; 07707 family = ast_strdupa(user->dbsecret); 07708 key = strchr(family, '/'); 07709 if (key) { 07710 *key = '\0'; 07711 key++; 07712 } 07713 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07714 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07715 else 07716 ast_string_field_set(iaxs[callno], secret, buf); 07717 } else 07718 ast_string_field_set(iaxs[callno], secret, user->secret); 07719 res = 0; 07720 user = user_unref(user); 07721 } else { 07722 /* user was not found, but we should still fake an AUTHREQ. 07723 * Set authmethods to the last known authmethod used by the system 07724 * Set a fake secret, it's not looked at, just required to attempt authentication. 07725 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07726 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07727 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07728 iaxs[callno]->authrej = 1; 07729 if (!ast_strlen_zero(iaxs[callno]->username)) { 07730 /* only send the AUTHREQ if a username was specified. */ 07731 res = 0; 07732 } 07733 } 07734 ast_set2_flag64(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07735 return res; 07736 }
static int check_provisioning | ( | struct sockaddr_in * | sin, | |
int | sockfd, | |||
char * | si, | |||
unsigned int | ver | |||
) | [static] |
Definition at line 9384 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
09385 { 09386 unsigned int ourver; 09387 char rsi[80]; 09388 snprintf(rsi, sizeof(rsi), "si-%s", si); 09389 if (iax_provision_version(&ourver, rsi, 1)) 09390 return 0; 09391 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09392 if (ourver != ver) 09393 iax2_provision(sin, sockfd, NULL, rsi, 1); 09394 return 0; 09395 }
static int check_srcaddr | ( | struct sockaddr * | sa, | |
socklen_t | salen | |||
) | [static] |
Check if address can be used as packet source.
Definition at line 12221 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
12222 { 12223 int sd; 12224 int res; 12225 12226 sd = socket(AF_INET, SOCK_DGRAM, 0); 12227 if (sd < 0) { 12228 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 12229 return -1; 12230 } 12231 12232 res = bind(sd, sa, salen); 12233 if (res < 0) { 12234 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 12235 close(sd); 12236 return 1; 12237 } 12238 12239 close(sd); 12240 return 0; 12241 }
static void cleanup_thread_list | ( | void * | head | ) | [static] |
Definition at line 14258 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().
14259 { 14260 AST_LIST_HEAD(iax2_thread_list, iax2_thread); 14261 struct iax2_thread_list *list_head = head; 14262 struct iax2_thread *thread; 14263 14264 AST_LIST_LOCK(list_head); 14265 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) { 14266 pthread_t thread_id = thread->threadid; 14267 14268 thread->stop = 1; 14269 signal_condition(&thread->lock, &thread->cond); 14270 14271 AST_LIST_UNLOCK(list_head); 14272 pthread_join(thread_id, NULL); 14273 AST_LIST_LOCK(list_head); 14274 } 14275 AST_LIST_UNLOCK(list_head); 14276 }
static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8301 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().
08302 { 08303 char exten[256] = ""; 08304 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 08305 struct iax2_dpcache *dp = NULL; 08306 08307 if (ies->called_number) 08308 ast_copy_string(exten, ies->called_number, sizeof(exten)); 08309 08310 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 08311 status = CACHE_FLAG_EXISTS; 08312 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 08313 status = CACHE_FLAG_CANEXIST; 08314 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 08315 status = CACHE_FLAG_NONEXISTENT; 08316 08317 if (ies->refresh) 08318 expiry = ies->refresh; 08319 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 08320 matchmore = CACHE_FLAG_MATCHMORE; 08321 08322 AST_LIST_LOCK(&dpcache); 08323 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08324 if (strcmp(dp->exten, exten)) 08325 continue; 08326 AST_LIST_REMOVE_CURRENT(peer_list); 08327 dp->callno = 0; 08328 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08329 if (dp->flags & CACHE_FLAG_PENDING) { 08330 dp->flags &= ~CACHE_FLAG_PENDING; 08331 dp->flags |= status; 08332 dp->flags |= matchmore; 08333 } 08334 /* Wake up waiters */ 08335 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08336 if (dp->waiters[x] > -1) { 08337 if (write(dp->waiters[x], "asdf", 4) < 0) { 08338 } 08339 } 08340 } 08341 } 08342 AST_LIST_TRAVERSE_SAFE_END; 08343 AST_LIST_UNLOCK(&dpcache); 08344 08345 return 0; 08346 }
static char * complete_iax2_peers | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state, | |||
uint64_t | flags | |||
) | [static] |
Definition at line 3809 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().
03810 { 03811 int which = 0; 03812 struct iax2_peer *peer; 03813 char *res = NULL; 03814 int wordlen = strlen(word); 03815 struct ao2_iterator i; 03816 03817 i = ao2_iterator_init(peers, 0); 03818 while ((peer = ao2_iterator_next(&i))) { 03819 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03820 && (!flags || ast_test_flag64(peer, flags))) { 03821 res = ast_strdup(peer->name); 03822 peer_unref(peer); 03823 break; 03824 } 03825 peer_unref(peer); 03826 } 03827 ao2_iterator_destroy(&i); 03828 03829 return res; 03830 }
static char * complete_iax2_unregister | ( | const char * | line, | |
const char * | word, | |||
int | pos, | |||
int | state | |||
) | [static] |
Definition at line 6864 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().
06865 { 06866 int which = 0; 06867 struct iax2_peer *p = NULL; 06868 char *res = NULL; 06869 int wordlen = strlen(word); 06870 06871 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06872 if (pos == 2) { 06873 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06874 while ((p = ao2_iterator_next(&i))) { 06875 if (!strncasecmp(p->name, word, wordlen) && 06876 ++which > state && p->expire > 0) { 06877 res = ast_strdup(p->name); 06878 peer_unref(p); 06879 break; 06880 } 06881 peer_unref(p); 06882 } 06883 ao2_iterator_destroy(&i); 06884 } 06885 06886 return res; 06887 }
static int complete_transfer | ( | int | callno, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8348 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().
08349 { 08350 int peercallno = 0; 08351 struct chan_iax2_pvt *pvt = iaxs[callno]; 08352 struct iax_frame *cur; 08353 jb_frame frame; 08354 08355 if (ies->callno) 08356 peercallno = ies->callno; 08357 08358 if (peercallno < 1) { 08359 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08360 return -1; 08361 } 08362 remove_by_transfercallno(pvt); 08363 /* since a transfer has taken place, the address will change. 08364 * This must be accounted for in the peercnts table. Remove 08365 * the old address and add the new one */ 08366 peercnt_remove_by_addr(&pvt->addr); 08367 peercnt_add(&pvt->transfer); 08368 /* now copy over the new address */ 08369 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08370 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08371 /* Reset sequence numbers */ 08372 pvt->oseqno = 0; 08373 pvt->rseqno = 0; 08374 pvt->iseqno = 0; 08375 pvt->aseqno = 0; 08376 08377 if (pvt->peercallno) { 08378 remove_by_peercallno(pvt); 08379 } 08380 pvt->peercallno = peercallno; 08381 /*this is where the transfering call swiches hash tables */ 08382 store_by_peercallno(pvt); 08383 pvt->transferring = TRANSFER_NONE; 08384 pvt->svoiceformat = -1; 08385 pvt->voiceformat = 0; 08386 pvt->svideoformat = -1; 08387 pvt->videoformat = 0; 08388 pvt->transfercallno = 0; 08389 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08390 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08391 /* reset jitterbuffer */ 08392 while(jb_getall(pvt->jb,&frame) == JB_OK) 08393 iax2_frame_free(frame.data); 08394 jb_reset(pvt->jb); 08395 pvt->lag = 0; 08396 pvt->last = 0; 08397 pvt->lastsent = 0; 08398 pvt->nextpred = 0; 08399 pvt->pingtime = DEFAULT_RETRY_TIME; 08400 AST_LIST_TRAVERSE(&frame_queue[callno], cur, list) { 08401 /* We must cancel any packets that would have been transmitted 08402 because now we're talking to someone new. It's okay, they 08403 were transmitted to someone that didn't care anyway. */ 08404 cur->retries = -1; 08405 } 08406 return 0; 08407 }
static unsigned char compress_subclass | ( | format_t | subclass | ) | [static] |
Definition at line 1607 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().
01608 { 01609 int x; 01610 int power=-1; 01611 /* If it's 64 or smaller, just return it */ 01612 if (subclass < IAX_FLAG_SC_LOG) 01613 return subclass; 01614 /* Otherwise find its power */ 01615 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01616 if (subclass & (1LL << x)) { 01617 if (power > -1) { 01618 ast_log(LOG_WARNING, "Can't compress subclass %lld\n", (long long) subclass); 01619 return 0; 01620 } else 01621 power = x; 01622 } 01623 } 01624 return power | IAX_FLAG_SC_LOG; 01625 }
static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ie_data * | iep | |||
) | [static] |
Definition at line 9397 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().
09398 { 09399 jb_info stats; 09400 jb_getinfo(pvt->jb, &stats); 09401 09402 memset(iep, 0, sizeof(*iep)); 09403 09404 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09405 if(stats.frames_in == 0) stats.frames_in = 1; 09406 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09407 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09408 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09409 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09410 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09411 }
static int create_addr | ( | const char * | peername, | |
struct ast_channel * | c, | |||
struct sockaddr_in * | sin, | |||
struct create_addr_info * | cai | |||
) | [static] |
Definition at line 4537 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.
04538 { 04539 struct iax2_peer *peer; 04540 int res = -1; 04541 struct ast_codec_pref ourprefs; 04542 struct sockaddr_in peer_addr; 04543 04544 ast_clear_flag64(cai, IAX_SENDANI | IAX_TRUNK); 04545 cai->sockfd = defaultsockfd; 04546 cai->maxtime = 0; 04547 sin->sin_family = AF_INET; 04548 04549 if (!(peer = find_peer(peername, 1))) { 04550 struct ast_sockaddr sin_tmp; 04551 04552 cai->found = 0; 04553 sin_tmp.ss.ss_family = AF_INET; 04554 if (ast_get_ip_or_srv(&sin_tmp, peername, srvlookup ? "_iax._udp" : NULL)) { 04555 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04556 return -1; 04557 } 04558 ast_sockaddr_to_sin(&sin_tmp, sin); 04559 if (sin->sin_port == 0) { 04560 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04561 } 04562 /* use global iax prefs for unknown peer/user */ 04563 /* But move the calling channel's native codec to the top of the preference list */ 04564 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04565 if (c) 04566 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04567 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04568 return 0; 04569 } 04570 04571 cai->found = 1; 04572 04573 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 04574 04575 /* if the peer has no address (current or default), return failure */ 04576 if (!(peer_addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) { 04577 goto return_unref; 04578 } 04579 04580 /* if the peer is being monitored and is currently unreachable, return failure */ 04581 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04582 goto return_unref; 04583 04584 ast_copy_flags64(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE | IAX_FORCE_ENCRYPT); 04585 cai->maxtime = peer->maxms; 04586 cai->capability = peer->capability; 04587 cai->encmethods = peer->encmethods; 04588 cai->sockfd = peer->sockfd; 04589 cai->adsi = peer->adsi; 04590 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04591 /* Move the calling channel's native codec to the top of the preference list */ 04592 if (c) { 04593 ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats); 04594 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04595 } 04596 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04597 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04598 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04599 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04600 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04601 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04602 ast_copy_string(cai->cid_num, peer->cid_num, sizeof(cai->cid_num)); 04603 ast_copy_string(cai->cid_name, peer->cid_name, sizeof(cai->cid_name)); 04604 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04605 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04606 if (ast_strlen_zero(peer->dbsecret)) { 04607 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04608 } else { 04609 char *family; 04610 char *key = NULL; 04611 04612 family = ast_strdupa(peer->dbsecret); 04613 key = strchr(family, '/'); 04614 if (key) 04615 *key++ = '\0'; 04616 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04617 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04618 goto return_unref; 04619 } 04620 } 04621 04622 if (peer_addr.sin_addr.s_addr) { 04623 sin->sin_addr = peer_addr.sin_addr; 04624 sin->sin_port = peer_addr.sin_port; 04625 } else { 04626 sin->sin_addr = peer->defaddr.sin_addr; 04627 sin->sin_port = peer->defaddr.sin_port; 04628 } 04629 04630 res = 0; 04631 04632 return_unref: 04633 peer_unref(peer); 04634 04635 return res; 04636 }
static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2663 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().
02664 { 02665 uint16_t i; 02666 02667 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02668 return -1; 02669 } 02670 02671 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02672 return -1; 02673 } 02674 02675 /* start at 2, 0 and 1 are reserved */ 02676 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02677 struct callno_entry *callno_entry; 02678 02679 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02680 return -1; 02681 } 02682 02683 callno_entry->callno = i; 02684 02685 if (i < TRUNK_CALL_START) { 02686 ao2_link(callno_pool, callno_entry); 02687 } else { 02688 ao2_link(callno_pool_trunk, callno_entry); 02689 } 02690 02691 ao2_ref(callno_entry, -1); 02692 } 02693 02694 return 0; 02695 }
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 6217 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().
06218 { 06219 int padding; 06220 unsigned char *workspace; 06221 06222 workspace = alloca(*datalen); 06223 memset(f, 0, sizeof(*f)); 06224 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06225 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06226 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 06227 return -1; 06228 /* Decrypt */ 06229 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 06230 06231 padding = 16 + (workspace[15] & 0x0f); 06232 if (iaxdebug) 06233 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 06234 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 06235 return -1; 06236 06237 *datalen -= padding; 06238 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06239 f->frametype = fh->type; 06240 if (f->frametype == AST_FRAME_VIDEO) { 06241 f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 06242 } else if (f->frametype == AST_FRAME_VOICE) { 06243 f->subclass.codec = uncompress_subclass(fh->csub); 06244 } else { 06245 f->subclass.integer = uncompress_subclass(fh->csub); 06246 } 06247 } else { 06248 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06249 if (iaxdebug) 06250 ast_debug(1, "Decoding mini with length %d\n", *datalen); 06251 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 06252 return -1; 06253 /* Decrypt */ 06254 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 06255 padding = 16 + (workspace[15] & 0x0f); 06256 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 06257 return -1; 06258 *datalen -= padding; 06259 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06260 } 06261 return 0; 06262 }
static int decrypt_frame | ( | int | callno, | |
struct ast_iax2_full_hdr * | fh, | |||
struct ast_frame * | f, | |||
int * | datalen | |||
) | [static] |
Definition at line 6305 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().
06306 { 06307 int res=-1; 06308 if (!ast_test_flag64(iaxs[callno], IAX_KEYPOPULATED)) { 06309 /* Search for possible keys, given secrets */ 06310 struct MD5Context md5; 06311 unsigned char digest[16]; 06312 char *tmppw, *stringp; 06313 06314 tmppw = ast_strdupa(iaxs[callno]->secret); 06315 stringp = tmppw; 06316 while ((tmppw = strsep(&stringp, ";"))) { 06317 MD5Init(&md5); 06318 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06319 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06320 MD5Final(digest, &md5); 06321 build_encryption_keys(digest, iaxs[callno]); 06322 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06323 if (!res) { 06324 ast_set_flag64(iaxs[callno], IAX_KEYPOPULATED); 06325 break; 06326 } 06327 } 06328 } else 06329 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06330 return res; 06331 }
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 9544 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().
09545 { 09546 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09547 struct ast_iax2_full_hdr *fh, *cur_fh; 09548 09549 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09550 return; 09551 09552 pkt_buf->len = from_here->buf_len; 09553 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09554 09555 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09556 ast_mutex_lock(&to_here->lock); 09557 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09558 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09559 if (fh->oseqno < cur_fh->oseqno) { 09560 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09561 break; 09562 } 09563 } 09564 AST_LIST_TRAVERSE_SAFE_END 09565 09566 if (!cur_pkt_buf) 09567 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09568 09569 ast_mutex_unlock(&to_here->lock); 09570 }
static void delete_users | ( | void | ) | [static] |
Definition at line 12909 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.
12910 { 12911 struct iax2_registry *reg; 12912 12913 ao2_callback(users, 0, user_delme_cb, NULL); 12914 12915 AST_LIST_LOCK(®istrations); 12916 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 12917 if (sched) { 12918 ast_sched_thread_del(sched, reg->expire); 12919 } 12920 if (reg->callno) { 12921 int callno = reg->callno; 12922 ast_mutex_lock(&iaxsl[callno]); 12923 if (iaxs[callno]) { 12924 iaxs[callno]->reg = NULL; 12925 iax2_destroy(callno); 12926 } 12927 ast_mutex_unlock(&iaxsl[callno]); 12928 } 12929 if (reg->dnsmgr) 12930 ast_dnsmgr_release(reg->dnsmgr); 12931 ast_free(reg); 12932 } 12933 AST_LIST_UNLOCK(®istrations); 12934 12935 ao2_callback(peers, 0, peer_delme_cb, NULL); 12936 }
static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2993 of file chan_iax2.c.
References ast_free, ast_iax2_firmware_header::datalen, iax_firmware::fd, and iax_firmware::fwh.
Referenced by reload_firmware().
02994 { 02995 /* Close firmware */ 02996 if (cur->fwh) { 02997 munmap((void*)cur->fwh, ntohl(cur->fwh->datalen) + sizeof(*(cur->fwh))); 02998 } 02999 close(cur->fd); 03000 ast_free(cur); 03001 }
static void dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid, | |||
int | skiplock | |||
) | [static] |
Definition at line 9199 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().
09200 { 09201 unsigned short dpstatus = 0; 09202 struct iax_ie_data ied1; 09203 int mm; 09204 09205 memset(&ied1, 0, sizeof(ied1)); 09206 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 09207 /* Must be started */ 09208 if (ast_parking_ext_valid(callednum, NULL, context) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 09209 dpstatus = IAX_DPSTATUS_EXISTS; 09210 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 09211 dpstatus = IAX_DPSTATUS_CANEXIST; 09212 } else { 09213 dpstatus = IAX_DPSTATUS_NONEXISTENT; 09214 } 09215 if (ast_ignore_pattern(context, callednum)) 09216 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 09217 if (mm) 09218 dpstatus |= IAX_DPSTATUS_MATCHMORE; 09219 if (!skiplock) 09220 ast_mutex_lock(&iaxsl[callno]); 09221 if (iaxs[callno]) { 09222 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 09223 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 09224 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 09225 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 09226 } 09227 if (!skiplock) 09228 ast_mutex_unlock(&iaxsl[callno]); 09229 }
static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 9231 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().
09232 { 09233 /* Look up for dpreq */ 09234 struct dpreq_data *dpr = data; 09235 dp_lookup(dpr->callno, dpr->context, dpr->callednum, dpr->callerid, 0); 09236 if (dpr->callerid) 09237 ast_free(dpr->callerid); 09238 ast_free(dpr); 09239 return NULL; 09240 }
static void encmethods_to_str | ( | int | e, | |
struct ast_str * | buf | |||
) | [static] |
Definition at line 1541 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().
01542 { 01543 ast_str_set(&buf, 0, "("); 01544 if (e & IAX_ENCRYPT_AES128) { 01545 ast_str_append(&buf, 0, "aes128"); 01546 } 01547 if (e & IAX_ENCRYPT_KEYROTATE) { 01548 ast_str_append(&buf, 0, ",keyrotate"); 01549 } 01550 if (ast_str_strlen(buf) > 1) { 01551 ast_str_append(&buf, 0, ")"); 01552 } else { 01553 ast_str_set(&buf, 0, "No"); 01554 } 01555 }
static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
struct ast_iax2_full_hdr * | fh, | |||
unsigned char * | poo, | |||
int * | datalen | |||
) | [static] |
Definition at line 6264 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().
06265 { 06266 int padding; 06267 unsigned char *workspace; 06268 workspace = alloca(*datalen + 32); 06269 if (!workspace) 06270 return -1; 06271 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 06272 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 06273 if (iaxdebug) 06274 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 06275 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 06276 padding = 16 + (padding & 0xf); 06277 memcpy(workspace, poo, padding); 06278 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 06279 workspace[15] &= 0xf0; 06280 workspace[15] |= (padding & 0xf); 06281 if (iaxdebug) 06282 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 06283 *datalen += padding; 06284 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 06285 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 06286 memcpy(poo, workspace + *datalen - 32, 32); 06287 } else { 06288 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06289 if (iaxdebug) 06290 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06291 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06292 padding = 16 + (padding & 0xf); 06293 memcpy(workspace, poo, padding); 06294 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06295 workspace[15] &= 0xf0; 06296 workspace[15] |= (padding & 0x0f); 06297 *datalen += padding; 06298 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06299 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06300 memcpy(poo, workspace + *datalen - 32, 32); 06301 } 06302 return 0; 06303 }
static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8616 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().
08617 { 08618 #ifdef SCHED_MULTITHREADED 08619 if (schedule_action(__expire_registry, data)) 08620 #endif 08621 __expire_registry(data); 08622 return 0; 08623 }
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 13596 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().
13597 { 13598 struct iax2_dpcache *dp = NULL; 13599 struct timeval now = ast_tvnow(); 13600 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13601 struct ast_channel *c = NULL; 13602 struct ast_frame *f = NULL; 13603 13604 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13605 if (ast_tvcmp(now, dp->expiry) > 0) { 13606 AST_LIST_REMOVE_CURRENT(cache_list); 13607 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13608 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13609 else 13610 ast_free(dp); 13611 continue; 13612 } 13613 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13614 break; 13615 } 13616 AST_LIST_TRAVERSE_SAFE_END; 13617 13618 if (!dp) { 13619 /* No matching entry. Create a new one. */ 13620 /* First, can we make a callno? */ 13621 if ((callno = cache_get_callno_locked(data)) < 0) { 13622 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13623 return NULL; 13624 } 13625 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13626 ast_mutex_unlock(&iaxsl[callno]); 13627 return NULL; 13628 } 13629 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13630 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13631 dp->expiry = ast_tvnow(); 13632 dp->orig = dp->expiry; 13633 /* Expires in 30 mins by default */ 13634 dp->expiry.tv_sec += iaxdefaultdpcache; 13635 dp->flags = CACHE_FLAG_PENDING; 13636 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13637 dp->waiters[x] = -1; 13638 /* Insert into the lists */ 13639 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13640 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13641 /* Send the request if we're already up */ 13642 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13643 iax2_dprequest(dp, callno); 13644 ast_mutex_unlock(&iaxsl[callno]); 13645 } 13646 13647 /* By here we must have a dp */ 13648 if (dp->flags & CACHE_FLAG_PENDING) { 13649 /* Okay, here it starts to get nasty. We need a pipe now to wait 13650 for a reply to come back so long as it's pending */ 13651 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13652 /* Find an empty slot */ 13653 if (dp->waiters[x] < 0) 13654 break; 13655 } 13656 if (x >= ARRAY_LEN(dp->waiters)) { 13657 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13658 return NULL; 13659 } 13660 if (pipe(com)) { 13661 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13662 return NULL; 13663 } 13664 dp->waiters[x] = com[1]; 13665 /* Okay, now we wait */ 13666 timeout = iaxdefaulttimeout * 1000; 13667 /* Temporarily unlock */ 13668 AST_LIST_UNLOCK(&dpcache); 13669 /* Defer any dtmf */ 13670 if (chan) 13671 old = ast_channel_defer_dtmf(chan); 13672 doabort = 0; 13673 while(timeout) { 13674 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 13675 if (outfd > -1) 13676 break; 13677 if (!c) 13678 continue; 13679 if (!(f = ast_read(c))) { 13680 doabort = 1; 13681 break; 13682 } 13683 ast_frfree(f); 13684 } 13685 if (!timeout) { 13686 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13687 } 13688 AST_LIST_LOCK(&dpcache); 13689 dp->waiters[x] = -1; 13690 close(com[1]); 13691 close(com[0]); 13692 if (doabort) { 13693 /* Don't interpret anything, just abort. Not sure what th epoint 13694 of undeferring dtmf on a hung up channel is but hey whatever */ 13695 if (!old && chan) 13696 ast_channel_undefer_dtmf(chan); 13697 return NULL; 13698 } 13699 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13700 /* Now to do non-independent analysis the results of our wait */ 13701 if (dp->flags & CACHE_FLAG_PENDING) { 13702 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13703 pending. Don't let it take as long to timeout. */ 13704 dp->flags &= ~CACHE_FLAG_PENDING; 13705 dp->flags |= CACHE_FLAG_TIMEOUT; 13706 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 13707 systems without leaving it unavailable once the server comes back online */ 13708 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 13709 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13710 if (dp->waiters[x] > -1) { 13711 if (write(dp->waiters[x], "asdf", 4) < 0) { 13712 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13713 } 13714 } 13715 } 13716 } 13717 } 13718 /* Our caller will obtain the rest */ 13719 if (!old && chan) 13720 ast_channel_undefer_dtmf(chan); 13721 } 13722 return dp; 13723 }
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 2918 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02918 { 02919 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02920 }
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 2922 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().
02922 { 02923 02924 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02925 }
static struct iax2_thread* find_idle_thread | ( | void | ) | [static] |
Definition at line 1393 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().
01394 { 01395 struct iax2_thread *thread = NULL; 01396 01397 /* Pop the head of the idle list off */ 01398 AST_LIST_LOCK(&idle_list); 01399 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01400 AST_LIST_UNLOCK(&idle_list); 01401 01402 /* If we popped a thread off the idle list, just return it */ 01403 if (thread) { 01404 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01405 return thread; 01406 } 01407 01408 /* Pop the head of the dynamic list off */ 01409 AST_LIST_LOCK(&dynamic_list); 01410 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01411 AST_LIST_UNLOCK(&dynamic_list); 01412 01413 /* If we popped a thread off the dynamic list, just return it */ 01414 if (thread) { 01415 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01416 return thread; 01417 } 01418 01419 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01420 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01421 return NULL; 01422 01423 /* Set default values */ 01424 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01425 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01426 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01427 01428 /* Initialize lock and condition */ 01429 ast_mutex_init(&thread->lock); 01430 ast_cond_init(&thread->cond, NULL); 01431 ast_mutex_init(&thread->init_lock); 01432 ast_cond_init(&thread->init_cond, NULL); 01433 ast_mutex_lock(&thread->init_lock); 01434 01435 /* Create thread and send it on it's way */ 01436 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01437 ast_cond_destroy(&thread->cond); 01438 ast_mutex_destroy(&thread->lock); 01439 ast_mutex_unlock(&thread->init_lock); 01440 ast_cond_destroy(&thread->init_cond); 01441 ast_mutex_destroy(&thread->init_lock); 01442 ast_free(thread); 01443 return NULL; 01444 } 01445 01446 /* this thread is not processing a full frame (since it is idle), 01447 so ensure that the field for the full frame call number is empty */ 01448 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01449 01450 /* Wait for the thread to be ready before returning it to the caller */ 01451 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01452 01453 /* Done with init_lock */ 01454 ast_mutex_unlock(&thread->init_lock); 01455 01456 return thread; 01457 }
static struct iax2_peer* find_peer | ( | const char * | name, | |
int | realtime | |||
) | [static] |
Definition at line 1685 of file chan_iax2.c.
References ao2_find, iax2_peer::name, OBJ_POINTER, peers, and realtime_peer().
01686 { 01687 struct iax2_peer *peer = NULL; 01688 struct iax2_peer tmp_peer = { 01689 .name = name, 01690 }; 01691 01692 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01693 01694 /* Now go for realtime if applicable */ 01695 if(!peer && realtime) 01696 peer = realtime_peer(name, NULL); 01697 01698 return peer; 01699 }
static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
int | fd | |||
) | [static] |
Definition at line 6036 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().
06037 { 06038 struct iax2_trunk_peer *tpeer = NULL; 06039 06040 /* Finds and locks trunk peer */ 06041 AST_LIST_LOCK(&tpeers); 06042 06043 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 06044 if (!inaddrcmp(&tpeer->addr, sin)) { 06045 ast_mutex_lock(&tpeer->lock); 06046 break; 06047 } 06048 } 06049 06050 if (!tpeer) { 06051 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 06052 ast_mutex_init(&tpeer->lock); 06053 tpeer->lastsent = 9999; 06054 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 06055 tpeer->trunkact = ast_tvnow(); 06056 ast_mutex_lock(&tpeer->lock); 06057 tpeer->sockfd = fd; 06058 #ifdef SO_NO_CHECK 06059 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 06060 #endif 06061 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 06062 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 06063 } 06064 } 06065 06066 AST_LIST_UNLOCK(&tpeers); 06067 06068 return tpeer; 06069 }
static struct iax2_user* find_user | ( | const char * | name | ) | [static] |
Definition at line 1713 of file chan_iax2.c.
References ao2_find, iax2_user::name, OBJ_POINTER, and users.
01714 { 01715 struct iax2_user tmp_user = { 01716 .name = name, 01717 }; 01718 01719 return ao2_find(users, &tmp_user, OBJ_POINTER); 01720 }
static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
int | callno, | |||
unsigned int | ts | |||
) | [static] |
Definition at line 5848 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), iaxs, and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05849 { 05850 long ms; /* NOT unsigned */ 05851 if (ast_tvzero(iaxs[callno]->rxcore)) { 05852 /* Initialize rxcore time if appropriate */ 05853 iaxs[callno]->rxcore = ast_tvnow(); 05854 /* Round to nearest 20ms so traces look pretty */ 05855 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05856 } 05857 /* Calculate difference between trunk and channel */ 05858 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05859 /* Return as the sum of trunk time and the difference between trunk and real time */ 05860 return ms + ts; 05861 }
static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 12055 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
12056 { 12057 struct iax2_context *conl; 12058 while(con) { 12059 conl = con; 12060 con = con->next; 12061 ast_free(conl); 12062 } 12063 }
static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1819 of file chan_iax2.c.
References ast_free, ast_frame::data, ast_frame::datalen, signaling_queue_entry::f, and ast_frame::ptr.
Referenced by pvt_destructor(), queue_signalling(), and send_signaling().
static int function_iaxpeer | ( | struct ast_channel * | chan, | |
const char * | cmd, | |||
char * | data, | |||
char * | buf, | |||
size_t | len | |||
) | [static] |
Definition at line 13846 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.
13847 { 13848 struct iax2_peer *peer; 13849 char *peername, *colname; 13850 13851 peername = ast_strdupa(data); 13852 13853 /* if our channel, return the IP address of the endpoint of current channel */ 13854 if (!strcmp(peername,"CURRENTCHANNEL")) { 13855 unsigned short callno; 13856 if (chan->tech != &iax2_tech) 13857 return -1; 13858 callno = PTR_TO_CALLNO(chan->tech_pvt); 13859 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 13860 return 0; 13861 } 13862 13863 if ((colname = strchr(peername, ','))) 13864 *colname++ = '\0'; 13865 else 13866 colname = "ip"; 13867 13868 if (!(peer = find_peer(peername, 1))) 13869 return -1; 13870 13871 if (!strcasecmp(colname, "ip")) { 13872 ast_copy_string(buf, ast_sockaddr_stringify_addr(&peer->addr), len); 13873 } else if (!strcasecmp(colname, "status")) { 13874 peer_status(peer, buf, len); 13875 } else if (!strcasecmp(colname, "mailbox")) { 13876 ast_copy_string(buf, peer->mailbox, len); 13877 } else if (!strcasecmp(colname, "context")) { 13878 ast_copy_string(buf, peer->context, len); 13879 } else if (!strcasecmp(colname, "expire")) { 13880 snprintf(buf, len, "%d", peer->expire); 13881 } else if (!strcasecmp(colname, "dynamic")) { 13882 ast_copy_string(buf, (ast_test_flag64(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 13883 } else if (!strcasecmp(colname, "callerid_name")) { 13884 ast_copy_string(buf, peer->cid_name, len); 13885 } else if (!strcasecmp(colname, "callerid_num")) { 13886 ast_copy_string(buf, peer->cid_num, len); 13887 } else if (!strcasecmp(colname, "codecs")) { 13888 ast_getformatname_multiple(buf, len -1, peer->capability); 13889 } else if (!strncasecmp(colname, "codec[", 6)) { 13890 char *codecnum, *ptr; 13891 int codec = 0; 13892 13893 codecnum = strchr(colname, '['); 13894 *codecnum = '\0'; 13895 codecnum++; 13896 if ((ptr = strchr(codecnum, ']'))) { 13897 *ptr = '\0'; 13898 } 13899 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 13900 ast_copy_string(buf, ast_getformatname(codec), len); 13901 } else { 13902 buf[0] = '\0'; 13903 } 13904 } else { 13905 buf[0] = '\0'; 13906 } 13907 13908 peer_unref(peer); 13909 13910 return 0; 13911 }
static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 12205 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
12206 { 12207 int methods = 0; 12208 if (strstr(value, "rsa")) 12209 methods |= IAX_AUTH_RSA; 12210 if (strstr(value, "md5")) 12211 methods |= IAX_AUTH_MD5; 12212 if (strstr(value, "plaintext")) 12213 methods |= IAX_AUTH_PLAINTEXT; 12214 return methods; 12215 }
static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1557 of file chan_iax2.c.
References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by build_peer(), build_user(), and set_config().
01558 { 01559 int e; 01560 if (!strcasecmp(s, "aes128")) 01561 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01562 else if (ast_true(s)) 01563 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01564 else 01565 e = 0; 01566 return e; 01567 }
static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 4119 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
04120 { 04121 #ifdef SCHED_MULTITHREADED 04122 if (schedule_action(__get_from_jb, data)) 04123 #endif 04124 __get_from_jb(data); 04125 return 0; 04126 }
static struct callno_entry * get_unused_callno | ( | int | trunk, | |
int | validated | |||
) | [static] |
Definition at line 2596 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().
02597 { 02598 struct callno_entry *callno_entry = NULL; 02599 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02600 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02601 /* Minor optimization for the extreme case. */ 02602 return NULL; 02603 } 02604 02605 /* the callno_pool container is locked here primarily to ensure thread 02606 * safety of the total_nonval_callno_used check and increment */ 02607 ao2_lock(callno_pool); 02608 02609 /* only a certain number of nonvalidated call numbers should be allocated. 02610 * If there ever is an attack, this separates the calltoken validating 02611 * users from the non calltoken validating users. */ 02612 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02613 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02614 ao2_unlock(callno_pool); 02615 return NULL; 02616 } 02617 02618 /* unlink the object from the container, taking over ownership 02619 * of the reference the container had to the object */ 02620 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02621 02622 if (callno_entry) { 02623 callno_entry->validated = validated; 02624 if (!validated) { 02625 total_nonval_callno_used++; 02626 } 02627 } 02628 02629 ao2_unlock(callno_pool); 02630 return callno_entry; 02631 }
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 4844 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().
04846 { 04847 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04848 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04849 struct ast_str *buf = ast_str_alloca(256); 04850 time_t t = time(NULL); 04851 char hash[41]; /* 40 char sha1 hash */ 04852 int subclass = uncompress_subclass(fh->csub); 04853 04854 /* ----- Case 1 ----- */ 04855 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04856 struct iax_ie_data ied = { 04857 .buf = { 0 }, 04858 .pos = 0, 04859 }; 04860 04861 /* create the hash with their address data and our timestamp */ 04862 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04863 ast_sha1_hash(hash, ast_str_buffer(buf)); 04864 04865 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04866 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04867 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04868 04869 return 1; 04870 04871 /* ----- Case 2 ----- */ 04872 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04873 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04874 char *rec_ts = NULL; /* received timestamp */ 04875 unsigned int rec_time; /* received time_t */ 04876 04877 /* split the timestamp from the hash data */ 04878 rec_hash = strchr((char *) ies->calltokendata, '?'); 04879 if (rec_hash) { 04880 *rec_hash++ = '\0'; 04881 rec_ts = (char *) ies->calltokendata; 04882 } 04883 04884 /* check that we have valid data before we do any comparisons */ 04885 if (!rec_hash || !rec_ts) { 04886 goto reject; 04887 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04888 goto reject; 04889 } 04890 04891 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04892 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04893 ast_sha1_hash(hash, ast_str_buffer(buf)); 04894 04895 /* compare hashes and then check timestamp delay */ 04896 if (strcmp(hash, rec_hash)) { 04897 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04898 goto reject; /* received hash does not match ours, reject */ 04899 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04900 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04901 goto reject; /* too much delay, reject */ 04902 } 04903 04904 /* at this point the call token is valid, returning 0 04905 * will allow socket_process to continue as usual */ 04906 requirecalltoken_mark_auto(ies->username, subclass); 04907 return 0; 04908 04909 /* ----- Case 3 ----- */ 04910 } else { /* calltokens are not supported for this client, how do we respond? */ 04911 if (calltoken_required(sin, ies->username, subclass)) { 04912 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")); 04913 goto reject; 04914 } 04915 return 0; /* calltoken is not required for this addr, so permit it. */ 04916 } 04917 04918 reject: 04919 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04920 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04921 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04922 } else { 04923 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04924 } 04925 04926 return 1; 04927 }
static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 11902 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.
11903 { 11904 int force = 0; 11905 int res; 11906 11907 switch (cmd) { 11908 case CLI_INIT: 11909 e->command = "iax2 provision"; 11910 e->usage = 11911 "Usage: iax2 provision <host> <template> [forced]\n" 11912 " Provisions the given peer or IP address using a template\n" 11913 " matching either 'template' or '*' if the template is not\n" 11914 " found. If 'forced' is specified, even empty provisioning\n" 11915 " fields will be provisioned as empty fields.\n"; 11916 return NULL; 11917 case CLI_GENERATE: 11918 if (a->pos == 3) 11919 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 11920 return NULL; 11921 } 11922 11923 if (a->argc < 4) 11924 return CLI_SHOWUSAGE; 11925 if (a->argc > 4) { 11926 if (!strcasecmp(a->argv[4], "forced")) 11927 force = 1; 11928 else 11929 return CLI_SHOWUSAGE; 11930 } 11931 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 11932 if (res < 0) 11933 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 11934 else if (res < 1) 11935 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 11936 else 11937 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 11938 return CLI_SUCCESS; 11939 }
static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3551 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.
03552 { 03553 struct iax2_peer *peer = NULL; 03554 struct iax2_user *user = NULL; 03555 static const char * const choices[] = { "all", NULL }; 03556 char *cmplt; 03557 03558 switch (cmd) { 03559 case CLI_INIT: 03560 e->command = "iax2 prune realtime"; 03561 e->usage = 03562 "Usage: iax2 prune realtime [<peername>|all]\n" 03563 " Prunes object(s) from the cache\n"; 03564 return NULL; 03565 case CLI_GENERATE: 03566 if (a->pos == 3) { 03567 cmplt = ast_cli_complete(a->word, choices, a->n); 03568 if (!cmplt) 03569 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03570 return cmplt; 03571 } 03572 return NULL; 03573 } 03574 if (a->argc != 4) 03575 return CLI_SHOWUSAGE; 03576 if (!strcmp(a->argv[3], "all")) { 03577 prune_users(); 03578 prune_peers(); 03579 ast_cli(a->fd, "Cache flushed successfully.\n"); 03580 return CLI_SUCCESS; 03581 } 03582 peer = find_peer(a->argv[3], 0); 03583 user = find_user(a->argv[3]); 03584 if (peer || user) { 03585 if (peer) { 03586 if (ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 03587 ast_set_flag64(peer, IAX_RTAUTOCLEAR); 03588 expire_registry(peer_ref(peer)); 03589 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03590 } else { 03591 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03592 } 03593 peer_unref(peer); 03594 } 03595 if (user) { 03596 if (ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 03597 ast_set_flag64(user, IAX_RTAUTOCLEAR); 03598 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03599 } else { 03600 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03601 } 03602 ao2_unlink(users,user); 03603 user_unref(user); 03604 } 03605 } else { 03606 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03607 } 03608 03609 return CLI_SUCCESS; 03610 }
static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 13500 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
13501 { 13502 switch (cmd) { 13503 case CLI_INIT: 13504 e->command = "iax2 reload"; 13505 e->usage = 13506 "Usage: iax2 reload\n" 13507 " Reloads IAX configuration from iax.conf\n"; 13508 return NULL; 13509 case CLI_GENERATE: 13510 return NULL; 13511 } 13512 13513 reload_config(); 13514 13515 return CLI_SUCCESS; 13516 }
static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7308 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.
07309 { 07310 switch (cmd) { 07311 case CLI_INIT: 07312 e->command = "iax2 set debug {on|off|peer}"; 07313 e->usage = 07314 "Usage: iax2 set debug {on|off|peer peername}\n" 07315 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07316 return NULL; 07317 case CLI_GENERATE: 07318 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07319 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07320 return NULL; 07321 } 07322 07323 if (a->argc < e->args || a->argc > e->args + 1) 07324 return CLI_SHOWUSAGE; 07325 07326 if (!strcasecmp(a->argv[3], "peer")) { 07327 struct iax2_peer *peer; 07328 struct sockaddr_in peer_addr; 07329 07330 07331 if (a->argc != e->args + 1) 07332 return CLI_SHOWUSAGE; 07333 07334 peer = find_peer(a->argv[4], 1); 07335 07336 if (!peer) { 07337 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07338 return CLI_FAILURE; 07339 } 07340 07341 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 07342 07343 debugaddr.sin_addr = peer_addr.sin_addr; 07344 debugaddr.sin_port = peer_addr.sin_port; 07345 07346 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07347 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07348 07349 ao2_ref(peer, -1); 07350 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07351 iaxdebug = 1; 07352 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07353 } else { 07354 iaxdebug = 0; 07355 memset(&debugaddr, 0, sizeof(debugaddr)); 07356 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07357 } 07358 return CLI_SUCCESS; 07359 }
static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7387 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.
07388 { 07389 switch (cmd) { 07390 case CLI_INIT: 07391 e->command = "iax2 set debug jb {on|off}"; 07392 e->usage = 07393 "Usage: iax2 set debug jb {on|off}\n" 07394 " Enables/Disables jitterbuffer debugging information\n"; 07395 return NULL; 07396 case CLI_GENERATE: 07397 return NULL; 07398 } 07399 07400 if (a->argc != e->args) 07401 return CLI_SHOWUSAGE; 07402 07403 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07404 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07405 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07406 } else { 07407 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07408 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07409 } 07410 return CLI_SUCCESS; 07411 }
static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7361 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.
07362 { 07363 switch (cmd) { 07364 case CLI_INIT: 07365 e->command = "iax2 set debug trunk {on|off}"; 07366 e->usage = 07367 "Usage: iax2 set debug trunk {on|off}\n" 07368 " Enables/Disables debugging of IAX trunking\n"; 07369 return NULL; 07370 case CLI_GENERATE: 07371 return NULL; 07372 } 07373 07374 if (a->argc != e->args) 07375 return CLI_SHOWUSAGE; 07376 07377 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07378 iaxtrunkdebug = 1; 07379 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07380 } else { 07381 iaxtrunkdebug = 0; 07382 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07383 } 07384 return CLI_SUCCESS; 07385 }
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 3878 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.
03879 { 03880 int mtuv; 03881 03882 switch (cmd) { 03883 case CLI_INIT: 03884 e->command = "iax2 set mtu"; 03885 e->usage = 03886 "Usage: iax2 set mtu <value>\n" 03887 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03888 " zero to disable. Disabling means that the operating system\n" 03889 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03890 " packet exceeds the UDP payload size. This is substantially\n" 03891 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03892 " greater for G.711 samples.\n"; 03893 return NULL; 03894 case CLI_GENERATE: 03895 return NULL; 03896 } 03897 03898 if (a->argc != 4) 03899 return CLI_SHOWUSAGE; 03900 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03901 mtuv = MAX_TRUNK_MTU; 03902 else 03903 mtuv = atoi(a->argv[3]); 03904 03905 if (mtuv == 0) { 03906 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03907 global_max_trunk_mtu = 0; 03908 return CLI_SUCCESS; 03909 } 03910 if (mtuv < 172 || mtuv > 4000) { 03911 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03912 return CLI_SHOWUSAGE; 03913 } 03914 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03915 global_max_trunk_mtu = mtuv; 03916 return CLI_SUCCESS; 03917 }
static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3919 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.
03920 { 03921 struct iax2_dpcache *dp = NULL; 03922 char tmp[1024], *pc = NULL; 03923 int s, x, y; 03924 struct timeval now = ast_tvnow(); 03925 03926 switch (cmd) { 03927 case CLI_INIT: 03928 e->command = "iax2 show cache"; 03929 e->usage = 03930 "Usage: iax2 show cache\n" 03931 " Display currently cached IAX Dialplan results.\n"; 03932 return NULL; 03933 case CLI_GENERATE: 03934 return NULL; 03935 } 03936 03937 AST_LIST_LOCK(&dpcache); 03938 03939 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03940 03941 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 03942 s = dp->expiry.tv_sec - now.tv_sec; 03943 tmp[0] = '\0'; 03944 if (dp->flags & CACHE_FLAG_EXISTS) 03945 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03946 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03947 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03948 if (dp->flags & CACHE_FLAG_CANEXIST) 03949 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03950 if (dp->flags & CACHE_FLAG_PENDING) 03951 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03952 if (dp->flags & CACHE_FLAG_TIMEOUT) 03953 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03954 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03955 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03956 if (dp->flags & CACHE_FLAG_MATCHMORE) 03957 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03958 if (dp->flags & CACHE_FLAG_UNKNOWN) 03959 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03960 /* Trim trailing pipe */ 03961 if (!ast_strlen_zero(tmp)) { 03962 tmp[strlen(tmp) - 1] = '\0'; 03963 } else { 03964 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03965 } 03966 y = 0; 03967 pc = strchr(dp->peercontext, '@'); 03968 if (!pc) { 03969 pc = dp->peercontext; 03970 } else { 03971 pc++; 03972 } 03973 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 03974 if (dp->waiters[x] > -1) 03975 y++; 03976 } 03977 if (s > 0) { 03978 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03979 } else { 03980 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 03981 } 03982 } 03983 03984 AST_LIST_UNLOCK(&dpcache); 03985 03986 return CLI_SUCCESS; 03987 }
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 ao2_ref(peercnt, -1); 02564 found = 1; 02565 break; 02566 } else { 02567 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02568 } 02569 ao2_ref(peercnt, -1); 02570 } 02571 ao2_iterator_destroy(&i); 02572 02573 if (a->argc == 4) { 02574 ast_cli(a->fd, "\nNon-CallToken Validation Callno Limit: %d\n" 02575 "Non-CallToken Validated Callno Used: %d\n", 02576 global_maxcallno_nonval, 02577 total_nonval_callno_used); 02578 02579 ast_cli(a->fd, "Total Available Callno: %d\n" 02580 "Regular Callno Available: %d\n" 02581 "Trunk Callno Available: %d\n", 02582 ao2_container_count(callno_pool) + ao2_container_count(callno_pool_trunk), 02583 ao2_container_count(callno_pool), 02584 ao2_container_count(callno_pool_trunk)); 02585 } else if (a->argc == 5 && !found) { 02586 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] ); 02587 } 02588 02589 02590 return CLI_SUCCESS; 02591 default: 02592 return NULL; 02593 } 02594 }
static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7135 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.
07136 { 07137 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 07138 #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" 07139 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 07140 int x; 07141 int numchans = 0; 07142 char first_message[10] = { 0, }; 07143 char last_message[10] = { 0, }; 07144 07145 switch (cmd) { 07146 case CLI_INIT: 07147 e->command = "iax2 show channels"; 07148 e->usage = 07149 "Usage: iax2 show channels\n" 07150 " Lists all currently active IAX channels.\n"; 07151 return NULL; 07152 case CLI_GENERATE: 07153 return NULL; 07154 } 07155 07156 if (a->argc != 3) 07157 return CLI_SHOWUSAGE; 07158 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 07159 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 07160 ast_mutex_lock(&iaxsl[x]); 07161 if (iaxs[x]) { 07162 int lag, jitter, localdelay; 07163 jb_info jbinfo; 07164 if (ast_test_flag64(iaxs[x], IAX_USEJITTERBUF)) { 07165 jb_getinfo(iaxs[x]->jb, &jbinfo); 07166 jitter = jbinfo.jitter; 07167 localdelay = jbinfo.current - jbinfo.min; 07168 } else { 07169 jitter = -1; 07170 localdelay = 0; 07171 } 07172 07173 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 07174 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 07175 lag = iaxs[x]->remote_rr.delay; 07176 ast_cli(a->fd, FORMAT, 07177 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 07178 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 07179 S_OR(iaxs[x]->username, "(None)"), 07180 iaxs[x]->callno, iaxs[x]->peercallno, 07181 iaxs[x]->oseqno, iaxs[x]->iseqno, 07182 lag, 07183 jitter, 07184 localdelay, 07185 ast_getformatname(iaxs[x]->voiceformat), 07186 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07187 first_message, 07188 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 07189 last_message); 07190 numchans++; 07191 } 07192 ast_mutex_unlock(&iaxsl[x]); 07193 } 07194 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07195 return CLI_SUCCESS; 07196 #undef FORMAT 07197 #undef FORMAT2 07198 #undef FORMATB 07199 }
static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6921 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.
06922 { 06923 struct iax_firmware *cur = NULL; 06924 06925 switch (cmd) { 06926 case CLI_INIT: 06927 e->command = "iax2 show firmware"; 06928 e->usage = 06929 "Usage: iax2 show firmware\n" 06930 " Lists all known IAX firmware images.\n"; 06931 return NULL; 06932 case CLI_GENERATE: 06933 return NULL; 06934 } 06935 06936 if (a->argc != 3 && a->argc != 4) 06937 return CLI_SHOWUSAGE; 06938 06939 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 06940 AST_LIST_LOCK(&firmwares); 06941 AST_LIST_TRAVERSE(&firmwares, cur, list) { 06942 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 06943 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 06944 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 06945 } 06946 } 06947 AST_LIST_UNLOCK(&firmwares); 06948 06949 return CLI_SUCCESS; 06950 }
static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7285 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.
07286 { 07287 int numchans = 0; 07288 07289 switch (cmd) { 07290 case CLI_INIT: 07291 e->command = "iax2 show netstats"; 07292 e->usage = 07293 "Usage: iax2 show netstats\n" 07294 " Lists network status for all currently active IAX channels.\n"; 07295 return NULL; 07296 case CLI_GENERATE: 07297 return NULL; 07298 } 07299 if (a->argc != 3) 07300 return CLI_SHOWUSAGE; 07301 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 07302 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 07303 numchans = ast_cli_netstats(NULL, a->fd, 1); 07304 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 07305 return CLI_SUCCESS; 07306 }
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 3726 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.
03727 { 03728 char status[30]; 03729 char cbuf[256]; 03730 struct iax2_peer *peer; 03731 char codec_buf[512]; 03732 struct ast_str *encmethods = ast_str_alloca(256); 03733 int x = 0, codec = 0, load_realtime = 0; 03734 03735 switch (cmd) { 03736 case CLI_INIT: 03737 e->command = "iax2 show peer"; 03738 e->usage = 03739 "Usage: iax2 show peer <name>\n" 03740 " Display details on specific IAX peer\n"; 03741 return NULL; 03742 case CLI_GENERATE: 03743 if (a->pos == 3) 03744 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03745 return NULL; 03746 } 03747 03748 if (a->argc < 4) 03749 return CLI_SHOWUSAGE; 03750 03751 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03752 03753 peer = find_peer(a->argv[3], load_realtime); 03754 if (peer) { 03755 struct sockaddr_in peer_addr; 03756 03757 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 03758 03759 encmethods_to_str(peer->encmethods, encmethods); 03760 ast_cli(a->fd, "\n\n"); 03761 ast_cli(a->fd, " * Name : %s\n", peer->name); 03762 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03763 ast_cli(a->fd, " Context : %s\n", peer->context); 03764 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03765 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03766 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03767 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03768 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03769 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 03770 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03771 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03772 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03773 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03774 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)); 03775 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03776 ast_cli(a->fd, " Username : %s\n", peer->username); 03777 ast_cli(a->fd, " Codecs : "); 03778 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03779 ast_cli(a->fd, "%s\n", codec_buf); 03780 03781 ast_cli(a->fd, " Codec Order : ("); 03782 for(x = 0; x < 32 ; x++) { 03783 codec = ast_codec_pref_index(&peer->prefs,x); 03784 if(!codec) 03785 break; 03786 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03787 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03788 ast_cli(a->fd, "|"); 03789 } 03790 03791 if (!x) 03792 ast_cli(a->fd, "none"); 03793 ast_cli(a->fd, ")\n"); 03794 03795 ast_cli(a->fd, " Status : "); 03796 peer_status(peer, status, sizeof(status)); 03797 ast_cli(a->fd, "%s\n",status); 03798 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"); 03799 ast_cli(a->fd, "\n"); 03800 peer_unref(peer); 03801 } else { 03802 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03803 ast_cli(a->fd, "\n"); 03804 } 03805 03806 return CLI_SUCCESS; 03807 }
static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6889 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.
06890 { 06891 switch (cmd) { 06892 case CLI_INIT: 06893 e->command = "iax2 show peers"; 06894 e->usage = 06895 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06896 " Lists all known IAX2 peers.\n" 06897 " Optional 'registered' argument lists only peers with known addresses.\n" 06898 " Optional regular expression pattern is used to filter the peer list.\n"; 06899 return NULL; 06900 case CLI_GENERATE: 06901 return NULL; 06902 } 06903 06904 switch (__iax2_show_peers(a->fd, NULL, NULL, a->argc, a->argv)) { 06905 case RESULT_SHOWUSAGE: 06906 return CLI_SHOWUSAGE; 06907 case RESULT_FAILURE: 06908 return CLI_FAILURE; 06909 default: 06910 return CLI_SUCCESS; 06911 } 06912 }
static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 7044 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.
07045 { 07046 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 07047 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 07048 struct iax2_registry *reg = NULL; 07049 char host[80]; 07050 char perceived[80]; 07051 int counter = 0; 07052 07053 switch (cmd) { 07054 case CLI_INIT: 07055 e->command = "iax2 show registry"; 07056 e->usage = 07057 "Usage: iax2 show registry\n" 07058 " Lists all registration requests and status.\n"; 07059 return NULL; 07060 case CLI_GENERATE: 07061 return NULL; 07062 } 07063 if (a->argc != 3) 07064 return CLI_SHOWUSAGE; 07065 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 07066 AST_LIST_LOCK(®istrations); 07067 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07068 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07069 if (reg->us.sin_addr.s_addr) 07070 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07071 else 07072 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07073 ast_cli(a->fd, FORMAT, host, 07074 (reg->dnsmgr) ? "Y" : "N", 07075 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 07076 counter++; 07077 } 07078 AST_LIST_UNLOCK(®istrations); 07079 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 07080 return CLI_SUCCESS; 07081 #undef FORMAT 07082 #undef FORMAT2 07083 }
static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3832 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.
03833 { 03834 struct iax_frame *cur; 03835 int cnt = 0, dead = 0, final = 0, i = 0; 03836 03837 switch (cmd) { 03838 case CLI_INIT: 03839 e->command = "iax2 show stats"; 03840 e->usage = 03841 "Usage: iax2 show stats\n" 03842 " Display statistics on IAX channel driver.\n"; 03843 return NULL; 03844 case CLI_GENERATE: 03845 return NULL; 03846 } 03847 03848 if (a->argc != 3) 03849 return CLI_SHOWUSAGE; 03850 03851 for (i = 0; i < ARRAY_LEN(frame_queue); i++) { 03852 ast_mutex_lock(&iaxsl[i]); 03853 AST_LIST_TRAVERSE(&frame_queue[i], cur, list) { 03854 if (cur->retries < 0) 03855 dead++; 03856 if (cur->final) 03857 final++; 03858 cnt++; 03859 } 03860 ast_mutex_unlock(&iaxsl[i]); 03861 } 03862 03863 ast_cli(a->fd, " IAX Statistics\n"); 03864 ast_cli(a->fd, "---------------------\n"); 03865 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03866 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03867 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03868 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03869 03870 trunk_timed = trunk_untimed = 0; 03871 if (trunk_maxmtu > trunk_nmaxmtu) 03872 trunk_nmaxmtu = trunk_maxmtu; 03873 03874 return CLI_SUCCESS; 03875 }
static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6752 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.
06753 { 06754 struct iax2_thread *thread = NULL; 06755 time_t t; 06756 int threadcount = 0, dynamiccount = 0; 06757 char type; 06758 06759 switch (cmd) { 06760 case CLI_INIT: 06761 e->command = "iax2 show threads"; 06762 e->usage = 06763 "Usage: iax2 show threads\n" 06764 " Lists status of IAX helper threads\n"; 06765 return NULL; 06766 case CLI_GENERATE: 06767 return NULL; 06768 } 06769 if (a->argc != 3) 06770 return CLI_SHOWUSAGE; 06771 06772 ast_cli(a->fd, "IAX2 Thread Information\n"); 06773 time(&t); 06774 ast_cli(a->fd, "Idle Threads:\n"); 06775 AST_LIST_LOCK(&idle_list); 06776 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06777 #ifdef DEBUG_SCHED_MULTITHREAD 06778 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06779 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06780 #else 06781 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06782 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06783 #endif 06784 threadcount++; 06785 } 06786 AST_LIST_UNLOCK(&idle_list); 06787 ast_cli(a->fd, "Active Threads:\n"); 06788 AST_LIST_LOCK(&active_list); 06789 AST_LIST_TRAVERSE(&active_list, thread, list) { 06790 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06791 type = 'D'; 06792 else 06793 type = 'P'; 06794 #ifdef DEBUG_SCHED_MULTITHREAD 06795 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06796 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06797 #else 06798 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06799 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06800 #endif 06801 threadcount++; 06802 } 06803 AST_LIST_UNLOCK(&active_list); 06804 ast_cli(a->fd, "Dynamic Threads:\n"); 06805 AST_LIST_LOCK(&dynamic_list); 06806 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06807 #ifdef DEBUG_SCHED_MULTITHREAD 06808 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06809 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06810 #else 06811 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06812 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06813 #endif 06814 dynamiccount++; 06815 } 06816 AST_LIST_UNLOCK(&dynamic_list); 06817 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06818 return CLI_SUCCESS; 06819 }
static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6543 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.
06544 { 06545 regex_t regexbuf; 06546 int havepattern = 0; 06547 06548 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06549 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06550 06551 struct iax2_user *user = NULL; 06552 char auth[90]; 06553 char *pstr = ""; 06554 struct ao2_iterator i; 06555 06556 switch (cmd) { 06557 case CLI_INIT: 06558 e->command = "iax2 show users [like]"; 06559 e->usage = 06560 "Usage: iax2 show users [like <pattern>]\n" 06561 " Lists all known IAX2 users.\n" 06562 " Optional regular expression pattern is used to filter the user list.\n"; 06563 return NULL; 06564 case CLI_GENERATE: 06565 return NULL; 06566 } 06567 06568 switch (a->argc) { 06569 case 5: 06570 if (!strcasecmp(a->argv[3], "like")) { 06571 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06572 return CLI_SHOWUSAGE; 06573 havepattern = 1; 06574 } else 06575 return CLI_SHOWUSAGE; 06576 case 3: 06577 break; 06578 default: 06579 return CLI_SHOWUSAGE; 06580 } 06581 06582 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06583 i = ao2_iterator_init(users, 0); 06584 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 06585 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06586 continue; 06587 06588 if (!ast_strlen_zero(user->secret)) { 06589 ast_copy_string(auth,user->secret, sizeof(auth)); 06590 } else if (!ast_strlen_zero(user->inkeys)) { 06591 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06592 } else 06593 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06594 06595 if(ast_test_flag64(user, IAX_CODEC_NOCAP)) 06596 pstr = "REQ Only"; 06597 else if(ast_test_flag64(user, IAX_CODEC_NOPREFS)) 06598 pstr = "Disabled"; 06599 else 06600 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06601 06602 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06603 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06604 user->ha ? "Yes" : "No", pstr); 06605 } 06606 ao2_iterator_destroy(&i); 06607 06608 if (havepattern) 06609 regfree(®exbuf); 06610 06611 return CLI_SUCCESS; 06612 #undef FORMAT 06613 #undef FORMAT2 06614 }
static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 3612 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.
03613 { 03614 switch (cmd) { 03615 case CLI_INIT: 03616 e->command = "iax2 test losspct"; 03617 e->usage = 03618 "Usage: iax2 test losspct <percentage>\n" 03619 " For testing, throws away <percentage> percent of incoming packets\n"; 03620 return NULL; 03621 case CLI_GENERATE: 03622 return NULL; 03623 } 03624 if (a->argc != 4) 03625 return CLI_SHOWUSAGE; 03626 03627 test_losspct = atoi(a->argv[3]); 03628 03629 return CLI_SUCCESS; 03630 }
static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 6821 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.
06822 { 06823 struct iax2_peer *p; 06824 06825 switch (cmd) { 06826 case CLI_INIT: 06827 e->command = "iax2 unregister"; 06828 e->usage = 06829 "Usage: iax2 unregister <peername>\n" 06830 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06831 return NULL; 06832 case CLI_GENERATE: 06833 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06834 } 06835 06836 if (a->argc != 3) 06837 return CLI_SHOWUSAGE; 06838 06839 p = find_peer(a->argv[2], 1); 06840 if (p) { 06841 if (p->expire > 0) { 06842 struct iax2_peer tmp_peer = { 06843 .name = a->argv[2], 06844 }; 06845 struct iax2_peer *peer; 06846 06847 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06848 if (peer) { 06849 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06850 peer_unref(peer); /* ref from ao2_find() */ 06851 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06852 } else { 06853 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06854 } 06855 } else { 06856 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06857 } 06858 } else { 06859 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06860 } 06861 return CLI_SUCCESS; 06862 }
static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9514 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.
09515 { 09516 struct iax2_pkt_buf *pkt_buf; 09517 09518 ast_mutex_lock(&thread->lock); 09519 09520 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09521 ast_mutex_unlock(&thread->lock); 09522 09523 thread->buf = pkt_buf->buf; 09524 thread->buf_len = pkt_buf->len; 09525 thread->buf_size = pkt_buf->len + 1; 09526 09527 socket_process(thread); 09528 09529 thread->buf = NULL; 09530 ast_free(pkt_buf); 09531 09532 ast_mutex_lock(&thread->lock); 09533 } 09534 09535 ast_mutex_unlock(&thread->lock); 09536 }
static int handle_error | ( | void | ) | [static] |
Definition at line 3267 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().
03268 { 03269 /* XXX Ideally we should figure out why an error occurred and then abort those 03270 rather than continuing to try. Unfortunately, the published interface does 03271 not seem to work XXX */ 03272 #if 0 03273 struct sockaddr_in *sin; 03274 int res; 03275 struct msghdr m; 03276 struct sock_extended_err e; 03277 m.msg_name = NULL; 03278 m.msg_namelen = 0; 03279 m.msg_iov = NULL; 03280 m.msg_control = &e; 03281 m.msg_controllen = sizeof(e); 03282 m.msg_flags = 0; 03283 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03284 if (res < 0) 03285 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03286 else { 03287 if (m.msg_controllen) { 03288 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03289 if (sin) 03290 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03291 else 03292 ast_log(LOG_WARNING, "No address detected??\n"); 03293 } else { 03294 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03295 } 03296 } 03297 #endif 03298 return 0; 03299 }
static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
struct sockaddr_in * | sin, | |||
int | callno | |||
) | [static] |
Acknowledgment received for OUR registration.
Definition at line 8410 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().
08411 { 08412 struct iax2_registry *reg; 08413 /* Start pessimistic */ 08414 char peer[256] = ""; 08415 char msgstatus[60]; 08416 int refresh = 60; 08417 char ourip[256] = "<Unspecified>"; 08418 struct sockaddr_in oldus; 08419 struct sockaddr_in us; 08420 int oldmsgs; 08421 struct sockaddr_in reg_addr; 08422 08423 memset(&us, 0, sizeof(us)); 08424 if (ies->apparent_addr) { 08425 memmove(&us, ies->apparent_addr, sizeof(us)); 08426 } 08427 if (ies->username) { 08428 ast_copy_string(peer, ies->username, sizeof(peer)); 08429 } 08430 if (ies->refresh) { 08431 refresh = ies->refresh; 08432 } 08433 if (ies->calling_number) { 08434 /* We don't do anything with it really, but maybe we should */ 08435 } 08436 reg = iaxs[callno]->reg; 08437 if (!reg) { 08438 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08439 return -1; 08440 } 08441 memcpy(&oldus, ®->us, sizeof(oldus)); 08442 oldmsgs = reg->messages; 08443 ast_sockaddr_to_sin(®->addr, ®_addr); 08444 if (inaddrcmp(®_addr, sin)) { 08445 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08446 return -1; 08447 } 08448 memcpy(®->us, &us, sizeof(reg->us)); 08449 if (ies->msgcount >= 0) { 08450 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08451 } 08452 /* always refresh the registration at the interval requested by the server 08453 we are registering to 08454 */ 08455 reg->refresh = refresh; 08456 reg->expire = iax2_sched_replace(reg->expire, sched, 08457 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08458 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08459 if (reg->messages > 255) { 08460 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08461 } else if (reg->messages > 1) { 08462 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting", reg->messages); 08463 } else if (reg->messages > 0) { 08464 ast_copy_string(msgstatus, " with 1 new message waiting", sizeof(msgstatus)); 08465 } else { 08466 ast_copy_string(msgstatus, " with no messages waiting", sizeof(msgstatus)); 08467 } 08468 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08469 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08470 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08471 } 08472 reg->regstate = REG_STATE_REGISTERED; 08473 return 0; 08474 }
static int attribute_pure iax2_allow_new | ( | int | frametype, | |
int | subclass, | |||
int | inbound | |||
) | [inline, static] |
Definition at line 2732 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().
02733 { 02734 if (frametype != AST_FRAME_IAX) { 02735 return 0; 02736 } 02737 switch (subclass) { 02738 case IAX_COMMAND_NEW: 02739 case IAX_COMMAND_REGREQ: 02740 case IAX_COMMAND_FWDOWNL: 02741 case IAX_COMMAND_REGREL: 02742 return 1; 02743 case IAX_COMMAND_POKE: 02744 if (!inbound) { 02745 return 1; 02746 } 02747 break; 02748 } 02749 return 0; 02750 }
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 1322 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().
01323 { 01324 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01325 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01326 pvt->owner ? pvt->owner->name : "", 01327 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01328 }
static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5594 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.
05595 { 05596 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05597 ast_debug(1, "Answering IAX2 call\n"); 05598 ast_mutex_lock(&iaxsl[callno]); 05599 if (iaxs[callno]) 05600 iax2_ami_channelupdate(iaxs[callno]); 05601 ast_mutex_unlock(&iaxsl[callno]); 05602 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05603 }
static int iax2_append_register | ( | const char * | hostname, | |
const char * | username, | |||
const char * | secret, | |||
const char * | porta | |||
) | [static] |
Definition at line 8476 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().
08478 { 08479 struct iax2_registry *reg; 08480 08481 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08482 return -1; 08483 08484 reg->addr.ss.ss_family = AF_INET; 08485 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08486 ast_free(reg); 08487 return -1; 08488 } 08489 08490 ast_copy_string(reg->username, username, sizeof(reg->username)); 08491 08492 if (secret) 08493 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08494 08495 reg->expire = -1; 08496 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08497 ast_sockaddr_set_port(®->addr, porta ? atoi(porta) : IAX_DEFAULT_PORTNO); 08498 08499 AST_LIST_LOCK(®istrations); 08500 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08501 AST_LIST_UNLOCK(®istrations); 08502 08503 return 0; 08504 }
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 5439 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().
05440 { 05441 struct ast_channel *cs[3]; 05442 struct ast_channel *who, *other; 05443 int to = -1; 05444 int res = -1; 05445 int transferstarted=0; 05446 struct ast_frame *f; 05447 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05448 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05449 struct timeval waittimer = {0, 0}; 05450 05451 /* We currently do not support native bridging if a timeoutms value has been provided */ 05452 if (timeoutms > 0) { 05453 return AST_BRIDGE_FAILED; 05454 } 05455 05456 timeoutms = -1; 05457 05458 lock_both(callno0, callno1); 05459 if (!iaxs[callno0] || !iaxs[callno1]) { 05460 unlock_both(callno0, callno1); 05461 return AST_BRIDGE_FAILED; 05462 } 05463 /* Put them in native bridge mode */ 05464 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05465 iaxs[callno0]->bridgecallno = callno1; 05466 iaxs[callno1]->bridgecallno = callno0; 05467 } 05468 unlock_both(callno0, callno1); 05469 05470 /* If not, try to bridge until we can execute a transfer, if we can */ 05471 cs[0] = c0; 05472 cs[1] = c1; 05473 for (/* ever */;;) { 05474 /* Check in case we got masqueraded into */ 05475 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05476 ast_verb(3, "Can't masquerade, we're different...\n"); 05477 /* Remove from native mode */ 05478 if (c0->tech == &iax2_tech) { 05479 ast_mutex_lock(&iaxsl[callno0]); 05480 iaxs[callno0]->bridgecallno = 0; 05481 ast_mutex_unlock(&iaxsl[callno0]); 05482 } 05483 if (c1->tech == &iax2_tech) { 05484 ast_mutex_lock(&iaxsl[callno1]); 05485 iaxs[callno1]->bridgecallno = 0; 05486 ast_mutex_unlock(&iaxsl[callno1]); 05487 } 05488 return AST_BRIDGE_FAILED_NOWARN; 05489 } 05490 if (c0->nativeformats != c1->nativeformats) { 05491 char buf0[256]; 05492 char buf1[256]; 05493 ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats); 05494 ast_getformatname_multiple(buf1, sizeof(buf1), c1->nativeformats); 05495 ast_verb(3, "Operating with different codecs [%s] [%s] , can't native bridge...\n", buf0, buf1); 05496 /* Remove from native mode */ 05497 lock_both(callno0, callno1); 05498 if (iaxs[callno0]) 05499 iaxs[callno0]->bridgecallno = 0; 05500 if (iaxs[callno1]) 05501 iaxs[callno1]->bridgecallno = 0; 05502 unlock_both(callno0, callno1); 05503 return AST_BRIDGE_FAILED_NOWARN; 05504 } 05505 /* check if transfered and if we really want native bridging */ 05506 if (!transferstarted && !ast_test_flag64(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag64(iaxs[callno1], IAX_NOTRANSFER)) { 05507 /* Try the transfer */ 05508 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05509 ast_test_flag64(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag64(iaxs[callno1], IAX_TRANSFERMEDIA))) 05510 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05511 transferstarted = 1; 05512 } 05513 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05514 /* Call has been transferred. We're no longer involved */ 05515 struct timeval now = ast_tvnow(); 05516 if (ast_tvzero(waittimer)) { 05517 waittimer = now; 05518 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05519 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05520 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05521 *fo = NULL; 05522 *rc = c0; 05523 res = AST_BRIDGE_COMPLETE; 05524 break; 05525 } 05526 } 05527 to = 1000; 05528 who = ast_waitfor_n(cs, 2, &to); 05529 if (timeoutms > -1) { 05530 timeoutms -= (1000 - to); 05531 if (timeoutms < 0) 05532 timeoutms = 0; 05533 } 05534 if (!who) { 05535 if (!timeoutms) { 05536 res = AST_BRIDGE_RETRY; 05537 break; 05538 } 05539 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05540 res = AST_BRIDGE_FAILED; 05541 break; 05542 } 05543 continue; 05544 } 05545 f = ast_read(who); 05546 if (!f) { 05547 *fo = NULL; 05548 *rc = who; 05549 res = AST_BRIDGE_COMPLETE; 05550 break; 05551 } 05552 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass.integer != AST_CONTROL_SRCUPDATE)) { 05553 *fo = f; 05554 *rc = who; 05555 res = AST_BRIDGE_COMPLETE; 05556 break; 05557 } 05558 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05559 if ((f->frametype == AST_FRAME_VOICE) || 05560 (f->frametype == AST_FRAME_TEXT) || 05561 (f->frametype == AST_FRAME_VIDEO) || 05562 (f->frametype == AST_FRAME_IMAGE) || 05563 (f->frametype == AST_FRAME_DTMF) || 05564 (f->frametype == AST_FRAME_CONTROL)) { 05565 /* monitored dtmf take out of the bridge. 05566 * check if we monitor the specific source. 05567 */ 05568 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05569 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 05570 *rc = who; 05571 *fo = f; 05572 res = AST_BRIDGE_COMPLETE; 05573 /* Remove from native mode */ 05574 break; 05575 } 05576 /* everything else goes to the other side */ 05577 ast_write(other, f); 05578 } 05579 ast_frfree(f); 05580 /* Swap who gets priority */ 05581 cs[2] = cs[0]; 05582 cs[0] = cs[1]; 05583 cs[1] = cs[2]; 05584 } 05585 lock_both(callno0, callno1); 05586 if(iaxs[callno0]) 05587 iaxs[callno0]->bridgecallno = 0; 05588 if(iaxs[callno1]) 05589 iaxs[callno1]->bridgecallno = 0; 05590 unlock_both(callno0, callno1); 05591 return res; 05592 }
static int iax2_call | ( | struct ast_channel * | c, | |
char * | dest, | |||
int | timeout | |||
) | [static] |
Definition at line 4987 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.
04988 { 04989 struct sockaddr_in sin; 04990 char *l=NULL, *n=NULL, *tmpstr; 04991 struct iax_ie_data ied; 04992 char *defaultrdest = "s"; 04993 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04994 struct parsed_dial_string pds; 04995 struct create_addr_info cai; 04996 struct ast_var_t *var; 04997 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 04998 const char* osp_token_ptr; 04999 unsigned int osp_token_length; 05000 unsigned char osp_block_index; 05001 unsigned int osp_block_length; 05002 unsigned char osp_buffer[256]; 05003 05004 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 05005 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 05006 return -1; 05007 } 05008 05009 memset(&cai, 0, sizeof(cai)); 05010 cai.encmethods = iax2_encryption; 05011 05012 memset(&pds, 0, sizeof(pds)); 05013 tmpstr = ast_strdupa(dest); 05014 parse_dial_string(tmpstr, &pds); 05015 05016 if (ast_strlen_zero(pds.peer)) { 05017 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 05018 return -1; 05019 } 05020 if (!pds.exten) { 05021 pds.exten = defaultrdest; 05022 } 05023 if (create_addr(pds.peer, c, &sin, &cai)) { 05024 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 05025 return -1; 05026 } 05027 if (ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) && !cai.encmethods) { 05028 ast_log(LOG_WARNING, "Encryption forced for call, but not enabled\n"); 05029 c->hangupcause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL; 05030 return -1; 05031 } 05032 if (ast_strlen_zero(cai.secret) && ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT)) { 05033 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 05034 return -1; 05035 } 05036 if (!pds.username && !ast_strlen_zero(cai.username)) 05037 pds.username = cai.username; 05038 if (!pds.password && !ast_strlen_zero(cai.secret)) 05039 pds.password = cai.secret; 05040 if (!pds.key && !ast_strlen_zero(cai.outkey)) 05041 pds.key = cai.outkey; 05042 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 05043 pds.context = cai.peercontext; 05044 05045 /* Keep track of the context for outgoing calls too */ 05046 ast_copy_string(c->context, cai.context, sizeof(c->context)); 05047 05048 if (pds.port) 05049 sin.sin_port = htons(atoi(pds.port)); 05050 05051 l = c->connected.id.number.valid ? c->connected.id.number.str : NULL; 05052 n = c->connected.id.name.valid ? c->connected.id.name.str : NULL; 05053 05054 /* Now build request */ 05055 memset(&ied, 0, sizeof(ied)); 05056 05057 /* On new call, first IE MUST be IAX version of caller */ 05058 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 05059 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 05060 if (pds.options && strchr(pds.options, 'a')) { 05061 /* Request auto answer */ 05062 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 05063 } 05064 05065 /* WARNING: this breaks down at 190 bits! */ 05066 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 05067 05068 if (l) { 05069 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 05070 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05071 ast_party_id_presentation(&c->connected.id)); 05072 } else if (n) { 05073 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, 05074 ast_party_id_presentation(&c->connected.id)); 05075 } else { 05076 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 05077 } 05078 05079 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->connected.id.number.plan); 05080 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->dialed.transit_network_select); 05081 05082 if (n) 05083 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 05084 if (ast_test_flag64(iaxs[callno], IAX_SENDANI) 05085 && c->connected.ani.number.valid 05086 && c->connected.ani.number.str) { 05087 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->connected.ani.number.str); 05088 } 05089 05090 if (!ast_strlen_zero(c->language)) 05091 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 05092 if (!ast_strlen_zero(c->dialed.number.str)) { 05093 iax_ie_append_str(&ied, IAX_IE_DNID, c->dialed.number.str); 05094 } 05095 if (c->redirecting.from.number.valid 05096 && !ast_strlen_zero(c->redirecting.from.number.str)) { 05097 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->redirecting.from.number.str); 05098 } 05099 05100 if (pds.context) 05101 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 05102 05103 if (pds.username) 05104 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 05105 05106 if (cai.encmethods) 05107 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 05108 05109 ast_mutex_lock(&iaxsl[callno]); 05110 05111 if (!ast_strlen_zero(c->context)) 05112 ast_string_field_set(iaxs[callno], context, c->context); 05113 05114 if (pds.username) 05115 ast_string_field_set(iaxs[callno], username, pds.username); 05116 05117 iaxs[callno]->encmethods = cai.encmethods; 05118 05119 iaxs[callno]->adsi = cai.adsi; 05120 05121 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 05122 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 05123 05124 if (pds.key) 05125 ast_string_field_set(iaxs[callno], outkey, pds.key); 05126 if (pds.password) 05127 ast_string_field_set(iaxs[callno], secret, pds.password); 05128 05129 iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats); 05130 iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats); 05131 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability); 05132 iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability); 05133 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 05134 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 05135 05136 if (iaxs[callno]->maxtime) { 05137 /* Initialize pingtime and auto-congest time */ 05138 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 05139 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 05140 } else if (autokill) { 05141 iaxs[callno]->pingtime = autokill / 2; 05142 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 05143 } 05144 05145 /* Check if there is an OSP token */ 05146 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 05147 if (!ast_strlen_zero(osp_token_ptr)) { 05148 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 05149 osp_block_index = 0; 05150 while (osp_token_length > 0) { 05151 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 05152 osp_buffer[0] = osp_block_index; 05153 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 05154 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 05155 osp_block_index++; 05156 osp_token_ptr += osp_block_length; 05157 osp_token_length -= osp_block_length; 05158 } 05159 } else 05160 ast_log(LOG_WARNING, "OSP token is too long\n"); 05161 } else if (iaxdebug) 05162 ast_debug(1, "OSP token is undefined\n"); 05163 05164 /* send the command using the appropriate socket for this peer */ 05165 iaxs[callno]->sockfd = cai.sockfd; 05166 05167 /* Add remote vars */ 05168 if (variablestore) { 05169 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 05170 ast_debug(1, "Found an IAX variable store on this channel\n"); 05171 AST_LIST_LOCK(variablelist); 05172 AST_LIST_TRAVERSE(variablelist, var, entries) { 05173 char tmp[256]; 05174 int i; 05175 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 05176 /* Automatically divide the value up into sized chunks */ 05177 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 05178 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 05179 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 05180 } 05181 } 05182 AST_LIST_UNLOCK(variablelist); 05183 } 05184 05185 /* Transmit the string in a "NEW" request */ 05186 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 05187 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 05188 05189 ast_mutex_unlock(&iaxsl[callno]); 05190 ast_setstate(c, AST_STATE_RINGING); 05191 05192 return 0; 05193 }
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 13749 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.
13750 { 13751 int res = 0; 13752 struct iax2_dpcache *dp = NULL; 13753 #if 0 13754 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13755 #endif 13756 if ((priority != 1) && (priority != 2)) 13757 return 0; 13758 13759 AST_LIST_LOCK(&dpcache); 13760 if ((dp = find_cache(chan, data, context, exten, priority))) { 13761 if (dp->flags & CACHE_FLAG_CANEXIST) 13762 res = 1; 13763 } else { 13764 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13765 } 13766 AST_LIST_UNLOCK(&dpcache); 13767 13768 return res; 13769 }
static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4660 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().
04661 { 04662 struct timeval t = ast_tvnow(); 04663 struct ast_tm tm; 04664 unsigned int tmp; 04665 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04666 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04667 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04668 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04669 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04670 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04671 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04672 return tmp; 04673 }
static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3373 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().
03374 { 03375 struct chan_iax2_pvt *pvt = NULL; 03376 struct ast_channel *owner = NULL; 03377 03378 retry: 03379 if ((pvt = iaxs[callno])) { 03380 #if 0 03381 /* iax2_destroy_helper gets called from this function later on. When 03382 * called twice, we get the (previously) familiar FRACK! errors in 03383 * devmode, from the scheduler. An alternative to this approach is to 03384 * reset the scheduler entries to -1 when they're deleted in 03385 * iax2_destroy_helper(). That approach was previously decided to be 03386 * "wrong" because "the memory is going to be deallocated anyway. Why 03387 * should we be resetting those values?" */ 03388 iax2_destroy_helper(pvt); 03389 #endif 03390 } 03391 03392 owner = pvt ? pvt->owner : NULL; 03393 03394 if (owner) { 03395 if (ast_channel_trylock(owner)) { 03396 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03397 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03398 goto retry; 03399 } 03400 } 03401 03402 if (!owner) { 03403 iaxs[callno] = NULL; 03404 } 03405 03406 if (pvt) { 03407 if (!owner) { 03408 pvt->owner = NULL; 03409 } else { 03410 /* If there's an owner, prod it to give up */ 03411 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03412 * because we already hold the owner channel lock. */ 03413 ast_queue_hangup(owner); 03414 } 03415 03416 if (pvt->peercallno) { 03417 remove_by_peercallno(pvt); 03418 } 03419 03420 if (pvt->transfercallno) { 03421 remove_by_transfercallno(pvt); 03422 } 03423 03424 if (!owner) { 03425 ao2_ref(pvt, -1); 03426 pvt = NULL; 03427 } 03428 } 03429 03430 if (owner) { 03431 ast_channel_unlock(owner); 03432 } 03433 03434 if (callno & 0x4000) { 03435 update_max_trunk(); 03436 } 03437 }
static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1770 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().
01771 { 01772 /* Decrement AUTHREQ count if needed */ 01773 if (ast_test_flag64(pvt, IAX_MAXAUTHREQ)) { 01774 struct iax2_user *user; 01775 struct iax2_user tmp_user = { 01776 .name = pvt->username, 01777 }; 01778 01779 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01780 if (user) { 01781 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01782 user_unref(user); 01783 } 01784 01785 ast_clear_flag64(pvt, IAX_MAXAUTHREQ); 01786 } 01787 /* No more pings or lagrq's */ 01788 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]); 01789 pvt->pingid = DONT_RESCHEDULE; 01790 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]); 01791 pvt->lagid = DONT_RESCHEDULE; 01792 ast_sched_thread_del(sched, pvt->autoid); 01793 ast_sched_thread_del(sched, pvt->authid); 01794 ast_sched_thread_del(sched, pvt->initid); 01795 ast_sched_thread_del(sched, pvt->jbid); 01796 ast_sched_thread_del(sched, pvt->keyrotateid); 01797 }
static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 13954 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().
13955 { 13956 struct parsed_dial_string pds; 13957 char *tmp = ast_strdupa(data); 13958 struct iax2_peer *p; 13959 int res = AST_DEVICE_INVALID; 13960 13961 memset(&pds, 0, sizeof(pds)); 13962 parse_dial_string(tmp, &pds); 13963 13964 if (ast_strlen_zero(pds.peer)) { 13965 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 13966 return res; 13967 } 13968 13969 ast_debug(3, "Checking device state for device %s\n", pds.peer); 13970 13971 /* SLD: FIXME: second call to find_peer during registration */ 13972 if (!(p = find_peer(pds.peer, 1))) 13973 return res; 13974 13975 res = AST_DEVICE_UNAVAILABLE; 13976 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 13977 pds.peer, ast_sockaddr_ipv4(&p->addr), p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 13978 13979 if ((ast_sockaddr_ipv4(&p->addr) || p->defaddr.sin_addr.s_addr) && 13980 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 13981 /* Peer is registered, or have default IP address 13982 and a valid registration */ 13983 if (p->historicms == 0 || p->historicms <= p->maxms) 13984 /* let the core figure out whether it is in use or not */ 13985 res = AST_DEVICE_UNKNOWN; 13986 } 13987 13988 peer_unref(p); 13989 13990 return res; 13991 }
static int iax2_digit_begin | ( | struct ast_channel * | c, | |
char | digit | |||
) | [static] |
Definition at line 4263 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04264 { 04265 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04266 }
static int iax2_digit_end | ( | struct ast_channel * | c, | |
char | digit, | |||
unsigned int | duration | |||
) | [static] |
Definition at line 4268 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04269 { 04270 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04271 }
static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11760 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().
11761 { 11762 struct iax_ie_data ied; 11763 if (iaxdebug) 11764 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11765 11766 if (reg->dnsmgr && 11767 ((reg->regstate == REG_STATE_TIMEOUT) || !ast_sockaddr_ipv4(®->addr))) { 11768 /* Maybe the IP has changed, force DNS refresh */ 11769 ast_dnsmgr_refresh(reg->dnsmgr); 11770 } 11771 11772 /* 11773 * if IP has Changed, free allocated call to create a new one with new IP 11774 * call has the pointer to IP and must be updated to the new one 11775 */ 11776 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11777 int callno = reg->callno; 11778 ast_mutex_lock(&iaxsl[callno]); 11779 iax2_destroy(callno); 11780 ast_mutex_unlock(&iaxsl[callno]); 11781 reg->callno = 0; 11782 } 11783 if (!ast_sockaddr_ipv4(®->addr)) { 11784 if (iaxdebug) 11785 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11786 /* Setup the next registration attempt */ 11787 reg->expire = iax2_sched_replace(reg->expire, sched, 11788 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11789 return -1; 11790 } 11791 11792 if (!reg->callno) { 11793 struct sockaddr_in reg_addr; 11794 11795 ast_debug(3, "Allocate call number\n"); 11796 11797 ast_sockaddr_to_sin(®->addr, ®_addr); 11798 11799 reg->callno = find_callno_locked(0, 0, ®_addr, NEW_FORCE, defaultsockfd, 0); 11800 if (reg->callno < 1) { 11801 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11802 return -1; 11803 } else 11804 ast_debug(3, "Registration created on call %d\n", reg->callno); 11805 iaxs[reg->callno]->reg = reg; 11806 ast_mutex_unlock(&iaxsl[reg->callno]); 11807 } 11808 /* Setup the next registration a little early */ 11809 reg->expire = iax2_sched_replace(reg->expire, sched, 11810 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11811 /* Send the request */ 11812 memset(&ied, 0, sizeof(ied)); 11813 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11814 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11815 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11816 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11817 reg->regstate = REG_STATE_REGSENT; 11818 return 0; 11819 }
static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 8257 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
08258 { 08259 #ifdef SCHED_MULTITHREADED 08260 if (schedule_action(__iax2_do_register_s, data)) 08261 #endif 08262 __iax2_do_register_s(data); 08263 return 0; 08264 }
static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
int | callno | |||
) | [static] |
Definition at line 9032 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().
09033 { 09034 struct iax_ie_data ied; 09035 /* Auto-hangup with 30 seconds of inactivity */ 09036 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 09037 sched, 30000, auto_hangup, (void *)(long)callno); 09038 memset(&ied, 0, sizeof(ied)); 09039 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 09040 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 09041 dp->flags |= CACHE_FLAG_TRANSMITTED; 09042 }
static void * iax2_dup_variable_datastore | ( | void * | ) | [static] |
Definition at line 1336 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.
01337 { 01338 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01339 struct ast_var_t *oldvar, *newvar; 01340 01341 newlist = ast_calloc(sizeof(*newlist), 1); 01342 if (!newlist) { 01343 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01344 return NULL; 01345 } 01346 01347 AST_LIST_HEAD_INIT(newlist); 01348 AST_LIST_LOCK(oldlist); 01349 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01350 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01351 if (newvar) 01352 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01353 else 01354 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01355 } 01356 AST_LIST_UNLOCK(oldlist); 01357 return newlist; 01358 }
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 13795 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().
13796 { 13797 char odata[256]; 13798 char req[256]; 13799 char *ncontext; 13800 struct iax2_dpcache *dp = NULL; 13801 struct ast_app *dial = NULL; 13802 #if 0 13803 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); 13804 #endif 13805 if (priority == 2) { 13806 /* Indicate status, can be overridden in dialplan */ 13807 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13808 if (dialstatus) { 13809 dial = pbx_findapp(dialstatus); 13810 if (dial) 13811 pbx_exec(chan, dial, ""); 13812 } 13813 return -1; 13814 } else if (priority != 1) 13815 return -1; 13816 13817 AST_LIST_LOCK(&dpcache); 13818 if ((dp = find_cache(chan, data, context, exten, priority))) { 13819 if (dp->flags & CACHE_FLAG_EXISTS) { 13820 ast_copy_string(odata, data, sizeof(odata)); 13821 ncontext = strchr(odata, '/'); 13822 if (ncontext) { 13823 *ncontext = '\0'; 13824 ncontext++; 13825 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13826 } else { 13827 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13828 } 13829 ast_verb(3, "Executing Dial('%s')\n", req); 13830 } else { 13831 AST_LIST_UNLOCK(&dpcache); 13832 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13833 return -1; 13834 } 13835 } 13836 AST_LIST_UNLOCK(&dpcache); 13837 13838 if ((dial = pbx_findapp("Dial"))) 13839 return pbx_exec(chan, dial, req); 13840 else 13841 ast_log(LOG_WARNING, "No dial application registered\n"); 13842 13843 return -1; 13844 }
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 13726 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.
13727 { 13728 int res = 0; 13729 struct iax2_dpcache *dp = NULL; 13730 #if 0 13731 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13732 #endif 13733 if ((priority != 1) && (priority != 2)) 13734 return 0; 13735 13736 AST_LIST_LOCK(&dpcache); 13737 if ((dp = find_cache(chan, data, context, exten, priority))) { 13738 if (dp->flags & CACHE_FLAG_EXISTS) 13739 res = 1; 13740 } else { 13741 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13742 } 13743 AST_LIST_UNLOCK(&dpcache); 13744 13745 return res; 13746 }
static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
struct ast_channel * | newchan | |||
) | [static] |
Definition at line 4290 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.
04291 { 04292 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04293 ast_mutex_lock(&iaxsl[callno]); 04294 if (iaxs[callno]) 04295 iaxs[callno]->owner = newchan; 04296 else 04297 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04298 ast_mutex_unlock(&iaxsl[callno]); 04299 return 0; 04300 }
static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1799 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().
01800 { 01801 ast_sched_thread_del(sched, fr->retrans); 01802 iax_frame_free(fr); 01803 }
static void iax2_free_variable_datastore | ( | void * | ) | [static] |
Definition at line 1360 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.
01361 { 01362 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01363 struct ast_var_t *oldvar; 01364 01365 AST_LIST_LOCK(oldlist); 01366 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01367 ast_free(oldvar); 01368 } 01369 AST_LIST_UNLOCK(oldlist); 01370 AST_LIST_HEAD_DESTROY(oldlist); 01371 ast_free(oldlist); 01372 }
static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
char * | host, | |||
int | len | |||
) | [static] |
Definition at line 1733 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().
01734 { 01735 struct iax2_peer *peer = NULL; 01736 int res = 0; 01737 struct ao2_iterator i; 01738 01739 i = ao2_iterator_init(peers, 0); 01740 while ((peer = ao2_iterator_next(&i))) { 01741 struct sockaddr_in peer_addr; 01742 01743 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 01744 01745 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01746 (peer_addr.sin_port == sin.sin_port)) { 01747 ast_copy_string(host, peer->name, len); 01748 peer_unref(peer); 01749 res = 1; 01750 break; 01751 } 01752 peer_unref(peer); 01753 } 01754 ao2_iterator_destroy(&i); 01755 01756 if (!peer) { 01757 peer = realtime_peer(NULL, &sin); 01758 if (peer) { 01759 ast_copy_string(host, peer->name, len); 01760 peer_unref(peer); 01761 res = 1; 01762 } 01763 } 01764 01765 return res; 01766 }
static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5669 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().
05670 { 05671 struct iax2_peer *peer; 05672 int res = 0; 05673 struct ao2_iterator i; 05674 05675 i = ao2_iterator_init(peers, 0); 05676 while ((peer = ao2_iterator_next(&i))) { 05677 struct sockaddr_in peer_addr; 05678 05679 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 05680 05681 if ((peer_addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05682 (peer_addr.sin_port == sin.sin_port)) { 05683 res = ast_test_flag64(peer, IAX_TRUNK); 05684 peer_unref(peer); 05685 break; 05686 } 05687 peer_unref(peer); 05688 } 05689 ao2_iterator_destroy(&i); 05690 05691 return res; 05692 }
static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5195 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.
05196 { 05197 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05198 struct iax_ie_data ied; 05199 int alreadygone; 05200 memset(&ied, 0, sizeof(ied)); 05201 ast_mutex_lock(&iaxsl[callno]); 05202 if (callno && iaxs[callno]) { 05203 ast_debug(1, "We're hanging up %s now...\n", c->name); 05204 alreadygone = ast_test_flag64(iaxs[callno], IAX_ALREADYGONE); 05205 /* Send the hangup unless we have had a transmission error or are already gone */ 05206 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 05207 if (!iaxs[callno]->error && !alreadygone) { 05208 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 05209 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 05210 } 05211 if (!iaxs[callno]) { 05212 ast_mutex_unlock(&iaxsl[callno]); 05213 return 0; 05214 } 05215 } 05216 /* Explicitly predestroy it */ 05217 iax2_predestroy(callno); 05218 /* If we were already gone to begin with, destroy us now */ 05219 if (iaxs[callno] && alreadygone) { 05220 ast_debug(1, "Really destroying %s now...\n", c->name); 05221 iax2_destroy(callno); 05222 } else if (iaxs[callno]) { 05223 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 05224 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05225 iax2_destroy(callno); 05226 } 05227 } 05228 } else if (c->tech_pvt) { 05229 /* If this call no longer exists, but the channel still 05230 * references it we need to set the channel's tech_pvt to null 05231 * to avoid ast_channel_free() trying to free it. 05232 */ 05233 c->tech_pvt = NULL; 05234 } 05235 ast_mutex_unlock(&iaxsl[callno]); 05236 ast_verb(3, "Hungup '%s'\n", c->name); 05237 return 0; 05238 }
static int iax2_indicate | ( | struct ast_channel * | c, | |
int | condition, | |||
const void * | data, | |||
size_t | datalen | |||
) | [static] |
Definition at line 5605 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().
05606 { 05607 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05608 struct chan_iax2_pvt *pvt; 05609 int res = 0; 05610 05611 if (iaxdebug) 05612 ast_debug(1, "Indicating condition %d\n", condition); 05613 05614 ast_mutex_lock(&iaxsl[callno]); 05615 pvt = iaxs[callno]; 05616 05617 if (wait_for_peercallno(pvt)) { 05618 res = -1; 05619 goto done; 05620 } 05621 05622 switch (condition) { 05623 case AST_CONTROL_HOLD: 05624 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05625 ast_moh_start(c, data, pvt->mohinterpret); 05626 goto done; 05627 } 05628 break; 05629 case AST_CONTROL_UNHOLD: 05630 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05631 ast_moh_stop(c); 05632 goto done; 05633 } 05634 break; 05635 case AST_CONTROL_CONNECTED_LINE: 05636 if (!ast_test_flag64(pvt, IAX_SENDCONNECTEDLINE)) 05637 goto done; 05638 break; 05639 } 05640 05641 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05642 05643 done: 05644 ast_mutex_unlock(&iaxsl[callno]); 05645 05646 return res; 05647 }
static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5357 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().
05358 { 05359 int res = 0; 05360 struct chan_iax2_pvt *pvt = (void *) vpvt; 05361 struct MD5Context md5; 05362 char key[17] = ""; 05363 struct iax_ie_data ied = { 05364 .pos = 0, 05365 }; 05366 05367 ast_mutex_lock(&iaxsl[pvt->callno]); 05368 pvt->keyrotateid = 05369 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05370 05371 snprintf(key, sizeof(key), "%lX", ast_random()); 05372 05373 MD5Init(&md5); 05374 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05375 MD5Final((unsigned char *) key, &md5); 05376 05377 IAX_DEBUGDIGEST("Sending", key); 05378 05379 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05380 05381 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05382 05383 build_ecx_key((unsigned char *) key, pvt); 05384 05385 ast_mutex_unlock(&iaxsl[pvt->callno]); 05386 05387 return res; 05388 }
static void iax2_lock_owner | ( | int | callno | ) | [static] |
Definition at line 1259 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().
01260 { 01261 for (;;) { 01262 if (!iaxs[callno] || !iaxs[callno]->owner) { 01263 /* There is no owner lock to get. */ 01264 break; 01265 } 01266 if (!ast_channel_trylock(iaxs[callno]->owner)) { 01267 /* We got the lock */ 01268 break; 01269 } 01270 /* Avoid deadlock by pausing and trying again */ 01271 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 01272 } 01273 }
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 13772 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.
13773 { 13774 int res = 0; 13775 struct iax2_dpcache *dp = NULL; 13776 #if 0 13777 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13778 #endif 13779 if ((priority != 1) && (priority != 2)) 13780 return 0; 13781 13782 AST_LIST_LOCK(&dpcache); 13783 if ((dp = find_cache(chan, data, context, exten, priority))) { 13784 if (dp->flags & CACHE_FLAG_MATCHMORE) 13785 res = 1; 13786 } else { 13787 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13788 } 13789 AST_LIST_UNLOCK(&dpcache); 13790 13791 return res; 13792 }
static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11964 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
11965 { 11966 struct iax2_peer *peer = (struct iax2_peer *)data; 11967 peer->pokeexpire = -1; 11968 #ifdef SCHED_MULTITHREADED 11969 if (schedule_action(__iax2_poke_noanswer, data)) 11970 #endif 11971 __iax2_poke_noanswer(data); 11972 peer_unref(peer); 11973 return 0; 11974 }
static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
int | heldcall | |||
) | [static] |
Definition at line 11985 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().
11986 { 11987 int callno; 11988 struct sockaddr_in peer_addr; 11989 11990 if (!peer->maxms || (!ast_sockaddr_ipv4(&peer->addr) && !peer->dnsmgr)) { 11991 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 11992 immediately after clearing things out */ 11993 peer->lastms = 0; 11994 peer->historicms = 0; 11995 peer->pokeexpire = -1; 11996 peer->callno = 0; 11997 return 0; 11998 } 11999 12000 ast_sockaddr_to_sin(&peer->addr, &peer_addr); 12001 12002 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 12003 if ((callno = peer->callno) > 0) { 12004 ast_log(LOG_NOTICE, "Still have a callno...\n"); 12005 ast_mutex_lock(&iaxsl[callno]); 12006 iax2_destroy(callno); 12007 ast_mutex_unlock(&iaxsl[callno]); 12008 } 12009 if (heldcall) 12010 ast_mutex_unlock(&iaxsl[heldcall]); 12011 callno = peer->callno = find_callno(0, 0, &peer_addr, NEW_FORCE, peer->sockfd, 0); 12012 if (heldcall) 12013 ast_mutex_lock(&iaxsl[heldcall]); 12014 if (peer->callno < 1) { 12015 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 12016 return -1; 12017 } 12018 12019 /* Speed up retransmission times for this qualify call */ 12020 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 12021 iaxs[peer->callno]->peerpoke = peer; 12022 12023 if (peer->pokeexpire > -1) { 12024 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 12025 peer->pokeexpire = -1; 12026 peer_unref(peer); 12027 } 12028 } 12029 12030 /* Queue up a new task to handle no reply */ 12031 /* If the host is already unreachable then use the unreachable interval instead */ 12032 if (peer->lastms < 0) 12033 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 12034 else 12035 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 12036 12037 if (peer->pokeexpire == -1) 12038 peer_unref(peer); 12039 12040 /* And send the poke */ 12041 ast_mutex_lock(&iaxsl[callno]); 12042 if (iaxs[callno]) { 12043 struct iax_ie_data ied = { 12044 .buf = { 0 }, 12045 .pos = 0, 12046 }; 12047 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 12048 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 12049 } 12050 ast_mutex_unlock(&iaxsl[callno]); 12051 12052 return 0; 12053 }
static int iax2_poke_peer_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 11976 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
11977 { 11978 struct iax2_peer *peer = obj; 11979 11980 iax2_poke_peer(peer, 0); 11981 11982 return 0; 11983 }
static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 9069 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
09070 { 09071 struct iax2_peer *peer = (struct iax2_peer *)data; 09072 peer->pokeexpire = -1; 09073 #ifdef SCHED_MULTITHREADED 09074 if (schedule_action(__iax2_poke_peer_s, data)) 09075 #endif 09076 __iax2_poke_peer_s(data); 09077 return 0; 09078 }
static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3350 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().
03351 { 03352 struct ast_channel *c = NULL; 03353 struct chan_iax2_pvt *pvt = iaxs[callno]; 03354 03355 if (!pvt) 03356 return -1; 03357 03358 if (!ast_test_flag64(pvt, IAX_ALREADYGONE)) { 03359 iax2_destroy_helper(pvt); 03360 ast_set_flag64(pvt, IAX_ALREADYGONE); 03361 } 03362 03363 if ((c = pvt->owner)) { 03364 c->tech_pvt = NULL; 03365 iax2_queue_hangup(callno); 03366 pvt->owner = NULL; 03367 ast_module_unref(ast_module_info->self); 03368 } 03369 03370 return 0; 03371 }
static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 11615 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().
11616 { 11617 struct iax2_thread *thread = data; 11618 struct timeval wait; 11619 struct timespec ts; 11620 int put_into_idle = 0; 11621 int first_time = 1; 11622 int old_state; 11623 11624 ast_atomic_fetchadd_int(&iaxactivethreadcount, 1); 11625 11626 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state); 11627 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11628 11629 for (;;) { 11630 /* Wait for something to signal us to be awake */ 11631 ast_mutex_lock(&thread->lock); 11632 11633 if (thread->stop) { 11634 ast_mutex_unlock(&thread->lock); 11635 break; 11636 } 11637 11638 /* Flag that we're ready to accept signals */ 11639 if (first_time) { 11640 signal_condition(&thread->init_lock, &thread->init_cond); 11641 first_time = 0; 11642 } 11643 11644 /* Put into idle list if applicable */ 11645 if (put_into_idle) { 11646 insert_idle_thread(thread); 11647 } 11648 11649 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11650 struct iax2_thread *t = NULL; 11651 /* Wait to be signalled or time out */ 11652 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11653 ts.tv_sec = wait.tv_sec; 11654 ts.tv_nsec = wait.tv_usec * 1000; 11655 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11656 /* This thread was never put back into the available dynamic 11657 * thread list, so just go away. */ 11658 if (!put_into_idle || thread->stop) { 11659 ast_mutex_unlock(&thread->lock); 11660 break; 11661 } 11662 AST_LIST_LOCK(&dynamic_list); 11663 /* Account for the case where this thread is acquired *right* after a timeout */ 11664 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11665 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11666 AST_LIST_UNLOCK(&dynamic_list); 11667 if (t) { 11668 /* This dynamic thread timed out waiting for a task and was 11669 * not acquired immediately after the timeout, 11670 * so it's time to go away. */ 11671 ast_mutex_unlock(&thread->lock); 11672 break; 11673 } 11674 /* Someone grabbed our thread *right* after we timed out. 11675 * Wait for them to set us up with something to do and signal 11676 * us to continue. */ 11677 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11678 ts.tv_sec = wait.tv_sec; 11679 ts.tv_nsec = wait.tv_usec * 1000; 11680 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11681 ast_mutex_unlock(&thread->lock); 11682 break; 11683 } 11684 } 11685 } else { 11686 ast_cond_wait(&thread->cond, &thread->lock); 11687 } 11688 11689 /* Go back into our respective list */ 11690 put_into_idle = 1; 11691 11692 ast_mutex_unlock(&thread->lock); 11693 11694 if (thread->stop) { 11695 break; 11696 } 11697 11698 if (thread->iostate == IAX_IOSTATE_IDLE) 11699 continue; 11700 11701 /* See what we need to do */ 11702 switch (thread->iostate) { 11703 case IAX_IOSTATE_READY: 11704 thread->actions++; 11705 thread->iostate = IAX_IOSTATE_PROCESSING; 11706 socket_process(thread); 11707 handle_deferred_full_frames(thread); 11708 break; 11709 case IAX_IOSTATE_SCHEDREADY: 11710 thread->actions++; 11711 thread->iostate = IAX_IOSTATE_PROCESSING; 11712 #ifdef SCHED_MULTITHREADED 11713 thread->schedfunc(thread->scheddata); 11714 #endif 11715 default: 11716 break; 11717 } 11718 time(&thread->checktime); 11719 thread->iostate = IAX_IOSTATE_IDLE; 11720 #ifdef DEBUG_SCHED_MULTITHREAD 11721 thread->curfunc[0]='\0'; 11722 #endif 11723 11724 /* The network thread added us to the active_thread list when we were given 11725 * frames to process, Now that we are done, we must remove ourselves from 11726 * the active list, and return to the idle list */ 11727 AST_LIST_LOCK(&active_list); 11728 AST_LIST_REMOVE(&active_list, thread, list); 11729 AST_LIST_UNLOCK(&active_list); 11730 11731 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11732 handle_deferred_full_frames(thread); 11733 } 11734 11735 /*! 11736 * \note For some reason, idle threads are exiting without being removed 11737 * from an idle list, which is causing memory corruption. Forcibly remove 11738 * it from the list, if it's there. 11739 */ 11740 AST_LIST_LOCK(&idle_list); 11741 AST_LIST_REMOVE(&idle_list, thread, list); 11742 AST_LIST_UNLOCK(&idle_list); 11743 11744 AST_LIST_LOCK(&dynamic_list); 11745 AST_LIST_REMOVE(&dynamic_list, thread, list); 11746 AST_LIST_UNLOCK(&dynamic_list); 11747 11748 if (!thread->stop) { 11749 /* Nobody asked me to stop so nobody is waiting to join me. */ 11750 pthread_detach(pthread_self()); 11751 } 11752 11753 /* I am exiting here on my own volition, I need to clean up my own data structures 11754 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11755 */ 11756 pthread_cleanup_pop(1); 11757 return NULL; 11758 }
static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11604 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().
11605 { 11606 struct iax2_thread *thread = data; 11607 ast_mutex_destroy(&thread->lock); 11608 ast_cond_destroy(&thread->cond); 11609 ast_mutex_destroy(&thread->init_lock); 11610 ast_cond_destroy(&thread->init_cond); 11611 ast_free(thread); 11612 ast_atomic_dec_and_test(&iaxactivethreadcount); 11613 }
static int iax2_provision | ( | struct sockaddr_in * | end, | |
int | sockfd, | |||
const char * | dest, | |||
const char * | template, | |||
int | force | |||
) | [static] |
Definition at line 11821 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().
11822 { 11823 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11824 is found for template */ 11825 struct iax_ie_data provdata; 11826 struct iax_ie_data ied; 11827 unsigned int sig; 11828 struct sockaddr_in sin; 11829 int callno; 11830 struct create_addr_info cai; 11831 11832 memset(&cai, 0, sizeof(cai)); 11833 11834 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11835 11836 if (iax_provision_build(&provdata, &sig, template, force)) { 11837 ast_debug(1, "No provisioning found for template '%s'\n", template); 11838 return 0; 11839 } 11840 11841 if (end) { 11842 memcpy(&sin, end, sizeof(sin)); 11843 cai.sockfd = sockfd; 11844 } else if (create_addr(dest, NULL, &sin, &cai)) 11845 return -1; 11846 11847 /* Build the rest of the message */ 11848 memset(&ied, 0, sizeof(ied)); 11849 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11850 11851 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11852 if (!callno) 11853 return -1; 11854 11855 if (iaxs[callno]) { 11856 /* Schedule autodestruct in case they don't ever give us anything back */ 11857 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11858 sched, 15000, auto_hangup, (void *)(long)callno); 11859 ast_set_flag64(iaxs[callno], IAX_PROVISION); 11860 /* Got a call number now, so go ahead and send the provisioning information */ 11861 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11862 } 11863 ast_mutex_unlock(&iaxsl[callno]); 11864 11865 return 1; 11866 }
static int iax2_queryoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int * | datalen | |||
) | [static] |
Definition at line 5334 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.
05335 { 05336 switch (option) { 05337 case AST_OPTION_SECURE_SIGNALING: 05338 case AST_OPTION_SECURE_MEDIA: 05339 { 05340 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05341 ast_mutex_lock(&iaxsl[callno]); 05342 *((int *) data) = ast_test_flag64(iaxs[callno], IAX_FORCE_ENCRYPT) ? 1 : 0; 05343 ast_mutex_unlock(&iaxsl[callno]); 05344 return 0; 05345 } 05346 default: 05347 return -1; 05348 } 05349 }
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 2983 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().
02985 { 02986 iax2_lock_owner(callno); 02987 if (iaxs[callno] && iaxs[callno]->owner) { 02988 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 02989 ast_channel_unlock(iaxs[callno]->owner); 02990 } 02991 return 0; 02992 }
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 2937 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().
02938 { 02939 iax2_lock_owner(callno); 02940 if (iaxs[callno] && iaxs[callno]->owner) { 02941 ast_queue_frame(iaxs[callno]->owner, f); 02942 ast_channel_unlock(iaxs[callno]->owner); 02943 } 02944 return 0; 02945 }
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 2960 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().
02961 { 02962 iax2_lock_owner(callno); 02963 if (iaxs[callno] && iaxs[callno]->owner) { 02964 ast_queue_hangup(iaxs[callno]->owner); 02965 ast_channel_unlock(iaxs[callno]->owner); 02966 } 02967 return 0; 02968 }
static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5351 of file chan_iax2.c.
References ast_debug, and ast_null_frame.
05352 { 05353 ast_debug(1, "I should never be called!\n"); 05354 return &ast_null_frame; 05355 }
static int iax2_register | ( | const char * | value, | |
int | lineno | |||
) | [static] |
Definition at line 8506 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().
08507 { 08508 char copy[256]; 08509 char *username, *hostname, *secret; 08510 char *porta; 08511 char *stringp=NULL; 08512 08513 if (!value) 08514 return -1; 08515 08516 ast_copy_string(copy, value, sizeof(copy)); 08517 stringp = copy; 08518 username = strsep(&stringp, "@"); 08519 hostname = strsep(&stringp, "@"); 08520 08521 if (!hostname) { 08522 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08523 return -1; 08524 } 08525 08526 stringp = username; 08527 username = strsep(&stringp, ":"); 08528 secret = strsep(&stringp, ":"); 08529 stringp = hostname; 08530 hostname = strsep(&stringp, ":"); 08531 porta = strsep(&stringp, ":"); 08532 08533 if (porta && !atoi(porta)) { 08534 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08535 return -1; 08536 } 08537 08538 return iax2_append_register(hostname, username, secret, porta); 08539 }
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 12065 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.
12066 { 12067 int callno; 12068 int res; 12069 format_t fmt, native; 12070 struct sockaddr_in sin; 12071 struct ast_channel *c; 12072 struct parsed_dial_string pds; 12073 struct create_addr_info cai; 12074 char *tmpstr; 12075 12076 memset(&pds, 0, sizeof(pds)); 12077 tmpstr = ast_strdupa(data); 12078 parse_dial_string(tmpstr, &pds); 12079 12080 if (ast_strlen_zero(pds.peer)) { 12081 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 12082 return NULL; 12083 } 12084 12085 memset(&cai, 0, sizeof(cai)); 12086 cai.capability = iax2_capability; 12087 12088 ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12089 12090 /* Populate our address from the given */ 12091 if (create_addr(pds.peer, NULL, &sin, &cai)) { 12092 *cause = AST_CAUSE_UNREGISTERED; 12093 return NULL; 12094 } 12095 12096 if (pds.port) 12097 sin.sin_port = htons(atoi(pds.port)); 12098 12099 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12100 if (callno < 1) { 12101 ast_log(LOG_WARNING, "Unable to create call\n"); 12102 *cause = AST_CAUSE_CONGESTION; 12103 return NULL; 12104 } 12105 12106 /* If this is a trunk, update it now */ 12107 ast_copy_flags64(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12108 if (ast_test_flag64(&cai, IAX_TRUNK)) { 12109 int new_callno; 12110 if ((new_callno = make_trunk(callno, 1)) != -1) 12111 callno = new_callno; 12112 } 12113 iaxs[callno]->maxtime = cai.maxtime; 12114 if (cai.found) 12115 ast_string_field_set(iaxs[callno], host, pds.peer); 12116 12117 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? requestor->linkedid : NULL); 12118 12119 ast_mutex_unlock(&iaxsl[callno]); 12120 12121 if (c) { 12122 /* Choose a format we can live with */ 12123 if (c->nativeformats & format) 12124 c->nativeformats &= format; 12125 else { 12126 native = c->nativeformats; 12127 fmt = format; 12128 res = ast_translator_best_choice(&fmt, &native); 12129 if (res < 0) { 12130 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 12131 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 12132 ast_hangup(c); 12133 return NULL; 12134 } 12135 c->nativeformats = native; 12136 } 12137 c->readformat = ast_best_codec(c->nativeformats); 12138 c->writeformat = c->readformat; 12139 } 12140 12141 return c; 12142 }
static int iax2_sched_add | ( | struct ast_sched_thread * | st, | |
int | when, | |||
ast_sched_cb | callback, | |||
const void * | data | |||
) | [static] |
Definition at line 1496 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().
01498 { 01499 return ast_sched_thread_add(st, when, callback, data); 01500 }
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 1488 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().
01490 { 01491 ast_sched_thread_del(st, id); 01492 01493 return ast_sched_thread_add(st, when, callback, data); 01494 }
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 6333 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().
06334 { 06335 /* Queue a packet for delivery on a given private structure. Use "ts" for 06336 timestamp, or calculate if ts is 0. Send immediately without retransmission 06337 or delayed, with retransmission */ 06338 struct ast_iax2_full_hdr *fh; 06339 struct ast_iax2_mini_hdr *mh; 06340 struct ast_iax2_video_hdr *vh; 06341 struct { 06342 struct iax_frame fr2; 06343 unsigned char buffer[4096]; 06344 } frb; 06345 struct iax_frame *fr; 06346 int res; 06347 int sendmini=0; 06348 unsigned int lastsent; 06349 unsigned int fts; 06350 06351 frb.fr2.afdatalen = sizeof(frb.buffer); 06352 06353 if (!pvt) { 06354 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06355 return -1; 06356 } 06357 06358 lastsent = pvt->lastsent; 06359 06360 /* Calculate actual timestamp */ 06361 fts = calc_timestamp(pvt, ts, f); 06362 06363 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06364 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06365 * increment the "predicted timestamps" for voice, if we're predicting */ 06366 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06367 return 0; 06368 #if 0 06369 ast_log(LOG_NOTICE, 06370 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06371 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06372 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06373 pvt->keyrotateid != -1 ? "" : "no " 06374 ); 06375 #endif 06376 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06377 iax2_key_rotate(pvt); 06378 } 06379 06380 if ((ast_test_flag64(pvt, IAX_TRUNK) || 06381 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06382 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06383 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06384 (f->frametype == AST_FRAME_VOICE) 06385 /* is a voice frame */ && 06386 (f->subclass.codec == pvt->svoiceformat) 06387 /* is the same type */ ) { 06388 /* Force immediate rather than delayed transmission */ 06389 now = 1; 06390 /* Mark that mini-style frame is appropriate */ 06391 sendmini = 1; 06392 } 06393 if ( f->frametype == AST_FRAME_VIDEO ) { 06394 /* 06395 * If the lower 15 bits of the timestamp roll over, or if 06396 * the video format changed then send a full frame. 06397 * Otherwise send a mini video frame 06398 */ 06399 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06400 ((f->subclass.codec & ~0x1LL) == pvt->svideoformat) 06401 ) { 06402 now = 1; 06403 sendmini = 1; 06404 } else { 06405 now = 0; 06406 sendmini = 0; 06407 } 06408 pvt->lastvsent = fts; 06409 } 06410 if (f->frametype == AST_FRAME_IAX) { 06411 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06412 pvt->last_iax_message = f->subclass.integer | MARK_IAX_SUBCLASS_TX; 06413 if (!pvt->first_iax_message) { 06414 pvt->first_iax_message = pvt->last_iax_message; 06415 } 06416 } 06417 /* Allocate an iax_frame */ 06418 if (now) { 06419 fr = &frb.fr2; 06420 } else 06421 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)); 06422 if (!fr) { 06423 ast_log(LOG_WARNING, "Out of memory\n"); 06424 return -1; 06425 } 06426 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06427 iax_frame_wrap(fr, f); 06428 06429 fr->ts = fts; 06430 fr->callno = pvt->callno; 06431 fr->transfer = transfer; 06432 fr->final = final; 06433 fr->encmethods = 0; 06434 if (!sendmini) { 06435 /* We need a full frame */ 06436 if (seqno > -1) 06437 fr->oseqno = seqno; 06438 else 06439 fr->oseqno = pvt->oseqno++; 06440 fr->iseqno = pvt->iseqno; 06441 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06442 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06443 fh->ts = htonl(fr->ts); 06444 fh->oseqno = fr->oseqno; 06445 if (transfer) { 06446 fh->iseqno = 0; 06447 } else 06448 fh->iseqno = fr->iseqno; 06449 /* Keep track of the last thing we've acknowledged */ 06450 if (!transfer) 06451 pvt->aseqno = fr->iseqno; 06452 fh->type = fr->af.frametype & 0xFF; 06453 06454 if (fr->af.frametype == AST_FRAME_VIDEO) { 06455 fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6); 06456 } else if (fr->af.frametype == AST_FRAME_VOICE) { 06457 fh->csub = compress_subclass(fr->af.subclass.codec); 06458 } else { 06459 fh->csub = compress_subclass(fr->af.subclass.integer); 06460 } 06461 06462 if (transfer) { 06463 fr->dcallno = pvt->transfercallno; 06464 } else 06465 fr->dcallno = pvt->peercallno; 06466 fh->dcallno = htons(fr->dcallno); 06467 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06468 fr->data = fh; 06469 fr->retries = 0; 06470 /* Retry after 2x the ping time has passed */ 06471 fr->retrytime = pvt->pingtime * 2; 06472 if (fr->retrytime < MIN_RETRY_TIME) 06473 fr->retrytime = MIN_RETRY_TIME; 06474 if (fr->retrytime > MAX_RETRY_TIME) 06475 fr->retrytime = MAX_RETRY_TIME; 06476 /* Acks' don't get retried */ 06477 if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK)) 06478 fr->retries = -1; 06479 else if (f->frametype == AST_FRAME_VOICE) 06480 pvt->svoiceformat = f->subclass.codec; 06481 else if (f->frametype == AST_FRAME_VIDEO) 06482 pvt->svideoformat = f->subclass.codec & ~0x1LL; 06483 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06484 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06485 if (fr->transfer) 06486 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06487 else 06488 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06489 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06490 fr->encmethods = pvt->encmethods; 06491 fr->ecx = pvt->ecx; 06492 fr->mydcx = pvt->mydcx; 06493 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06494 } else 06495 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06496 } 06497 06498 if (now) { 06499 res = send_packet(fr); 06500 } else 06501 res = iax2_transmit(fr); 06502 } else { 06503 if (ast_test_flag64(pvt, IAX_TRUNK)) { 06504 iax2_trunk_queue(pvt, fr); 06505 res = 0; 06506 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06507 /* Video frame have no sequence number */ 06508 fr->oseqno = -1; 06509 fr->iseqno = -1; 06510 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06511 vh->zeros = 0; 06512 vh->callno = htons(0x8000 | fr->callno); 06513 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0)); 06514 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06515 fr->data = vh; 06516 fr->retries = -1; 06517 res = send_packet(fr); 06518 } else { 06519 /* Mini-frames have no sequence number */ 06520 fr->oseqno = -1; 06521 fr->iseqno = -1; 06522 /* Mini frame will do */ 06523 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06524 mh->callno = htons(fr->callno); 06525 mh->ts = htons(fr->ts & 0xFFFF); 06526 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06527 fr->data = mh; 06528 fr->retries = -1; 06529 if (pvt->transferring == TRANSFER_MEDIAPASS) 06530 fr->transfer = 1; 06531 if (ast_test_flag64(pvt, IAX_ENCRYPTED)) { 06532 if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) { 06533 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06534 } else 06535 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06536 } 06537 res = send_packet(fr); 06538 } 06539 } 06540 return res; 06541 }
static int iax2_sendhtml | ( | struct ast_channel * | c, | |
int | subclass, | |||
const char * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 4285 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04286 { 04287 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04288 }
static int iax2_sendimage | ( | struct ast_channel * | c, | |
struct ast_frame * | img | |||
) | [static] |
Definition at line 4280 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.
04281 { 04282 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass.integer, 0, img->data.ptr, img->datalen, -1); 04283 }
static int iax2_sendtext | ( | struct ast_channel * | c, | |
const char * | text | |||
) | [static] |
Definition at line 4273 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04274 { 04275 04276 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04277 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04278 }
static int iax2_setoption | ( | struct ast_channel * | c, | |
int | option, | |||
void * | data, | |||
int | datalen | |||
) | [static] |
Definition at line 5262 of file chan_iax2.c.
References ast_clear_flag64, AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock, ast_mutex_unlock, AST_OPTION_AUDIO_MODE, AST_OPTION_DIGIT_DETECT, AST_OPTION_FAX_DETECT, AST_OPTION_FLAG_REQUEST, AST_OPTION_OPRMODE, AST_OPTION_RELAXDTMF, AST_OPTION_RXGAIN, AST_OPTION_SECURE_MEDIA, AST_OPTION_SECURE_SIGNALING, AST_OPTION_TDD, AST_OPTION_TONE_VERIFY, AST_OPTION_TXGAIN, ast_set_flag64, errno, IAX_FORCE_ENCRYPT, iaxs, iaxsl, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
05263 { 05264 struct ast_option_header *h; 05265 int res; 05266 05267 switch (option) { 05268 case AST_OPTION_TXGAIN: 05269 case AST_OPTION_RXGAIN: 05270 /* these two cannot be sent, because they require a result */ 05271 errno = ENOSYS; 05272 return -1; 05273 case AST_OPTION_OPRMODE: 05274 errno = EINVAL; 05275 return -1; 05276 case AST_OPTION_SECURE_SIGNALING: 05277 case AST_OPTION_SECURE_MEDIA: 05278 { 05279 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05280 ast_mutex_lock(&iaxsl[callno]); 05281 if ((*(int *) data)) { 05282 ast_set_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05283 } else { 05284 ast_clear_flag64(iaxs[callno], IAX_FORCE_ENCRYPT); 05285 } 05286 ast_mutex_unlock(&iaxsl[callno]); 05287 return 0; 05288 } 05289 /* These options are sent to the other side across the network where 05290 * they will be passed to whatever channel is bridged there. Don't 05291 * do anything silly like pass an option that transmits pointers to 05292 * memory on this machine to a remote machine to use */ 05293 case AST_OPTION_TONE_VERIFY: 05294 case AST_OPTION_TDD: 05295 case AST_OPTION_RELAXDTMF: 05296 case AST_OPTION_AUDIO_MODE: 05297 case AST_OPTION_DIGIT_DETECT: 05298 case AST_OPTION_FAX_DETECT: 05299 { 05300 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05301 struct chan_iax2_pvt *pvt; 05302 05303 ast_mutex_lock(&iaxsl[callno]); 05304 pvt = iaxs[callno]; 05305 05306 if (wait_for_peercallno(pvt)) { 05307 ast_mutex_unlock(&iaxsl[callno]); 05308 return -1; 05309 } 05310 05311 ast_mutex_unlock(&iaxsl[callno]); 05312 05313 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05314 return -1; 05315 } 05316 05317 h->flag = AST_OPTION_FLAG_REQUEST; 05318 h->option = htons(option); 05319 memcpy(h->data, data, datalen); 05320 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05321 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05322 datalen + sizeof(*h), -1); 05323 ast_free(h); 05324 return res; 05325 } 05326 default: 05327 return -1; 05328 } 05329 05330 /* Just in case someone does a break instead of a return */ 05331 return -1; 05332 }
static int iax2_start_transfer | ( | unsigned short | callno0, | |
unsigned short | callno1, | |||
int | mediaonly | |||
) | [static] |
Definition at line 5390 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.
05391 { 05392 int res; 05393 struct iax_ie_data ied0; 05394 struct iax_ie_data ied1; 05395 unsigned int transferid = (unsigned int)ast_random(); 05396 05397 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05398 ast_debug(1, "transfers are not supported for encrypted calls at this time"); 05399 ast_set_flag64(iaxs[callno0], IAX_NOTRANSFER); 05400 ast_set_flag64(iaxs[callno1], IAX_NOTRANSFER); 05401 return 0; 05402 } 05403 05404 memset(&ied0, 0, sizeof(ied0)); 05405 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05406 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05407 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05408 05409 memset(&ied1, 0, sizeof(ied1)); 05410 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05411 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05412 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05413 05414 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05415 if (res) 05416 return -1; 05417 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05418 if (res) 05419 return -1; 05420 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05421 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05422 return 0; 05423 }
static int iax2_transfer | ( | struct ast_channel * | c, | |
const char * | dest | |||
) | [static] |
Definition at line 5649 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.
05650 { 05651 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05652 struct iax_ie_data ied = { "", }; 05653 char tmp[256], *context; 05654 enum ast_control_transfer message = AST_TRANSFER_SUCCESS; 05655 ast_copy_string(tmp, dest, sizeof(tmp)); 05656 context = strchr(tmp, '@'); 05657 if (context) { 05658 *context = '\0'; 05659 context++; 05660 } 05661 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05662 if (context) 05663 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05664 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05665 ast_queue_control_data(c, AST_CONTROL_TRANSFER, &message, sizeof(message)); 05666 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05667 }
static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4256 of file chan_iax2.c.
References ast_taskprocessor_push(), iax_frame::sentyet, and transmit_frame().
Referenced by iax2_send().
04257 { 04258 fr->sentyet = 0; 04259 04260 return ast_taskprocessor_push(transmit_processor, transmit_frame, fr); 04261 }
static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
struct timeval * | now | |||
) | [inline, static] |
Definition at line 9123 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
09124 { 09125 /* Drop when trunk is about 5 seconds idle */ 09126 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 09127 return 1; 09128 return 0; 09129 }
static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_frame * | fr | |||
) | [static] |
Definition at line 6071 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().
06072 { 06073 struct ast_frame *f; 06074 struct iax2_trunk_peer *tpeer; 06075 void *tmp, *ptr; 06076 struct timeval now; 06077 struct ast_iax2_meta_trunk_entry *met; 06078 struct ast_iax2_meta_trunk_mini *mtm; 06079 06080 f = &fr->af; 06081 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 06082 if (tpeer) { 06083 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 06084 /* Need to reallocate space */ 06085 if (tpeer->trunkdataalloc < trunkmaxsize) { 06086 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 06087 ast_mutex_unlock(&tpeer->lock); 06088 return -1; 06089 } 06090 06091 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 06092 tpeer->trunkdata = tmp; 06093 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); 06094 } else { 06095 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)); 06096 ast_mutex_unlock(&tpeer->lock); 06097 return -1; 06098 } 06099 } 06100 06101 /* Append to meta frame */ 06102 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 06103 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) { 06104 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 06105 mtm->len = htons(f->datalen); 06106 mtm->mini.callno = htons(pvt->callno); 06107 mtm->mini.ts = htons(0xffff & fr->ts); 06108 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 06109 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 06110 } else { 06111 met = (struct ast_iax2_meta_trunk_entry *)ptr; 06112 /* Store call number and length in meta header */ 06113 met->callno = htons(pvt->callno); 06114 met->len = htons(f->datalen); 06115 /* Advance pointers/decrease length past trunk entry header */ 06116 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 06117 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 06118 } 06119 /* Copy actual trunk data */ 06120 memcpy(ptr, f->data.ptr, f->datalen); 06121 tpeer->trunkdatalen += f->datalen; 06122 06123 tpeer->calls++; 06124 06125 /* track the largest mtu we actually have sent */ 06126 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 06127 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 06128 06129 /* if we have enough for a full MTU, ship it now without waiting */ 06130 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 06131 now = ast_tvnow(); 06132 send_trunk(tpeer, &now); 06133 trunk_untimed ++; 06134 } 06135 06136 ast_mutex_unlock(&tpeer->lock); 06137 } 06138 return 0; 06139 }
static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 9044 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().
09045 { 09046 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 09047 }
static int iax2_write | ( | struct ast_channel * | c, | |
struct ast_frame * | f | |||
) | [static] |
Definition at line 7413 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.
07414 { 07415 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07416 int res = -1; 07417 ast_mutex_lock(&iaxsl[callno]); 07418 if (iaxs[callno]) { 07419 /* If there's an outstanding error, return failure now */ 07420 if (!iaxs[callno]->error) { 07421 if (ast_test_flag64(iaxs[callno], IAX_ALREADYGONE)) 07422 res = 0; 07423 /* Don't waste bandwidth sending null frames */ 07424 else if (f->frametype == AST_FRAME_NULL) 07425 res = 0; 07426 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag64(iaxs[callno], IAX_QUELCH)) 07427 res = 0; 07428 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07429 res = 0; 07430 else 07431 /* Simple, just queue for transmission */ 07432 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07433 } else { 07434 ast_debug(1, "Write error: %s\n", strerror(errno)); 07435 } 07436 } 07437 /* If it's already gone, just return */ 07438 ast_mutex_unlock(&iaxsl[callno]); 07439 return res; 07440 }
static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 3142 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().
03143 { 03144 int res = 0; 03145 struct iax_firmware *cur = NULL; 03146 03147 if (ast_strlen_zero(dev)) 03148 return 0; 03149 03150 AST_LIST_LOCK(&firmwares); 03151 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03152 if (!strcmp(dev, (char *)cur->fwh->devname)) { 03153 res = ntohs(cur->fwh->version); 03154 break; 03155 } 03156 } 03157 AST_LIST_UNLOCK(&firmwares); 03158 03159 return res; 03160 }
static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 1116 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
01117 { 01118 if (iaxdebug) 01119 ast_verbose("%s", data); 01120 }
static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 1122 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
01123 { 01124 ast_log(LOG_WARNING, "%s", data); 01125 }
static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
const unsigned char * | dev, | |||
unsigned int | desc | |||
) | [static] |
Definition at line 3162 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().
03163 { 03164 int res = -1; 03165 unsigned int bs = desc & 0xff; 03166 unsigned int start = (desc >> 8) & 0xffffff; 03167 unsigned int bytes; 03168 struct iax_firmware *cur; 03169 03170 if (ast_strlen_zero((char *)dev) || !bs) 03171 return -1; 03172 03173 start *= bs; 03174 03175 AST_LIST_LOCK(&firmwares); 03176 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03177 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 03178 continue; 03179 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 03180 if (start < ntohl(cur->fwh->datalen)) { 03181 bytes = ntohl(cur->fwh->datalen) - start; 03182 if (bytes > bs) 03183 bytes = bs; 03184 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 03185 } else { 03186 bytes = 0; 03187 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 03188 } 03189 if (bytes == bs) 03190 res = 0; 03191 else 03192 res = 1; 03193 break; 03194 } 03195 AST_LIST_UNLOCK(&firmwares); 03196 03197 return res; 03198 }
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 1099 of file chan_iax2.c.
References debugaddr, f, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), and socket_process().
01100 { 01101 if (iaxdebug || 01102 (sin && debugaddr.sin_addr.s_addr && 01103 (!ntohs(debugaddr.sin_port) || 01104 debugaddr.sin_port == sin->sin_port) && 01105 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 01106 if (iaxdebug) { 01107 iax_showframe(f, fhi, rx, sin, datalen); 01108 } else { 01109 iaxdebug = 1; 01110 iax_showframe(f, fhi, rx, sin, datalen); 01111 iaxdebug = 0; 01112 } 01113 } 01114 }
static int iax_park | ( | struct ast_channel * | chan1, | |
struct ast_channel * | chan2, | |||
const char * | park_exten, | |||
const char * | park_context | |||
) | [static] |
DO NOT hold any locks while calling iax_park
Definition at line 9294 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_pthread_create_detached_background, AST_STATE_DOWN, ast_strdup, ast_string_field_set, ast_channel::context, ast_channel::exten, iax_park_thread(), ast_channel::linkedid, ast_channel::name, ast_channel::parkinglot, parkinglot, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
09295 { 09296 struct iax_dual *d; 09297 struct ast_channel *chan1m, *chan2m;/* Chan2m: The transferer, chan1m: The transferee */ 09298 pthread_t th; 09299 09300 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->linkedid, chan1->amaflags, "Parking/%s", chan1->name); 09301 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->linkedid, chan2->amaflags, "IAXPeer/%s", chan2->name); 09302 d = ast_calloc(1, sizeof(*d)); 09303 if (!chan1m || !chan2m || !d) { 09304 if (chan1m) { 09305 ast_hangup(chan1m); 09306 } 09307 if (chan2m) { 09308 ast_hangup(chan2m); 09309 } 09310 ast_free(d); 09311 return -1; 09312 } 09313 d->park_exten = ast_strdup(park_exten); 09314 d->park_context = ast_strdup(park_context); 09315 if (!d->park_exten || !d->park_context) { 09316 ast_hangup(chan1m); 09317 ast_hangup(chan2m); 09318 ast_free(d->park_exten); 09319 ast_free(d->park_context); 09320 ast_free(d); 09321 return -1; 09322 } 09323 09324 /* Make formats okay */ 09325 chan1m->readformat = chan1->readformat; 09326 chan1m->writeformat = chan1->writeformat; 09327 09328 /* Prepare for taking over the channel */ 09329 if (ast_channel_masquerade(chan1m, chan1)) { 09330 ast_hangup(chan1m); 09331 ast_hangup(chan2m); 09332 ast_free(d->park_exten); 09333 ast_free(d->park_context); 09334 ast_free(d); 09335 return -1; 09336 } 09337 09338 /* Setup the extensions and such */ 09339 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 09340 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 09341 chan1m->priority = chan1->priority; 09342 09343 ast_do_masquerade(chan1m); 09344 09345 /* We make a clone of the peer channel too, so we can play 09346 back the announcement */ 09347 09348 /* Make formats okay */ 09349 chan2m->readformat = chan2->readformat; 09350 chan2m->writeformat = chan2->writeformat; 09351 ast_string_field_set(chan2m, parkinglot, chan2->parkinglot); 09352 09353 /* Prepare for taking over the channel */ 09354 if (ast_channel_masquerade(chan2m, chan2)) { 09355 ast_hangup(chan1m); 09356 ast_hangup(chan2m); 09357 ast_free(d->park_exten); 09358 ast_free(d->park_context); 09359 ast_free(d); 09360 return -1; 09361 } 09362 09363 /* Setup the extensions and such */ 09364 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 09365 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 09366 chan2m->priority = chan2->priority; 09367 09368 ast_do_masquerade(chan2m); 09369 09370 d->chan1 = chan1m; /* Transferee */ 09371 d->chan2 = chan2m; /* Transferer */ 09372 if (ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d) < 0) { 09373 /* Could not start thread */ 09374 ast_hangup(chan1m); 09375 ast_hangup(chan2m); 09376 ast_free(d->park_exten); 09377 ast_free(d->park_context); 09378 ast_free(d); 09379 return -1; 09380 } 09381 return 0; 09382 }
static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 9267 of file chan_iax2.c.
References ast_debug, ast_free, ast_hangup(), ast_log(), ast_park_call_exten(), iax_dual::chan1, iax_dual::chan2, ext, LOG_NOTICE, ast_channel::name, iax_dual::park_context, and iax_dual::park_exten.
Referenced by iax_park().
09268 { 09269 struct iax_dual *d; 09270 int res; 09271 int ext = 0; 09272 09273 d = stuff; 09274 09275 ast_debug(4, "IAX Park: Transferer channel %s, Transferee %s\n", 09276 d->chan2->name, d->chan1->name); 09277 09278 res = ast_park_call_exten(d->chan1, d->chan2, d->park_exten, d->park_context, 0, &ext); 09279 if (res) { 09280 /* Parking failed. */ 09281 ast_hangup(d->chan1); 09282 } else { 09283 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 09284 } 09285 ast_hangup(d->chan2); 09286 09287 ast_free(d->park_exten); 09288 ast_free(d->park_context); 09289 ast_free(d); 09290 return NULL; 09291 }
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 1378 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().
01379 { 01380 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01381 AST_LIST_LOCK(&dynamic_list); 01382 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01383 AST_LIST_UNLOCK(&dynamic_list); 01384 } else { 01385 AST_LIST_LOCK(&idle_list); 01386 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01387 AST_LIST_UNLOCK(&idle_list); 01388 } 01389 01390 return; 01391 }
static void jb_debug_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1151 of file chan_iax2.c.
References args, and ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01152 { 01153 va_list args; 01154 char buf[1024]; 01155 01156 va_start(args, fmt); 01157 vsnprintf(buf, sizeof(buf), fmt, args); 01158 va_end(args); 01159 01160 ast_verbose("%s", buf); 01161 }
static void jb_error_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1127 of file chan_iax2.c.
References args, ast_log(), and LOG_ERROR.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01128 { 01129 va_list args; 01130 char buf[1024]; 01131 01132 va_start(args, fmt); 01133 vsnprintf(buf, sizeof(buf), fmt, args); 01134 va_end(args); 01135 01136 ast_log(LOG_ERROR, "%s", buf); 01137 }
static void jb_warning_output | ( | const char * | fmt, | |
... | ||||
) | [static] |
Definition at line 1139 of file chan_iax2.c.
References args, ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01140 { 01141 va_list args; 01142 char buf[1024]; 01143 01144 va_start(args, fmt); 01145 vsnprintf(buf, sizeof(buf), fmt, args); 01146 va_end(args); 01147 01148 ast_log(LOG_WARNING, "%s", buf); 01149 }
static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 14652 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.
14653 { 14654 static const char config[] = "iax.conf"; 14655 int x = 0; 14656 struct iax2_registry *reg = NULL; 14657 14658 if (load_objects()) { 14659 return AST_MODULE_LOAD_FAILURE; 14660 } 14661 14662 memset(iaxs, 0, sizeof(iaxs)); 14663 14664 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 14665 ast_mutex_init(&iaxsl[x]); 14666 } 14667 14668 if (!(sched = ast_sched_thread_create())) { 14669 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 14670 return AST_MODULE_LOAD_FAILURE; 14671 } 14672 14673 if (!(io = io_context_create())) { 14674 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 14675 sched = ast_sched_thread_destroy(sched); 14676 return AST_MODULE_LOAD_FAILURE; 14677 } 14678 14679 if (!(netsock = ast_netsock_list_alloc())) { 14680 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 14681 io_context_destroy(io); 14682 sched = ast_sched_thread_destroy(sched); 14683 return AST_MODULE_LOAD_FAILURE; 14684 } 14685 ast_netsock_init(netsock); 14686 14687 outsock = ast_netsock_list_alloc(); 14688 if (!outsock) { 14689 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 14690 io_context_destroy(io); 14691 sched = ast_sched_thread_destroy(sched); 14692 return AST_MODULE_LOAD_FAILURE; 14693 } 14694 ast_netsock_init(outsock); 14695 14696 randomcalltokendata = ast_random(); 14697 14698 iax_set_output(iax_debug_output); 14699 iax_set_error(iax_error_output); 14700 jb_setoutput(jb_error_output, jb_warning_output, NULL); 14701 14702 if ((timer = ast_timer_open())) { 14703 ast_timer_set_rate(timer, trunkfreq); 14704 } 14705 14706 if (set_config(config, 0) == -1) { 14707 if (timer) { 14708 ast_timer_close(timer); 14709 } 14710 return AST_MODULE_LOAD_DECLINE; 14711 } 14712 14713 #ifdef TEST_FRAMEWORK 14714 AST_TEST_REGISTER(test_iax2_peers_get); 14715 AST_TEST_REGISTER(test_iax2_users_get); 14716 #endif 14717 14718 /* Register AstData providers */ 14719 ast_data_register_multiple(iax2_data_providers, ARRAY_LEN(iax2_data_providers)); 14720 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 14721 14722 ast_register_application_xml(papp, iax2_prov_app); 14723 14724 ast_custom_function_register(&iaxpeer_function); 14725 ast_custom_function_register(&iaxvar_function); 14726 14727 ast_manager_register_xml("IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers); 14728 ast_manager_register_xml("IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list); 14729 ast_manager_register_xml("IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats); 14730 ast_manager_register_xml("IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry); 14731 14732 if (ast_channel_register(&iax2_tech)) { 14733 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 14734 __unload_module(); 14735 return AST_MODULE_LOAD_FAILURE; 14736 } 14737 14738 if (ast_register_switch(&iax2_switch)) { 14739 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 14740 } 14741 14742 if (start_network_thread()) { 14743 ast_log(LOG_ERROR, "Unable to start network thread\n"); 14744 __unload_module(); 14745 return AST_MODULE_LOAD_FAILURE; 14746 } else { 14747 ast_verb(2, "IAX Ready and Listening\n"); 14748 } 14749 14750 AST_LIST_LOCK(®istrations); 14751 AST_LIST_TRAVERSE(®istrations, reg, entry) 14752 iax2_do_register(reg); 14753 AST_LIST_UNLOCK(®istrations); 14754 14755 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 14756 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 14757 14758 14759 reload_firmware(0); 14760 iax_provision_reload(0); 14761 14762 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 14763 14764 network_change_event_subscribe(); 14765 14766 return AST_MODULE_LOAD_SUCCESS; 14767 }
static int load_objects | ( | void | ) | [static] |
Definition at line 14414 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().
14415 { 14416 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 14417 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 14418 14419 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 14420 goto container_fail; 14421 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 14422 goto container_fail; 14423 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 14424 goto container_fail; 14425 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 14426 goto container_fail; 14427 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 14428 goto container_fail; 14429 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14430 goto container_fail; 14431 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 14432 goto container_fail; 14433 } else if (create_callno_pools()) { 14434 goto container_fail; 14435 } else if (!(transmit_processor = ast_taskprocessor_get("iax2_transmit", TPS_REF_DEFAULT))) { 14436 goto container_fail; 14437 } 14438 14439 return 0; 14440 14441 container_fail: 14442 if (peers) { 14443 ao2_ref(peers, -1); 14444 } 14445 if (users) { 14446 ao2_ref(users, -1); 14447 } 14448 if (iax_peercallno_pvts) { 14449 ao2_ref(iax_peercallno_pvts, -1); 14450 } 14451 if (iax_transfercallno_pvts) { 14452 ao2_ref(iax_transfercallno_pvts, -1); 14453 } 14454 if (peercnts) { 14455 ao2_ref(peercnts, -1); 14456 } 14457 if (callno_limits) { 14458 ao2_ref(callno_limits, -1); 14459 } 14460 if (calltoken_ignores) { 14461 ao2_ref(calltoken_ignores, -1); 14462 } 14463 if (callno_pool) { 14464 ao2_ref(callno_pool, -1); 14465 } 14466 if (callno_pool_trunk) { 14467 ao2_ref(callno_pool_trunk, -1); 14468 } 14469 return AST_MODULE_LOAD_FAILURE; 14470 }
static void lock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5425 of file chan_iax2.c.
References ast_mutex_lock, ast_mutex_trylock, DEADLOCK_AVOIDANCE, and iaxsl.
Referenced by iax2_bridge().
05426 { 05427 ast_mutex_lock(&iaxsl[callno0]); 05428 while (ast_mutex_trylock(&iaxsl[callno1])) { 05429 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05430 } 05431 }
static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9454 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().
09455 { 09456 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09457 jb_info jbinfo; 09458 09459 ast_mutex_lock(&iaxsl[callno]); 09460 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 09461 if(ast_test_flag64(iaxs[callno], IAX_USEJITTERBUF)) { 09462 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09463 localjitter = jbinfo.jitter; 09464 localdelay = jbinfo.current - jbinfo.min; 09465 locallost = jbinfo.frames_lost; 09466 locallosspct = jbinfo.losspct/1000; 09467 localdropped = jbinfo.frames_dropped; 09468 localooo = jbinfo.frames_ooo; 09469 localpackets = jbinfo.frames_in; 09470 } 09471 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", 09472 iaxs[callno]->owner->name, 09473 iaxs[callno]->pingtime, 09474 localjitter, 09475 localdelay, 09476 locallost, 09477 locallosspct, 09478 localdropped, 09479 localooo, 09480 localpackets, 09481 iaxs[callno]->remote_rr.jitter, 09482 iaxs[callno]->remote_rr.delay, 09483 iaxs[callno]->remote_rr.losscnt, 09484 iaxs[callno]->remote_rr.losspct/1000, 09485 iaxs[callno]->remote_rr.dropped, 09486 iaxs[callno]->remote_rr.ooo, 09487 iaxs[callno]->remote_rr.packets); 09488 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", 09489 iaxs[callno]->owner->name, 09490 iaxs[callno]->pingtime, 09491 localjitter, 09492 localdelay, 09493 locallost, 09494 locallosspct, 09495 localdropped, 09496 localooo, 09497 localpackets, 09498 iaxs[callno]->remote_rr.jitter, 09499 iaxs[callno]->remote_rr.delay, 09500 iaxs[callno]->remote_rr.losscnt, 09501 iaxs[callno]->remote_rr.losspct/1000, 09502 iaxs[callno]->remote_rr.dropped, 09503 iaxs[callno]->remote_rr.ooo, 09504 iaxs[callno]->remote_rr.packets); 09505 } 09506 ast_mutex_unlock(&iaxsl[callno]); 09507 }
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 6914 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
06915 { 06916 ast_cli_netstats(s, -1, 0); 06917 astman_append(s, "\r\n"); 06918 return RESULT_SUCCESS; 06919 }
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 6977 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().
06978 { 06979 struct iax2_peer *peer = NULL; 06980 int peer_count = 0; 06981 char nm[20]; 06982 char status[20]; 06983 const char *id = astman_get_header(m,"ActionID"); 06984 char idtext[256] = ""; 06985 struct ast_str *encmethods = ast_str_alloca(256); 06986 struct ao2_iterator i; 06987 06988 if (!ast_strlen_zero(id)) 06989 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06990 06991 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 06992 06993 06994 i = ao2_iterator_init(peers, 0); 06995 for (; (peer = ao2_iterator_next(&i)); peer_unref(peer)) { 06996 encmethods_to_str(peer->encmethods, encmethods); 06997 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 06998 if (!ast_strlen_zero(peer->username)) { 06999 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 07000 } else { 07001 astman_append(s, "ObjectName: %s\r\n", peer->name); 07002 } 07003 astman_append(s, "ChanObjectType: peer\r\n"); 07004 astman_append(s, "IPaddress: %s\r\n", ast_sockaddr_stringify_addr(&peer->addr)); 07005 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 07006 astman_append(s, "Mask: %s\r\n", nm); 07007 astman_append(s, "Port: %d\r\n", ast_sockaddr_port(&peer->addr)); 07008 astman_append(s, "Dynamic: %s\r\n", ast_test_flag64(peer, IAX_DYNAMIC) ? "Yes" : "No"); 07009 astman_append(s, "Trunk: %s\r\n", ast_test_flag64(peer, IAX_TRUNK) ? "Yes" : "No"); 07010 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 07011 peer_status(peer, status, sizeof(status)); 07012 astman_append(s, "Status: %s\r\n\r\n", status); 07013 peer_count++; 07014 } 07015 ao2_iterator_destroy(&i); 07016 07017 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 07018 return RESULT_SUCCESS; 07019 }
static int manager_iax2_show_peers | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
callback to display iax peers in manager
Definition at line 6953 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().
06954 { 06955 static const char * const a[] = { "iax2", "show", "peers" }; 06956 const char *id = astman_get_header(m,"ActionID"); 06957 char idtext[256] = ""; 06958 int total = 0; 06959 06960 if (!ast_strlen_zero(id)) 06961 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06962 06963 astman_send_listack(s, m, "Peer status list will follow", "start"); 06964 /* List the peers in separate manager events */ 06965 __iax2_show_peers(-1, &total, s, 3, a); 06966 /* Send final confirmation */ 06967 astman_append(s, 06968 "Event: PeerlistComplete\r\n" 06969 "EventList: Complete\r\n" 06970 "ListItems: %d\r\n" 06971 "%s" 06972 "\r\n", total, idtext); 06973 return 0; 06974 }
static int manager_iax2_show_registry | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 7085 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().
07086 { 07087 const char *id = astman_get_header(m, "ActionID"); 07088 struct iax2_registry *reg = NULL; 07089 char idtext[256] = ""; 07090 char host[80] = ""; 07091 char perceived[80] = ""; 07092 int total = 0; 07093 07094 if (!ast_strlen_zero(id)) 07095 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 07096 07097 astman_send_listack(s, m, "Registrations will follow", "start"); 07098 07099 AST_LIST_LOCK(®istrations); 07100 AST_LIST_TRAVERSE(®istrations, reg, entry) { 07101 snprintf(host, sizeof(host), "%s", ast_sockaddr_stringify(®->addr)); 07102 07103 if (reg->us.sin_addr.s_addr) { 07104 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07105 } else { 07106 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 07107 } 07108 07109 astman_append(s, 07110 "Event: RegistryEntry\r\n" 07111 "%s" 07112 "Host: %s\r\n" 07113 "DNSmanager: %s\r\n" 07114 "Username: %s\r\n" 07115 "Perceived: %s\r\n" 07116 "Refresh: %d\r\n" 07117 "State: %s\r\n" 07118 "\r\n", idtext, host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 07119 reg->refresh, regstate2str(reg->regstate)); 07120 07121 total++; 07122 } 07123 AST_LIST_UNLOCK(®istrations); 07124 07125 astman_append(s, 07126 "Event: RegistrationsComplete\r\n" 07127 "EventList: Complete\r\n" 07128 "ListItems: %d\r\n" 07129 "%s" 07130 "\r\n", total, idtext); 07131 07132 return 0; 07133 }
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(), transfercallno_pvt_cmp_cb(), and xmldoc_attribute_match().
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 6169 of file chan_iax2.c.
References ast_aes_decrypt(), ast_log(), and LOG_WARNING.
Referenced by decode_frame().
06170 { 06171 #if 0 06172 /* Debug with "fake encryption" */ 06173 int x; 06174 if (len % 16) 06175 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06176 for (x=0;x<len;x++) 06177 dst[x] = src[x] ^ 0xff; 06178 #else 06179 unsigned char lastblock[16] = { 0 }; 06180 int x; 06181 while(len > 0) { 06182 ast_aes_decrypt(src, dst, dcx); 06183 for (x=0;x<16;x++) 06184 dst[x] ^= lastblock[x]; 06185 memcpy(lastblock, src, sizeof(lastblock)); 06186 dst += 16; 06187 src += 16; 06188 len -= 16; 06189 } 06190 #endif 06191 }
static void memcpy_encrypt | ( | unsigned char * | dst, | |
const unsigned char * | src, | |||
int | len, | |||
ast_aes_encrypt_key * | ecx | |||
) | [static] |
Definition at line 6193 of file chan_iax2.c.
References ast_aes_encrypt(), ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
06194 { 06195 #if 0 06196 /* Debug with "fake encryption" */ 06197 int x; 06198 if (len % 16) 06199 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 06200 for (x=0;x<len;x++) 06201 dst[x] = src[x] ^ 0xff; 06202 #else 06203 unsigned char curblock[16] = { 0 }; 06204 int x; 06205 while(len > 0) { 06206 for (x=0;x<16;x++) 06207 curblock[x] ^= src[x]; 06208 ast_aes_encrypt(curblock, dst, ecx); 06209 memcpy(curblock, dst, sizeof(curblock)); 06210 dst += 16; 06211 src += 16; 06212 len -= 16; 06213 } 06214 #endif 06215 }
static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
unsigned int | enc | |||
) | [static] |
Definition at line 7757 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().
07758 { 07759 /* Select exactly one common encryption if there are any */ 07760 p->encmethods &= enc; 07761 if (p->encmethods) { 07762 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07763 p->keyrotateid = -2; 07764 } 07765 if (p->encmethods & IAX_ENCRYPT_AES128) 07766 p->encmethods = IAX_ENCRYPT_AES128; 07767 else 07768 p->encmethods = 0; 07769 } 07770 }
static void mwi_event_cb | ( | const struct ast_event * | event, | |
void * | userdata | |||
) | [static] |
Definition at line 1275 of file chan_iax2.c.
01276 { 01277 /* The MWI subscriptions exist just so the core knows we care about those 01278 * mailboxes. However, we just grab the events out of the cache when it 01279 * is time to send MWI, since it is only sent with a REGACK. */ 01280 }
static void network_change_event_cb | ( | const struct ast_event * | , | |
void * | ||||
) | [static] |
Definition at line 1310 of file chan_iax2.c.
References ast_debug, iax2_sched_add(), network_change_event_sched_cb(), and sched.
Referenced by network_change_event_subscribe().
01311 { 01312 ast_debug(1, "IAX, got a network change event, renewing all IAX registrations.\n"); 01313 if (network_change_event_sched_id == -1) { 01314 network_change_event_sched_id = iax2_sched_add(sched, 1000, network_change_event_sched_cb, NULL); 01315 } 01316 01317 }
static int network_change_event_sched_cb | ( | const void * | data | ) | [static] |
Definition at line 1297 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().
01298 { 01299 struct iax2_registry *reg; 01300 network_change_event_sched_id = -1; 01301 AST_LIST_LOCK(®istrations); 01302 AST_LIST_TRAVERSE(®istrations, reg, entry) { 01303 iax2_do_register(reg); 01304 } 01305 AST_LIST_UNLOCK(®istrations); 01306 01307 return 0; 01308 }
static void network_change_event_subscribe | ( | void | ) | [static] |
Definition at line 1282 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().
01283 { 01284 if (!network_change_event_subscription) { 01285 network_change_event_subscription = ast_event_subscribe(AST_EVENT_NETWORK_CHANGE, 01286 network_change_event_cb, "IAX2 Network Change", NULL, AST_EVENT_IE_END); 01287 } 01288 }
static void network_change_event_unsubscribe | ( | void | ) | [static] |
Definition at line 1290 of file chan_iax2.c.
References ast_event_unsubscribe(), and network_change_event_subscription.
Referenced by __unload_module(), set_config(), and unload_module().
01291 { 01292 if (network_change_event_subscription) { 01293 network_change_event_subscription = ast_event_unsubscribe(network_change_event_subscription); 01294 } 01295 }
static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 12144 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().
12145 { 12146 if (timer) { 12147 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 12148 } 12149 12150 for (;;) { 12151 pthread_testcancel(); 12152 /* Wake up once a second just in case SIGURG was sent while 12153 * we weren't in poll(), to make sure we don't hang when trying 12154 * to unload. */ 12155 ast_io_wait(io, 1000); 12156 } 12157 12158 return NULL; 12159 }
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 4947 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().
04948 { 04949 if (ast_strlen_zero(data)) 04950 return; 04951 04952 pds->peer = strsep(&data, "/"); 04953 pds->exten = strsep(&data, "/"); 04954 pds->options = data; 04955 04956 if (pds->exten) { 04957 data = pds->exten; 04958 pds->exten = strsep(&data, "@"); 04959 pds->context = data; 04960 } 04961 04962 if (strchr(pds->peer, '@')) { 04963 data = pds->peer; 04964 pds->username = strsep(&data, "@"); 04965 pds->peer = data; 04966 } 04967 04968 if (pds->username) { 04969 data = pds->username; 04970 pds->username = strsep(&data, ":"); 04971 pds->password = data; 04972 } 04973 04974 data = pds->peer; 04975 pds->peer = strsep(&data, ":"); 04976 pds->port = data; 04977 04978 /* check for a key name wrapped in [] in the secret position, if found, 04979 move it to the key field instead 04980 */ 04981 if (pds->password && (pds->password[0] == '[')) { 04982 pds->key = ast_strip_quoted(pds->password, "[", "]"); 04983 pds->password = NULL; 04984 } 04985 }
static int peer_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1654 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and iax2_peer::name.
Referenced by load_module(), and load_objects().
01655 { 01656 struct iax2_peer *peer = obj, *peer2 = arg; 01657 01658 return !strcmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0; 01659 }
static int peer_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12891 of file chan_iax2.c.
References ast_set_flag64, and IAX_DELME.
Referenced by delete_users().
12892 { 12893 struct iax2_peer *peer = obj; 12894 12895 ast_set_flag64(peer, IAX_DELME); 12896 12897 return 0; 12898 }
static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 12321 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().
12322 { 12323 struct iax2_peer *peer = obj; 12324 int callno = peer->callno; 12325 12326 ast_free_ha(peer->ha); 12327 12328 if (callno > 0) { 12329 ast_mutex_lock(&iaxsl[callno]); 12330 iax2_destroy(callno); 12331 ast_mutex_unlock(&iaxsl[callno]); 12332 } 12333 12334 register_peer_exten(peer, 0); 12335 12336 if (peer->dnsmgr) 12337 ast_dnsmgr_release(peer->dnsmgr); 12338 12339 if (peer->mwi_event_sub) 12340 ast_event_unsubscribe(peer->mwi_event_sub); 12341 12342 ast_string_field_free_memory(peer); 12343 }
static int peer_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1644 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_module(), and load_objects().
01645 { 01646 const struct iax2_peer *peer = obj; 01647 01648 return ast_str_hash(peer->name); 01649 }
Definition at line 1701 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().
01702 { 01703 ao2_ref(peer, +1); 01704 return peer; 01705 }
static int peer_set_sock_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14368 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
14369 { 14370 struct iax2_peer *peer = obj; 14371 14372 if (peer->sockfd < 0) 14373 peer->sockfd = defaultsockfd; 14374 14375 return 0; 14376 }
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 12246 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, ast_sockaddr::ss, and strsep().
Referenced by build_peer().
12247 { 12248 struct sockaddr_in sin; 12249 struct ast_sockaddr sin_tmp; 12250 int nonlocal = 1; 12251 int port = IAX_DEFAULT_PORTNO; 12252 int sockfd = defaultsockfd; 12253 char *tmp; 12254 char *addr; 12255 char *portstr; 12256 12257 if (!(tmp = ast_strdupa(srcaddr))) 12258 return -1; 12259 12260 addr = strsep(&tmp, ":"); 12261 portstr = tmp; 12262 12263 if (portstr) { 12264 port = atoi(portstr); 12265 if (port < 1) 12266 port = IAX_DEFAULT_PORTNO; 12267 } 12268 12269 sin_tmp.ss.ss_family = AF_INET; 12270 if (!ast_get_ip(&sin_tmp, addr)) { 12271 struct ast_netsock *sock; 12272 int res; 12273 12274 ast_sockaddr_to_sin(&sin_tmp, &sin); 12275 sin.sin_port = 0; 12276 sin.sin_family = AF_INET; 12277 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 12278 if (res == 0) { 12279 /* ip address valid. */ 12280 sin.sin_port = htons(port); 12281 if (!(sock = ast_netsock_find(netsock, &sin))) 12282 sock = ast_netsock_find(outsock, &sin); 12283 if (sock) { 12284 sockfd = ast_netsock_sockfd(sock); 12285 nonlocal = 0; 12286 } else { 12287 unsigned int orig_saddr = sin.sin_addr.s_addr; 12288 /* INADDR_ANY matches anyway! */ 12289 sin.sin_addr.s_addr = INADDR_ANY; 12290 if (ast_netsock_find(netsock, &sin)) { 12291 sin.sin_addr.s_addr = orig_saddr; 12292 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 12293 if (sock) { 12294 sockfd = ast_netsock_sockfd(sock); 12295 ast_netsock_unref(sock); 12296 nonlocal = 0; 12297 } else { 12298 nonlocal = 2; 12299 } 12300 } 12301 } 12302 } 12303 } 12304 12305 peer->sockfd = sockfd; 12306 12307 if (nonlocal == 1) { 12308 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 12309 srcaddr, peer->name); 12310 return -1; 12311 } else if (nonlocal == 2) { 12312 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 12313 srcaddr, peer->name); 12314 return -1; 12315 } else { 12316 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 12317 return 0; 12318 } 12319 }
static int peer_status | ( | struct iax2_peer * | peer, | |
char * | status, | |||
int | statuslen | |||
) | [static] |
peer_status: Report Peer status in character string
Definition at line 3703 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().
03704 { 03705 int res = 0; 03706 if (peer->maxms) { 03707 if (peer->lastms < 0) { 03708 ast_copy_string(status, "UNREACHABLE", statuslen); 03709 } else if (peer->lastms > peer->maxms) { 03710 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03711 res = 1; 03712 } else if (peer->lastms) { 03713 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03714 res = 1; 03715 } else { 03716 ast_copy_string(status, "UNKNOWN", statuslen); 03717 } 03718 } else { 03719 ast_copy_string(status, "Unmonitored", statuslen); 03720 res = -1; 03721 } 03722 return res; 03723 }
Definition at line 1707 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().
01708 { 01709 ao2_ref(peer, -1); 01710 return NULL; 01711 }
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 14502 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.
14504 { 14505 struct ast_data *data_peer; 14506 struct iax2_peer *peer; 14507 struct ao2_iterator i; 14508 char status[20]; 14509 struct ast_str *encmethods = ast_str_alloca(256); 14510 14511 i = ao2_iterator_init(peers, 0); 14512 while ((peer = ao2_iterator_next(&i))) { 14513 data_peer = ast_data_add_node(data_root, "peer"); 14514 if (!data_peer) { 14515 peer_unref(peer); 14516 continue; 14517 } 14518 14519 ast_data_add_structure(iax2_peer, data_peer, peer); 14520 14521 ast_data_add_codecs(data_peer, "codecs", peer->capability); 14522 14523 peer_status(peer, status, sizeof(status)); 14524 ast_data_add_str(data_peer, "status", status); 14525 14526 ast_data_add_str(data_peer, "host", ast_sockaddr_stringify_host(&peer->addr)); 14527 14528 ast_data_add_str(data_peer, "mask", ast_inet_ntoa(peer->mask)); 14529 14530 ast_data_add_int(data_peer, "port", ast_sockaddr_port(&peer->addr)); 14531 14532 ast_data_add_bool(data_peer, "trunk", ast_test_flag64(peer, IAX_TRUNK)); 14533 14534 ast_data_add_bool(data_peer, "dynamic", ast_test_flag64(peer, IAX_DYNAMIC)); 14535 14536 encmethods_to_str(peer->encmethods, encmethods); 14537 ast_data_add_str(data_peer, "encryption", peer->encmethods ? ast_str_buffer(encmethods) : "no"); 14538 14539 peer_unref(peer); 14540 14541 if (!ast_data_search_match(search, data_peer)) { 14542 ast_data_remove_node(data_root, data_peer); 14543 } 14544 } 14545 ao2_iterator_destroy(&i); 14546 14547 return 0; 14548 }
static void poke_all_peers | ( | void | ) | [static] |
Definition at line 13457 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().
13458 { 13459 struct ao2_iterator i; 13460 struct iax2_peer *peer; 13461 13462 i = ao2_iterator_init(peers, 0); 13463 while ((peer = ao2_iterator_next(&i))) { 13464 iax2_poke_peer(peer, 0); 13465 peer_unref(peer); 13466 } 13467 ao2_iterator_destroy(&i); 13468 }
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 12954 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().
12955 { 12956 struct iax2_peer *peer; 12957 struct ao2_iterator i; 12958 12959 i = ao2_iterator_init(peers, 0); 12960 while ((peer = ao2_iterator_next(&i))) { 12961 if (ast_test_flag64(peer, IAX_DELME) || ast_test_flag64(peer, IAX_RTCACHEFRIENDS)) { 12962 unlink_peer(peer); 12963 } 12964 peer_unref(peer); 12965 } 12966 ao2_iterator_destroy(&i); 12967 }
static void prune_users | ( | void | ) | [static] |
Definition at line 12938 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().
12939 { 12940 struct iax2_user *user; 12941 struct ao2_iterator i; 12942 12943 i = ao2_iterator_init(users, 0); 12944 while ((user = ao2_iterator_next(&i))) { 12945 if (ast_test_flag64(user, IAX_DELME) || ast_test_flag64(user, IAX_RTCACHEFRIENDS)) { 12946 ao2_unlink(users, user); 12947 } 12948 user_unref(user); 12949 } 12950 ao2_iterator_destroy(&i); 12951 }
static int pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14385 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
14386 { 14387 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14388 14389 /* The frames_received field is used to hold whether we're matching 14390 * against a full frame or not ... */ 14391 14392 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 14393 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14394 }
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 14378 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
14379 { 14380 const struct chan_iax2_pvt *pvt = obj; 14381 14382 return pvt->peercallno; 14383 }
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 7738 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().
07739 { 07740 struct ast_iax2_full_hdr fh; 07741 fh.scallno = htons(src | IAX_FLAG_FULL); 07742 fh.dcallno = htons(dst); 07743 fh.ts = 0; 07744 fh.oseqno = 0; 07745 fh.iseqno = 0; 07746 fh.type = AST_FRAME_IAX; 07747 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07748 iax_outputframe(NULL, &fh, 0, sin, 0); 07749 #if 0 07750 if (option_debug) 07751 #endif 07752 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07753 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07754 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07755 }
static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4306 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.
04307 { 04308 struct ast_variable *var = NULL; 04309 struct ast_variable *tmp; 04310 struct iax2_peer *peer=NULL; 04311 time_t regseconds = 0, nowtime; 04312 int dynamic=0; 04313 04314 if (peername) { 04315 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04316 if (!var && sin) 04317 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04318 } else if (sin) { 04319 char porta[25]; 04320 sprintf(porta, "%d", ntohs(sin->sin_port)); 04321 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04322 if (var) { 04323 /* We'll need the peer name in order to build the structure! */ 04324 for (tmp = var; tmp; tmp = tmp->next) { 04325 if (!strcasecmp(tmp->name, "name")) 04326 peername = tmp->value; 04327 } 04328 } 04329 } 04330 if (!var && peername) { /* Last ditch effort */ 04331 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04332 /*!\note 04333 * If this one loaded something, then we need to ensure that the host 04334 * field matched. The only reason why we can't have this as a criteria 04335 * is because we only have the IP address and the host field might be 04336 * set as a name (and the reverse PTR might not match). 04337 */ 04338 if (var && sin) { 04339 for (tmp = var; tmp; tmp = tmp->next) { 04340 if (!strcasecmp(tmp->name, "host")) { 04341 struct ast_hostent ahp; 04342 struct hostent *hp; 04343 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04344 /* No match */ 04345 ast_variables_destroy(var); 04346 var = NULL; 04347 } 04348 break; 04349 } 04350 } 04351 } 04352 } 04353 if (!var) 04354 return NULL; 04355 04356 peer = build_peer(peername, var, NULL, ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04357 04358 if (!peer) { 04359 ast_variables_destroy(var); 04360 return NULL; 04361 } 04362 04363 for (tmp = var; tmp; tmp = tmp->next) { 04364 /* Make sure it's not a user only... */ 04365 if (!strcasecmp(tmp->name, "type")) { 04366 if (strcasecmp(tmp->value, "friend") && 04367 strcasecmp(tmp->value, "peer")) { 04368 /* Whoops, we weren't supposed to exist! */ 04369 peer = peer_unref(peer); 04370 break; 04371 } 04372 } else if (!strcasecmp(tmp->name, "regseconds")) { 04373 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04374 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04375 ast_sockaddr_parse(&peer->addr, tmp->value, PARSE_PORT_IGNORE); 04376 } else if (!strcasecmp(tmp->name, "port")) { 04377 ast_sockaddr_set_port(&peer->addr, atoi(tmp->value)); 04378 } else if (!strcasecmp(tmp->name, "host")) { 04379 if (!strcasecmp(tmp->value, "dynamic")) 04380 dynamic = 1; 04381 } 04382 } 04383 04384 ast_variables_destroy(var); 04385 04386 if (!peer) 04387 return NULL; 04388 04389 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04390 ast_copy_flags64(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04391 if (ast_test_flag64(peer, IAX_RTAUTOCLEAR)) { 04392 if (peer->expire > -1) { 04393 if (!ast_sched_thread_del(sched, peer->expire)) { 04394 peer->expire = -1; 04395 peer_unref(peer); 04396 } 04397 } 04398 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04399 if (peer->expire == -1) 04400 peer_unref(peer); 04401 } 04402 ao2_link(peers, peer); 04403 if (ast_test_flag64(peer, IAX_DYNAMIC)) 04404 reg_source_db(peer); 04405 } else { 04406 ast_set_flag64(peer, IAX_TEMPONLY); 04407 } 04408 04409 if (!ast_test_flag64(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04410 time(&nowtime); 04411 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04412 memset(&peer->addr, 0, sizeof(peer->addr)); 04413 realtime_update_peer(peer->name, &peer->addr, 0); 04414 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04415 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04416 } 04417 else { 04418 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04419 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04420 } 04421 } 04422 04423 return peer; 04424 }
static void realtime_update_peer | ( | const char * | peername, | |
struct ast_sockaddr * | sockaddr, | |||
time_t | regtime | |||
) | [static] |
Definition at line 4497 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().
04498 { 04499 char port[10]; 04500 char regseconds[20]; 04501 const char *sysname = ast_config_AST_SYSTEM_NAME; 04502 char *syslabel = NULL; 04503 04504 if (ast_strlen_zero(sysname)) /* No system name, disable this */ 04505 sysname = NULL; 04506 else if (ast_test_flag64(&globalflags, IAX_RTSAVE_SYSNAME)) 04507 syslabel = "regserver"; 04508 04509 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04510 snprintf(port, sizeof(port), "%d", ast_sockaddr_port(sockaddr)); 04511 ast_update_realtime("iaxpeers", "name", peername, 04512 "ipaddr", ast_sockaddr_stringify_addr(sockaddr), "port", port, 04513 "regseconds", regseconds, syslabel, sysname, SENTINEL); /* note syslable can be NULL */ 04514 }
static struct iax2_user * realtime_user | ( | const char * | username, | |
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 4426 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.
04427 { 04428 struct ast_variable *var; 04429 struct ast_variable *tmp; 04430 struct iax2_user *user=NULL; 04431 04432 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04433 if (!var) 04434 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04435 if (!var && sin) { 04436 char porta[6]; 04437 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04438 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04439 if (!var) 04440 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04441 } 04442 if (!var) { /* Last ditch effort */ 04443 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04444 /*!\note 04445 * If this one loaded something, then we need to ensure that the host 04446 * field matched. The only reason why we can't have this as a criteria 04447 * is because we only have the IP address and the host field might be 04448 * set as a name (and the reverse PTR might not match). 04449 */ 04450 if (var) { 04451 for (tmp = var; tmp; tmp = tmp->next) { 04452 if (!strcasecmp(tmp->name, "host")) { 04453 struct ast_hostent ahp; 04454 struct hostent *hp; 04455 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04456 /* No match */ 04457 ast_variables_destroy(var); 04458 var = NULL; 04459 } 04460 break; 04461 } 04462 } 04463 } 04464 } 04465 if (!var) 04466 return NULL; 04467 04468 tmp = var; 04469 while(tmp) { 04470 /* Make sure it's not a peer only... */ 04471 if (!strcasecmp(tmp->name, "type")) { 04472 if (strcasecmp(tmp->value, "friend") && 04473 strcasecmp(tmp->value, "user")) { 04474 return NULL; 04475 } 04476 } 04477 tmp = tmp->next; 04478 } 04479 04480 user = build_user(username, var, NULL, !ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)); 04481 04482 ast_variables_destroy(var); 04483 04484 if (!user) 04485 return NULL; 04486 04487 if (ast_test_flag64((&globalflags), IAX_RTCACHEFRIENDS)) { 04488 ast_set_flag64(user, IAX_RTCACHEFRIENDS); 04489 ao2_link(users, user); 04490 } else { 04491 ast_set_flag64(user, IAX_TEMPONLY); 04492 } 04493 04494 return user; 04495 }
static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8627 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().
08628 { 08629 char data[80]; 08630 char *expiry; 08631 08632 if (ast_test_flag64(p, IAX_TEMPONLY) || ast_db_get("IAX/Registry", p->name, data, sizeof(data))) { 08633 return; 08634 } 08635 08636 expiry = strrchr(data, ':'); 08637 if (!expiry) { 08638 ast_log(LOG_NOTICE, "IAX/Registry astdb entry missing expiry: '%s'\n", data); 08639 } 08640 *expiry++ = '\0'; 08641 08642 if (!ast_sockaddr_parse(&p->addr, data, PARSE_PORT_REQUIRE)) { 08643 ast_log(LOG_NOTICE, "IAX/Registry astdb host:port invalid - '%s'\n", data); 08644 return; 08645 } 08646 08647 p->expiry = atoi(expiry); 08648 08649 ast_verb(3, "Seeding '%s' at %s for %d\n", p->name, 08650 ast_sockaddr_stringify(&p->addr), p->expiry); 08651 08652 iax2_poke_peer(p, 0); 08653 if (p->expire > -1) { 08654 if (!ast_sched_thread_del(sched, p->expire)) { 08655 p->expire = -1; 08656 peer_unref(p); 08657 } 08658 } 08659 08660 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08661 08662 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08663 if (p->expire == -1) { 08664 peer_unref(p); 08665 } 08666 08667 if (iax2_regfunk) { 08668 iax2_regfunk(p->name, 1); 08669 } 08670 08671 register_peer_exten(p, 1); 08672 }
static void register_peer_exten | ( | struct iax2_peer * | peer, | |
int | onoff | |||
) | [static] |
Definition at line 8542 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().
08543 { 08544 char multi[256]; 08545 char *stringp, *ext; 08546 if (!ast_strlen_zero(regcontext)) { 08547 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08548 stringp = multi; 08549 while((ext = strsep(&stringp, "&"))) { 08550 if (onoff) { 08551 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08552 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08553 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08554 } else 08555 ast_context_remove_extension(regcontext, ext, 1, NULL); 08556 } 08557 } 08558 }
static int register_verify | ( | int | callno, | |
struct sockaddr_in * | sin, | |||
struct iax_ies * | ies | |||
) | [static] |
Verify inbound registration.
Definition at line 7912 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().
07913 { 07914 char requeststr[256] = ""; 07915 char peer[256] = ""; 07916 char md5secret[256] = ""; 07917 char rsasecret[256] = ""; 07918 char secret[256] = ""; 07919 struct iax2_peer *p = NULL; 07920 struct ast_key *key; 07921 char *keyn; 07922 int x; 07923 int expire = 0; 07924 int res = -1; 07925 struct ast_sockaddr addr; 07926 07927 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07928 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 07929 if (ies->username) 07930 ast_copy_string(peer, ies->username, sizeof(peer)); 07931 if (ies->password) 07932 ast_copy_string(secret, ies->password, sizeof(secret)); 07933 if (ies->md5_result) 07934 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07935 if (ies->rsa_result) 07936 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07937 if (ies->refresh) 07938 expire = ies->refresh; 07939 07940 if (ast_strlen_zero(peer)) { 07941 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 07942 return -1; 07943 } 07944 07945 /* SLD: first call to lookup peer during registration */ 07946 ast_mutex_unlock(&iaxsl[callno]); 07947 p = find_peer(peer, 1); 07948 ast_mutex_lock(&iaxsl[callno]); 07949 if (!p || !iaxs[callno]) { 07950 if (iaxs[callno]) { 07951 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 07952 /* Anything, as long as it's non-blank */ 07953 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07954 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 07955 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 07956 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 07957 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 07958 * to be plaintext, indicating it is an authmethod used by other peers on the system. 07959 * 07960 * If none of these cases exist, res will be returned as 0 without authentication indicating 07961 * an AUTHREQ needs to be sent out. */ 07962 07963 if (ast_strlen_zero(iaxs[callno]->challenge) && 07964 !(!ast_strlen_zero(secret) && plaintext)) { 07965 /* by setting res to 0, an REGAUTH will be sent */ 07966 res = 0; 07967 } 07968 } 07969 if (authdebug && !p) 07970 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07971 goto return_unref; 07972 } 07973 07974 if (!ast_test_flag64(p, IAX_DYNAMIC)) { 07975 if (authdebug) 07976 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07977 goto return_unref; 07978 } 07979 07980 ast_sockaddr_from_sin(&addr, sin); 07981 if (!ast_apply_ha(p->ha, &addr)) { 07982 if (authdebug) 07983 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 07984 goto return_unref; 07985 } 07986 ast_string_field_set(iaxs[callno], secret, p->secret); 07987 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 07988 /* Check secret against what we have on file */ 07989 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 07990 if (!ast_strlen_zero(p->inkeys)) { 07991 char tmpkeys[256]; 07992 char *stringp=NULL; 07993 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 07994 stringp=tmpkeys; 07995 keyn = strsep(&stringp, ":"); 07996 while(keyn) { 07997 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07998 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 07999 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08000 break; 08001 } else if (!key) 08002 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 08003 keyn = strsep(&stringp, ":"); 08004 } 08005 if (!keyn) { 08006 if (authdebug) 08007 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 08008 goto return_unref; 08009 } 08010 } else { 08011 if (authdebug) 08012 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 08013 goto return_unref; 08014 } 08015 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 08016 struct MD5Context md5; 08017 unsigned char digest[16]; 08018 char *tmppw, *stringp; 08019 08020 tmppw = ast_strdupa(p->secret); 08021 stringp = tmppw; 08022 while((tmppw = strsep(&stringp, ";"))) { 08023 MD5Init(&md5); 08024 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 08025 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 08026 MD5Final(digest, &md5); 08027 for (x=0;x<16;x++) 08028 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 08029 if (!strcasecmp(requeststr, md5secret)) 08030 break; 08031 } 08032 if (tmppw) { 08033 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08034 } else { 08035 if (authdebug) 08036 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 08037 goto return_unref; 08038 } 08039 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 08040 /* They've provided a plain text password and we support that */ 08041 if (strcmp(secret, p->secret)) { 08042 if (authdebug) 08043 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 08044 goto return_unref; 08045 } else 08046 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 08047 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 08048 /* if challenge has been sent, but no challenge response if given, reject. */ 08049 goto return_unref; 08050 } 08051 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08052 08053 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 08054 res = 0; 08055 08056 return_unref: 08057 if (iaxs[callno]) { 08058 ast_string_field_set(iaxs[callno], peer, peer); 08059 08060 /* Choose lowest expiry number */ 08061 if (expire && (expire < iaxs[callno]->expiry)) { 08062 iaxs[callno]->expiry = expire; 08063 } 08064 } 08065 08066 if (p) { 08067 peer_unref(p); 08068 } 08069 return res; 08070 }
static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8848 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().
08849 { 08850 struct iax_ie_data ied; 08851 struct iax2_peer *p; 08852 char challenge[10]; 08853 const char *peer_name; 08854 int sentauthmethod; 08855 08856 peer_name = ast_strdupa(iaxs[callno]->peer); 08857 08858 /* SLD: third call to find_peer in registration */ 08859 ast_mutex_unlock(&iaxsl[callno]); 08860 if ((p = find_peer(peer_name, 1))) { 08861 last_authmethod = p->authmethods; 08862 } 08863 08864 ast_mutex_lock(&iaxsl[callno]); 08865 if (!iaxs[callno]) 08866 goto return_unref; 08867 08868 memset(&ied, 0, sizeof(ied)); 08869 /* The selection of which delayed reject is sent may leak information, 08870 * if it sets a static response. For example, if a host is known to only 08871 * use MD5 authentication, then an RSA response would indicate that the 08872 * peer does not exist, and vice-versa. 08873 * Therefore, we use whatever the last peer used (which may vary over the 08874 * course of a server, which should leak minimal information). */ 08875 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08876 if (!p) { 08877 iaxs[callno]->authmethods = sentauthmethod; 08878 } 08879 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08880 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08881 /* Build the challenge */ 08882 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08883 ast_string_field_set(iaxs[callno], challenge, challenge); 08884 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08885 } 08886 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08887 08888 return_unref: 08889 if (p) { 08890 peer_unref(p); 08891 } 08892 08893 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08894 }
static int registry_rerequest | ( | struct iax_ies * | ies, | |
int | callno, | |||
struct sockaddr_in * | sin | |||
) | [static] |
Definition at line 8896 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().
08897 { 08898 struct iax2_registry *reg; 08899 /* Start pessimistic */ 08900 struct iax_ie_data ied; 08901 char peer[256] = ""; 08902 char challenge[256] = ""; 08903 int res; 08904 int authmethods = 0; 08905 if (ies->authmethods) 08906 authmethods = ies->authmethods; 08907 if (ies->username) 08908 ast_copy_string(peer, ies->username, sizeof(peer)); 08909 if (ies->challenge) 08910 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 08911 memset(&ied, 0, sizeof(ied)); 08912 reg = iaxs[callno]->reg; 08913 if (reg) { 08914 struct sockaddr_in reg_addr; 08915 08916 ast_sockaddr_to_sin(®->addr, ®_addr); 08917 08918 if (inaddrcmp(®_addr, sin)) { 08919 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08920 return -1; 08921 } 08922 if (ast_strlen_zero(reg->secret)) { 08923 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 08924 reg->regstate = REG_STATE_NOAUTH; 08925 return -1; 08926 } 08927 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08928 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08929 if (reg->secret[0] == '[') { 08930 char tmpkey[256]; 08931 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 08932 tmpkey[strlen(tmpkey) - 1] = '\0'; 08933 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 08934 } else 08935 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 08936 if (!res) { 08937 reg->regstate = REG_STATE_AUTHSENT; 08938 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 08939 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08940 } else 08941 return -1; 08942 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 08943 } else 08944 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 08945 return -1; 08946 }
static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 7022 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().
07023 { 07024 switch(regstate) { 07025 case REG_STATE_UNREGISTERED: 07026 return "Unregistered"; 07027 case REG_STATE_REGSENT: 07028 return "Request Sent"; 07029 case REG_STATE_AUTHSENT: 07030 return "Auth. Sent"; 07031 case REG_STATE_REGISTERED: 07032 return "Registered"; 07033 case REG_STATE_REJECTED: 07034 return "Rejected"; 07035 case REG_STATE_TIMEOUT: 07036 return "Timeout"; 07037 case REG_STATE_NOAUTH: 07038 return "No Authentication"; 07039 default: 07040 return "Unknown"; 07041 } 07042 }
static int reload | ( | void | ) | [static] |
Definition at line 13518 of file chan_iax2.c.
References reload_config().
13519 { 13520 return reload_config(); 13521 }
static int reload_config | ( | void | ) | [static] |
Definition at line 13469 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().
13470 { 13471 static const char config[] = "iax.conf"; 13472 struct iax2_registry *reg; 13473 13474 if (set_config(config, 1) > 0) { 13475 prune_peers(); 13476 prune_users(); 13477 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13478 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 13479 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 13480 trunk_timed = trunk_untimed = 0; 13481 trunk_nmaxmtu = trunk_maxmtu = 0; 13482 memset(&debugaddr, '\0', sizeof(debugaddr)); 13483 13484 AST_LIST_LOCK(®istrations); 13485 AST_LIST_TRAVERSE(®istrations, reg, entry) 13486 iax2_do_register(reg); 13487 AST_LIST_UNLOCK(®istrations); 13488 13489 /* Qualify hosts, too */ 13490 poke_all_peers(); 13491 } 13492 13493 reload_firmware(0); 13494 iax_provision_reload(1); 13495 ast_unload_realtime("iaxpeers"); 13496 13497 return 0; 13498 }
static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 3201 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().
03202 { 03203 struct iax_firmware *cur = NULL; 03204 DIR *fwd; 03205 struct dirent *de; 03206 char dir[256], fn[256]; 03207 03208 AST_LIST_LOCK(&firmwares); 03209 03210 /* Mark all as dead */ 03211 AST_LIST_TRAVERSE(&firmwares, cur, list) 03212 cur->dead = 1; 03213 03214 /* Now that we have marked them dead... load new ones */ 03215 if (!unload) { 03216 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 03217 fwd = opendir(dir); 03218 if (fwd) { 03219 while((de = readdir(fwd))) { 03220 if (de->d_name[0] != '.') { 03221 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 03222 if (!try_firmware(fn)) { 03223 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 03224 } 03225 } 03226 } 03227 closedir(fwd); 03228 } else 03229 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 03230 } 03231 03232 /* Clean up leftovers */ 03233 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 03234 if (!cur->dead) 03235 continue; 03236 AST_LIST_REMOVE_CURRENT(list); 03237 destroy_firmware(cur); 03238 } 03239 AST_LIST_TRAVERSE_SAFE_END; 03240 03241 AST_LIST_UNLOCK(&firmwares); 03242 }
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 2633 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().
02634 { 02635 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02636 02637 /* the callno_pool container is locked here primarily to ensure thread 02638 * safety of the total_nonval_callno_used check and decrement */ 02639 ao2_lock(callno_pool); 02640 02641 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02642 total_nonval_callno_used--; 02643 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02644 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02645 } 02646 02647 if (callno_entry->callno < TRUNK_CALL_START) { 02648 ao2_link(callno_pool, callno_entry); 02649 } else { 02650 ao2_link(callno_pool_trunk, callno_entry); 02651 } 02652 ao2_ref(callno_entry, -1); /* only container ref remains */ 02653 02654 ao2_unlock(callno_pool); 02655 return 0; 02656 }
static void requirecalltoken_mark_auto | ( | const char * | name, | |
int | subclass | |||
) | [static] |
Definition at line 4804 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().
04805 { 04806 struct iax2_user *user = NULL; 04807 struct iax2_peer *peer = NULL; 04808 04809 if (ast_strlen_zero(name)) { 04810 return; /* no username given */ 04811 } 04812 04813 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04814 user->calltoken_required = CALLTOKEN_YES; 04815 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04816 peer->calltoken_required = CALLTOKEN_YES; 04817 } 04818 04819 if (peer) { 04820 peer_unref(peer); 04821 } 04822 if (user) { 04823 user_unref(user); 04824 } 04825 }
static void resend_with_token | ( | int | callno, | |
struct iax_frame * | f, | |||
const char * | newtoken | |||
) | [static] |
Definition at line 4722 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().
04723 { 04724 struct chan_iax2_pvt *pvt = iaxs[callno]; 04725 int frametype = f->af.frametype; 04726 int subclass = f->af.subclass.integer; 04727 struct { 04728 struct ast_iax2_full_hdr fh; 04729 struct iax_ie_data ied; 04730 } data = { 04731 .ied.buf = { 0 }, 04732 .ied.pos = 0, 04733 }; 04734 /* total len - header len gives us the frame's IE len */ 04735 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04736 04737 if (!pvt) { 04738 return; /* this should not be possible if called from socket_process() */ 04739 } 04740 04741 /* 04742 * Check to make sure last frame sent is valid for call token resend 04743 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04744 * 2. Frame should _NOT_ already have a destination callno 04745 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04746 * 4. Pvt must have a calltoken_ie_len which represents the number of 04747 * bytes at the end of the frame used for the previous calltoken ie. 04748 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04749 * 6. Total length of f->data must be _LESS_ than size of our data struct 04750 * because f->data must be able to fit within data. 04751 */ 04752 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04753 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04754 (f->datalen > sizeof(data))) { 04755 04756 return; /* ignore resend, token was not valid for the dialog */ 04757 } 04758 04759 /* token is valid 04760 * 1. Copy frame data over 04761 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04762 * NOTE: Having the ie always be last is not protocol specified, 04763 * it is only an implementation choice. Since we only expect the ie to 04764 * be last for frames we have sent, this can no way be affected by 04765 * another end point. 04766 * 3. Remove frame from queue 04767 * 4. Free old frame 04768 * 5. Clear previous seqnos 04769 * 6. Resend with CALLTOKEN ie. 04770 */ 04771 04772 /* ---1.--- */ 04773 memcpy(&data, f->data, f->datalen); 04774 data.ied.pos = ie_data_pos; 04775 04776 /* ---2.--- */ 04777 /* move to the beginning of the calltoken ie so we can write over it */ 04778 data.ied.pos -= pvt->calltoken_ie_len; 04779 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04780 04781 /* make sure to update token length incase it ever has to be stripped off again */ 04782 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04783 04784 /* ---3.--- */ 04785 AST_LIST_REMOVE(&frame_queue[callno], f, list); 04786 04787 /* ---4.--- */ 04788 iax2_frame_free(f); 04789 04790 /* ---5.--- */ 04791 pvt->oseqno = 0; 04792 pvt->rseqno = 0; 04793 pvt->iseqno = 0; 04794 pvt->aseqno = 0; 04795 if (pvt->peercallno) { 04796 remove_by_peercallno(pvt); 04797 pvt->peercallno = 0; 04798 } 04799 04800 /* ---6.--- */ 04801 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04802 }
Definition at line 9424 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().
09425 { 09426 int i; 09427 unsigned int length, offset = 0; 09428 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09429 09430 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09431 length = ies->ospblocklength[i]; 09432 if (length != 0) { 09433 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09434 /* OSP token block length wrong, clear buffer */ 09435 offset = 0; 09436 break; 09437 } else { 09438 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09439 offset += length; 09440 } 09441 } else { 09442 break; 09443 } 09444 } 09445 *(full_osptoken + offset) = '\0'; 09446 if (strlen(full_osptoken) != offset) { 09447 /* OSP token length wrong, clear buffer */ 09448 *full_osptoken = '\0'; 09449 } 09450 09451 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09452 }
Definition at line 9413 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().
09414 { 09415 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09416 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09417 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09418 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09419 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09420 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09421 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09422 }
static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
struct callno_entry * | callno_entry | |||
) | [static] |
Definition at line 2705 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().
02706 { 02707 int i; 02708 struct peercnt *peercnt; 02709 struct peercnt tmp = { 02710 .addr = sin->sin_addr.s_addr, 02711 }; 02712 02713 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02714 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02715 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02716 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02717 if (i == -1) { 02718 ao2_ref(peercnt, -1); 02719 } 02720 } 02721 02722 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02723 }
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 4134 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().
04135 { 04136 int type, len; 04137 int ret; 04138 int needfree = 0; 04139 struct ast_channel *owner = NULL; 04140 struct ast_channel *bridge = NULL; 04141 04142 /* Attempt to recover wrapped timestamps */ 04143 unwrap_timestamp(fr); 04144 04145 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 04146 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 04147 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 04148 else { 04149 #if 0 04150 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 04151 #endif 04152 fr->af.delivery = ast_tv(0,0); 04153 } 04154 04155 type = JB_TYPE_CONTROL; 04156 len = 0; 04157 04158 if(fr->af.frametype == AST_FRAME_VOICE) { 04159 type = JB_TYPE_VOICE; 04160 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000); 04161 } else if(fr->af.frametype == AST_FRAME_CNG) { 04162 type = JB_TYPE_SILENCE; 04163 } 04164 04165 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04166 if (tsout) 04167 *tsout = fr->ts; 04168 __do_deliver(fr); 04169 return -1; 04170 } 04171 04172 iax2_lock_owner(fr->callno); 04173 if (!iaxs[fr->callno]) { 04174 /* The call dissappeared so discard this frame that we could not send. */ 04175 iax2_frame_free(fr); 04176 return -1; 04177 } 04178 if ((owner = iaxs[fr->callno]->owner)) 04179 bridge = ast_bridged_channel(owner); 04180 04181 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04182 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04183 if ( (!ast_test_flag64(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04184 jb_frame frame; 04185 04186 ast_channel_unlock(owner); 04187 04188 /* deliver any frames in the jb */ 04189 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04190 __do_deliver(frame.data); 04191 /* __do_deliver() can make the call disappear */ 04192 if (!iaxs[fr->callno]) 04193 return -1; 04194 } 04195 04196 jb_reset(iaxs[fr->callno]->jb); 04197 04198 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid); 04199 04200 /* deliver this frame now */ 04201 if (tsout) 04202 *tsout = fr->ts; 04203 __do_deliver(fr); 04204 return -1; 04205 } 04206 if (owner) { 04207 ast_channel_unlock(owner); 04208 } 04209 04210 /* insert into jitterbuffer */ 04211 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04212 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04213 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04214 if (ret == JB_DROP) { 04215 needfree++; 04216 } else if (ret == JB_SCHED) { 04217 update_jbsched(iaxs[fr->callno]); 04218 } 04219 if (tsout) 04220 *tsout = fr->ts; 04221 if (needfree) { 04222 /* Free our iax frame */ 04223 iax2_frame_free(fr); 04224 return -1; 04225 } 04226 return 0; 04227 }
static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1805 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().
01806 { 01807 unsigned short callno = PTR_TO_CALLNO(vid); 01808 ast_mutex_lock(&iaxsl[callno]); 01809 if (iaxs[callno]) { 01810 if (option_debug) { 01811 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01812 } 01813 iax2_destroy(callno); 01814 } 01815 ast_mutex_unlock(&iaxsl[callno]); 01816 return 0; 01817 }
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 4686 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().
04689 { 04690 struct { 04691 struct ast_iax2_full_hdr f; 04692 struct iax_ie_data ied; 04693 } data; 04694 size_t size = sizeof(struct ast_iax2_full_hdr); 04695 04696 if (ied) { 04697 size += ied->pos; 04698 memcpy(&data.ied, ied->buf, ied->pos); 04699 } 04700 04701 data.f.scallno = htons(0x8000 | callno); 04702 data.f.dcallno = htons(dcallno); 04703 data.f.ts = htonl(ts); 04704 data.f.iseqno = seqno; 04705 data.f.oseqno = 0; 04706 data.f.type = AST_FRAME_IAX; 04707 data.f.csub = compress_subclass(command); 04708 04709 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04710 }
static int send_command | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7461 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().
07462 { 07463 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07464 }
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 7480 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().
07481 { 07482 int call_num = i->callno; 07483 /* It is assumed that the callno has already been locked */ 07484 iax2_predestroy(i->callno); 07485 if (!iaxs[call_num]) 07486 return -1; 07487 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07488 }
static int send_command_immediate | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7490 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07491 { 07492 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07493 }
static int send_command_locked | ( | unsigned short | callno, | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | , | |||
int | ||||
) | [static] |
Definition at line 7466 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().
07467 { 07468 int res; 07469 ast_mutex_lock(&iaxsl[callno]); 07470 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07471 ast_mutex_unlock(&iaxsl[callno]); 07472 return res; 07473 }
static int send_command_transfer | ( | struct chan_iax2_pvt * | , | |
char | , | |||
int | , | |||
unsigned | int, | |||
const unsigned char * | , | |||
int | ||||
) | [static] |
Definition at line 7495 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07496 { 07497 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07498 }
static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1591 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().
01592 { 01593 int callno = (long) data; 01594 ast_mutex_lock(&iaxsl[callno]); 01595 if (iaxs[callno] && iaxs[callno]->lagid != DONT_RESCHEDULE) { 01596 iaxs[callno]->lagid = -1; 01597 } 01598 ast_mutex_unlock(&iaxsl[callno]); 01599 01600 #ifdef SCHED_MULTITHREADED 01601 if (schedule_action(__send_lagrq, data)) 01602 #endif 01603 __send_lagrq(data); 01604 return 0; 01605 }
static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3314 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().
03315 { 03316 int res; 03317 int callno = f->callno; 03318 03319 /* Don't send if there was an error, but return error instead */ 03320 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03321 return -1; 03322 03323 /* Called with iaxsl held */ 03324 if (iaxdebug) 03325 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)); 03326 03327 if (f->transfer) { 03328 if (iaxdebug) 03329 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03330 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03331 } else { 03332 if (iaxdebug) 03333 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03334 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03335 } 03336 if (res < 0) { 03337 if (iaxdebug) 03338 ast_debug(1, "Received error: %s\n", strerror(errno)); 03339 handle_error(); 03340 } else 03341 res = 0; 03342 03343 return res; 03344 }
static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1524 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().
01525 { 01526 int callno = (long) data; 01527 ast_mutex_lock(&iaxsl[callno]); 01528 if (iaxs[callno] && iaxs[callno]->pingid != DONT_RESCHEDULE) { 01529 iaxs[callno]->pingid = -1; 01530 } 01531 ast_mutex_unlock(&iaxsl[callno]); 01532 01533 #ifdef SCHED_MULTITHREADED 01534 if (schedule_action(__send_ping, data)) 01535 #endif 01536 __send_ping(data); 01537 01538 return 0; 01539 }
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 9080 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().
09081 { 09082 int res = 0; 09083 struct iax_frame *fr; 09084 struct ast_iax2_meta_hdr *meta; 09085 struct ast_iax2_meta_trunk_hdr *mth; 09086 int calls = 0; 09087 09088 /* Point to frame */ 09089 fr = (struct iax_frame *)tpeer->trunkdata; 09090 /* Point to meta data */ 09091 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 09092 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 09093 if (tpeer->trunkdatalen) { 09094 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 09095 meta->zeros = 0; 09096 meta->metacmd = IAX_META_TRUNK; 09097 if (ast_test_flag64(&globalflags, IAX_TRUNKTIMESTAMPS)) 09098 meta->cmddata = IAX_META_TRUNK_MINI; 09099 else 09100 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 09101 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 09102 /* And the rest of the ast_iax2 header */ 09103 fr->direction = DIRECTION_OUTGRESS; 09104 fr->retrans = -1; 09105 fr->transfer = 0; 09106 /* Any appropriate call will do */ 09107 fr->data = fr->afdata; 09108 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 09109 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 09110 calls = tpeer->calls; 09111 #if 0 09112 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)); 09113 #endif 09114 /* Reset transmit trunk side data */ 09115 tpeer->trunkdatalen = 0; 09116 tpeer->calls = 0; 09117 } 09118 if (res < 0) 09119 return res; 09120 return calls; 09121 }
static int set_config | ( | const char * | config_file, | |
int | reload | |||
) | [static] |
Load configuration.
Definition at line 12986 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().
12987 { 12988 struct ast_config *cfg, *ucfg; 12989 format_t capability = iax2_capability; 12990 struct ast_variable *v; 12991 char *cat; 12992 const char *utype; 12993 const char *tosval; 12994 int format; 12995 int portno = IAX_DEFAULT_PORTNO; 12996 int x; 12997 int mtuv; 12998 int subscribe_network_change = 1; 12999 struct iax2_user *user; 13000 struct iax2_peer *peer; 13001 struct ast_netsock *ns; 13002 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 13003 #if 0 13004 static unsigned short int last_port=0; 13005 #endif 13006 13007 cfg = ast_config_load(config_file, config_flags); 13008 13009 if (!cfg) { 13010 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 13011 return -1; 13012 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 13013 ucfg = ast_config_load("users.conf", config_flags); 13014 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 13015 return 0; 13016 /* Otherwise we need to reread both files */ 13017 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13018 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 13019 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13020 ast_config_destroy(ucfg); 13021 return 0; 13022 } 13023 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 13024 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 13025 return 0; 13026 } else { /* iax.conf changed, gotta reread users.conf, too */ 13027 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 13028 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 13029 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 13030 ast_config_destroy(cfg); 13031 return 0; 13032 } 13033 } 13034 13035 if (reload) { 13036 set_config_destroy(); 13037 } 13038 13039 /* Reset global codec prefs */ 13040 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 13041 13042 /* Reset Global Flags */ 13043 memset(&globalflags, 0, sizeof(globalflags)); 13044 ast_set_flag64(&globalflags, IAX_RTUPDATE); 13045 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13046 13047 #ifdef SO_NO_CHECK 13048 nochecksums = 0; 13049 #endif 13050 /* Reset default parking lot */ 13051 default_parkinglot[0] = '\0'; 13052 13053 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13054 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 13055 global_max_trunk_mtu = MAX_TRUNK_MTU; 13056 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 13057 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 13058 13059 maxauthreq = 3; 13060 13061 srvlookup = 0; 13062 13063 v = ast_variable_browse(cfg, "general"); 13064 13065 /* Seed initial tos value */ 13066 tosval = ast_variable_retrieve(cfg, "general", "tos"); 13067 if (tosval) { 13068 if (ast_str2tos(tosval, &qos.tos)) 13069 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 13070 } 13071 /* Seed initial cos value */ 13072 tosval = ast_variable_retrieve(cfg, "general", "cos"); 13073 if (tosval) { 13074 if (ast_str2cos(tosval, &qos.cos)) 13075 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 13076 } 13077 while(v) { 13078 if (!strcasecmp(v->name, "bindport")){ 13079 if (reload) 13080 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 13081 else 13082 portno = atoi(v->value); 13083 } else if (!strcasecmp(v->name, "pingtime")) 13084 ping_time = atoi(v->value); 13085 else if (!strcasecmp(v->name, "iaxthreadcount")) { 13086 if (reload) { 13087 if (atoi(v->value) != iaxthreadcount) 13088 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 13089 } else { 13090 iaxthreadcount = atoi(v->value); 13091 if (iaxthreadcount < 1) { 13092 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 13093 iaxthreadcount = 1; 13094 } else if (iaxthreadcount > 256) { 13095 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 13096 iaxthreadcount = 256; 13097 } 13098 } 13099 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 13100 if (reload) { 13101 AST_LIST_LOCK(&dynamic_list); 13102 iaxmaxthreadcount = atoi(v->value); 13103 AST_LIST_UNLOCK(&dynamic_list); 13104 } else { 13105 iaxmaxthreadcount = atoi(v->value); 13106 if (iaxmaxthreadcount < 0) { 13107 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 13108 iaxmaxthreadcount = 0; 13109 } else if (iaxmaxthreadcount > 256) { 13110 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 13111 iaxmaxthreadcount = 256; 13112 } 13113 } 13114 } else if (!strcasecmp(v->name, "nochecksums")) { 13115 #ifdef SO_NO_CHECK 13116 if (ast_true(v->value)) 13117 nochecksums = 1; 13118 else 13119 nochecksums = 0; 13120 #else 13121 if (ast_true(v->value)) 13122 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 13123 #endif 13124 } 13125 else if (!strcasecmp(v->name, "maxjitterbuffer")) 13126 maxjitterbuffer = atoi(v->value); 13127 else if (!strcasecmp(v->name, "resyncthreshold")) 13128 resyncthreshold = atoi(v->value); 13129 else if (!strcasecmp(v->name, "maxjitterinterps")) 13130 maxjitterinterps = atoi(v->value); 13131 else if (!strcasecmp(v->name, "jittertargetextra")) 13132 jittertargetextra = atoi(v->value); 13133 else if (!strcasecmp(v->name, "lagrqtime")) 13134 lagrq_time = atoi(v->value); 13135 else if (!strcasecmp(v->name, "maxregexpire")) 13136 max_reg_expire = atoi(v->value); 13137 else if (!strcasecmp(v->name, "minregexpire")) 13138 min_reg_expire = atoi(v->value); 13139 else if (!strcasecmp(v->name, "bindaddr")) { 13140 if (reload) { 13141 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 13142 } else { 13143 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 13144 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 13145 } else { 13146 if (strchr(v->value, ':')) 13147 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 13148 else 13149 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 13150 if (defaultsockfd < 0) 13151 defaultsockfd = ast_netsock_sockfd(ns); 13152 ast_netsock_unref(ns); 13153 } 13154 } 13155 } else if (!strcasecmp(v->name, "authdebug")) { 13156 authdebug = ast_true(v->value); 13157 } else if (!strcasecmp(v->name, "encryption")) { 13158 iax2_encryption |= get_encrypt_methods(v->value); 13159 if (!iax2_encryption) { 13160 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13161 } 13162 } else if (!strcasecmp(v->name, "forceencryption")) { 13163 if (ast_false(v->value)) { 13164 ast_clear_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13165 } else { 13166 iax2_encryption |= get_encrypt_methods(v->value); 13167 if (iax2_encryption) { 13168 ast_set_flag64((&globalflags), IAX_FORCE_ENCRYPT); 13169 } 13170 } 13171 } else if (!strcasecmp(v->name, "transfer")) { 13172 if (!strcasecmp(v->value, "mediaonly")) { 13173 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 13174 } else if (ast_true(v->value)) { 13175 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 13176 } else 13177 ast_set_flags_to64((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 13178 } else if (!strcasecmp(v->name, "codecpriority")) { 13179 if(!strcasecmp(v->value, "caller")) 13180 ast_set_flag64((&globalflags), IAX_CODEC_USER_FIRST); 13181 else if(!strcasecmp(v->value, "disabled")) 13182 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13183 else if(!strcasecmp(v->value, "reqonly")) { 13184 ast_set_flag64((&globalflags), IAX_CODEC_NOCAP); 13185 ast_set_flag64((&globalflags), IAX_CODEC_NOPREFS); 13186 } 13187 } else if (!strcasecmp(v->name, "jitterbuffer")) 13188 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 13189 else if (!strcasecmp(v->name, "forcejitterbuffer")) 13190 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 13191 else if (!strcasecmp(v->name, "delayreject")) 13192 delayreject = ast_true(v->value); 13193 else if (!strcasecmp(v->name, "allowfwdownload")) 13194 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 13195 else if (!strcasecmp(v->name, "rtcachefriends")) 13196 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 13197 else if (!strcasecmp(v->name, "rtignoreregexpire")) 13198 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 13199 else if (!strcasecmp(v->name, "rtupdate")) 13200 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTUPDATE); 13201 else if (!strcasecmp(v->name, "rtsavesysname")) 13202 ast_set2_flag64((&globalflags), ast_true(v->value), IAX_RTSAVE_SYSNAME); 13203 else if (!strcasecmp(v->name, "trunktimestamps")) 13204 ast_set2_flag64(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 13205 else if (!strcasecmp(v->name, "rtautoclear")) { 13206 int i = atoi(v->value); 13207 if(i > 0) 13208 global_rtautoclear = i; 13209 else 13210 i = 0; 13211 ast_set2_flag64((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 13212 } else if (!strcasecmp(v->name, "trunkfreq")) { 13213 trunkfreq = atoi(v->value); 13214 if (trunkfreq < 10) 13215 trunkfreq = 10; 13216 } else if (!strcasecmp(v->name, "trunkmtu")) { 13217 mtuv = atoi(v->value); 13218 if (mtuv == 0 ) 13219 global_max_trunk_mtu = 0; 13220 else if (mtuv >= 172 && mtuv < 4000) 13221 global_max_trunk_mtu = mtuv; 13222 else 13223 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 13224 mtuv, v->lineno); 13225 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 13226 trunkmaxsize = atoi(v->value); 13227 if (trunkmaxsize == 0) 13228 trunkmaxsize = MAX_TRUNKDATA; 13229 } else if (!strcasecmp(v->name, "autokill")) { 13230 if (sscanf(v->value, "%30d", &x) == 1) { 13231 if (x >= 0) 13232 autokill = x; 13233 else 13234 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 13235 } else if (ast_true(v->value)) { 13236 autokill = DEFAULT_MAXMS; 13237 } else { 13238 autokill = 0; 13239 } 13240 } else if (!strcasecmp(v->name, "bandwidth")) { 13241 if (!strcasecmp(v->value, "low")) { 13242 capability = IAX_CAPABILITY_LOWBANDWIDTH; 13243 } else if (!strcasecmp(v->value, "medium")) { 13244 capability = IAX_CAPABILITY_MEDBANDWIDTH; 13245 } else if (!strcasecmp(v->value, "high")) { 13246 capability = IAX_CAPABILITY_FULLBANDWIDTH; 13247 } else 13248 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 13249 } else if (!strcasecmp(v->name, "allow")) { 13250 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 13251 } else if (!strcasecmp(v->name, "disallow")) { 13252 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 13253 } else if (!strcasecmp(v->name, "register")) { 13254 iax2_register(v->value, v->lineno); 13255 } else if (!strcasecmp(v->name, "iaxcompat")) { 13256 iaxcompat = ast_true(v->value); 13257 } else if (!strcasecmp(v->name, "regcontext")) { 13258 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 13259 /* Create context if it doesn't exist already */ 13260 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 13261 } else if (!strcasecmp(v->name, "tos")) { 13262 if (ast_str2tos(v->value, &qos.tos)) 13263 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 13264 } else if (!strcasecmp(v->name, "cos")) { 13265 if (ast_str2cos(v->value, &qos.cos)) 13266 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 13267 } else if (!strcasecmp(v->name, "parkinglot")) { 13268 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 13269 } else if (!strcasecmp(v->name, "accountcode")) { 13270 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 13271 } else if (!strcasecmp(v->name, "mohinterpret")) { 13272 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 13273 } else if (!strcasecmp(v->name, "mohsuggest")) { 13274 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 13275 } else if (!strcasecmp(v->name, "amaflags")) { 13276 format = ast_cdr_amaflags2int(v->value); 13277 if (format < 0) { 13278 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 13279 } else { 13280 amaflags = format; 13281 } 13282 } else if (!strcasecmp(v->name, "language")) { 13283 ast_copy_string(language, v->value, sizeof(language)); 13284 } else if (!strcasecmp(v->name, "maxauthreq")) { 13285 maxauthreq = atoi(v->value); 13286 if (maxauthreq < 0) 13287 maxauthreq = 0; 13288 } else if (!strcasecmp(v->name, "adsi")) { 13289 adsi = ast_true(v->value); 13290 } else if (!strcasecmp(v->name, "srvlookup")) { 13291 srvlookup = ast_true(v->value); 13292 } else if (!strcasecmp(v->name, "connectedline")) { 13293 if (ast_true(v->value)) { 13294 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13295 } else if (!strcasecmp(v->value, "send")) { 13296 ast_clear_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13297 ast_set_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13298 } else if (!strcasecmp(v->value, "receive")) { 13299 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE); 13300 ast_set_flag64((&globalflags), IAX_RECVCONNECTEDLINE); 13301 } else { 13302 ast_clear_flag64((&globalflags), IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 13303 } 13304 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 13305 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 13306 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 13307 } 13308 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 13309 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 13310 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); 13311 } 13312 } else if (!strcasecmp(v->name, "calltokenoptional")) { 13313 if (add_calltoken_ignore(v->value)) { 13314 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 13315 } 13316 } else if (!strcasecmp(v->name, "subscribe_network_change_event")) { 13317 if (ast_true(v->value)) { 13318 subscribe_network_change = 1; 13319 } else if (ast_false(v->value)) { 13320 subscribe_network_change = 0; 13321 } else { 13322 ast_log(LOG_WARNING, "subscribe_network_change_event value %s is not valid at line %d.\n", v->value, v->lineno); 13323 } 13324 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 13325 if (ast_true(v->value)) { 13326 ast_set_flag64((&globalflags), IAX_SHRINKCALLERID); 13327 } else if (ast_false(v->value)) { 13328 ast_clear_flag64((&globalflags), IAX_SHRINKCALLERID); 13329 } else { 13330 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 13331 } 13332 }/*else if (strcasecmp(v->name,"type")) */ 13333 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 13334 v = v->next; 13335 } 13336 13337 if (subscribe_network_change) { 13338 network_change_event_subscribe(); 13339 } else { 13340 network_change_event_unsubscribe(); 13341 } 13342 13343 if (defaultsockfd < 0) { 13344 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 13345 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 13346 } else { 13347 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 13348 defaultsockfd = ast_netsock_sockfd(ns); 13349 ast_netsock_unref(ns); 13350 } 13351 } 13352 if (reload) { 13353 ast_netsock_release(outsock); 13354 outsock = ast_netsock_list_alloc(); 13355 if (!outsock) { 13356 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13357 return -1; 13358 } 13359 ast_netsock_init(outsock); 13360 } 13361 13362 if (min_reg_expire > max_reg_expire) { 13363 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 13364 min_reg_expire, max_reg_expire, max_reg_expire); 13365 min_reg_expire = max_reg_expire; 13366 } 13367 iax2_capability = capability; 13368 13369 if (ucfg) { 13370 struct ast_variable *gen; 13371 int genhasiax; 13372 int genregisteriax; 13373 const char *hasiax, *registeriax; 13374 13375 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 13376 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 13377 gen = ast_variable_browse(ucfg, "general"); 13378 cat = ast_category_browse(ucfg, NULL); 13379 while (cat) { 13380 if (strcasecmp(cat, "general")) { 13381 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 13382 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 13383 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 13384 /* Start with general parameters, then specific parameters, user and peer */ 13385 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 13386 if (user) { 13387 ao2_link(users, user); 13388 user = user_unref(user); 13389 } 13390 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 13391 if (peer) { 13392 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13393 reg_source_db(peer); 13394 ao2_link(peers, peer); 13395 peer = peer_unref(peer); 13396 } 13397 } 13398 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 13399 char tmp[256]; 13400 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 13401 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 13402 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 13403 if (!host) 13404 host = ast_variable_retrieve(ucfg, "general", "host"); 13405 if (!username) 13406 username = ast_variable_retrieve(ucfg, "general", "username"); 13407 if (!secret) 13408 secret = ast_variable_retrieve(ucfg, "general", "secret"); 13409 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 13410 if (!ast_strlen_zero(secret)) 13411 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 13412 else 13413 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 13414 iax2_register(tmp, 0); 13415 } 13416 } 13417 } 13418 cat = ast_category_browse(ucfg, cat); 13419 } 13420 ast_config_destroy(ucfg); 13421 } 13422 13423 cat = ast_category_browse(cfg, NULL); 13424 while(cat) { 13425 if (strcasecmp(cat, "general")) { 13426 utype = ast_variable_retrieve(cfg, cat, "type"); 13427 if (!strcasecmp(cat, "callnumberlimits")) { 13428 build_callno_limits(ast_variable_browse(cfg, cat)); 13429 } else if (utype) { 13430 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 13431 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 13432 if (user) { 13433 ao2_link(users, user); 13434 user = user_unref(user); 13435 } 13436 } 13437 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 13438 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 13439 if (peer) { 13440 if (ast_test_flag64(peer, IAX_DYNAMIC)) 13441 reg_source_db(peer); 13442 ao2_link(peers, peer); 13443 peer = peer_unref(peer); 13444 } 13445 } else if (strcasecmp(utype, "user")) { 13446 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 13447 } 13448 } else 13449 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 13450 } 13451 cat = ast_category_browse(cfg, cat); 13452 } 13453 ast_config_destroy(cfg); 13454 return 1; 13455 }
static void set_config_destroy | ( | void | ) | [static] |
Definition at line 12969 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().
12970 { 12971 strcpy(accountcode, ""); 12972 strcpy(language, ""); 12973 strcpy(mohinterpret, "default"); 12974 strcpy(mohsuggest, ""); 12975 trunkmaxsize = MAX_TRUNKDATA; 12976 amaflags = 0; 12977 delayreject = 0; 12978 ast_clear_flag64((&globalflags), IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | 12979 IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE); 12980 delete_users(); 12981 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 12982 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 12983 }
static void set_hangup_source_and_cause | ( | int | callno, | |
unsigned char | causecode | |||
) | [static] |
Definition at line 9849 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().
09850 { 09851 iax2_lock_owner(callno); 09852 if (iaxs[callno] && iaxs[callno]->owner) { 09853 if (causecode) { 09854 iaxs[callno]->owner->hangupcause = causecode; 09855 } 09856 ast_set_hangupsource(iaxs[callno]->owner, iaxs[callno]->owner->name, 0); 09857 ast_channel_unlock(iaxs[callno]->owner); 09858 } 09859 }
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 1048 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().
01049 { 01050 ast_mutex_lock(lock); 01051 ast_cond_signal(cond); 01052 ast_mutex_unlock(lock); 01053 }
static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 9861 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_ref, ast_channel_unlock, ast_channel_unref, ast_clear_flag, ast_clear_flag64, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), ast_connected_line_parse_data(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_UNHOLD, ast_datastore_alloc, ast_datastore_free(), ast_debug, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNAVAILABLE, ast_devstate_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(), 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().
09862 { 09863 struct sockaddr_in sin; 09864 int res; 09865 int updatehistory=1; 09866 int new = NEW_PREVENT; 09867 int dcallno = 0; 09868 char decrypted = 0; 09869 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09870 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09871 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09872 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09873 struct iax_frame *fr; 09874 struct iax_frame *cur; 09875 struct ast_frame f = { 0, }; 09876 struct ast_channel *c = NULL; 09877 struct iax2_dpcache *dp; 09878 struct iax2_peer *peer; 09879 struct iax_ies ies; 09880 struct iax_ie_data ied0, ied1; 09881 format_t format; 09882 int fd; 09883 int exists; 09884 int minivid = 0; 09885 char empty[32]=""; /* Safety measure */ 09886 struct iax_frame *duped_fr; 09887 char host_pref_buf[128]; 09888 char caller_pref_buf[128]; 09889 struct ast_codec_pref pref; 09890 char *using_prefs = "mine"; 09891 09892 /* allocate an iax_frame with 4096 bytes of data buffer */ 09893 fr = alloca(sizeof(*fr) + 4096); 09894 memset(fr, 0, sizeof(*fr)); 09895 fr->afdatalen = 4096; /* From alloca() above */ 09896 09897 /* Copy frequently used parameters to the stack */ 09898 res = thread->buf_len; 09899 fd = thread->iofd; 09900 memcpy(&sin, &thread->iosin, sizeof(sin)); 09901 09902 if (res < sizeof(*mh)) { 09903 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09904 return 1; 09905 } 09906 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09907 if (res < sizeof(*vh)) { 09908 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)); 09909 return 1; 09910 } 09911 09912 /* This is a video frame, get call number */ 09913 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 09914 minivid = 1; 09915 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 09916 return socket_process_meta(res, meta, &sin, fd, fr); 09917 09918 #ifdef DEBUG_SUPPORT 09919 if (res >= sizeof(*fh)) 09920 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 09921 #endif 09922 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09923 if (res < sizeof(*fh)) { 09924 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)); 09925 return 1; 09926 } 09927 09928 /* Get the destination call number */ 09929 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 09930 09931 09932 /* check to make sure this full frame isn't encrypted before we attempt 09933 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 09934 * callno is not found here, that just means one hasn't been allocated for 09935 * this connection yet. */ 09936 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 09937 ast_mutex_lock(&iaxsl[fr->callno]); 09938 if (iaxs[fr->callno] && ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED)) { 09939 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09940 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09941 ast_mutex_unlock(&iaxsl[fr->callno]); 09942 return 1; 09943 } 09944 decrypted = 1; 09945 } 09946 ast_mutex_unlock(&iaxsl[fr->callno]); 09947 } 09948 09949 /* Retrieve the type and subclass */ 09950 f.frametype = fh->type; 09951 if (f.frametype == AST_FRAME_VIDEO) { 09952 f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 09953 } else if (f.frametype == AST_FRAME_VOICE) { 09954 f.subclass.codec = uncompress_subclass(fh->csub); 09955 } else { 09956 f.subclass.integer = uncompress_subclass(fh->csub); 09957 } 09958 09959 /* Deal with POKE/PONG without allocating a callno */ 09960 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_POKE) { 09961 /* Reply back with a PONG, but don't care about the result. */ 09962 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09963 return 1; 09964 } else if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_ACK && dcallno == 1) { 09965 /* Ignore */ 09966 return 1; 09967 } 09968 09969 f.datalen = res - sizeof(*fh); 09970 if (f.datalen) { 09971 if (f.frametype == AST_FRAME_IAX) { 09972 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 09973 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 09974 ast_variables_destroy(ies.vars); 09975 return 1; 09976 } 09977 f.data.ptr = NULL; 09978 f.datalen = 0; 09979 } else { 09980 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 09981 memset(&ies, 0, sizeof(ies)); 09982 } 09983 } else { 09984 if (f.frametype == AST_FRAME_IAX) 09985 f.data.ptr = NULL; 09986 else 09987 f.data.ptr = empty; 09988 memset(&ies, 0, sizeof(ies)); 09989 } 09990 09991 if (!dcallno && iax2_allow_new(f.frametype, f.subclass.integer, 1)) { 09992 /* only set NEW_ALLOW if calltoken checks out */ 09993 if (handle_call_token(fh, &ies, &sin, fd)) { 09994 ast_variables_destroy(ies.vars); 09995 return 1; 09996 } 09997 09998 if (ies.calltoken && ies.calltokendata) { 09999 /* if we've gotten this far, and the calltoken ie data exists, 10000 * then calltoken validation _MUST_ have taken place. If calltoken 10001 * data is provided, it is always validated reguardless of any 10002 * calltokenoptional or requirecalltoken options */ 10003 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 10004 } else { 10005 new = NEW_ALLOW; 10006 } 10007 } 10008 } else { 10009 /* Don't know anything about it yet */ 10010 f.frametype = AST_FRAME_NULL; 10011 f.subclass.integer = 0; 10012 memset(&ies, 0, sizeof(ies)); 10013 } 10014 10015 if (!fr->callno) { 10016 int check_dcallno = 0; 10017 10018 /* 10019 * We enforce accurate destination call numbers for ACKs. This forces the other 10020 * end to know the destination call number before call setup can complete. 10021 * 10022 * Discussed in the following thread: 10023 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 10024 */ 10025 10026 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer == IAX_COMMAND_ACK))) { 10027 check_dcallno = 1; 10028 } 10029 10030 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 10031 if (f.frametype == AST_FRAME_IAX && f.subclass.integer == IAX_COMMAND_NEW) { 10032 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10033 } else if (f.frametype == AST_FRAME_IAX && (f.subclass.integer == IAX_COMMAND_REGREQ || f.subclass.integer == IAX_COMMAND_REGREL)) { 10034 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 10035 } 10036 ast_variables_destroy(ies.vars); 10037 return 1; 10038 } 10039 } 10040 10041 if (fr->callno > 0) 10042 ast_mutex_lock(&iaxsl[fr->callno]); 10043 10044 if (!fr->callno || !iaxs[fr->callno]) { 10045 /* A call arrived for a nonexistent destination. Unless it's an "inval" 10046 frame, reply with an inval */ 10047 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10048 /* We can only raw hangup control frames */ 10049 if (((f.subclass.integer != IAX_COMMAND_INVAL) && 10050 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10051 (f.subclass.integer != IAX_COMMAND_TXACC) && 10052 (f.subclass.integer != IAX_COMMAND_FWDOWNL))|| 10053 (f.frametype != AST_FRAME_IAX)) 10054 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 10055 fd); 10056 } 10057 if (fr->callno > 0) 10058 ast_mutex_unlock(&iaxsl[fr->callno]); 10059 ast_variables_destroy(ies.vars); 10060 return 1; 10061 } 10062 if (ast_test_flag64(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 10063 if (decrypt_frame(fr->callno, fh, &f, &res)) { 10064 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 10065 ast_variables_destroy(ies.vars); 10066 ast_mutex_unlock(&iaxsl[fr->callno]); 10067 return 1; 10068 } 10069 decrypted = 1; 10070 } 10071 10072 #ifdef DEBUG_SUPPORT 10073 if (decrypted) { 10074 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 10075 } 10076 #endif 10077 10078 10079 /* count this frame */ 10080 iaxs[fr->callno]->frames_received++; 10081 10082 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 10083 f.subclass.integer != IAX_COMMAND_TXCNT && /* for attended transfer */ 10084 f.subclass.integer != IAX_COMMAND_TXACC) { /* for attended transfer */ 10085 unsigned short new_peercallno; 10086 10087 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 10088 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 10089 if (iaxs[fr->callno]->peercallno) { 10090 remove_by_peercallno(iaxs[fr->callno]); 10091 } 10092 iaxs[fr->callno]->peercallno = new_peercallno; 10093 store_by_peercallno(iaxs[fr->callno]); 10094 } 10095 } 10096 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 10097 if (iaxdebug) 10098 ast_debug(1, "Received packet %d, (%d, %u)\n", fh->oseqno, f.frametype, f.subclass.integer); 10099 /* Check if it's out of order (and not an ACK or INVAL) */ 10100 fr->oseqno = fh->oseqno; 10101 fr->iseqno = fh->iseqno; 10102 fr->ts = ntohl(fh->ts); 10103 #ifdef IAXTESTS 10104 if (test_resync) { 10105 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 10106 fr->ts += test_resync; 10107 } 10108 #endif /* IAXTESTS */ 10109 #if 0 10110 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 10111 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 10112 (f.subclass == IAX_COMMAND_NEW || 10113 f.subclass == IAX_COMMAND_AUTHREQ || 10114 f.subclass == IAX_COMMAND_ACCEPT || 10115 f.subclass == IAX_COMMAND_REJECT)) ) ) 10116 #endif 10117 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 10118 updatehistory = 0; 10119 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 10120 (iaxs[fr->callno]->iseqno || 10121 ((f.subclass.integer != IAX_COMMAND_TXCNT) && 10122 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10123 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10124 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10125 (f.subclass.integer != IAX_COMMAND_TXACC)) || 10126 (f.frametype != AST_FRAME_IAX))) { 10127 if ( 10128 ((f.subclass.integer != IAX_COMMAND_ACK) && 10129 (f.subclass.integer != IAX_COMMAND_INVAL) && 10130 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10131 (f.subclass.integer != IAX_COMMAND_TXREADY) && /* for attended transfer */ 10132 (f.subclass.integer != IAX_COMMAND_TXREL) && /* for attended transfer */ 10133 (f.subclass.integer != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 10134 (f.subclass.integer != IAX_COMMAND_TXACC) && 10135 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10136 (f.frametype != AST_FRAME_IAX)) { 10137 /* If it's not an ACK packet, it's out of order. */ 10138 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 10139 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass.integer); 10140 /* Check to see if we need to request retransmission, 10141 * and take sequence number wraparound into account */ 10142 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 10143 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 10144 if ((f.frametype != AST_FRAME_IAX) || 10145 ((f.subclass.integer != IAX_COMMAND_ACK) && (f.subclass.integer != IAX_COMMAND_INVAL))) { 10146 ast_debug(1, "Acking anyway\n"); 10147 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 10148 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 10149 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10150 } 10151 } else { 10152 /* Send a VNAK requesting retransmission */ 10153 iax2_vnak(fr->callno); 10154 } 10155 ast_variables_destroy(ies.vars); 10156 ast_mutex_unlock(&iaxsl[fr->callno]); 10157 return 1; 10158 } 10159 } else { 10160 /* Increment unless it's an ACK or VNAK */ 10161 if (((f.subclass.integer != IAX_COMMAND_ACK) && 10162 (f.subclass.integer != IAX_COMMAND_INVAL) && 10163 (f.subclass.integer != IAX_COMMAND_TXCNT) && 10164 (f.subclass.integer != IAX_COMMAND_TXACC) && 10165 (f.subclass.integer != IAX_COMMAND_VNAK)) || 10166 (f.frametype != AST_FRAME_IAX)) 10167 iaxs[fr->callno]->iseqno++; 10168 } 10169 /* Ensure text frames are NULL-terminated */ 10170 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 10171 if (res < thread->buf_size) 10172 thread->buf[res++] = '\0'; 10173 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 10174 thread->buf[res - 1] = '\0'; 10175 } 10176 10177 /* Handle implicit ACKing unless this is an INVAL, and only if this is 10178 from the real peer, not the transfer peer */ 10179 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10180 ((f.subclass.integer != IAX_COMMAND_INVAL) || 10181 (f.frametype != AST_FRAME_IAX))) { 10182 unsigned char x; 10183 int call_to_destroy; 10184 /* First we have to qualify that the ACKed value is within our window */ 10185 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 10186 x = fr->iseqno; 10187 else 10188 x = iaxs[fr->callno]->oseqno; 10189 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 10190 /* The acknowledgement is within our window. Time to acknowledge everything 10191 that it says to */ 10192 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 10193 /* Ack the packet with the given timestamp */ 10194 if (iaxdebug) 10195 ast_debug(1, "Cancelling transmission of packet %d\n", x); 10196 call_to_destroy = 0; 10197 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10198 /* If it's our call, and our timestamp, mark -1 retries */ 10199 if (x == cur->oseqno) { 10200 cur->retries = -1; 10201 /* Destroy call if this is the end */ 10202 if (cur->final) 10203 call_to_destroy = fr->callno; 10204 } 10205 } 10206 if (call_to_destroy) { 10207 if (iaxdebug) 10208 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 10209 ast_mutex_lock(&iaxsl[call_to_destroy]); 10210 iax2_destroy(call_to_destroy); 10211 ast_mutex_unlock(&iaxsl[call_to_destroy]); 10212 } 10213 } 10214 /* Note how much we've received acknowledgement for */ 10215 if (iaxs[fr->callno]) 10216 iaxs[fr->callno]->rseqno = fr->iseqno; 10217 else { 10218 /* Stop processing now */ 10219 ast_variables_destroy(ies.vars); 10220 ast_mutex_unlock(&iaxsl[fr->callno]); 10221 return 1; 10222 } 10223 } else { 10224 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 10225 } 10226 } 10227 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 10228 ((f.frametype != AST_FRAME_IAX) || 10229 ((f.subclass.integer != IAX_COMMAND_TXACC) && 10230 (f.subclass.integer != IAX_COMMAND_TXCNT)))) { 10231 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 10232 ast_variables_destroy(ies.vars); 10233 ast_mutex_unlock(&iaxsl[fr->callno]); 10234 return 1; 10235 } 10236 10237 /* when we receive the first full frame for a new incoming channel, 10238 it is safe to start the PBX on the channel because we have now 10239 completed a 3-way handshake with the peer */ 10240 if ((f.frametype == AST_FRAME_VOICE) || 10241 (f.frametype == AST_FRAME_VIDEO) || 10242 (f.frametype == AST_FRAME_IAX)) { 10243 if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 10244 ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10245 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL)) { 10246 ast_variables_destroy(ies.vars); 10247 ast_mutex_unlock(&iaxsl[fr->callno]); 10248 return 1; 10249 } 10250 } 10251 10252 if (ies.vars) { 10253 struct ast_datastore *variablestore = NULL; 10254 struct ast_variable *var, *prev = NULL; 10255 AST_LIST_HEAD(, ast_var_t) *varlist; 10256 10257 iax2_lock_owner(fr->callno); 10258 if (!iaxs[fr->callno]) { 10259 ast_variables_destroy(ies.vars); 10260 ast_mutex_unlock(&iaxsl[fr->callno]); 10261 return 1; 10262 } 10263 if ((c = iaxs[fr->callno]->owner)) { 10264 varlist = ast_calloc(1, sizeof(*varlist)); 10265 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10266 10267 if (variablestore && varlist) { 10268 variablestore->data = varlist; 10269 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10270 AST_LIST_HEAD_INIT(varlist); 10271 ast_debug(1, "I can haz IAX vars?\n"); 10272 for (var = ies.vars; var; var = var->next) { 10273 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10274 if (prev) { 10275 ast_free(prev); 10276 } 10277 prev = var; 10278 if (!newvar) { 10279 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10280 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10281 } else { 10282 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10283 } 10284 } 10285 if (prev) { 10286 ast_free(prev); 10287 } 10288 ies.vars = NULL; 10289 ast_channel_datastore_add(c, variablestore); 10290 } else { 10291 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10292 if (variablestore) { 10293 ast_datastore_free(variablestore); 10294 } 10295 if (varlist) { 10296 ast_free(varlist); 10297 } 10298 } 10299 ast_channel_unlock(c); 10300 } else { 10301 /* No channel yet, so transfer the variables directly over to the pvt, 10302 * for later inheritance. */ 10303 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 10304 for (var = ies.vars; var && var->next; var = var->next); 10305 if (var) { 10306 var->next = iaxs[fr->callno]->iaxvars; 10307 iaxs[fr->callno]->iaxvars = ies.vars; 10308 ies.vars = NULL; 10309 } 10310 } 10311 } 10312 10313 if (ies.vars) { 10314 ast_debug(1, "I have IAX variables, but they were not processed\n"); 10315 } 10316 } 10317 10318 /* once we receive our first IAX Full Frame that is not CallToken related, send all 10319 * queued signaling frames that were being held. */ 10320 if ((f.frametype == AST_FRAME_IAX) && (f.subclass.integer != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 10321 send_signaling(iaxs[fr->callno]); 10322 } 10323 10324 if (f.frametype == AST_FRAME_VOICE) { 10325 if (f.subclass.codec != iaxs[fr->callno]->voiceformat) { 10326 iaxs[fr->callno]->voiceformat = f.subclass.codec; 10327 ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec)); 10328 if (iaxs[fr->callno]->owner) { 10329 iax2_lock_owner(fr->callno); 10330 if (iaxs[fr->callno]) { 10331 if (iaxs[fr->callno]->owner) { 10332 format_t orignative; 10333 10334 orignative = iaxs[fr->callno]->owner->nativeformats; 10335 iaxs[fr->callno]->owner->nativeformats = f.subclass.codec; 10336 if (iaxs[fr->callno]->owner->readformat) 10337 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10338 iaxs[fr->callno]->owner->nativeformats = orignative; 10339 ast_channel_unlock(iaxs[fr->callno]->owner); 10340 } 10341 } else { 10342 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 10343 /* Free remote variables (if any) */ 10344 if (ies.vars) { 10345 ast_variables_destroy(ies.vars); 10346 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 10347 ies.vars = NULL; 10348 } 10349 ast_mutex_unlock(&iaxsl[fr->callno]); 10350 return 1; 10351 } 10352 } 10353 } 10354 } 10355 if (f.frametype == AST_FRAME_VIDEO) { 10356 if (f.subclass.codec != iaxs[fr->callno]->videoformat) { 10357 ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL)); 10358 iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL; 10359 } 10360 } 10361 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 10362 if (f.subclass.integer == AST_CONTROL_BUSY) { 10363 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 10364 } else if (f.subclass.integer == AST_CONTROL_CONGESTION) { 10365 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 10366 } 10367 } 10368 if (f.frametype == AST_FRAME_IAX) { 10369 ast_sched_thread_del(sched, iaxs[fr->callno]->initid); 10370 /* Handle the IAX pseudo frame itself */ 10371 if (iaxdebug) 10372 ast_debug(1, "IAX subclass %d received\n", f.subclass.integer); 10373 10374 /* Update last ts unless the frame's timestamp originated with us. */ 10375 if (iaxs[fr->callno]->last < fr->ts && 10376 f.subclass.integer != IAX_COMMAND_ACK && 10377 f.subclass.integer != IAX_COMMAND_PONG && 10378 f.subclass.integer != IAX_COMMAND_LAGRP) { 10379 iaxs[fr->callno]->last = fr->ts; 10380 if (iaxdebug) 10381 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10382 } 10383 iaxs[fr->callno]->last_iax_message = f.subclass.integer; 10384 if (!iaxs[fr->callno]->first_iax_message) { 10385 iaxs[fr->callno]->first_iax_message = f.subclass.integer; 10386 } 10387 switch(f.subclass.integer) { 10388 case IAX_COMMAND_ACK: 10389 /* Do nothing */ 10390 break; 10391 case IAX_COMMAND_QUELCH: 10392 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10393 /* Generate Manager Hold event, if necessary*/ 10394 if (iaxs[fr->callno]->owner) { 10395 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10396 "Status: On\r\n" 10397 "Channel: %s\r\n" 10398 "Uniqueid: %s\r\n", 10399 iaxs[fr->callno]->owner->name, 10400 iaxs[fr->callno]->owner->uniqueid); 10401 } 10402 10403 ast_set_flag64(iaxs[fr->callno], IAX_QUELCH); 10404 if (ies.musiconhold) { 10405 iax2_lock_owner(fr->callno); 10406 if (!iaxs[fr->callno] || !iaxs[fr->callno]->owner) { 10407 break; 10408 } 10409 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10410 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 10411 10412 /* 10413 * We already hold the owner lock so we do not 10414 * need to check iaxs[fr->callno] after it returns. 10415 */ 10416 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 10417 S_OR(moh_suggest, NULL), 10418 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 10419 } 10420 ast_channel_unlock(iaxs[fr->callno]->owner); 10421 } 10422 } 10423 break; 10424 case IAX_COMMAND_UNQUELCH: 10425 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10426 iax2_lock_owner(fr->callno); 10427 if (!iaxs[fr->callno]) { 10428 break; 10429 } 10430 /* Generate Manager Unhold event, if necessary */ 10431 if (iaxs[fr->callno]->owner && ast_test_flag64(iaxs[fr->callno], IAX_QUELCH)) { 10432 ast_manager_event(iaxs[fr->callno]->owner, EVENT_FLAG_CALL, "Hold", 10433 "Status: Off\r\n" 10434 "Channel: %s\r\n" 10435 "Uniqueid: %s\r\n", 10436 iaxs[fr->callno]->owner->name, 10437 iaxs[fr->callno]->owner->uniqueid); 10438 } 10439 10440 ast_clear_flag64(iaxs[fr->callno], IAX_QUELCH); 10441 if (!iaxs[fr->callno]->owner) { 10442 break; 10443 } 10444 if (ast_bridged_channel(iaxs[fr->callno]->owner)) { 10445 /* 10446 * We already hold the owner lock so we do not 10447 * need to check iaxs[fr->callno] after it returns. 10448 */ 10449 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10450 } 10451 ast_channel_unlock(iaxs[fr->callno]->owner); 10452 } 10453 break; 10454 case IAX_COMMAND_TXACC: 10455 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10456 /* Ack the packet with the given timestamp */ 10457 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 10458 /* Cancel any outstanding txcnt's */ 10459 if (cur->transfer) { 10460 cur->retries = -1; 10461 } 10462 } 10463 memset(&ied1, 0, sizeof(ied1)); 10464 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10465 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10466 iaxs[fr->callno]->transferring = TRANSFER_READY; 10467 } 10468 break; 10469 case IAX_COMMAND_NEW: 10470 /* Ignore if it's already up */ 10471 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10472 break; 10473 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10474 ast_mutex_unlock(&iaxsl[fr->callno]); 10475 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10476 ast_mutex_lock(&iaxsl[fr->callno]); 10477 if (!iaxs[fr->callno]) { 10478 break; 10479 } 10480 } 10481 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10482 if (ast_test_flag64(iaxs[fr->callno], IAX_TRUNK)) { 10483 int new_callno; 10484 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10485 fr->callno = new_callno; 10486 } 10487 /* For security, always ack immediately */ 10488 if (delayreject) 10489 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10490 if (check_access(fr->callno, &sin, &ies)) { 10491 /* They're not allowed on */ 10492 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10493 if (authdebug) 10494 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); 10495 break; 10496 } 10497 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag64(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10498 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10499 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10500 break; 10501 } 10502 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10503 const char *context, *exten, *cid_num; 10504 10505 context = ast_strdupa(iaxs[fr->callno]->context); 10506 exten = ast_strdupa(iaxs[fr->callno]->exten); 10507 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10508 10509 /* This might re-enter the IAX code and need the lock */ 10510 ast_mutex_unlock(&iaxsl[fr->callno]); 10511 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10512 ast_mutex_lock(&iaxsl[fr->callno]); 10513 10514 if (!iaxs[fr->callno]) { 10515 break; 10516 } 10517 } else 10518 exists = 0; 10519 /* Get OSP token if it does exist */ 10520 save_osptoken(fr, &ies); 10521 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10522 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10523 memset(&ied0, 0, sizeof(ied0)); 10524 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10525 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10526 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10527 if (!iaxs[fr->callno]) { 10528 break; 10529 } 10530 if (authdebug) 10531 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); 10532 } else { 10533 /* Select an appropriate format */ 10534 10535 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10536 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10537 using_prefs = "reqonly"; 10538 } else { 10539 using_prefs = "disabled"; 10540 } 10541 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10542 memset(&pref, 0, sizeof(pref)); 10543 strcpy(caller_pref_buf, "disabled"); 10544 strcpy(host_pref_buf, "disabled"); 10545 } else { 10546 using_prefs = "mine"; 10547 /* If the information elements are in here... use them */ 10548 if (ies.codec_prefs) 10549 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10550 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10551 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10552 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10553 pref = iaxs[fr->callno]->rprefs; 10554 using_prefs = "caller"; 10555 } else { 10556 pref = iaxs[fr->callno]->prefs; 10557 } 10558 } else 10559 pref = iaxs[fr->callno]->prefs; 10560 10561 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10562 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10563 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10564 } 10565 if (!format) { 10566 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10567 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10568 if (!format) { 10569 memset(&ied0, 0, sizeof(ied0)); 10570 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10571 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10572 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10573 if (!iaxs[fr->callno]) { 10574 break; 10575 } 10576 if (authdebug) { 10577 char tmp[256], tmp2[256], tmp3[256]; 10578 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10579 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 10580 ast_inet_ntoa(sin.sin_addr), 10581 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10582 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10583 } else { 10584 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10585 ast_inet_ntoa(sin.sin_addr), 10586 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10587 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10588 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10589 } 10590 } 10591 } else { 10592 /* Pick one... */ 10593 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10594 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10595 format = 0; 10596 } else { 10597 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10598 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10599 memset(&pref, 0, sizeof(pref)); 10600 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10601 strcpy(caller_pref_buf,"disabled"); 10602 strcpy(host_pref_buf,"disabled"); 10603 } else { 10604 using_prefs = "mine"; 10605 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10606 /* Do the opposite of what we tried above. */ 10607 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10608 pref = iaxs[fr->callno]->prefs; 10609 } else { 10610 pref = iaxs[fr->callno]->rprefs; 10611 using_prefs = "caller"; 10612 } 10613 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10614 } else /* if no codec_prefs IE do it the old way */ 10615 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10616 } 10617 } 10618 10619 if (!format) { 10620 char tmp[256], tmp2[256], tmp3[256]; 10621 memset(&ied0, 0, sizeof(ied0)); 10622 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10623 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10624 ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 10625 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10626 if (!iaxs[fr->callno]) { 10627 break; 10628 } 10629 if (authdebug) { 10630 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 10631 ast_inet_ntoa(sin.sin_addr), 10632 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat), 10633 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 10634 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 10635 } 10636 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10637 break; 10638 } 10639 } 10640 } 10641 if (format) { 10642 /* No authentication required, let them in */ 10643 memset(&ied1, 0, sizeof(ied1)); 10644 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10645 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 10646 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10647 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10648 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10649 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10650 "%srequested format = %s,\n" 10651 "%srequested prefs = %s,\n" 10652 "%sactual format = %s,\n" 10653 "%shost prefs = %s,\n" 10654 "%spriority = %s\n", 10655 ast_inet_ntoa(sin.sin_addr), 10656 VERBOSE_PREFIX_4, 10657 ast_getformatname(iaxs[fr->callno]->peerformat), 10658 VERBOSE_PREFIX_4, 10659 caller_pref_buf, 10660 VERBOSE_PREFIX_4, 10661 ast_getformatname(format), 10662 VERBOSE_PREFIX_4, 10663 host_pref_buf, 10664 VERBOSE_PREFIX_4, 10665 using_prefs); 10666 10667 iaxs[fr->callno]->chosenformat = format; 10668 ast_set_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART); 10669 } else { 10670 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10671 /* If this is a TBD call, we're ready but now what... */ 10672 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10673 } 10674 } 10675 } 10676 break; 10677 } 10678 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10679 merge_encryption(iaxs[fr->callno],ies.encmethods); 10680 else 10681 iaxs[fr->callno]->encmethods = 0; 10682 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10683 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10684 break; 10685 case IAX_COMMAND_DPREQ: 10686 /* Request status in the dialplan */ 10687 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10688 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10689 if (iaxcompat) { 10690 /* Spawn a thread for the lookup */ 10691 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10692 } else { 10693 /* Just look it up */ 10694 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10695 } 10696 } 10697 break; 10698 case IAX_COMMAND_HANGUP: 10699 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 10700 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10701 /* Set hangup cause according to remote and hangupsource */ 10702 if (iaxs[fr->callno]->owner) { 10703 set_hangup_source_and_cause(fr->callno, ies.causecode); 10704 if (!iaxs[fr->callno]) { 10705 break; 10706 } 10707 } 10708 10709 /* Send ack immediately, before we destroy */ 10710 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10711 iax2_destroy(fr->callno); 10712 break; 10713 case IAX_COMMAND_REJECT: 10714 /* Set hangup cause according to remote and hangup source */ 10715 if (iaxs[fr->callno]->owner) { 10716 set_hangup_source_and_cause(fr->callno, ies.causecode); 10717 if (!iaxs[fr->callno]) { 10718 break; 10719 } 10720 } 10721 10722 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10723 if (iaxs[fr->callno]->owner && authdebug) 10724 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10725 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10726 ies.cause ? ies.cause : "<Unknown>"); 10727 ast_debug(1, "Immediately destroying %d, having received reject\n", 10728 fr->callno); 10729 } 10730 /* Send ack immediately, before we destroy */ 10731 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10732 fr->ts, NULL, 0, fr->iseqno); 10733 if (!ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) 10734 iaxs[fr->callno]->error = EPERM; 10735 iax2_destroy(fr->callno); 10736 break; 10737 case IAX_COMMAND_TRANSFER: 10738 { 10739 struct ast_channel *bridged_chan; 10740 struct ast_channel *owner; 10741 10742 iax2_lock_owner(fr->callno); 10743 if (!iaxs[fr->callno]) { 10744 /* Initiating call went away before we could transfer. */ 10745 break; 10746 } 10747 owner = iaxs[fr->callno]->owner; 10748 bridged_chan = owner ? ast_bridged_channel(owner) : NULL; 10749 if (bridged_chan && ies.called_number) { 10750 const char *context; 10751 10752 context = ast_strdupa(iaxs[fr->callno]->context); 10753 10754 ast_channel_ref(owner); 10755 ast_channel_ref(bridged_chan); 10756 ast_channel_unlock(owner); 10757 ast_mutex_unlock(&iaxsl[fr->callno]); 10758 10759 /* Set BLINDTRANSFER channel variables */ 10760 pbx_builtin_setvar_helper(owner, "BLINDTRANSFER", bridged_chan->name); 10761 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", owner->name); 10762 10763 /* DO NOT hold any locks while calling ast_parking_ext_valid() */ 10764 if (ast_parking_ext_valid(ies.called_number, owner, context)) { 10765 ast_debug(1, "Parking call '%s'\n", bridged_chan->name); 10766 if (iax_park(bridged_chan, owner, ies.called_number, context)) { 10767 ast_log(LOG_WARNING, "Failed to park call '%s'\n", 10768 bridged_chan->name); 10769 } 10770 } else { 10771 if (ast_async_goto(bridged_chan, context, ies.called_number, 1)) { 10772 ast_log(LOG_WARNING, 10773 "Async goto of '%s' to '%s@%s' failed\n", 10774 bridged_chan->name, ies.called_number, context); 10775 } else { 10776 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", 10777 bridged_chan->name, ies.called_number, context); 10778 } 10779 } 10780 ast_channel_unref(owner); 10781 ast_channel_unref(bridged_chan); 10782 10783 ast_mutex_lock(&iaxsl[fr->callno]); 10784 } else { 10785 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10786 if (owner) { 10787 ast_channel_unlock(owner); 10788 } 10789 } 10790 10791 break; 10792 } 10793 case IAX_COMMAND_ACCEPT: 10794 /* Ignore if call is already up or needs authentication or is a TBD */ 10795 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10796 break; 10797 if (ast_test_flag64(iaxs[fr->callno], IAX_PROVISION)) { 10798 /* Send ack immediately, before we destroy */ 10799 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10800 iax2_destroy(fr->callno); 10801 break; 10802 } 10803 if (ies.format) { 10804 iaxs[fr->callno]->peerformat = ies.format; 10805 } else { 10806 if (iaxs[fr->callno]->owner) 10807 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10808 else 10809 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10810 } 10811 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)); 10812 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10813 memset(&ied0, 0, sizeof(ied0)); 10814 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10815 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10816 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10817 if (!iaxs[fr->callno]) { 10818 break; 10819 } 10820 if (authdebug) { 10821 char tmp1[256], tmp2[256]; 10822 ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n", 10823 ast_inet_ntoa(sin.sin_addr), 10824 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 10825 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 10826 } 10827 } else { 10828 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10829 iax2_lock_owner(fr->callno); 10830 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10831 /* Switch us to use a compatible format */ 10832 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 10833 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 10834 10835 /* Setup read/write formats properly. */ 10836 if (iaxs[fr->callno]->owner->writeformat) 10837 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 10838 if (iaxs[fr->callno]->owner->readformat) 10839 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10840 ast_channel_unlock(iaxs[fr->callno]->owner); 10841 } 10842 } 10843 if (iaxs[fr->callno]) { 10844 AST_LIST_LOCK(&dpcache); 10845 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10846 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10847 iax2_dprequest(dp, fr->callno); 10848 AST_LIST_UNLOCK(&dpcache); 10849 } 10850 break; 10851 case IAX_COMMAND_POKE: 10852 /* Send back a pong packet with the original timestamp */ 10853 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10854 break; 10855 case IAX_COMMAND_PING: 10856 { 10857 struct iax_ie_data pingied; 10858 construct_rr(iaxs[fr->callno], &pingied); 10859 /* Send back a pong packet with the original timestamp */ 10860 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10861 } 10862 break; 10863 case IAX_COMMAND_PONG: 10864 /* Calculate ping time */ 10865 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10866 /* save RR info */ 10867 save_rr(fr, &ies); 10868 10869 /* Good time to write jb stats for this call */ 10870 log_jitterstats(fr->callno); 10871 10872 if (iaxs[fr->callno]->peerpoke) { 10873 peer = iaxs[fr->callno]->peerpoke; 10874 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10875 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10876 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10877 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); 10878 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */ 10879 } 10880 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10881 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10882 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10883 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); 10884 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 10885 } 10886 } 10887 peer->lastms = iaxs[fr->callno]->pingtime; 10888 if (peer->smoothing && (peer->lastms > -1)) 10889 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10890 else if (peer->smoothing && peer->lastms < 0) 10891 peer->historicms = (0 + peer->historicms) / 2; 10892 else 10893 peer->historicms = iaxs[fr->callno]->pingtime; 10894 10895 /* Remove scheduled iax2_poke_noanswer */ 10896 if (peer->pokeexpire > -1) { 10897 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 10898 peer_unref(peer); 10899 peer->pokeexpire = -1; 10900 } 10901 } 10902 /* Schedule the next cycle */ 10903 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 10904 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10905 else 10906 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 10907 if (peer->pokeexpire == -1) 10908 peer_unref(peer); 10909 /* and finally send the ack */ 10910 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10911 /* And wrap up the qualify call */ 10912 iax2_destroy(fr->callno); 10913 peer->callno = 0; 10914 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 10915 } 10916 break; 10917 case IAX_COMMAND_LAGRQ: 10918 case IAX_COMMAND_LAGRP: 10919 f.src = "LAGRQ"; 10920 f.mallocd = 0; 10921 f.offset = 0; 10922 f.samples = 0; 10923 iax_frame_wrap(fr, &f); 10924 if (f.subclass.integer == IAX_COMMAND_LAGRQ) { 10925 /* Received a LAGRQ - echo back a LAGRP */ 10926 fr->af.subclass.integer = IAX_COMMAND_LAGRP; 10927 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 10928 } else { 10929 /* Received LAGRP in response to our LAGRQ */ 10930 unsigned int ts; 10931 /* This is a reply we've been given, actually measure the difference */ 10932 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 10933 iaxs[fr->callno]->lag = ts - fr->ts; 10934 if (iaxdebug) 10935 ast_debug(1, "Peer %s lag measured as %dms\n", 10936 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 10937 } 10938 break; 10939 case IAX_COMMAND_AUTHREQ: 10940 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10941 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>"); 10942 break; 10943 } 10944 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 10945 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 10946 .subclass.integer = AST_CONTROL_HANGUP, 10947 }; 10948 ast_log(LOG_WARNING, 10949 "I don't know how to authenticate %s to %s\n", 10950 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 10951 iax2_queue_frame(fr->callno, &hangup_fr); 10952 } 10953 break; 10954 case IAX_COMMAND_AUTHREP: 10955 /* For security, always ack immediately */ 10956 if (delayreject) 10957 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10958 /* Ignore once we've started */ 10959 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10960 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>"); 10961 break; 10962 } 10963 if (authenticate_verify(iaxs[fr->callno], &ies)) { 10964 if (authdebug) 10965 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); 10966 memset(&ied0, 0, sizeof(ied0)); 10967 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10968 break; 10969 } 10970 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10971 /* This might re-enter the IAX code and need the lock */ 10972 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 10973 } else 10974 exists = 0; 10975 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10976 if (authdebug) 10977 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); 10978 memset(&ied0, 0, sizeof(ied0)); 10979 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10980 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10981 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10982 if (!iaxs[fr->callno]) { 10983 break; 10984 } 10985 } else { 10986 /* Select an appropriate format */ 10987 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10988 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10989 using_prefs = "reqonly"; 10990 } else { 10991 using_prefs = "disabled"; 10992 } 10993 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10994 memset(&pref, 0, sizeof(pref)); 10995 strcpy(caller_pref_buf, "disabled"); 10996 strcpy(host_pref_buf, "disabled"); 10997 } else { 10998 using_prefs = "mine"; 10999 if (ies.codec_prefs) 11000 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 11001 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11002 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11003 pref = iaxs[fr->callno]->rprefs; 11004 using_prefs = "caller"; 11005 } else { 11006 pref = iaxs[fr->callno]->prefs; 11007 } 11008 } else /* if no codec_prefs IE do it the old way */ 11009 pref = iaxs[fr->callno]->prefs; 11010 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 11011 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 11012 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 11013 } 11014 if (!format) { 11015 char tmp1[256], tmp2[256], tmp3[256]; 11016 if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11017 ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n", 11018 ast_getformatname(iaxs[fr->callno]->peerformat), 11019 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability)); 11020 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 11021 } 11022 if (!format) { 11023 if (authdebug) { 11024 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11025 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr), 11026 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11027 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11028 } else { 11029 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11030 ast_inet_ntoa(sin.sin_addr), 11031 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11032 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11033 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11034 } 11035 } 11036 memset(&ied0, 0, sizeof(ied0)); 11037 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11038 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11039 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11040 if (!iaxs[fr->callno]) { 11041 break; 11042 } 11043 } else { 11044 /* Pick one... */ 11045 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11046 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 11047 format = 0; 11048 } else { 11049 if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 11050 using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 11051 memset(&pref, 0, sizeof(pref)); 11052 format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 11053 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11054 strcpy(caller_pref_buf,"disabled"); 11055 strcpy(host_pref_buf,"disabled"); 11056 } else { 11057 using_prefs = "mine"; 11058 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 11059 /* Do the opposite of what we tried above. */ 11060 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 11061 pref = iaxs[fr->callno]->prefs; 11062 } else { 11063 pref = iaxs[fr->callno]->rprefs; 11064 using_prefs = "caller"; 11065 } 11066 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 11067 } else /* if no codec_prefs IE do it the old way */ 11068 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 11069 } 11070 } 11071 if (!format) { 11072 char tmp1[256], tmp2[256], tmp3[256]; 11073 ast_log(LOG_ERROR, "No best format in %s???\n", 11074 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability)); 11075 if (authdebug) { 11076 if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 11077 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", 11078 ast_inet_ntoa(sin.sin_addr), 11079 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11080 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability)); 11081 } else { 11082 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n", 11083 ast_inet_ntoa(sin.sin_addr), 11084 ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat), 11085 ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability), 11086 ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability)); 11087 } 11088 } 11089 memset(&ied0, 0, sizeof(ied0)); 11090 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 11091 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 11092 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11093 if (!iaxs[fr->callno]) { 11094 break; 11095 } 11096 } 11097 } 11098 } 11099 if (format) { 11100 /* Authentication received */ 11101 memset(&ied1, 0, sizeof(ied1)); 11102 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 11103 iax_ie_append_versioned_uint64(&ied1, IAX_IE_FORMAT2, 0, format); 11104 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 11105 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 11106 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11107 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 11108 "%srequested format = %s,\n" 11109 "%srequested prefs = %s,\n" 11110 "%sactual format = %s,\n" 11111 "%shost prefs = %s,\n" 11112 "%spriority = %s\n", 11113 ast_inet_ntoa(sin.sin_addr), 11114 VERBOSE_PREFIX_4, 11115 ast_getformatname(iaxs[fr->callno]->peerformat), 11116 VERBOSE_PREFIX_4, 11117 caller_pref_buf, 11118 VERBOSE_PREFIX_4, 11119 ast_getformatname(format), 11120 VERBOSE_PREFIX_4, 11121 host_pref_buf, 11122 VERBOSE_PREFIX_4, 11123 using_prefs); 11124 11125 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11126 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, 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 if (variablestore && varlist) { 11135 variablestore->data = varlist; 11136 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11137 AST_LIST_HEAD_INIT(varlist); 11138 ast_debug(1, "I can haz IAX vars? w00t\n"); 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 } else { 11164 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11165 /* If this is a TBD call, we're ready but now what... */ 11166 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 11167 if (ast_test_flag64(iaxs[fr->callno], IAX_IMMEDIATE)) { 11168 goto immediatedial; 11169 } 11170 } 11171 } 11172 } 11173 break; 11174 case IAX_COMMAND_DIAL: 11175 immediatedial: 11176 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 11177 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 11178 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 11179 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 11180 if (authdebug) 11181 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); 11182 memset(&ied0, 0, sizeof(ied0)); 11183 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 11184 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 11185 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11186 if (!iaxs[fr->callno]) { 11187 break; 11188 } 11189 } else { 11190 char tmp[256]; 11191 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11192 ast_verb(3, "Accepting DIAL from %s, formats = %s\n", 11193 ast_inet_ntoa(sin.sin_addr), 11194 ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat)); 11195 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 11196 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 11197 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL))) 11198 iax2_destroy(fr->callno); 11199 else if (ies.vars) { 11200 struct ast_datastore *variablestore; 11201 struct ast_variable *var, *prev = NULL; 11202 AST_LIST_HEAD(, ast_var_t) *varlist; 11203 varlist = ast_calloc(1, sizeof(*varlist)); 11204 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 11205 ast_debug(1, "I can haz IAX vars? w00t\n"); 11206 if (variablestore && varlist) { 11207 variablestore->data = varlist; 11208 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 11209 AST_LIST_HEAD_INIT(varlist); 11210 for (var = ies.vars; var; var = var->next) { 11211 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 11212 if (prev) 11213 ast_free(prev); 11214 prev = var; 11215 if (!newvar) { 11216 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 11217 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11218 } else { 11219 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 11220 } 11221 } 11222 if (prev) 11223 ast_free(prev); 11224 ies.vars = NULL; 11225 ast_channel_datastore_add(c, variablestore); 11226 } else { 11227 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 11228 if (variablestore) 11229 ast_datastore_free(variablestore); 11230 if (varlist) 11231 ast_free(varlist); 11232 } 11233 } 11234 } 11235 } 11236 break; 11237 case IAX_COMMAND_INVAL: 11238 iaxs[fr->callno]->error = ENOTCONN; 11239 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 11240 iax2_destroy(fr->callno); 11241 ast_debug(1, "Destroying call %d\n", fr->callno); 11242 break; 11243 case IAX_COMMAND_VNAK: 11244 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 11245 /* Force retransmission */ 11246 vnak_retransmit(fr->callno, fr->iseqno); 11247 break; 11248 case IAX_COMMAND_REGREQ: 11249 case IAX_COMMAND_REGREL: 11250 /* For security, always ack immediately */ 11251 if (delayreject) 11252 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11253 if (register_verify(fr->callno, &sin, &ies)) { 11254 if (!iaxs[fr->callno]) { 11255 break; 11256 } 11257 /* Send delayed failure */ 11258 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 11259 break; 11260 } 11261 if (!iaxs[fr->callno]) { 11262 break; 11263 } 11264 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 11265 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 11266 11267 if (f.subclass.integer == IAX_COMMAND_REGREL) { 11268 memset(&sin, 0, sizeof(sin)); 11269 sin.sin_family = AF_INET; 11270 } 11271 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) { 11272 ast_log(LOG_WARNING, "Registry error\n"); 11273 } 11274 if (!iaxs[fr->callno]) { 11275 break; 11276 } 11277 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 11278 ast_mutex_unlock(&iaxsl[fr->callno]); 11279 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 11280 ast_mutex_lock(&iaxsl[fr->callno]); 11281 } 11282 break; 11283 } 11284 registry_authrequest(fr->callno); 11285 break; 11286 case IAX_COMMAND_REGACK: 11287 if (iax2_ack_registry(&ies, &sin, fr->callno)) 11288 ast_log(LOG_WARNING, "Registration failure\n"); 11289 /* Send ack immediately, before we destroy */ 11290 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11291 iax2_destroy(fr->callno); 11292 break; 11293 case IAX_COMMAND_REGREJ: 11294 if (iaxs[fr->callno]->reg) { 11295 if (authdebug) { 11296 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)); 11297 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>"); 11298 } 11299 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 11300 } 11301 /* Send ack immediately, before we destroy */ 11302 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11303 iax2_destroy(fr->callno); 11304 break; 11305 case IAX_COMMAND_REGAUTH: 11306 /* Authentication request */ 11307 if (registry_rerequest(&ies, fr->callno, &sin)) { 11308 memset(&ied0, 0, sizeof(ied0)); 11309 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 11310 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 11311 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11312 } 11313 break; 11314 case IAX_COMMAND_TXREJ: 11315 iaxs[fr->callno]->transferring = 0; 11316 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11317 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 11318 if (iaxs[fr->callno]->bridgecallno) { 11319 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 11320 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 11321 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 11322 } 11323 } 11324 break; 11325 case IAX_COMMAND_TXREADY: 11326 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 11327 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 11328 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 11329 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 11330 else 11331 iaxs[fr->callno]->transferring = TRANSFER_READY; 11332 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 11333 if (iaxs[fr->callno]->bridgecallno) { 11334 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 11335 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 11336 /* They're both ready, now release them. */ 11337 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 11338 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11339 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11340 11341 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 11342 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 11343 11344 memset(&ied0, 0, sizeof(ied0)); 11345 memset(&ied1, 0, sizeof(ied1)); 11346 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11347 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11348 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 11349 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 11350 } else { 11351 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 11352 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 11353 11354 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 11355 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 11356 ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 11357 ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE); 11358 11359 /* Stop doing lag & ping requests */ 11360 stop_stuff(fr->callno); 11361 stop_stuff(iaxs[fr->callno]->bridgecallno); 11362 11363 memset(&ied0, 0, sizeof(ied0)); 11364 memset(&ied1, 0, sizeof(ied1)); 11365 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 11366 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 11367 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 11368 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 11369 } 11370 11371 } 11372 } 11373 } 11374 break; 11375 case IAX_COMMAND_TXREQ: 11376 try_transfer(iaxs[fr->callno], &ies); 11377 break; 11378 case IAX_COMMAND_TXCNT: 11379 if (iaxs[fr->callno]->transferring) 11380 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 11381 break; 11382 case IAX_COMMAND_TXREL: 11383 /* Send ack immediately, rather than waiting until we've changed addresses */ 11384 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11385 complete_transfer(fr->callno, &ies); 11386 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 11387 break; 11388 case IAX_COMMAND_TXMEDIA: 11389 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 11390 AST_LIST_TRAVERSE(&frame_queue[fr->callno], cur, list) { 11391 /* Cancel any outstanding frames and start anew */ 11392 if (cur->transfer) { 11393 cur->retries = -1; 11394 } 11395 } 11396 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 11397 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 11398 } 11399 break; 11400 case IAX_COMMAND_RTKEY: 11401 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 11402 ast_log(LOG_WARNING, 11403 "we've been told to rotate our encryption key, " 11404 "but this isn't an encrypted call. bad things will happen.\n" 11405 ); 11406 break; 11407 } 11408 11409 IAX_DEBUGDIGEST("Receiving", ies.challenge); 11410 11411 ast_aes_set_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 11412 break; 11413 case IAX_COMMAND_DPREP: 11414 complete_dpreply(iaxs[fr->callno], &ies); 11415 break; 11416 case IAX_COMMAND_UNSUPPORT: 11417 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 11418 break; 11419 case IAX_COMMAND_FWDOWNL: 11420 /* Firmware download */ 11421 if (!ast_test_flag64(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 11422 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 11423 break; 11424 } 11425 memset(&ied0, 0, sizeof(ied0)); 11426 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 11427 if (res < 0) 11428 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 11429 else if (res > 0) 11430 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11431 else 11432 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 11433 break; 11434 case IAX_COMMAND_CALLTOKEN: 11435 { 11436 struct iax_frame *cur; 11437 /* find last sent frame */ 11438 if ((cur = AST_LIST_LAST(&frame_queue[fr->callno])) && ies.calltoken && ies.calltokendata) { 11439 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 11440 } 11441 break; 11442 } 11443 default: 11444 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass.integer, fr->callno, iaxs[fr->callno]->peercallno); 11445 memset(&ied0, 0, sizeof(ied0)); 11446 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass.integer); 11447 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11448 } 11449 /* Free remote variables (if any) */ 11450 if (ies.vars) { 11451 ast_variables_destroy(ies.vars); 11452 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11453 ies.vars = NULL; 11454 } 11455 11456 /* Don't actually pass these frames along */ 11457 if ((f.subclass.integer != IAX_COMMAND_ACK) && 11458 (f.subclass.integer != IAX_COMMAND_TXCNT) && 11459 (f.subclass.integer != IAX_COMMAND_TXACC) && 11460 (f.subclass.integer != IAX_COMMAND_INVAL) && 11461 (f.subclass.integer != IAX_COMMAND_VNAK)) { 11462 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11463 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11464 } 11465 ast_mutex_unlock(&iaxsl[fr->callno]); 11466 return 1; 11467 } 11468 /* Unless this is an ACK or INVAL frame, ack it */ 11469 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11470 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11471 } else if (minivid) { 11472 f.frametype = AST_FRAME_VIDEO; 11473 if (iaxs[fr->callno]->videoformat > 0) 11474 f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0); 11475 else { 11476 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11477 iax2_vnak(fr->callno); 11478 ast_variables_destroy(ies.vars); 11479 ast_mutex_unlock(&iaxsl[fr->callno]); 11480 return 1; 11481 } 11482 f.datalen = res - sizeof(*vh); 11483 if (f.datalen) 11484 f.data.ptr = thread->buf + sizeof(*vh); 11485 else 11486 f.data.ptr = NULL; 11487 #ifdef IAXTESTS 11488 if (test_resync) { 11489 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11490 } else 11491 #endif /* IAXTESTS */ 11492 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11493 } else { 11494 /* A mini frame */ 11495 f.frametype = AST_FRAME_VOICE; 11496 if (iaxs[fr->callno]->voiceformat > 0) 11497 f.subclass.codec = iaxs[fr->callno]->voiceformat; 11498 else { 11499 ast_debug(1, "Received mini frame before first full voice frame\n"); 11500 iax2_vnak(fr->callno); 11501 ast_variables_destroy(ies.vars); 11502 ast_mutex_unlock(&iaxsl[fr->callno]); 11503 return 1; 11504 } 11505 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11506 if (f.datalen < 0) { 11507 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11508 ast_variables_destroy(ies.vars); 11509 ast_mutex_unlock(&iaxsl[fr->callno]); 11510 return 1; 11511 } 11512 if (f.datalen) 11513 f.data.ptr = thread->buf + sizeof(*mh); 11514 else 11515 f.data.ptr = NULL; 11516 #ifdef IAXTESTS 11517 if (test_resync) { 11518 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11519 } else 11520 #endif /* IAXTESTS */ 11521 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11522 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11523 } 11524 /* Don't pass any packets until we're started */ 11525 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11526 ast_variables_destroy(ies.vars); 11527 ast_mutex_unlock(&iaxsl[fr->callno]); 11528 return 1; 11529 } 11530 /* Don't allow connected line updates unless we are configured to */ 11531 if (f.frametype == AST_FRAME_CONTROL && f.subclass.integer == AST_CONTROL_CONNECTED_LINE) { 11532 struct ast_party_connected_line connected; 11533 11534 if (!ast_test_flag64(iaxs[fr->callno], IAX_RECVCONNECTEDLINE)) { 11535 ast_variables_destroy(ies.vars); 11536 ast_mutex_unlock(&iaxsl[fr->callno]); 11537 return 1; 11538 } 11539 11540 /* Initialize defaults */ 11541 ast_party_connected_line_init(&connected); 11542 connected.id.number.presentation = iaxs[fr->callno]->calling_pres; 11543 connected.id.name.presentation = iaxs[fr->callno]->calling_pres; 11544 11545 if (!ast_connected_line_parse_data(f.data.ptr, f.datalen, &connected)) { 11546 ast_string_field_set(iaxs[fr->callno], cid_num, connected.id.number.str); 11547 ast_string_field_set(iaxs[fr->callno], cid_name, connected.id.name.str); 11548 iaxs[fr->callno]->calling_pres = ast_party_id_presentation(&connected.id); 11549 11550 if (iaxs[fr->callno]->owner) { 11551 ast_set_callerid(iaxs[fr->callno]->owner, 11552 S_COR(connected.id.number.valid, connected.id.number.str, ""), 11553 S_COR(connected.id.name.valid, connected.id.name.str, ""), 11554 NULL); 11555 iaxs[fr->callno]->owner->caller.id.number.presentation = connected.id.number.presentation; 11556 iaxs[fr->callno]->owner->caller.id.name.presentation = connected.id.name.presentation; 11557 } 11558 } 11559 ast_party_connected_line_free(&connected); 11560 } 11561 /* Common things */ 11562 f.src = "IAX2"; 11563 f.mallocd = 0; 11564 f.offset = 0; 11565 f.len = 0; 11566 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11567 f.samples = ast_codec_get_samples(&f); 11568 /* We need to byteswap incoming slinear samples from network byte order */ 11569 if (f.subclass.codec == AST_FORMAT_SLINEAR) 11570 ast_frame_byteswap_be(&f); 11571 } else 11572 f.samples = 0; 11573 iax_frame_wrap(fr, &f); 11574 11575 /* If this is our most recent packet, use it as our basis for timestamping */ 11576 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11577 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11578 fr->outoforder = 0; 11579 } else { 11580 if (iaxdebug && iaxs[fr->callno]) 11581 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); 11582 fr->outoforder = -1; 11583 } 11584 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11585 duped_fr = iaxfrdup2(fr); 11586 if (duped_fr) { 11587 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11588 } 11589 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11590 iaxs[fr->callno]->last = fr->ts; 11591 #if 1 11592 if (iaxdebug) 11593 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 11594 #endif 11595 } 11596 11597 /* Always run again */ 11598 ast_variables_destroy(ies.vars); 11599 ast_mutex_unlock(&iaxsl[fr->callno]); 11600 return 1; 11601 }
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 9651 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().
09653 { 09654 unsigned char metatype; 09655 struct ast_iax2_meta_trunk_mini *mtm; 09656 struct ast_iax2_meta_trunk_hdr *mth; 09657 struct ast_iax2_meta_trunk_entry *mte; 09658 struct iax2_trunk_peer *tpeer; 09659 unsigned int ts; 09660 void *ptr; 09661 struct timeval rxtrunktime; 09662 struct ast_frame f = { 0, }; 09663 09664 if (packet_len < sizeof(*meta)) { 09665 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09666 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09667 return 1; 09668 } 09669 09670 if (meta->metacmd != IAX_META_TRUNK) 09671 return 1; 09672 09673 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09674 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09675 (int) (sizeof(*meta) + sizeof(*mth))); 09676 return 1; 09677 } 09678 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09679 ts = ntohl(mth->ts); 09680 metatype = meta->cmddata; 09681 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09682 ptr = mth->data; 09683 tpeer = find_tpeer(sin, sockfd); 09684 if (!tpeer) { 09685 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09686 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09687 return 1; 09688 } 09689 tpeer->trunkact = ast_tvnow(); 09690 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09691 tpeer->rxtrunktime = tpeer->trunkact; 09692 rxtrunktime = tpeer->rxtrunktime; 09693 ast_mutex_unlock(&tpeer->lock); 09694 while (packet_len >= sizeof(*mte)) { 09695 /* Process channels */ 09696 unsigned short callno, trunked_ts, len; 09697 09698 if (metatype == IAX_META_TRUNK_MINI) { 09699 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09700 ptr += sizeof(*mtm); 09701 packet_len -= sizeof(*mtm); 09702 len = ntohs(mtm->len); 09703 callno = ntohs(mtm->mini.callno); 09704 trunked_ts = ntohs(mtm->mini.ts); 09705 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09706 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09707 ptr += sizeof(*mte); 09708 packet_len -= sizeof(*mte); 09709 len = ntohs(mte->len); 09710 callno = ntohs(mte->callno); 09711 trunked_ts = 0; 09712 } else { 09713 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09714 break; 09715 } 09716 /* Stop if we don't have enough data */ 09717 if (len > packet_len) 09718 break; 09719 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09720 if (!fr->callno) 09721 continue; 09722 09723 /* If it's a valid call, deliver the contents. If not, we 09724 drop it, since we don't have a scallno to use for an INVAL */ 09725 /* Process as a mini frame */ 09726 memset(&f, 0, sizeof(f)); 09727 f.frametype = AST_FRAME_VOICE; 09728 if (!iaxs[fr->callno]) { 09729 /* drop it */ 09730 } else if (iaxs[fr->callno]->voiceformat == 0) { 09731 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09732 iax2_vnak(fr->callno); 09733 } else { 09734 f.subclass.codec = iaxs[fr->callno]->voiceformat; 09735 f.datalen = len; 09736 if (f.datalen >= 0) { 09737 if (f.datalen) 09738 f.data.ptr = ptr; 09739 else 09740 f.data.ptr = NULL; 09741 if (trunked_ts) 09742 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09743 else 09744 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09745 /* Don't pass any packets until we're started */ 09746 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09747 struct iax_frame *duped_fr; 09748 09749 /* Common things */ 09750 f.src = "IAX2"; 09751 f.mallocd = 0; 09752 f.offset = 0; 09753 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09754 f.samples = ast_codec_get_samples(&f); 09755 else 09756 f.samples = 0; 09757 fr->outoforder = 0; 09758 iax_frame_wrap(fr, &f); 09759 duped_fr = iaxfrdup2(fr); 09760 if (duped_fr) 09761 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09762 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09763 iaxs[fr->callno]->last = fr->ts; 09764 } 09765 } else { 09766 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09767 } 09768 } 09769 ast_mutex_unlock(&iaxsl[fr->callno]); 09770 ptr += len; 09771 packet_len -= len; 09772 } 09773 09774 return 1; 09775 }
static int socket_read | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 9572 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().
09573 { 09574 struct iax2_thread *thread; 09575 socklen_t len; 09576 time_t t; 09577 static time_t last_errtime = 0; 09578 struct ast_iax2_full_hdr *fh; 09579 09580 if (!(thread = find_idle_thread())) { 09581 time(&t); 09582 if (t != last_errtime) 09583 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09584 last_errtime = t; 09585 usleep(1); 09586 return 1; 09587 } 09588 09589 len = sizeof(thread->iosin); 09590 thread->iofd = fd; 09591 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09592 thread->buf_size = sizeof(thread->readbuf); 09593 thread->buf = thread->readbuf; 09594 if (thread->buf_len < 0) { 09595 if (errno != ECONNREFUSED && errno != EAGAIN) 09596 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09597 handle_error(); 09598 thread->iostate = IAX_IOSTATE_IDLE; 09599 signal_condition(&thread->lock, &thread->cond); 09600 return 1; 09601 } 09602 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09603 thread->iostate = IAX_IOSTATE_IDLE; 09604 signal_condition(&thread->lock, &thread->cond); 09605 return 1; 09606 } 09607 09608 /* Determine if this frame is a full frame; if so, and any thread is currently 09609 processing a full frame for the same callno from this peer, then drop this 09610 frame (and the peer will retransmit it) */ 09611 fh = (struct ast_iax2_full_hdr *) thread->buf; 09612 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09613 struct iax2_thread *cur = NULL; 09614 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09615 09616 AST_LIST_LOCK(&active_list); 09617 AST_LIST_TRAVERSE(&active_list, cur, list) { 09618 if ((cur->ffinfo.callno == callno) && 09619 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09620 break; 09621 } 09622 if (cur) { 09623 /* we found another thread processing a full frame for this call, 09624 so queue it up for processing later. */ 09625 defer_full_frame(thread, cur); 09626 AST_LIST_UNLOCK(&active_list); 09627 thread->iostate = IAX_IOSTATE_IDLE; 09628 signal_condition(&thread->lock, &thread->cond); 09629 return 1; 09630 } else { 09631 /* this thread is going to process this frame, so mark it */ 09632 thread->ffinfo.callno = callno; 09633 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09634 thread->ffinfo.type = fh->type; 09635 thread->ffinfo.csub = fh->csub; 09636 AST_LIST_INSERT_HEAD(&active_list, thread, list); 09637 } 09638 AST_LIST_UNLOCK(&active_list); 09639 } 09640 09641 /* Mark as ready and send on its way */ 09642 thread->iostate = IAX_IOSTATE_READY; 09643 #ifdef DEBUG_SCHED_MULTITHREAD 09644 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09645 #endif 09646 signal_condition(&thread->lock, &thread->cond); 09647 09648 return 1; 09649 }
static void spawn_dp_lookup | ( | int | callno, | |
const char * | context, | |||
const char * | callednum, | |||
const char * | callerid | |||
) | [static] |
Definition at line 9242 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().
09243 { 09244 pthread_t newthread; 09245 struct dpreq_data *dpr; 09246 09247 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 09248 return; 09249 09250 dpr->callno = callno; 09251 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 09252 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 09253 if (callerid) 09254 dpr->callerid = ast_strdup(callerid); 09255 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 09256 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 09257 } 09258 }
static int start_network_thread | ( | void | ) | [static] |
Definition at line 12161 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().
12162 { 12163 struct iax2_thread *thread; 12164 int threadcount = 0; 12165 int x; 12166 for (x = 0; x < iaxthreadcount; x++) { 12167 thread = ast_calloc(1, sizeof(*thread)); 12168 if (thread) { 12169 thread->type = IAX_THREAD_TYPE_POOL; 12170 thread->threadnum = ++threadcount; 12171 ast_mutex_init(&thread->lock); 12172 ast_cond_init(&thread->cond, NULL); 12173 ast_mutex_init(&thread->init_lock); 12174 ast_cond_init(&thread->init_cond, NULL); 12175 if (ast_pthread_create_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 12176 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 12177 ast_mutex_destroy(&thread->lock); 12178 ast_cond_destroy(&thread->cond); 12179 ast_mutex_destroy(&thread->init_lock); 12180 ast_cond_destroy(&thread->init_cond); 12181 ast_free(thread); 12182 thread = NULL; 12183 continue; 12184 } 12185 AST_LIST_LOCK(&idle_list); 12186 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 12187 AST_LIST_UNLOCK(&idle_list); 12188 } 12189 } 12190 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 12191 ast_verb(2, "%d helper threads started\n", threadcount); 12192 return 0; 12193 }
static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 8948 of file chan_iax2.c.
References iax2_destroy_helper(), and iaxs.
Referenced by socket_process().
08949 { 08950 iax2_destroy_helper(iaxs[callno]); 08951 }
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 9131 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().
09132 { 09133 int res, processed = 0, totalcalls = 0; 09134 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 09135 struct timeval now = ast_tvnow(); 09136 09137 if (iaxtrunkdebug) 09138 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 09139 09140 if (timer) { 09141 ast_timer_ack(timer, 1); 09142 } 09143 09144 /* For each peer that supports trunking... */ 09145 AST_LIST_LOCK(&tpeers); 09146 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 09147 processed++; 09148 res = 0; 09149 ast_mutex_lock(&tpeer->lock); 09150 /* We can drop a single tpeer per pass. That makes all this logic 09151 substantially easier */ 09152 if (!drop && iax2_trunk_expired(tpeer, &now)) { 09153 /* Take it out of the list, but don't free it yet, because it 09154 could be in use */ 09155 AST_LIST_REMOVE_CURRENT(list); 09156 drop = tpeer; 09157 } else { 09158 res = send_trunk(tpeer, &now); 09159 trunk_timed++; 09160 if (iaxtrunkdebug) 09161 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); 09162 } 09163 totalcalls += res; 09164 res = 0; 09165 ast_mutex_unlock(&tpeer->lock); 09166 } 09167 AST_LIST_TRAVERSE_SAFE_END; 09168 AST_LIST_UNLOCK(&tpeers); 09169 09170 if (drop) { 09171 ast_mutex_lock(&drop->lock); 09172 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 09173 because by the time they could get tpeerlock, we've already grabbed it */ 09174 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 09175 if (drop->trunkdata) { 09176 ast_free(drop->trunkdata); 09177 drop->trunkdata = NULL; 09178 } 09179 ast_mutex_unlock(&drop->lock); 09180 ast_mutex_destroy(&drop->lock); 09181 ast_free(drop); 09182 09183 } 09184 09185 if (iaxtrunkdebug) 09186 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 09187 iaxtrunkdebug = 0; 09188 09189 return 1; 09190 }
static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 14403 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
14404 { 14405 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 14406 14407 /* The frames_received field is used to hold whether we're matching 14408 * against a full frame or not ... */ 14409 14410 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 14411 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 14412 }
static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 14396 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
14397 { 14398 const struct chan_iax2_pvt *pvt = obj; 14399 14400 return pvt->transfercallno; 14401 }
static int transmit_frame | ( | void * | data | ) | [static] |
Definition at line 4229 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().
04230 { 04231 struct iax_frame *fr = data; 04232 04233 ast_mutex_lock(&iaxsl[fr->callno]); 04234 04235 fr->sentyet = 1; 04236 04237 if (iaxs[fr->callno]) { 04238 send_packet(fr); 04239 } 04240 04241 if (fr->retries < 0) { 04242 ast_mutex_unlock(&iaxsl[fr->callno]); 04243 /* No retransmit requested */ 04244 iax_frame_free(fr); 04245 } else { 04246 /* We need reliable delivery. Schedule a retransmission */ 04247 AST_LIST_INSERT_TAIL(&frame_queue[fr->callno], fr, list); 04248 fr->retries++; 04249 fr->retrans = iax2_sched_add(sched, fr->retrytime, attempt_transmit, fr); 04250 ast_mutex_unlock(&iaxsl[fr->callno]); 04251 } 04252 04253 return 0; 04254 }
static int transmit_trunk | ( | struct iax_frame * | f, | |
struct sockaddr_in * | sin, | |||
int | sockfd | |||
) | [static] |
Definition at line 3301 of file chan_iax2.c.
References ast_debug, errno, f, and handle_error().
Referenced by send_trunk().
03302 { 03303 int res; 03304 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03305 sizeof(*sin)); 03306 if (res < 0) { 03307 ast_debug(1, "Received error: %s\n", strerror(errno)); 03308 handle_error(); 03309 } else 03310 res = 0; 03311 return res; 03312 }
static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 3003 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().
03004 { 03005 struct stat stbuf; 03006 struct iax_firmware *cur = NULL; 03007 int ifd, fd, res, len, chunk; 03008 struct ast_iax2_firmware_header *fwh, fwh2; 03009 struct MD5Context md5; 03010 unsigned char sum[16], buf[1024]; 03011 char *s2, *last; 03012 03013 if (!(s2 = alloca(strlen(s) + 100))) { 03014 ast_log(LOG_WARNING, "Alloca failed!\n"); 03015 return -1; 03016 } 03017 03018 last = strrchr(s, '/'); 03019 if (last) 03020 last++; 03021 else 03022 last = s; 03023 03024 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 03025 03026 if ((res = stat(s, &stbuf) < 0)) { 03027 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 03028 return -1; 03029 } 03030 03031 /* Make sure it's not a directory */ 03032 if (S_ISDIR(stbuf.st_mode)) 03033 return -1; 03034 ifd = open(s, O_RDONLY); 03035 if (ifd < 0) { 03036 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 03037 return -1; 03038 } 03039 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 03040 if (fd < 0) { 03041 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 03042 close(ifd); 03043 return -1; 03044 } 03045 /* Unlink our newly created file */ 03046 unlink(s2); 03047 03048 /* Now copy the firmware into it */ 03049 len = stbuf.st_size; 03050 while(len) { 03051 chunk = len; 03052 if (chunk > sizeof(buf)) 03053 chunk = sizeof(buf); 03054 res = read(ifd, buf, chunk); 03055 if (res != chunk) { 03056 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03057 close(ifd); 03058 close(fd); 03059 return -1; 03060 } 03061 res = write(fd, buf, chunk); 03062 if (res != chunk) { 03063 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 03064 close(ifd); 03065 close(fd); 03066 return -1; 03067 } 03068 len -= chunk; 03069 } 03070 close(ifd); 03071 /* Return to the beginning */ 03072 lseek(fd, 0, SEEK_SET); 03073 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 03074 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 03075 close(fd); 03076 return -1; 03077 } 03078 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 03079 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 03080 close(fd); 03081 return -1; 03082 } 03083 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 03084 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 03085 close(fd); 03086 return -1; 03087 } 03088 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 03089 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 03090 close(fd); 03091 return -1; 03092 } 03093 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 03094 if (fwh == MAP_FAILED) { 03095 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 03096 close(fd); 03097 return -1; 03098 } 03099 MD5Init(&md5); 03100 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 03101 MD5Final(sum, &md5); 03102 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 03103 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 03104 munmap((void*)fwh, stbuf.st_size); 03105 close(fd); 03106 return -1; 03107 } 03108 03109 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03110 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 03111 /* Found a candidate */ 03112 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 03113 /* The version we have on loaded is older, load this one instead */ 03114 break; 03115 /* This version is no newer than what we have. Don't worry about it. 03116 We'll consider it a proper load anyhow though */ 03117 munmap((void*)fwh, stbuf.st_size); 03118 close(fd); 03119 return 0; 03120 } 03121 } 03122 03123 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 03124 cur->fd = -1; 03125 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 03126 } 03127 03128 if (cur) { 03129 if (cur->fwh) 03130 munmap((void*)cur->fwh, cur->mmaplen); 03131 if (cur->fd > -1) 03132 close(cur->fd); 03133 cur->fwh = fwh; 03134 cur->fd = fd; 03135 cur->mmaplen = stbuf.st_size; 03136 cur->dead = 0; 03137 } 03138 03139 return 0; 03140 }
static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
struct iax_ies * | ies | |||
) | [static] |
Definition at line 8266 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().
08267 { 08268 int newcall = 0; 08269 char newip[256]; 08270 struct iax_ie_data ied; 08271 struct sockaddr_in new; 08272 08273 08274 memset(&ied, 0, sizeof(ied)); 08275 if (ies->apparent_addr) 08276 memmove(&new, ies->apparent_addr, sizeof(new)); 08277 if (ies->callno) 08278 newcall = ies->callno; 08279 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 08280 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08281 return -1; 08282 } 08283 pvt->transfercallno = newcall; 08284 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 08285 inet_aton(newip, &pvt->transfer.sin_addr); 08286 pvt->transfer.sin_family = AF_INET; 08287 pvt->transferid = ies->transferid; 08288 /* only store by transfercallno if this is a new transfer, 08289 * just in case we get a duplicate TXREQ */ 08290 if (pvt->transferring == TRANSFER_NONE) { 08291 store_by_transfercallno(pvt); 08292 } 08293 pvt->transferring = TRANSFER_BEGIN; 08294 08295 if (ies->transferid) 08296 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 08297 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 08298 return 0; 08299 }
static format_t uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1627 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01628 { 01629 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01630 if (csub & IAX_FLAG_SC_LOG) { 01631 /* special case for 'compressed' -1 */ 01632 if (csub == 0xff) 01633 return -1; 01634 else 01635 return 1LL << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01636 } 01637 else 01638 return csub; 01639 }
static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8561 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().
08562 { 08563 if (peer->expire > -1) { 08564 if (!ast_sched_thread_del(sched, peer->expire)) { 08565 peer->expire = -1; 08566 peer_unref(peer); 08567 } 08568 } 08569 08570 if (peer->pokeexpire > -1) { 08571 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 08572 peer->pokeexpire = -1; 08573 peer_unref(peer); 08574 } 08575 } 08576 08577 ao2_unlink(peers, peer); 08578 }
static int unload_module | ( | void | ) | [static] |
Definition at line 14361 of file chan_iax2.c.
References __unload_module(), ast_custom_function_unregister(), iaxpeer_function, and iaxvar_function.
14362 { 14363 ast_custom_function_unregister(&iaxpeer_function); 14364 ast_custom_function_unregister(&iaxvar_function); 14365 return __unload_module(); 14366 }
static void unlock_both | ( | unsigned short | callno0, | |
unsigned short | callno1 | |||
) | [static] |
Definition at line 5433 of file chan_iax2.c.
References ast_mutex_unlock, and iaxsl.
Referenced by iax2_bridge().
05434 { 05435 ast_mutex_unlock(&iaxsl[callno1]); 05436 ast_mutex_unlock(&iaxsl[callno0]); 05437 }
static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3991 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().
03992 { 03993 /* Video mini frames only encode the lower 15 bits of the session 03994 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 03995 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 03996 const int lower_mask = (1 << ts_shift) - 1; 03997 const int upper_mask = ~lower_mask; 03998 const int last_upper = iaxs[fr->callno]->last & upper_mask; 03999 04000 if ( (fr->ts & upper_mask) == last_upper ) { 04001 const int x = fr->ts - iaxs[fr->callno]->last; 04002 const int threshold = (ts_shift == 15) ? 25000 : 50000; 04003 04004 if (x < -threshold) { 04005 /* Sudden big jump backwards in timestamp: 04006 What likely happened here is that miniframe timestamp has circled but we haven't 04007 gotten the update from the main packet. We'll just pretend that we did, and 04008 update the timestamp appropriately. */ 04009 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 04010 if (iaxdebug) 04011 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 04012 } else if (x > threshold) { 04013 /* Sudden apparent big jump forwards in timestamp: 04014 What's likely happened is this is an old miniframe belonging to the previous 04015 top 15 or 16-bit timestamp that has turned up out of order. 04016 Adjust the timestamp appropriately. */ 04017 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 04018 if (iaxdebug) 04019 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 04020 } 04021 } 04022 }
static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4026 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().
04027 { 04028 int when; 04029 04030 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 04031 04032 when = jb_next(pvt->jb) - when; 04033 04034 if (when <= 0) { 04035 /* XXX should really just empty until when > 0.. */ 04036 when = 1; 04037 } 04038 04039 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 04040 CALLNO_TO_PTR(pvt->callno)); 04041 }
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 3439 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().
03440 { 03441 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03442 struct ast_iax2_full_hdr *fh = f->data; 03443 struct ast_frame af; 03444 03445 /* if frame is encrypted. decrypt before updating it. */ 03446 if (f->encmethods) { 03447 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03448 } 03449 /* Mark this as a retransmission */ 03450 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03451 /* Update iseqno */ 03452 f->iseqno = iaxs[f->callno]->iseqno; 03453 fh->iseqno = f->iseqno; 03454 03455 /* Now re-encrypt the frame */ 03456 if (f->encmethods) { 03457 /* since this is a retransmit frame, create a new random padding 03458 * before re-encrypting. */ 03459 build_rand_pad(f->semirand, sizeof(f->semirand)); 03460 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03461 } 03462 return 0; 03463 }
static int update_registry | ( | struct sockaddr_in * | sin, | |
int | callno, | |||
char * | devtype, | |||
int | fd, | |||
unsigned short | refresh | |||
) | [static] |
Definition at line 8680 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().
08681 { 08682 /* Called from IAX thread only, with proper iaxsl lock */ 08683 struct iax_ie_data ied = { 08684 .pos = 0, 08685 }; 08686 struct iax2_peer *p; 08687 int msgcount; 08688 char data[80]; 08689 int version; 08690 const char *peer_name; 08691 int res = -1; 08692 struct ast_sockaddr sockaddr; 08693 08694 ast_sockaddr_from_sin(&sockaddr, sin); 08695 08696 peer_name = ast_strdupa(iaxs[callno]->peer); 08697 08698 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08699 ast_mutex_unlock(&iaxsl[callno]); 08700 if (!(p = find_peer(peer_name, 1))) { 08701 ast_mutex_lock(&iaxsl[callno]); 08702 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08703 return -1; 08704 } 08705 ast_mutex_lock(&iaxsl[callno]); 08706 if (!iaxs[callno]) 08707 goto return_unref; 08708 08709 if (ast_test_flag64((&globalflags), IAX_RTUPDATE) && (ast_test_flag64(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08710 if (sin->sin_addr.s_addr) { 08711 time_t nowtime; 08712 time(&nowtime); 08713 realtime_update_peer(peer_name, &sockaddr, nowtime); 08714 } else { 08715 realtime_update_peer(peer_name, &sockaddr, 0); 08716 } 08717 } 08718 08719 if (ast_sockaddr_cmp(&p->addr, &sockaddr)) { 08720 if (iax2_regfunk) { 08721 iax2_regfunk(p->name, 1); 08722 } 08723 08724 /* modify entry in peercnts table as _not_ registered */ 08725 peercnt_modify(0, 0, &p->addr); 08726 08727 /* Stash the IP address from which they registered */ 08728 ast_sockaddr_from_sin(&p->addr, sin); 08729 08730 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08731 if (!ast_test_flag64(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08732 ast_db_put("IAX/Registry", p->name, data); 08733 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08734 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08735 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08736 register_peer_exten(p, 1); 08737 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08738 } else if (!ast_test_flag64(p, IAX_TEMPONLY)) { 08739 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08740 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08741 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08742 register_peer_exten(p, 0); 08743 ast_db_del("IAX/Registry", p->name); 08744 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */ 08745 } 08746 /* Update the host */ 08747 /* Verify that the host is really there */ 08748 iax2_poke_peer(p, callno); 08749 } 08750 08751 /* modify entry in peercnts table as registered */ 08752 if (p->maxcallno) { 08753 peercnt_modify(1, p->maxcallno, &p->addr); 08754 } 08755 08756 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08757 if (!iaxs[callno]) { 08758 res = -1; 08759 goto return_unref; 08760 } 08761 08762 /* Store socket fd */ 08763 p->sockfd = fd; 08764 /* Setup the expiry */ 08765 if (p->expire > -1) { 08766 if (!ast_sched_thread_del(sched, p->expire)) { 08767 p->expire = -1; 08768 peer_unref(p); 08769 } 08770 } 08771 /* treat an unspecified refresh interval as the minimum */ 08772 if (!refresh) 08773 refresh = min_reg_expire; 08774 if (refresh > max_reg_expire) { 08775 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08776 p->name, max_reg_expire, refresh); 08777 p->expiry = max_reg_expire; 08778 } else if (refresh < min_reg_expire) { 08779 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08780 p->name, min_reg_expire, refresh); 08781 p->expiry = min_reg_expire; 08782 } else { 08783 p->expiry = refresh; 08784 } 08785 if (p->expiry && sin->sin_addr.s_addr) { 08786 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08787 if (p->expire == -1) 08788 peer_unref(p); 08789 } 08790 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08791 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08792 if (sin->sin_addr.s_addr) { 08793 struct sockaddr_in peer_addr; 08794 08795 ast_sockaddr_to_sin(&p->addr, &peer_addr); 08796 08797 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08798 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &peer_addr); 08799 if (!ast_strlen_zero(p->mailbox)) { 08800 struct ast_event *event; 08801 int new, old; 08802 char *mailbox, *context; 08803 08804 context = mailbox = ast_strdupa(p->mailbox); 08805 strsep(&context, "@"); 08806 if (ast_strlen_zero(context)) 08807 context = "default"; 08808 08809 event = ast_event_get_cached(AST_EVENT_MWI, 08810 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08811 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08812 AST_EVENT_IE_END); 08813 if (event) { 08814 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08815 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08816 ast_event_destroy(event); 08817 } else { /* Fall back on checking the mailbox directly */ 08818 ast_app_inboxcount(p->mailbox, &new, &old); 08819 } 08820 08821 if (new > 255) { 08822 new = 255; 08823 } 08824 if (old > 255) { 08825 old = 255; 08826 } 08827 msgcount = (old << 8) | new; 08828 08829 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08830 } 08831 if (ast_test_flag64(p, IAX_HASCALLERID)) { 08832 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08833 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08834 } 08835 } 08836 version = iax_check_version(devtype); 08837 if (version) 08838 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08839 08840 res = 0; 08841 08842 return_unref: 08843 peer_unref(p); 08844 08845 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08846 }
static int user_cmp_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 1674 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and user.
Referenced by load_objects().
01675 { 01676 struct iax2_user *user = obj, *user2 = arg; 01677 01678 return !strcmp(user->name, user2->name) ? CMP_MATCH | CMP_STOP : 0; 01679 }
static int user_delme_cb | ( | void * | obj, | |
void * | arg, | |||
int | flags | |||
) | [static] |
Definition at line 12900 of file chan_iax2.c.
References ast_set_flag64, IAX_DELME, and user.
Referenced by delete_users().
12901 { 12902 struct iax2_user *user = obj; 12903 12904 ast_set_flag64(user, IAX_DELME); 12905 12906 return 0; 12907 }
static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12625 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().
12626 { 12627 struct iax2_user *user = obj; 12628 12629 ast_free_ha(user->ha); 12630 free_context(user->contexts); 12631 if(user->vars) { 12632 ast_variables_destroy(user->vars); 12633 user->vars = NULL; 12634 } 12635 ast_string_field_free_memory(user); 12636 }
static int user_hash_cb | ( | const void * | obj, | |
const int | flags | |||
) | [static] |
Definition at line 1664 of file chan_iax2.c.
References ast_str_hash(), and user.
Referenced by load_objects().
01665 { 01666 const struct iax2_user *user = obj; 01667 01668 return ast_str_hash(user->name); 01669 }
Definition at line 1727 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 14566 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.
14568 { 14569 struct ast_data *data_user, *data_authmethods, *data_enum_node; 14570 struct iax2_user *user; 14571 struct ao2_iterator i; 14572 char auth[90]; 14573 char *pstr = ""; 14574 14575 i = ao2_iterator_init(users, 0); 14576 for (; (user = ao2_iterator_next(&i)); user_unref(user)) { 14577 data_user = ast_data_add_node(data_root, "user"); 14578 if (!data_user) { 14579 continue; 14580 } 14581 14582 ast_data_add_structure(iax2_user, data_user, user); 14583 14584 ast_data_add_codecs(data_user, "codecs", user->capability); 14585 14586 if (!ast_strlen_zero(user->secret)) { 14587 ast_copy_string(auth, user->secret, sizeof(auth)); 14588 } else if (!ast_strlen_zero(user->inkeys)) { 14589 snprintf(auth, sizeof(auth), "Key: %s", user->inkeys); 14590 } else { 14591 ast_copy_string(auth, "no secret", sizeof(auth)); 14592 } 14593 ast_data_add_password(data_user, "secret", auth); 14594 14595 ast_data_add_str(data_user, "context", user->contexts ? user->contexts->context : DEFAULT_CONTEXT); 14596 14597 /* authmethods */ 14598 data_authmethods = ast_data_add_node(data_user, "authmethods"); 14599 if (!data_authmethods) { 14600 ast_data_remove_node(data_root, data_user); 14601 continue; 14602 } 14603 ast_data_add_bool(data_authmethods, "rsa", user->authmethods & IAX_AUTH_RSA); 14604 ast_data_add_bool(data_authmethods, "md5", user->authmethods & IAX_AUTH_MD5); 14605 ast_data_add_bool(data_authmethods, "plaintext", user->authmethods & IAX_AUTH_PLAINTEXT); 14606 14607 /* amaflags */ 14608 data_enum_node = ast_data_add_node(data_user, "amaflags"); 14609 if (!data_enum_node) { 14610 ast_data_remove_node(data_root, data_user); 14611 continue; 14612 } 14613 ast_data_add_int(data_enum_node, "value", user->amaflags); 14614 ast_data_add_str(data_enum_node, "text", ast_cdr_flags2str(user->amaflags)); 14615 14616 ast_data_add_bool(data_user, "access-control", user->ha ? 1 : 0); 14617 14618 if (ast_test_flag64(user, IAX_CODEC_NOCAP)) { 14619 pstr = "REQ only"; 14620 } else if (ast_test_flag64(user, IAX_CODEC_NOPREFS)) { 14621 pstr = "disabled"; 14622 } else { 14623 pstr = ast_test_flag64(user, IAX_CODEC_USER_FIRST) ? "caller" : "host"; 14624 } 14625 ast_data_add_str(data_user, "codec-preferences", pstr); 14626 14627 if (!ast_data_search_match(search, data_user)) { 14628 ast_data_remove_node(data_root, data_user); 14629 } 14630 } 14631 ao2_iterator_destroy(&i); 14632 14633 return 0; 14634 }
static void vnak_retransmit | ( | int | callno, | |
int | last | |||
) | [static] |
Definition at line 9049 of file chan_iax2.c.
References AST_LIST_TRAVERSE, f, frame_queue, iax_frame::list, and send_packet().
Referenced by socket_process().
09050 { 09051 struct iax_frame *f; 09052 09053 AST_LIST_TRAVERSE(&frame_queue[callno], f, list) { 09054 /* Send a copy immediately */ 09055 if (((unsigned char) (f->oseqno - last) < 128) && 09056 (f->retries >= 0)) { 09057 send_packet(f); 09058 } 09059 } 09060 }
static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5243 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().
05244 { 05245 unsigned short callno = pvt->callno; 05246 05247 if (!pvt->peercallno) { 05248 /* We don't know the remote side's call number, yet. :( */ 05249 int count = 10; 05250 while (count-- && pvt && !pvt->peercallno) { 05251 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05252 pvt = iaxs[callno]; 05253 } 05254 if (!pvt->peercallno) { 05255 return -1; 05256 } 05257 } 05258 05259 return 0; 05260 }
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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .reload = reload, .load_pri = AST_MODPRI_CHANNEL_DRIVER, .nonoptreq = "res_crypto", } [static] |
Definition at line 14775 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 379 of file chan_iax2.c.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_async_goto(), ast_call_forward(), ast_cdr_setaccount(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_set_owners_and_peers(), begin_dial_channel(), build_peer(), check_peer_ok(), create_addr_from_peer(), dahdi_new(), 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 383 of file chan_iax2.c.
int amaflags = 0 [static] |
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 14775 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 290 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 291 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 890 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 845 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 850 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 848 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 893 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 301 of file chan_iax2.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1097 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 895 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 897 of file chan_iax2.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Definition at line 268 of file chan_iax2.c.
Referenced by create_dynamic_parkinglot(), handle_parkedcalls(), load_config(), park_call_exec(), park_space_reserve(), parked_call_exec(), reload_config(), sip_alloc(), and xfer_park_call_helper().
int defaultsockfd = -1 [static] |
Definition at line 313 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 384 of file chan_iax2.c.
Definition at line 861 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 263 of file chan_iax2.c.
uint16_t global_maxcallno [static] |
Definition at line 899 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 902 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 435 of file chan_iax2.c.
struct ast_flags64 globalflags = { 0 } [static] |
Definition at line 387 of file chan_iax2.c.
format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 365 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 14646 of file chan_iax2.c.
Referenced by load_module().
int iax2_encryption = 0 [static] |
Definition at line 385 of file chan_iax2.c.
int(*) iax2_regfunk(const char *username, int onoff) = NULL [static] |
Definition at line 315 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 1215 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 1330 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 1074 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 1090 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 634 of file chan_iax2.c.
Referenced by iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 292 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 367 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 295 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 297 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 13913 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 1063 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 1083 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 630 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 369 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 9843 of file chan_iax2.c.
Referenced by load_module(), and unload_module().
struct io_context* io [static] |
Definition at line 360 of file chan_iax2.c.
int jittertargetextra = 40 [static] |
Definition at line 283 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 279 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 270 of file chan_iax2.c.
Definition at line 861 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 293 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 867 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 305 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 277 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 276 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 280 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 282 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 1164 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 1163 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 304 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 380 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 381 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 311 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 389 of file chan_iax2.c.
int network_change_event_sched_id = -1 [static] |
Definition at line 274 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 273 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 312 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 887 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 881 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(), get_insecure_variable_from_sipregs(), 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 14636 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 278 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 254 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 865 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 271 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 281 of file chan_iax2.c.
struct ast_sched_thread* sched [static] |
Definition at line 361 of file chan_iax2.c.
int srvlookup = 0 [static] |
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 256 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 371 of file chan_iax2.c.
Definition at line 309 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 300 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 904 of file chan_iax2.c.
struct ast_taskprocessor* transmit_processor [static] |
Definition at line 863 of file chan_iax2.c.
int trunk_maxmtu [static] |
Definition at line 264 of file chan_iax2.c.
int trunk_nmaxmtu [static] |
Trunk MTU statistics
Definition at line 264 of file chan_iax2.c.
int trunk_timed [static] |
Definition at line 264 of file chan_iax2.c.
int trunk_untimed [static] |
Definition at line 264 of file chan_iax2.c.
int trunkfreq = 20 [static] |
Definition at line 287 of file chan_iax2.c.
int trunkmaxsize = MAX_TRUNKDATA [static] |
Definition at line 288 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 884 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 14641 of file chan_iax2.c.