Implementation of Inter-Asterisk eXchange Version 2. More...
#include "asterisk.h"#include <sys/mman.h>#include <dirent.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <sys/time.h>#include <sys/signal.h>#include <signal.h>#include <strings.h>#include <netdb.h>#include <fcntl.h>#include <sys/stat.h>#include <regex.h>#include "asterisk/paths.h"#include "asterisk/lock.h"#include "asterisk/frame.h"#include "asterisk/channel.h"#include "asterisk/module.h"#include "asterisk/pbx.h"#include "asterisk/sched.h"#include "asterisk/io.h"#include "asterisk/config.h"#include "asterisk/cli.h"#include "asterisk/translate.h"#include "asterisk/md5.h"#include "asterisk/cdr.h"#include "asterisk/crypto.h"#include "asterisk/acl.h"#include "asterisk/manager.h"#include "asterisk/callerid.h"#include "asterisk/app.h"#include "asterisk/astdb.h"#include "asterisk/musiconhold.h"#include "asterisk/features.h"#include "asterisk/utils.h"#include "asterisk/causes.h"#include "asterisk/localtime.h"#include "asterisk/aes.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 "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 | create_addr_info |
| struct | dpcache |
| struct | dpreq_data |
| struct | dynamic_list |
| struct | firmwares |
| struct | frame_queue |
| a list of frames that may need to be retransmitted More... | |
| 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 |
| 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 | 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 | 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%s" |
| #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%s" |
| #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_CALLENCRYPTED(pvt) (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED)) |
| #define | IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
| #define | IAX_CAPABILITY_LOWBANDWIDTH |
| #define | IAX_CAPABILITY_LOWFREE |
| #define | IAX_CAPABILITY_MEDBANDWIDTH |
| #define | IAX_DEBUGDIGEST(msg, key) |
| #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 ARRAY_LEN(iaxs) / 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_flags { IAX_HASCALLERID = (1 << 0), IAX_DELME = (1 << 1), IAX_TEMPONLY = (1 << 2), IAX_TRUNK = (1 << 3), IAX_NOTRANSFER = (1 << 4), IAX_USEJITTERBUF = (1 << 5), IAX_DYNAMIC = (1 << 6), IAX_SENDANI = (1 << 7), IAX_ALREADYGONE = (1 << 9), IAX_PROVISION = (1 << 10), IAX_QUELCH = (1 << 11), IAX_ENCRYPTED = (1 << 12), IAX_KEYPOPULATED = (1 << 13), IAX_CODEC_USER_FIRST = (1 << 14), IAX_CODEC_NOPREFS = (1 << 15), IAX_CODEC_NOCAP = (1 << 16), IAX_RTCACHEFRIENDS = (1 << 17), IAX_RTUPDATE = (1 << 18), IAX_RTAUTOCLEAR = (1 << 19), IAX_FORCEJITTERBUF = (1 << 20), IAX_RTIGNOREREGEXPIRE = (1 << 21), IAX_TRUNKTIMESTAMPS = (1 << 22), IAX_TRANSFERMEDIA = (1 << 23), IAX_MAXAUTHREQ = (1 << 24), IAX_DELAYPBXSTART = (1 << 25), IAX_ALLOWFWDOWNLOAD = (1 << 26), IAX_SHRINKCALLERID = (1 << 27) } |
| 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 manager, int fd, struct mansession *s, int argc, char *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_channel_write (struct ast_channel *chan, const char *function, char *data, const char *value) |
| 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) |
| static struct ast_channel * | ast_iax2_new (int callno, int state, int capability) |
| 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 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) |
| 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 (int 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 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 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, void *data) |
| static int | iax2_provision (struct sockaddr_in *end, int sockfd, char *dest, const char *template, int force) |
| 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, int format, void *data, int *cause) |
| static int | iax2_sched_add (struct sched_context *con, int when, ast_sched_cb callback, const void *data) |
| static int | iax2_sched_replace (int id, struct sched_context *con, 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) |
| 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 | 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_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 sockaddr_in *sin) |
| 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 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 sockaddr_in *sin, 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 void * | sched_thread (void *ignore) |
| 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_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_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 int | 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 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_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } |
| 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 |
| 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_flags | globalflags = { 0 } |
| static int | iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH |
| static int | iax2_encryption = 0 |
| 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 |
| struct ast_custom_function | iaxpeer_function |
| static struct chan_iax2_pvt * | iaxs [IAX_MAX_CALLS] |
| an array of iax2 pvt structures | |
| static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
| chan_iax2_pvt structure locks | |
| static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
| static int | iaxtrunkdebug = 0 |
| static struct ast_custom_function | iaxvar_function |
| static struct io_context * | io |
| static int | jittertargetextra = 40 |
| static int | lagrq_time = 10 |
| static char | language [MAX_LANGUAGE] = "" |
| static int | last_authmethod = 0 |
| static 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 struct ast_netsock_list * | outsock |
| static char * | papp = "IAX2Provision" |
| static char * | pdescrip |
| static struct ao2_container * | peercnts |
| static struct ao2_container * | peers |
| static int | ping_time = 21 |
| static struct ast_codec_pref | prefs |
| static char * | psyn = "Provision a calling IAXy with a given template" |
| struct { | |
| unsigned int cos | |
| unsigned int tos | |
| } | qos |
| static int | randomcalltokendata |
| static char | regcontext [AST_MAX_CONTEXT] = "" |
| static int | resyncthreshold = 1000 |
| static struct sched_context * | sched |
| static ast_cond_t | sched_cond |
| static ast_mutex_t | sched_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) |
| static pthread_t | schedthreadid = AST_PTHREADT_NULL |
| 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 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 |
Implementation of Inter-Asterisk eXchange Version 2.
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 111 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 DEBUG_SCHED_MULTITHREAD |
Definition at line 103 of file chan_iax2.c.
| #define DEBUG_SUPPORT |
Definition at line 119 of file chan_iax2.c.
| #define DEFAULT_CONTEXT "default" |
Definition at line 138 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), and reload_config().
| #define DEFAULT_DROP 3 |
Definition at line 117 of file chan_iax2.c.
| #define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 207 of file chan_iax2.c.
Referenced by build_peer(), handle_response_peerpoke(), and sip_poke_noanswer().
| #define DEFAULT_FREQ_OK 60 * 1000 |
Definition at line 206 of file chan_iax2.c.
Referenced by build_peer().
| #define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 114 of file chan_iax2.c.
| #define DEFAULT_MAXMS 2000 |
Definition at line 205 of file chan_iax2.c.
| #define DEFAULT_RETRY_TIME 1000 |
Definition at line 115 of file chan_iax2.c.
Referenced by __find_callno(), and complete_transfer().
| #define DEFAULT_THREAD_COUNT 10 |
Definition at line 113 of file chan_iax2.c.
| #define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 487 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
| #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%s" |
| #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%s" |
| #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 124 of file chan_iax2.c.
| #define IAX2_TRUNK_PREFACE (sizeof(struct iax_frame) + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) |
Definition at line 408 of file chan_iax2.c.
Referenced by iax2_trunk_queue().
| #define IAX_CALLENCRYPTED | ( | pvt | ) | (ast_test_flag(pvt, IAX_ENCRYPTED) && ast_test_flag(pvt, IAX_KEYPOPULATED)) |
Definition at line 210 of file chan_iax2.c.
Referenced by iax2_send(), iax2_start_transfer(), and socket_process().
| #define IAX_CAPABILITY_FULLBANDWIDTH (0xFFFF & ~AST_FORMAT_AUDIO_UNDEFINED) |
Definition at line 187 of file chan_iax2.c.
Referenced by cache_get_callno_locked(), and set_config().
| #define IAX_CAPABILITY_LOWBANDWIDTH |
(IAX_CAPABILITY_MEDBANDWIDTH & \ ~AST_FORMAT_G726 & \ ~AST_FORMAT_G726_AAL2 & \ ~AST_FORMAT_ADPCM)
Definition at line 196 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_CAPABILITY_LOWFREE |
Definition at line 201 of file chan_iax2.c.
| #define IAX_CAPABILITY_MEDBANDWIDTH |
Definition at line 189 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_DEBUGDIGEST | ( | msg, | |||
| key | ) |
Definition at line 213 of file chan_iax2.c.
Referenced by iax2_key_rotate(), and socket_process().
| #define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 495 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 484 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 742 of file chan_iax2.c.
Referenced by load_objects().
| #define MAX_RETRY_TIME 10000 |
Definition at line 482 of file chan_iax2.c.
Referenced by __attempt_transmit(), and iax2_send().
| #define MAX_TIMESTAMP_SKEW 160 |
maximum difference between actual and predicted ts for sending
Definition at line 489 of file chan_iax2.c.
| #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 133 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 154 of file chan_iax2.c.
Referenced by set_config(), and set_config_destroy().
| #define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
Definition at line 746 of file chan_iax2.c.
Referenced by load_module(), and load_objects().
| #define MEMORY_SIZE 100 |
Definition at line 116 of file chan_iax2.c.
| #define MIN_JITTER_BUFFER 10 |
Definition at line 485 of file chan_iax2.c.
| #define MIN_RETRY_TIME 100 |
Definition at line 481 of file chan_iax2.c.
Referenced by iax2_send().
| #define MIN_REUSE_TIME 60 |
Definition at line 121 of file chan_iax2.c.
Referenced by make_trunk(), and sched_delay_remove().
| #define PTR_TO_CALLNO | ( | a | ) | ((unsigned short)(unsigned long)(a)) |
Definition at line 110 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), acf_channel_read(), acf_channel_write(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
| #define SCHED_MULTITHREADED |
Definition at line 99 of file chan_iax2.c.
| #define schedule_action | ( | func, | |||
| data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1271 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 ARRAY_LEN(iaxs) / 2 |
Definition at line 956 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 492 of file chan_iax2.c.
| anonymous enum |
Definition at line 802 of file chan_iax2.c.
00802 { 00803 /*! Extension exists */ 00804 CACHE_FLAG_EXISTS = (1 << 0), 00805 /*! Extension is nonexistent */ 00806 CACHE_FLAG_NONEXISTENT = (1 << 1), 00807 /*! Extension can exist */ 00808 CACHE_FLAG_CANEXIST = (1 << 2), 00809 /*! Waiting to hear back response */ 00810 CACHE_FLAG_PENDING = (1 << 3), 00811 /*! Timed out */ 00812 CACHE_FLAG_TIMEOUT = (1 << 4), 00813 /*! Request transmitted */ 00814 CACHE_FLAG_TRANSMITTED = (1 << 5), 00815 /*! Timeout */ 00816 CACHE_FLAG_UNKNOWN = (1 << 6), 00817 /*! Matchmore */ 00818 CACHE_FLAG_MATCHMORE = (1 << 7), 00819 };
| anonymous enum |
Definition at line 1728 of file chan_iax2.c.
01728 { 01729 /* do not allow a new call number, only search ones in use for match */ 01730 NEW_PREVENT = 0, 01731 /* search for match first, then allow a new one to be allocated */ 01732 NEW_ALLOW = 1, 01733 /* do not search for match, force a new call number */ 01734 NEW_FORCE = 2, 01735 /* do not search for match, force a new call number. Signifies call number 01736 * has been calltoken validated */ 01737 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01738 };
| enum calltoken_peer_enum |
Call token validation settings.
Definition at line 309 of file chan_iax2.c.
00309 { 00310 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00311 CALLTOKEN_DEFAULT = 0, 00312 /*! \brief Require call token validation. */ 00313 CALLTOKEN_YES = 1, 00314 /*! \brief Require call token validation after a successful registration 00315 * using call token validation occurs. */ 00316 CALLTOKEN_AUTO = 2, 00317 /*! \brief Do not require call token validation. */ 00318 CALLTOKEN_NO = 3, 00319 };
| enum iax2_flags |
Definition at line 269 of file chan_iax2.c.
00269 { 00270 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00271 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00272 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00273 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00274 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00275 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00276 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00277 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00278 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00279 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00280 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00281 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00282 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00283 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00284 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00285 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00286 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00287 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00288 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00289 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00290 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00291 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00292 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00293 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00294 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00295 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00296 response, so that we've achieved a three-way handshake with 00297 them before sending voice or anything else*/ 00298 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00299 IAX_SHRINKCALLERID = (1 << 27), /*!< Turn on and off caller id shrinking */ 00300 };
| enum iax2_state |
Definition at line 258 of file chan_iax2.c.
00258 { 00259 IAX_STATE_STARTED = (1 << 0), 00260 IAX_STATE_AUTHENTICATED = (1 << 1), 00261 IAX_STATE_TBD = (1 << 2), 00262 };
| enum iax2_thread_iostate |
Definition at line 843 of file chan_iax2.c.
00843 { 00844 IAX_IOSTATE_IDLE, 00845 IAX_IOSTATE_READY, 00846 IAX_IOSTATE_PROCESSING, 00847 IAX_IOSTATE_SCHEDREADY, 00848 };
| enum iax2_thread_type |
Definition at line 850 of file chan_iax2.c.
00850 { 00851 IAX_THREAD_TYPE_POOL, 00852 IAX_THREAD_TYPE_DYNAMIC, 00853 };
| 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 440 of file chan_iax2.c.
00440 { 00441 REG_STATE_UNREGISTERED = 0, 00442 REG_STATE_REGSENT, 00443 REG_STATE_AUTHSENT, 00444 REG_STATE_REGISTERED, 00445 REG_STATE_REJECTED, 00446 REG_STATE_TIMEOUT, 00447 REG_STATE_NOAUTH 00448 };
| 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 450 of file chan_iax2.c.
00450 { 00451 TRANSFER_NONE = 0, 00452 TRANSFER_BEGIN, 00453 TRANSFER_READY, 00454 TRANSFER_RELEASED, 00455 TRANSFER_PASSTHROUGH, 00456 TRANSFER_MBEGIN, 00457 TRANSFER_MREADY, 00458 TRANSFER_MRELEASED, 00459 TRANSFER_MPASSTHROUGH, 00460 TRANSFER_MEDIA, 00461 TRANSFER_MEDIAPASS 00462 };
| static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3214 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_IAX, ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), attempt_transmit(), iax_frame::callno, chan_iax2_pvt::error, f, iax_frame::final, ast_frame::frametype, ast_channel::hangupcause, iax2_destroy(), iax2_frame_free(), iax2_queue_frame(), iax2_sched_add(), IAX_COMMAND_TXREJ, IAX_DEFAULT_REG_EXPIRE, LOG_WARNING, MAX_RETRY_TIME, iax_frame::oseqno, chan_iax2_pvt::owner, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_TIMEOUT, iax2_registry::regstate, iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_command(), send_packet(), ast_frame::subclass, iax_frame::transfer, iax_frame::ts, update_packet(), and iax2_registry::us.
Referenced by attempt_transmit().
03215 { 03216 /* Attempt to transmit the frame to the remote peer... 03217 Called without iaxsl held. */ 03218 struct iax_frame *f = (struct iax_frame *)data; 03219 int freeme = 0; 03220 int callno = f->callno; 03221 /* Make sure this call is still active */ 03222 if (callno) 03223 ast_mutex_lock(&iaxsl[callno]); 03224 if (callno && iaxs[callno]) { 03225 if ((f->retries < 0) /* Already ACK'd */ || 03226 (f->retries >= max_retries) /* Too many attempts */) { 03227 /* Record an error if we've transmitted too many times */ 03228 if (f->retries >= max_retries) { 03229 if (f->transfer) { 03230 /* Transfer timeout */ 03231 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03232 } else if (f->final) { 03233 if (f->final) 03234 iax2_destroy(callno); 03235 } else { 03236 if (iaxs[callno]->owner) 03237 ast_log(LOG_WARNING, "Max retries exceeded to host %s on %s (type = %d, subclass = %d, 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, f->ts, f->oseqno); 03238 iaxs[callno]->error = ETIMEDOUT; 03239 if (iaxs[callno]->owner) { 03240 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03241 /* Hangup the fd */ 03242 iax2_queue_frame(callno, &fr); /* XXX */ 03243 /* Remember, owner could disappear */ 03244 if (iaxs[callno] && iaxs[callno]->owner) 03245 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03246 } else { 03247 if (iaxs[callno]->reg) { 03248 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03249 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03250 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03251 } 03252 iax2_destroy(callno); 03253 } 03254 } 03255 03256 } 03257 freeme = 1; 03258 } else { 03259 /* Update it if it needs it */ 03260 update_packet(f); 03261 /* Attempt transmission */ 03262 send_packet(f); 03263 f->retries++; 03264 /* Try again later after 10 times as long */ 03265 f->retrytime *= 10; 03266 if (f->retrytime > MAX_RETRY_TIME) 03267 f->retrytime = MAX_RETRY_TIME; 03268 /* Transfer messages max out at one second */ 03269 if (f->transfer && (f->retrytime > 1000)) 03270 f->retrytime = 1000; 03271 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03272 } 03273 } else { 03274 /* Make sure it gets freed */ 03275 f->retries = -1; 03276 freeme = 1; 03277 } 03278 if (callno) 03279 ast_mutex_unlock(&iaxsl[callno]); 03280 /* Do not try again */ 03281 if (freeme) { 03282 /* Don't attempt delivery, just remove it from the queue */ 03283 AST_LIST_LOCK(&frame_queue); 03284 AST_LIST_REMOVE(&frame_queue, f, list); 03285 AST_LIST_UNLOCK(&frame_queue); 03286 f->retrans = -1; /* this is safe because this is the scheduled function */ 03287 /* Free the IAX frame */ 03288 iax2_frame_free(f); 03289 } 03290 }
| static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 8436 of file chan_iax2.c.
References AST_CAUSE_FACILITY_NOT_SUBSCRIBED, AST_CAUSE_FACILITY_REJECTED, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax_ie_data::buf, IAX_COMMAND_REGREJ, IAX_COMMAND_REJECT, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iax_ie_data::pos, and send_command_final().
Referenced by auth_reject().
08437 { 08438 /* Called from IAX thread only, without iaxs lock */ 08439 int callno = (int)(long)(nothing); 08440 struct iax_ie_data ied; 08441 ast_mutex_lock(&iaxsl[callno]); 08442 if (iaxs[callno]) { 08443 memset(&ied, 0, sizeof(ied)); 08444 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 08445 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 08446 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 08447 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 08448 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 08449 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08450 } 08451 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 08452 } 08453 ast_mutex_unlock(&iaxsl[callno]); 08454 }
| static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4324 of file chan_iax2.c.
References AST_CONTROL_CONGESTION, AST_FRAME_CONTROL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_queue_frame(), chan_iax2_pvt::initid, LOG_NOTICE, and PTR_TO_CALLNO.
Referenced by auto_congest().
04325 { 04326 int callno = PTR_TO_CALLNO(nothing); 04327 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 04328 ast_mutex_lock(&iaxsl[callno]); 04329 if (iaxs[callno]) { 04330 iaxs[callno]->initid = -1; 04331 iax2_queue_frame(callno, &f); 04332 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04333 } 04334 ast_mutex_unlock(&iaxsl[callno]); 04335 }
| static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 8485 of file chan_iax2.c.
References AST_CAUSE_NO_USER_RESPONSE, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax_ie_data::buf, IAX_COMMAND_HANGUP, iax_ie_append_byte(), iax_ie_append_str(), IAX_IE_CAUSE, IAX_IE_CAUSECODE, iax_ie_data::pos, and send_command_final().
Referenced by auto_hangup().
08486 { 08487 /* Called from IAX thread only, without iaxs lock */ 08488 int callno = (int)(long)(nothing); 08489 struct iax_ie_data ied; 08490 ast_mutex_lock(&iaxsl[callno]); 08491 if (iaxs[callno]) { 08492 memset(&ied, 0, sizeof(ied)); 08493 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 08494 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 08495 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 08496 } 08497 ast_mutex_unlock(&iaxsl[callno]); 08498 }
| static int __do_deliver | ( | void * | data | ) | [static] |
Definition at line 3009 of file chan_iax2.c.
References iax_frame::af, ast_clear_flag, AST_FRFLAG_HAS_TIMING_INFO, ast_test_flag, iax_frame::callno, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, and iax_frame::retrans.
Referenced by __get_from_jb(), and schedule_delivery().
03010 { 03011 /* Just deliver the packet by using queueing. This is called by 03012 the IAX thread with the iaxsl lock held. */ 03013 struct iax_frame *fr = data; 03014 fr->retrans = -1; 03015 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03016 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 03017 iax2_queue_frame(fr->callno, &fr->af); 03018 /* Free our iax frame */ 03019 iax2_frame_free(fr); 03020 /* And don't run again */ 03021 return 0; 03022 }
| static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8084 of file chan_iax2.c.
References iax2_peer::addr, ast_db_del(), ast_debug, AST_DEVICE_UNAVAILABLE, ast_devstate_changed(), ast_test_flag, EVENT_FLAG_SYSTEM, iax2_peer::expire, iax2_peer::expiry, 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().
08085 { 08086 struct iax2_peer *peer = (struct iax2_peer *) data; 08087 08088 if (!peer) 08089 return; 08090 08091 peer->expire = -1; 08092 08093 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08094 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08095 realtime_update_peer(peer->name, &peer->addr, 0); 08096 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08097 /* modify entry in peercnts table as _not_ registered */ 08098 peercnt_modify(0, 0, &peer->addr); 08099 /* Reset the address */ 08100 memset(&peer->addr, 0, sizeof(peer->addr)); 08101 /* Reset expiry value */ 08102 peer->expiry = min_reg_expire; 08103 if (!ast_test_flag(peer, IAX_TEMPONLY)) 08104 ast_db_del("IAX/Registry", peer->name); 08105 register_peer_exten(peer, 0); 08106 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 08107 if (iax2_regfunk) 08108 iax2_regfunk(peer->name, 0); 08109 08110 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 08111 unlink_peer(peer); 08112 08113 peer_unref(peer); 08114 }
| 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 2486 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::amaflags, ao2_find, ao2_ref, ast_copy_flags, ast_debug, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_set, callno_entry::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, DEFAULT_RETRY_TIME, chan_iax2_pvt::expiry, get_unused_callno(), iax2_getpeername(), iax2_sched_add(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, chan_iax2_pvt::lagid, LOG_WARNING, match(), NEW_ALLOW, new_iax(), OBJ_POINTER, parkinglot, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingid, chan_iax2_pvt::pingtime, replace_callno(), send_lagrq(), send_ping(), chan_iax2_pvt::sockfd, store_by_peercallno(), chan_iax2_pvt::transfer, TRUNK_CALL_START, and update_max_nontrunk().
Referenced by find_callno(), and find_callno_locked().
02487 { 02488 int res = 0; 02489 int x; 02490 /* this call is calltoken validated as long as it is either NEW_FORCE 02491 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02492 int validated = (new > NEW_ALLOW) ? 1 : 0; 02493 char host[80]; 02494 02495 if (new <= NEW_ALLOW) { 02496 if (callno) { 02497 struct chan_iax2_pvt *pvt; 02498 struct chan_iax2_pvt tmp_pvt = { 02499 .callno = dcallno, 02500 .peercallno = callno, 02501 .transfercallno = callno, 02502 /* hack!! */ 02503 .frames_received = check_dcallno, 02504 }; 02505 02506 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02507 /* this works for finding normal call numbers not involving transfering */ 02508 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02509 if (return_locked) { 02510 ast_mutex_lock(&iaxsl[pvt->callno]); 02511 } 02512 res = pvt->callno; 02513 ao2_ref(pvt, -1); 02514 pvt = NULL; 02515 return res; 02516 } 02517 /* this searches for transfer call numbers that might not get caught otherwise */ 02518 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02519 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02520 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02521 if (return_locked) { 02522 ast_mutex_lock(&iaxsl[pvt->callno]); 02523 } 02524 res = pvt->callno; 02525 ao2_ref(pvt, -1); 02526 pvt = NULL; 02527 return res; 02528 } 02529 } 02530 /* This will occur on the first response to a message that we initiated, 02531 * such as a PING. */ 02532 if (dcallno) { 02533 ast_mutex_lock(&iaxsl[dcallno]); 02534 } 02535 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02536 iaxs[dcallno]->peercallno = callno; 02537 res = dcallno; 02538 store_by_peercallno(iaxs[dcallno]); 02539 if (!res || !return_locked) { 02540 ast_mutex_unlock(&iaxsl[dcallno]); 02541 } 02542 return res; 02543 } 02544 if (dcallno) { 02545 ast_mutex_unlock(&iaxsl[dcallno]); 02546 } 02547 #ifdef IAX_OLD_FIND 02548 /* If we get here, we SHOULD NOT find a call structure for this 02549 callno; if we do, it means that there is a call structure that 02550 has a peer callno but did NOT get entered into the hash table, 02551 which is bad. 02552 02553 If we find a call structure using this old, slow method, output a log 02554 message so we'll know about it. After a few months of leaving this in 02555 place, if we don't hear about people seeing these messages, we can 02556 remove this code for good. 02557 */ 02558 02559 for (x = 1; !res && x < maxnontrunkcall; x++) { 02560 ast_mutex_lock(&iaxsl[x]); 02561 if (iaxs[x]) { 02562 /* Look for an exact match */ 02563 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02564 res = x; 02565 } 02566 } 02567 if (!res || !return_locked) 02568 ast_mutex_unlock(&iaxsl[x]); 02569 } 02570 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02571 ast_mutex_lock(&iaxsl[x]); 02572 if (iaxs[x]) { 02573 /* Look for an exact match */ 02574 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02575 res = x; 02576 } 02577 } 02578 if (!res || !return_locked) 02579 ast_mutex_unlock(&iaxsl[x]); 02580 } 02581 #endif 02582 } 02583 if (!res && (new >= NEW_ALLOW)) { 02584 struct callno_entry *callno_entry; 02585 /* It may seem odd that we look through the peer list for a name for 02586 * this *incoming* call. Well, it is weird. However, users don't 02587 * have an IP address/port number that we can match against. So, 02588 * this is just checking for a peer that has that IP/port and 02589 * assuming that we have a user of the same name. This isn't always 02590 * correct, but it will be changed if needed after authentication. */ 02591 if (!iax2_getpeername(*sin, host, sizeof(host))) 02592 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02593 02594 if (peercnt_add(sin)) { 02595 /* This address has hit its callnumber limit. When the limit 02596 * is reached, the connection is not added to the peercnts table.*/ 02597 return 0; 02598 } 02599 02600 if (!(callno_entry = get_unused_callno(0, validated))) { 02601 /* since we ran out of space, remove the peercnt 02602 * entry we added earlier */ 02603 peercnt_remove_by_addr(sin); 02604 ast_log(LOG_WARNING, "No more space\n"); 02605 return 0; 02606 } 02607 x = callno_entry->callno; 02608 ast_mutex_lock(&iaxsl[x]); 02609 02610 iaxs[x] = new_iax(sin, host); 02611 update_max_nontrunk(); 02612 if (iaxs[x]) { 02613 if (iaxdebug) 02614 ast_debug(1, "Creating new call structure %d\n", x); 02615 iaxs[x]->callno_entry = callno_entry; 02616 iaxs[x]->sockfd = sockfd; 02617 iaxs[x]->addr.sin_port = sin->sin_port; 02618 iaxs[x]->addr.sin_family = sin->sin_family; 02619 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02620 iaxs[x]->peercallno = callno; 02621 iaxs[x]->callno = x; 02622 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02623 iaxs[x]->expiry = min_reg_expire; 02624 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02625 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02626 iaxs[x]->amaflags = amaflags; 02627 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 02628 02629 ast_string_field_set(iaxs[x], accountcode, accountcode); 02630 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02631 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02632 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02633 02634 if (iaxs[x]->peercallno) { 02635 store_by_peercallno(iaxs[x]); 02636 } 02637 } else { 02638 ast_log(LOG_WARNING, "Out of resources\n"); 02639 ast_mutex_unlock(&iaxsl[x]); 02640 replace_callno(callno_entry); 02641 return 0; 02642 } 02643 if (!return_locked) 02644 ast_mutex_unlock(&iaxsl[x]); 02645 res = x; 02646 } 02647 return res; 02648 }
| static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3777 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_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), iax2_queue_frame(), IAX_ALREADYGONE, chan_iax2_pvt::jb, JB_DROP, JB_EMPTY, jb_get(), JB_INTERP, jb_next(), JB_NOFRAME, JB_OK, chan_iax2_pvt::jbid, jb_frame::ms, ast_frame::offset, PTR_TO_CALLNO, chan_iax2_pvt::rxcore, ast_frame::samples, ast_frame::src, ast_frame::subclass, update_jbsched(), and chan_iax2_pvt::voiceformat.
Referenced by get_from_jb().
03778 { 03779 int callno = PTR_TO_CALLNO(p); 03780 struct chan_iax2_pvt *pvt = NULL; 03781 struct iax_frame *fr; 03782 jb_frame frame; 03783 int ret; 03784 long ms; 03785 long next; 03786 struct timeval now = ast_tvnow(); 03787 03788 /* Make sure we have a valid private structure before going on */ 03789 ast_mutex_lock(&iaxsl[callno]); 03790 pvt = iaxs[callno]; 03791 if (!pvt) { 03792 /* No go! */ 03793 ast_mutex_unlock(&iaxsl[callno]); 03794 return; 03795 } 03796 03797 pvt->jbid = -1; 03798 03799 /* round up a millisecond since ast_sched_runq does; */ 03800 /* prevents us from spinning while waiting for our now */ 03801 /* to catch up with runq's now */ 03802 now.tv_usec += 1000; 03803 03804 ms = ast_tvdiff_ms(now, pvt->rxcore); 03805 03806 if(ms >= (next = jb_next(pvt->jb))) { 03807 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 03808 switch(ret) { 03809 case JB_OK: 03810 fr = frame.data; 03811 __do_deliver(fr); 03812 /* __do_deliver() can cause the call to disappear */ 03813 pvt = iaxs[callno]; 03814 break; 03815 case JB_INTERP: 03816 { 03817 struct ast_frame af = { 0, }; 03818 03819 /* create an interpolation frame */ 03820 af.frametype = AST_FRAME_VOICE; 03821 af.subclass = pvt->voiceformat; 03822 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 03823 af.src = "IAX2 JB interpolation"; 03824 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 03825 af.offset = AST_FRIENDLY_OFFSET; 03826 03827 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 03828 * which we'd need to malloc, and then it would free it. That seems like a drag */ 03829 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 03830 iax2_queue_frame(callno, &af); 03831 /* iax2_queue_frame() could cause the call to disappear */ 03832 pvt = iaxs[callno]; 03833 } 03834 } 03835 break; 03836 case JB_DROP: 03837 iax2_frame_free(frame.data); 03838 break; 03839 case JB_NOFRAME: 03840 case JB_EMPTY: 03841 /* do nothing */ 03842 break; 03843 default: 03844 /* shouldn't happen */ 03845 break; 03846 } 03847 } 03848 if (pvt) 03849 update_jbsched(pvt); 03850 ast_mutex_unlock(&iaxsl[callno]); 03851 }
| static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7763 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
07764 { 07765 struct iax2_registry *reg = (struct iax2_registry *)data; 07766 reg->expire = -1; 07767 iax2_do_register(reg); 07768 }
| static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11269 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(), iax2_peer::lastms, LOG_NOTICE, manager_event, iax2_peer::name, peer_ref(), peer_unref(), iax2_peer::pokeexpire, and iax2_peer::pokefreqnotok.
Referenced by iax2_poke_noanswer().
11270 { 11271 struct iax2_peer *peer = (struct iax2_peer *)data; 11272 int callno; 11273 11274 if (peer->lastms > -1) { 11275 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 11276 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 11277 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 11278 } 11279 if ((callno = peer->callno) > 0) { 11280 ast_mutex_lock(&iaxsl[callno]); 11281 iax2_destroy(callno); 11282 ast_mutex_unlock(&iaxsl[callno]); 11283 } 11284 peer->callno = 0; 11285 peer->lastms = -1; 11286 /* Try again quickly */ 11287 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11288 if (peer->pokeexpire == -1) 11289 peer_unref(peer); 11290 }
| static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 8548 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
08549 { 08550 struct iax2_peer *peer = (struct iax2_peer *)data; 08551 iax2_poke_peer(peer, 0); 08552 peer_unref(peer); 08553 }
| static int __iax2_show_peers | ( | int | manager, | |
| int | fd, | |||
| struct mansession * | s, | |||
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 6218 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_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), RESULT_SHOWUSAGE, RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().
06219 { 06220 regex_t regexbuf; 06221 int havepattern = 0; 06222 int total_peers = 0; 06223 int online_peers = 0; 06224 int offline_peers = 0; 06225 int unmonitored_peers = 0; 06226 struct ao2_iterator i; 06227 06228 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 06229 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 06230 06231 struct iax2_peer *peer = NULL; 06232 char name[256]; 06233 int registeredonly=0; 06234 char *term = manager ? "\r\n" : "\n"; 06235 char idtext[256] = ""; 06236 switch (argc) { 06237 case 6: 06238 if (!strcasecmp(argv[3], "registered")) 06239 registeredonly = 1; 06240 else 06241 return RESULT_SHOWUSAGE; 06242 if (!strcasecmp(argv[4], "like")) { 06243 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06244 return RESULT_SHOWUSAGE; 06245 havepattern = 1; 06246 } else 06247 return RESULT_SHOWUSAGE; 06248 break; 06249 case 5: 06250 if (!strcasecmp(argv[3], "like")) { 06251 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06252 return RESULT_SHOWUSAGE; 06253 havepattern = 1; 06254 } else 06255 return RESULT_SHOWUSAGE; 06256 break; 06257 case 4: 06258 if (!strcasecmp(argv[3], "registered")) 06259 registeredonly = 1; 06260 else 06261 return RESULT_SHOWUSAGE; 06262 break; 06263 case 3: 06264 break; 06265 default: 06266 return RESULT_SHOWUSAGE; 06267 } 06268 06269 06270 if (!s) 06271 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 06272 06273 i = ao2_iterator_init(peers, 0); 06274 for (peer = ao2_iterator_next(&i); peer; 06275 peer_unref(peer), peer = ao2_iterator_next(&i)) { 06276 char nm[20]; 06277 char status[20]; 06278 char srch[2000]; 06279 int retstatus; 06280 06281 if (registeredonly && !peer->addr.sin_addr.s_addr) 06282 continue; 06283 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 06284 continue; 06285 06286 if (!ast_strlen_zero(peer->username)) 06287 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06288 else 06289 ast_copy_string(name, peer->name, sizeof(name)); 06290 06291 retstatus = peer_status(peer, status, sizeof(status)); 06292 if (retstatus > 0) 06293 online_peers++; 06294 else if (!retstatus) 06295 offline_peers++; 06296 else 06297 unmonitored_peers++; 06298 06299 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06300 06301 snprintf(srch, sizeof(srch), FORMAT, name, 06302 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 06303 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06304 nm, 06305 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 06306 peer->encmethods ? "(E)" : " ", status, term); 06307 06308 if (s) 06309 astman_append(s, 06310 "Event: PeerEntry\r\n%s" 06311 "Channeltype: IAX2\r\n" 06312 "ChanObjectType: peer\r\n" 06313 "ObjectName: %s\r\n" 06314 "IPaddress: %s\r\n" 06315 "IPport: %d\r\n" 06316 "Dynamic: %s\r\n" 06317 "Status: %s\r\n\r\n", 06318 idtext, 06319 name, 06320 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-", 06321 ntohs(peer->addr.sin_port), 06322 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no", 06323 status); 06324 06325 else 06326 ast_cli(fd, FORMAT, name, 06327 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 06328 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06329 nm, 06330 ntohs(peer->addr.sin_port), ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 06331 peer->encmethods ? "(E)" : " ", status, term); 06332 total_peers++; 06333 } 06334 ao2_iterator_destroy(&i); 06335 06336 if (!s) 06337 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 06338 06339 if (havepattern) 06340 regfree(®exbuf); 06341 06342 return RESULT_SUCCESS; 06343 #undef FORMAT 06344 #undef FORMAT2 06345 }
| static void __reg_module | ( | void | ) | [static] |
Definition at line 13776 of file chan_iax2.c.
| static int __schedule_action | ( | void(*)(const void *data) | func, | |
| const void * | data, | |||
| const char * | funcname | |||
| ) | [static] |
Definition at line 1246 of file chan_iax2.c.
References ast_copy_string(), ast_debug, iax2_thread::cond, iax2_thread::curfunc, find_idle_thread(), IAX_IOSTATE_SCHEDREADY, iax2_thread::iostate, iax2_thread::lock, iax2_thread::scheddata, iax2_thread::schedfunc, signal_condition(), and thread.
01247 { 01248 struct iax2_thread *thread = NULL; 01249 static time_t lasterror; 01250 static time_t t; 01251 01252 thread = find_idle_thread(); 01253 01254 if (thread != NULL) { 01255 thread->schedfunc = func; 01256 thread->scheddata = data; 01257 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01258 #ifdef DEBUG_SCHED_MULTITHREAD 01259 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01260 #endif 01261 signal_condition(&thread->lock, &thread->cond); 01262 return 0; 01263 } 01264 time(&t); 01265 if (t != lasterror) 01266 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01267 lasterror = t; 01268 01269 return -1; 01270 }
| 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 6969 of file chan_iax2.c.
References ast_frame::data, ast_frame::datalen, ast_frame::frametype, iax2_send(), ast_frame::ptr, queue_signalling(), ast_frame::src, and ast_frame::subclass.
Referenced by send_command(), send_command_final(), send_command_immediate(), and send_command_transfer().
06971 { 06972 struct ast_frame f = { 0, }; 06973 int res = 0; 06974 06975 f.frametype = type; 06976 f.subclass = command; 06977 f.datalen = datalen; 06978 f.src = __FUNCTION__; 06979 f.data.ptr = (void *) data; 06980 06981 if ((res = queue_signalling(i, &f)) <= 0) { 06982 return res; 06983 } 06984 06985 return iax2_send(i, &f, ts, seqno, now, transfer, final); 06986 }
| static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1339 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_thread::callno, iax2_sched_add(), IAX_COMMAND_LAGRQ, chan_iax2_pvt::lagid, send_command(), and send_lagrq().
Referenced by send_lagrq().
01340 { 01341 int callno = (long) data; 01342 01343 ast_mutex_lock(&iaxsl[callno]); 01344 01345 if (iaxs[callno]) { 01346 if (iaxs[callno]->peercallno) { 01347 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01348 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01349 } else { 01350 /* I am the schedule, so I'm allowed to do this */ 01351 iaxs[callno]->lagid = -1; 01352 } 01353 } else { 01354 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01355 } 01356 01357 ast_mutex_unlock(&iaxsl[callno]); 01358 }
| static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1294 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), iax2_thread::callno, iax2_sched_add(), IAX_COMMAND_PING, chan_iax2_pvt::pingid, send_command(), and send_ping().
Referenced by send_ping().
01295 { 01296 int callno = (long) data; 01297 01298 ast_mutex_lock(&iaxsl[callno]); 01299 01300 if (iaxs[callno]) { 01301 if (iaxs[callno]->peercallno) { 01302 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01303 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01304 } else { 01305 /* I am the schedule, so I'm allowed to do this */ 01306 iaxs[callno]->pingid = -1; 01307 } 01308 } else { 01309 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01310 } 01311 01312 ast_mutex_unlock(&iaxsl[callno]); 01313 }
| static int __unload_module | ( | void | ) | [static] |
Definition at line 13463 of file chan_iax2.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_cond_signal(), ast_context_destroy(), ast_context_find(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_netsock_release(), AST_PTHREADT_NULL, ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), delete_users(), iax2_destroy(), iax_provision_unload(), iaxactivethreadcount, reload_firmware(), sched_context_destroy(), sched_lock, thread, and iax2_thread::threadid.
Referenced by load_module(), and unload_module().
13464 { 13465 struct iax2_thread *thread = NULL; 13466 struct ast_context *con; 13467 int x; 13468 13469 /* Make sure threads do not hold shared resources when they are canceled */ 13470 13471 /* Grab the sched lock resource to keep it away from threads about to die */ 13472 /* Cancel the network thread, close the net socket */ 13473 if (netthreadid != AST_PTHREADT_NULL) { 13474 AST_LIST_LOCK(&frame_queue); 13475 ast_mutex_lock(&sched_lock); 13476 pthread_cancel(netthreadid); 13477 ast_cond_signal(&sched_cond); 13478 ast_mutex_unlock(&sched_lock); /* Release the schedule lock resource */ 13479 AST_LIST_UNLOCK(&frame_queue); 13480 pthread_join(netthreadid, NULL); 13481 } 13482 if (schedthreadid != AST_PTHREADT_NULL) { 13483 ast_mutex_lock(&sched_lock); 13484 pthread_cancel(schedthreadid); 13485 ast_cond_signal(&sched_cond); 13486 ast_mutex_unlock(&sched_lock); 13487 pthread_join(schedthreadid, NULL); 13488 } 13489 13490 /* Call for all threads to halt */ 13491 AST_LIST_LOCK(&idle_list); 13492 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) 13493 pthread_cancel(thread->threadid); 13494 AST_LIST_UNLOCK(&idle_list); 13495 13496 AST_LIST_LOCK(&active_list); 13497 while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list))) 13498 pthread_cancel(thread->threadid); 13499 AST_LIST_UNLOCK(&active_list); 13500 13501 AST_LIST_LOCK(&dynamic_list); 13502 while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list))) 13503 pthread_cancel(thread->threadid); 13504 AST_LIST_UNLOCK(&dynamic_list); 13505 13506 /* Wait for threads to exit */ 13507 while(0 < iaxactivethreadcount) 13508 usleep(10000); 13509 13510 ast_netsock_release(netsock); 13511 ast_netsock_release(outsock); 13512 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13513 if (iaxs[x]) { 13514 iax2_destroy(x); 13515 } 13516 } 13517 ast_manager_unregister( "IAXpeers" ); 13518 ast_manager_unregister( "IAXpeerlist" ); 13519 ast_manager_unregister( "IAXnetstats" ); 13520 ast_unregister_application(papp); 13521 ast_cli_unregister_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 13522 ast_unregister_switch(&iax2_switch); 13523 ast_channel_unregister(&iax2_tech); 13524 delete_users(); 13525 iax_provision_unload(); 13526 sched_context_destroy(sched); 13527 reload_firmware(1); 13528 13529 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 13530 ast_mutex_destroy(&iaxsl[x]); 13531 } 13532 13533 ao2_ref(peers, -1); 13534 ao2_ref(users, -1); 13535 ao2_ref(iax_peercallno_pvts, -1); 13536 ao2_ref(iax_transfercallno_pvts, -1); 13537 ao2_ref(peercnts, -1); 13538 ao2_ref(callno_limits, -1); 13539 ao2_ref(calltoken_ignores, -1); 13540 ao2_ref(callno_pool, -1); 13541 ao2_ref(callno_pool_trunk, -1); 13542 if (timer) { 13543 ast_timer_close(timer); 13544 } 13545 13546 con = ast_context_find(regcontext); 13547 if (con) 13548 ast_context_destroy(con, "IAX2"); 13549 ast_unload_realtime("iaxpeers"); 13550 return 0; 13551 }
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 13776 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 13248 of file chan_iax2.c.
References chan_iax2_pvt::addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::callno, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, ast_channel::tech_pvt, and chan_iax2_pvt::username.
13249 { 13250 struct chan_iax2_pvt *pvt; 13251 unsigned int callno; 13252 int res = 0; 13253 13254 if (!chan || chan->tech != &iax2_tech) { 13255 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13256 return -1; 13257 } 13258 13259 callno = PTR_TO_CALLNO(chan->tech_pvt); 13260 ast_mutex_lock(&iaxsl[callno]); 13261 if (!(pvt = iaxs[callno])) { 13262 ast_mutex_unlock(&iaxsl[callno]); 13263 return -1; 13264 } 13265 13266 if (!strcasecmp(args, "osptoken")) { 13267 ast_copy_string(buf, pvt->osptoken, buflen); 13268 } else if (!strcasecmp(args, "peerip")) { 13269 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 13270 } else if (!strcasecmp(args, "peername")) { 13271 ast_copy_string(buf, pvt->username, buflen); 13272 } else { 13273 res = -1; 13274 } 13275 13276 ast_mutex_unlock(&iaxsl[callno]); 13277 13278 return res; 13279 }
| static int acf_channel_write | ( | struct ast_channel * | chan, | |
| const char * | function, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 13220 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_set, chan_iax2_pvt::callno, LOG_ERROR, chan_iax2_pvt::osptoken, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
13221 { 13222 struct chan_iax2_pvt *pvt; 13223 unsigned int callno; 13224 int res = 0; 13225 13226 if (!chan || chan->tech != &iax2_tech) { 13227 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13228 return -1; 13229 } 13230 13231 callno = PTR_TO_CALLNO(chan->tech_pvt); 13232 ast_mutex_lock(&iaxsl[callno]); 13233 if (!(pvt = iaxs[callno])) { 13234 ast_mutex_unlock(&iaxsl[callno]); 13235 return -1; 13236 } 13237 13238 if (!strcasecmp(args, "osptoken")) 13239 ast_string_field_set(pvt, osptoken, value); 13240 else 13241 res = -1; 13242 13243 ast_mutex_unlock(&iaxsl[callno]); 13244 13245 return res; 13246 }
| static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 9216 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::name, ast_var_t::value, and var.
09217 { 09218 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09219 AST_LIST_HEAD(, ast_var_t) *varlist; 09220 struct ast_var_t *var; 09221 09222 if (!variablestore) { 09223 *buf = '\0'; 09224 return 0; 09225 } 09226 varlist = variablestore->data; 09227 09228 AST_LIST_LOCK(varlist); 09229 AST_LIST_TRAVERSE(varlist, var, entries) { 09230 if (strcmp(var->name, data) == 0) { 09231 ast_copy_string(buf, var->value, len); 09232 break; 09233 } 09234 } 09235 AST_LIST_UNLOCK(varlist); 09236 return 0; 09237 }
| static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 9239 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_datastore::inheritance, LOG_ERROR, ast_var_t::name, and var.
09240 { 09241 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09242 AST_LIST_HEAD(, ast_var_t) *varlist; 09243 struct ast_var_t *var; 09244 09245 if (!variablestore) { 09246 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09247 if (!variablestore) { 09248 ast_log(LOG_ERROR, "Memory allocation error\n"); 09249 return -1; 09250 } 09251 varlist = ast_calloc(1, sizeof(*varlist)); 09252 if (!varlist) { 09253 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09254 return -1; 09255 } 09256 09257 AST_LIST_HEAD_INIT(varlist); 09258 variablestore->data = varlist; 09259 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09260 ast_channel_datastore_add(chan, variablestore); 09261 } else 09262 varlist = variablestore->data; 09263 09264 AST_LIST_LOCK(varlist); 09265 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09266 if (strcmp(var->name, data) == 0) { 09267 AST_LIST_REMOVE_CURRENT(entries); 09268 ast_var_delete(var); 09269 break; 09270 } 09271 } 09272 AST_LIST_TRAVERSE_SAFE_END; 09273 var = ast_var_assign(data, value); 09274 if (var) 09275 AST_LIST_INSERT_TAIL(varlist, var, entries); 09276 else 09277 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09278 AST_LIST_UNLOCK(varlist); 09279 return 0; 09280 }
| static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2239 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock(), ao2_ref, ao2_unlock(), ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), ast_strlen_zero(), addr_range::delme, addr_range::ha, LOG_WARNING, and OBJ_POINTER.
Referenced by set_config().
02240 { 02241 struct addr_range tmp; 02242 struct addr_range *addr_range = NULL; 02243 struct ast_ha *ha = NULL; 02244 int error = 0; 02245 02246 if (ast_strlen_zero(addr)) { 02247 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02248 return -1; 02249 } 02250 02251 ha = ast_append_ha("permit", addr, NULL, &error); 02252 02253 /* check for valid config information */ 02254 if (error) { 02255 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02256 return -1; 02257 } 02258 02259 ast_copy_ha(ha, &tmp.ha); 02260 /* find or create the addr_range */ 02261 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02262 ao2_lock(addr_range); 02263 addr_range->delme = 0; 02264 ao2_unlock(addr_range); 02265 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02266 /* copy over config data into addr_range object */ 02267 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02268 ao2_link(calltoken_ignores, addr_range); 02269 } else { 02270 ast_free_ha(ha); 02271 return -1; 02272 } 02273 02274 ast_free_ha(ha); 02275 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02276 02277 return 0; 02278 }
| static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | ied | |||
| ) | [static] |
Definition at line 4398 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().
04399 { 04400 /* first make sure their are two empty bytes left in ied->buf */ 04401 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04402 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04403 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04404 pvt->calltoken_ie_len = 2; 04405 } 04406 }
| static int addr_range_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1901 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by load_objects().
| static int addr_range_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1888 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
01889 { 01890 struct addr_range *lim = obj; 01891 lim->delme = 1; 01892 return 0; 01893 }
| static int addr_range_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1895 of file chan_iax2.c.
References addr_range::ha, and ast_ha::netaddr.
Referenced by load_objects().
01896 { 01897 const struct addr_range *lim = obj; 01898 return abs((int) lim->ha.netaddr.s_addr); 01899 }
| static int addr_range_match_address_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1921 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, addr_range::ha, ast_ha::netaddr, and ast_ha::netmask.
Referenced by calltoken_required(), and set_peercnt_limit().
01922 { 01923 struct addr_range *addr_range = obj; 01924 struct sockaddr_in *sin = arg; 01925 01926 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) { 01927 return CMP_MATCH | CMP_STOP; 01928 } 01929 return 0; 01930 }
| static int apply_context | ( | struct iax2_context * | con, | |
| const char * | context | |||
| ) | [static] |
Definition at line 7027 of file chan_iax2.c.
References iax2_context::context, and iax2_context::next.
Referenced by check_access().
| static int ast_cli_netstats | ( | struct mansession * | s, | |
| int | fd, | |||
| int | limit_fmt | |||
| ) | [static] |
Definition at line 6732 of file chan_iax2.c.
References ACN_FORMAT1, ACN_FORMAT2, ARRAY_LEN, ast_cli(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, 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, 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().
06733 { 06734 int x; 06735 int numchans = 0; 06736 char first_message[10] = { 0, }; 06737 char last_message[10] = { 0, }; 06738 #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" 06739 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 06740 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06741 ast_mutex_lock(&iaxsl[x]); 06742 if (iaxs[x]) { 06743 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 06744 jb_info jbinfo; 06745 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06746 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06747 06748 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06749 jb_getinfo(iaxs[x]->jb, &jbinfo); 06750 localjitter = jbinfo.jitter; 06751 localdelay = jbinfo.current - jbinfo.min; 06752 locallost = jbinfo.frames_lost; 06753 locallosspct = jbinfo.losspct/1000; 06754 localdropped = jbinfo.frames_dropped; 06755 localooo = jbinfo.frames_ooo; 06756 } else { 06757 localjitter = -1; 06758 localdelay = 0; 06759 locallost = -1; 06760 locallosspct = -1; 06761 localdropped = 0; 06762 localooo = -1; 06763 } 06764 if (s) 06765 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 06766 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06767 iaxs[x]->pingtime, 06768 localjitter, 06769 localdelay, 06770 locallost, 06771 locallosspct, 06772 localdropped, 06773 localooo, 06774 iaxs[x]->frames_received/1000, 06775 iaxs[x]->remote_rr.jitter, 06776 iaxs[x]->remote_rr.delay, 06777 iaxs[x]->remote_rr.losscnt, 06778 iaxs[x]->remote_rr.losspct, 06779 iaxs[x]->remote_rr.dropped, 06780 iaxs[x]->remote_rr.ooo, 06781 iaxs[x]->remote_rr.packets/1000, 06782 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06783 first_message, 06784 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06785 last_message); 06786 else 06787 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 06788 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06789 iaxs[x]->pingtime, 06790 localjitter, 06791 localdelay, 06792 locallost, 06793 locallosspct, 06794 localdropped, 06795 localooo, 06796 iaxs[x]->frames_received/1000, 06797 iaxs[x]->remote_rr.jitter, 06798 iaxs[x]->remote_rr.delay, 06799 iaxs[x]->remote_rr.losscnt, 06800 iaxs[x]->remote_rr.losspct, 06801 iaxs[x]->remote_rr.dropped, 06802 iaxs[x]->remote_rr.ooo, 06803 iaxs[x]->remote_rr.packets/1000, 06804 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06805 first_message, 06806 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06807 last_message); 06808 numchans++; 06809 } 06810 ast_mutex_unlock(&iaxsl[x]); 06811 } 06812 06813 return numchans; 06814 }
| static struct ast_channel* ast_iax2_new | ( | int | callno, | |
| int | state, | |||
| int | capability | |||
| ) | [static, read] |
Create new call, interface with the PBX core.
Definition at line 5309 of file chan_iax2.c.
References chan_iax2_pvt::accountcode, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_channel::amaflags, chan_iax2_pvt::amaflags, chan_iax2_pvt::ani, AST_ADSI_UNAVAILABLE, ast_best_codec(), ast_calloc, ast_channel_alloc, ast_channel_datastore_add(), ast_channel_free(), 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(), chan_iax2_pvt::calling_pres, chan_iax2_pvt::calling_tns, chan_iax2_pvt::calling_ton, chan_iax2_pvt::callno, CALLNO_TO_PTR, chan_iax2_pvt::capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, chan_iax2_pvt::cid_name, chan_iax2_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, ast_channel::context, chan_iax2_pvt::context, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::dnid, ast_channel::exten, chan_iax2_pvt::exten, chan_iax2_pvt::host, iax2_ami_channelupdate(), chan_iax2_pvt::iaxvars, ast_datastore::inheritance, chan_iax2_pvt::language, LOG_ERROR, LOG_WARNING, ast_variable::name, ast_channel::nativeformats, ast_variable::next, chan_iax2_pvt::owner, parkinglot, chan_iax2_pvt::parkinglot, pbx_builtin_setvar_helper(), chan_iax2_pvt::peeradsicpe, ast_channel::rawreadformat, ast_channel::rawwriteformat, chan_iax2_pvt::rdnis, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, ast_variable::value, var, chan_iax2_pvt::vars, and ast_channel::writeformat.
Referenced by iax2_request(), and socket_process().
05310 { 05311 struct ast_channel *tmp; 05312 struct chan_iax2_pvt *i; 05313 struct ast_variable *v = NULL; 05314 05315 if (!(i = iaxs[callno])) { 05316 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05317 return NULL; 05318 } 05319 05320 /* Don't hold call lock */ 05321 ast_mutex_unlock(&iaxsl[callno]); 05322 tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno); 05323 ast_mutex_lock(&iaxsl[callno]); 05324 if (i != iaxs[callno]) { 05325 if (tmp) { 05326 /* unlock and relock iaxsl[callno] to preserve locking order */ 05327 ast_mutex_unlock(&iaxsl[callno]); 05328 ast_channel_free(tmp); 05329 ast_mutex_lock(&iaxsl[callno]); 05330 } 05331 return NULL; 05332 } 05333 iax2_ami_channelupdate(i); 05334 if (!tmp) 05335 return NULL; 05336 tmp->tech = &iax2_tech; 05337 /* We can support any format by default, until we get restricted */ 05338 tmp->nativeformats = capability; 05339 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05340 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05341 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05342 05343 if (!ast_strlen_zero(i->parkinglot)) 05344 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05345 /* Don't use ast_set_callerid() here because it will 05346 * generate a NewCallerID event before the NewChannel event */ 05347 if (!ast_strlen_zero(i->ani)) 05348 tmp->cid.cid_ani = ast_strdup(i->ani); 05349 else 05350 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05351 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05352 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05353 tmp->cid.cid_pres = i->calling_pres; 05354 tmp->cid.cid_ton = i->calling_ton; 05355 tmp->cid.cid_tns = i->calling_tns; 05356 if (!ast_strlen_zero(i->language)) 05357 ast_string_field_set(tmp, language, i->language); 05358 if (!ast_strlen_zero(i->accountcode)) 05359 ast_string_field_set(tmp, accountcode, i->accountcode); 05360 if (i->amaflags) 05361 tmp->amaflags = i->amaflags; 05362 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05363 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05364 if (i->adsi) 05365 tmp->adsicpe = i->peeradsicpe; 05366 else 05367 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05368 i->owner = tmp; 05369 i->capability = capability; 05370 05371 /* Set inherited variables */ 05372 if (i->vars) { 05373 for (v = i->vars ; v ; v = v->next) 05374 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05375 } 05376 if (i->iaxvars) { 05377 struct ast_datastore *variablestore; 05378 struct ast_variable *var, *prev = NULL; 05379 AST_LIST_HEAD(, ast_var_t) *varlist; 05380 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05381 varlist = ast_calloc(1, sizeof(*varlist)); 05382 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05383 if (variablestore && varlist) { 05384 variablestore->data = varlist; 05385 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05386 AST_LIST_HEAD_INIT(varlist); 05387 for (var = i->iaxvars; var; var = var->next) { 05388 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05389 if (prev) 05390 ast_free(prev); 05391 prev = var; 05392 if (!newvar) { 05393 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05394 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05395 } else { 05396 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05397 } 05398 } 05399 if (prev) 05400 ast_free(prev); 05401 i->iaxvars = NULL; 05402 ast_channel_datastore_add(i->owner, variablestore); 05403 } else { 05404 if (variablestore) { 05405 ast_datastore_free(variablestore); 05406 } 05407 if (varlist) { 05408 ast_free(varlist); 05409 } 05410 } 05411 } 05412 05413 if (state != AST_STATE_DOWN) { 05414 if (ast_pbx_start(tmp)) { 05415 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05416 ast_hangup(tmp); 05417 i->owner = NULL; 05418 return NULL; 05419 } 05420 } 05421 05422 ast_module_ref(ast_module_info->self); 05423 return tmp; 05424 }
| static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3292 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
03293 { 03294 #ifdef SCHED_MULTITHREADED 03295 if (schedule_action(__attempt_transmit, data)) 03296 #endif 03297 __attempt_transmit(data); 03298 return 0; 03299 }
| static int auth_fail | ( | int | callno, | |
| int | failcode | |||
| ) | [static] |
Definition at line 8470 of file chan_iax2.c.
References auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, and iax2_sched_replace().
Referenced by socket_process().
08471 { 08472 /* Schedule sending the authentication failure in one second, to prevent 08473 guessing */ 08474 if (iaxs[callno]) { 08475 iaxs[callno]->authfail = failcode; 08476 if (delayreject) { 08477 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 08478 sched, 1000, auth_reject, (void *)(long)callno); 08479 } else 08480 auth_reject((void *)(long)callno); 08481 } 08482 return 0; 08483 }
| static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 8456 of file chan_iax2.c.
References __auth_reject(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::authid, and schedule_action.
Referenced by auth_fail().
08457 { 08458 int callno = (int)(long)(data); 08459 ast_mutex_lock(&iaxsl[callno]); 08460 if (iaxs[callno]) 08461 iaxs[callno]->authid = -1; 08462 ast_mutex_unlock(&iaxsl[callno]); 08463 #ifdef SCHED_MULTITHREADED 08464 if (schedule_action(__auth_reject, data)) 08465 #endif 08466 __auth_reject(data); 08467 return 0; 08468 }
| 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 7594 of file chan_iax2.c.
References ast_inet_ntoa(), ast_key_get, AST_KEY_PRIVATE, ast_log(), ast_sign, ast_strlen_zero(), build_encryption_keys(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, iax_ie_append_str(), IAX_IE_MD5_RESULT, IAX_IE_PASSWORD, IAX_IE_RSA_RESULT, LOG_NOTICE, MD5Final(), MD5Init(), and MD5Update().
Referenced by authenticate_reply(), and registry_rerequest().
07595 { 07596 int res = -1; 07597 int x; 07598 if (!ast_strlen_zero(keyn)) { 07599 if (!(authmethods & IAX_AUTH_RSA)) { 07600 if (ast_strlen_zero(secret)) 07601 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)); 07602 } else if (ast_strlen_zero(challenge)) { 07603 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 07604 } else { 07605 char sig[256]; 07606 struct ast_key *key; 07607 key = ast_key_get(keyn, AST_KEY_PRIVATE); 07608 if (!key) { 07609 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 07610 } else { 07611 if (ast_sign(key, (char*)challenge, sig)) { 07612 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 07613 res = -1; 07614 } else { 07615 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 07616 res = 0; 07617 } 07618 } 07619 } 07620 } 07621 /* Fall back */ 07622 if (res && !ast_strlen_zero(secret)) { 07623 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 07624 struct MD5Context md5; 07625 unsigned char digest[16]; 07626 char digres[128]; 07627 MD5Init(&md5); 07628 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 07629 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 07630 MD5Final(digest, &md5); 07631 /* If they support md5, authenticate with it. */ 07632 for (x=0;x<16;x++) 07633 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 07634 if (pvt) { 07635 build_encryption_keys(digest, pvt); 07636 } 07637 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 07638 res = 0; 07639 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 07640 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 07641 res = 0; 07642 } else 07643 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 07644 } 07645 return res; 07646 }
| 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 7652 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_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_var_assign(), authenticate(), iax_ies::authmethods, iax2_peer::authmethods, iax_ie_data::buf, chan_iax2_pvt::callno, chan_iax2_pvt::challenge, iax_ies::challenge, ast_datastore::data, DATASTORE_INHERIT_FOREVER, chan_iax2_pvt::encmethods, iax_ies::encmethods, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_KEYPOPULATED, ast_datastore::inheritance, LOG_ERROR, iax2_peer::mask, merge_encryption(), ast_variable::name, iax2_peer::name, ast_variable::next, iax2_peer::outkey, chan_iax2_pvt::owner, chan_iax2_pvt::peer, peer_unref(), iax_ie_data::pos, realtime_peer(), iax2_peer::secret, send_command(), chan_iax2_pvt::username, iax2_peer::username, iax_ies::username, ast_variable::value, var, and iax_ies::vars.
Referenced by socket_process().
07653 { 07654 struct iax2_peer *peer = NULL; 07655 /* Start pessimistic */ 07656 int res = -1; 07657 int authmethods = 0; 07658 struct iax_ie_data ied; 07659 uint16_t callno = p->callno; 07660 07661 memset(&ied, 0, sizeof(ied)); 07662 07663 if (ies->username) 07664 ast_string_field_set(p, username, ies->username); 07665 if (ies->challenge) 07666 ast_string_field_set(p, challenge, ies->challenge); 07667 if (ies->authmethods) 07668 authmethods = ies->authmethods; 07669 if (authmethods & IAX_AUTH_MD5) 07670 merge_encryption(p, ies->encmethods); 07671 else 07672 p->encmethods = 0; 07673 07674 /* Check for override RSA authentication first */ 07675 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 07676 /* Normal password authentication */ 07677 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 07678 } else { 07679 struct ao2_iterator i = ao2_iterator_init(peers, 0); 07680 while ((peer = ao2_iterator_next(&i))) { 07681 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 07682 /* No peer specified at our end, or this is the peer */ 07683 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 07684 /* No username specified in peer rule, or this is the right username */ 07685 && (!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))) 07686 /* No specified host, or this is our host */ 07687 ) { 07688 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 07689 if (!res) { 07690 peer_unref(peer); 07691 break; 07692 } 07693 } 07694 peer_unref(peer); 07695 } 07696 ao2_iterator_destroy(&i); 07697 if (!peer) { 07698 /* We checked our list and didn't find one. It's unlikely, but possible, 07699 that we're trying to authenticate *to* a realtime peer */ 07700 const char *peer_name = ast_strdupa(p->peer); 07701 ast_mutex_unlock(&iaxsl[callno]); 07702 if ((peer = realtime_peer(peer_name, NULL))) { 07703 ast_mutex_lock(&iaxsl[callno]); 07704 if (!(p = iaxs[callno])) { 07705 peer_unref(peer); 07706 return -1; 07707 } 07708 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 07709 peer_unref(peer); 07710 } 07711 if (!peer) { 07712 ast_mutex_lock(&iaxsl[callno]); 07713 if (!(p = iaxs[callno])) 07714 return -1; 07715 } 07716 } 07717 } 07718 if (ies->encmethods) 07719 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 07720 if (!res) { 07721 struct ast_datastore *variablestore; 07722 struct ast_variable *var, *prev = NULL; 07723 AST_LIST_HEAD(, ast_var_t) *varlist; 07724 varlist = ast_calloc(1, sizeof(*varlist)); 07725 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 07726 if (variablestore && varlist && p->owner) { 07727 variablestore->data = varlist; 07728 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 07729 AST_LIST_HEAD_INIT(varlist); 07730 for (var = ies->vars; var; var = var->next) { 07731 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 07732 if (prev) 07733 ast_free(prev); 07734 prev = var; 07735 if (!newvar) { 07736 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 07737 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 07738 } else { 07739 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 07740 } 07741 } 07742 if (prev) 07743 ast_free(prev); 07744 ies->vars = NULL; 07745 ast_channel_datastore_add(p->owner, variablestore); 07746 } else { 07747 if (p->owner) 07748 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 07749 if (variablestore) 07750 ast_datastore_free(variablestore); 07751 if (varlist) 07752 ast_free(varlist); 07753 } 07754 } 07755 07756 if (!res) 07757 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 07758 return res; 07759 }
| static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7305 of file chan_iax2.c.
References ao2_find, AST_CAUSE_CALL_REJECTED, AST_FRAME_IAX, ast_random(), ast_set_flag, ast_string_field_set, ast_test_flag, chan_iax2_pvt::authmethods, iax_ie_data::buf, chan_iax2_pvt::challenge, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_RSA, IAX_COMMAND_AUTHREQ, IAX_COMMAND_REJECT, IAX_ENCRYPTED, iax_ie_append_byte(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_CHALLENGE, IAX_IE_ENCRYPTION, IAX_IE_USERNAME, IAX_MAXAUTHREQ, iax2_user::maxauthreq, OBJ_POINTER, iax_ie_data::pos, send_command(), send_command_final(), user_unref(), and chan_iax2_pvt::username.
Referenced by socket_process().
07306 { 07307 struct iax_ie_data ied; 07308 int res = -1, authreq_restrict = 0; 07309 char challenge[10]; 07310 struct chan_iax2_pvt *p = iaxs[call_num]; 07311 07312 memset(&ied, 0, sizeof(ied)); 07313 07314 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07315 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 07316 struct iax2_user *user, tmp_user = { 07317 .name = p->username, 07318 }; 07319 07320 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07321 if (user) { 07322 if (user->curauthreq == user->maxauthreq) 07323 authreq_restrict = 1; 07324 else 07325 user->curauthreq++; 07326 user = user_unref(user); 07327 } 07328 } 07329 07330 /* If the AUTHREQ limit test failed, send back an error */ 07331 if (authreq_restrict) { 07332 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07333 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07334 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07335 return 0; 07336 } 07337 07338 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07339 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07340 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07341 ast_string_field_set(p, challenge, challenge); 07342 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07343 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07344 } 07345 if (p->encmethods) 07346 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07347 07348 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07349 07350 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07351 07352 if (p->encmethods) 07353 ast_set_flag(p, IAX_ENCRYPTED); 07354 07355 return res; 07356 }
| static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7358 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_check_signature, ast_clear_flag, ast_copy_string(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, iax2_user::curauthreq, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_user::name, OBJ_POINTER, iax_ies::password, iax_ies::rsa_result, chan_iax2_pvt::secret, secret, chan_iax2_pvt::state, strsep(), user_unref(), and chan_iax2_pvt::username.
Referenced by socket_process().
07359 { 07360 char requeststr[256]; 07361 char md5secret[256] = ""; 07362 char secret[256] = ""; 07363 char rsasecret[256] = ""; 07364 int res = -1; 07365 int x; 07366 struct iax2_user *user, tmp_user = { 07367 .name = p->username, 07368 }; 07369 07370 if (p->authrej) { 07371 return res; 07372 } 07373 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07374 if (user) { 07375 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 07376 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07377 ast_clear_flag(p, IAX_MAXAUTHREQ); 07378 } 07379 ast_string_field_set(p, host, user->name); 07380 user = user_unref(user); 07381 } 07382 07383 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07384 return res; 07385 if (ies->password) 07386 ast_copy_string(secret, ies->password, sizeof(secret)); 07387 if (ies->md5_result) 07388 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07389 if (ies->rsa_result) 07390 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07391 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07392 struct ast_key *key; 07393 char *keyn; 07394 char tmpkey[256]; 07395 char *stringp=NULL; 07396 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07397 stringp=tmpkey; 07398 keyn = strsep(&stringp, ":"); 07399 while(keyn) { 07400 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07401 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07402 res = 0; 07403 break; 07404 } else if (!key) 07405 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07406 keyn = strsep(&stringp, ":"); 07407 } 07408 } else if (p->authmethods & IAX_AUTH_MD5) { 07409 struct MD5Context md5; 07410 unsigned char digest[16]; 07411 char *tmppw, *stringp; 07412 07413 tmppw = ast_strdupa(p->secret); 07414 stringp = tmppw; 07415 while((tmppw = strsep(&stringp, ";"))) { 07416 MD5Init(&md5); 07417 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07418 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07419 MD5Final(digest, &md5); 07420 /* If they support md5, authenticate with it. */ 07421 for (x=0;x<16;x++) 07422 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07423 if (!strcasecmp(requeststr, md5secret)) { 07424 res = 0; 07425 break; 07426 } 07427 } 07428 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07429 if (!strcmp(secret, p->secret)) 07430 res = 0; 07431 } 07432 return res; 07433 }
| static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4337 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call().
04338 { 04339 #ifdef SCHED_MULTITHREADED 04340 if (schedule_action(__auto_congest, data)) 04341 #endif 04342 __auto_congest(data); 04343 return 0; 04344 }
| static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 8500 of file chan_iax2.c.
References __auto_hangup(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::autoid, and schedule_action.
Referenced by iax2_dprequest(), and iax2_provision().
08501 { 08502 int callno = (int)(long)(data); 08503 ast_mutex_lock(&iaxsl[callno]); 08504 if (iaxs[callno]) { 08505 iaxs[callno]->autoid = -1; 08506 } 08507 ast_mutex_unlock(&iaxsl[callno]); 08508 #ifdef SCHED_MULTITHREADED 08509 if (schedule_action(__auto_hangup, data)) 08510 #endif 08511 __auto_hangup(data); 08512 return 0; 08513 }
| static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2184 of file chan_iax2.c.
References ao2_alloc, ao2_find, ao2_link, ao2_lock(), ao2_ref, ao2_unlock(), ast_append_ha(), ast_copy_ha(), ast_free_ha(), ast_log(), addr_range::delme, addr_range::ha, addr_range::limit, LOG_ERROR, ast_variable::name, ast_variable::next, OBJ_POINTER, and ast_variable::value.
Referenced by set_config().
02185 { 02186 struct addr_range *addr_range = NULL; 02187 struct addr_range tmp; 02188 struct ast_ha *ha; 02189 int limit; 02190 int error; 02191 int found; 02192 02193 for (; v; v = v->next) { 02194 limit = -1; 02195 error = 0; 02196 found = 0; 02197 ha = ast_append_ha("permit", v->name, NULL, &error); 02198 02199 /* check for valid config information */ 02200 if (error) { 02201 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02202 continue; 02203 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02204 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02205 ast_free_ha(ha); 02206 continue; 02207 } 02208 02209 ast_copy_ha(ha, &tmp.ha); 02210 /* find or create the addr_range */ 02211 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02212 ao2_lock(addr_range); 02213 found = 1; 02214 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02215 ast_free_ha(ha); 02216 return; /* out of memory */ 02217 } 02218 02219 /* copy over config data into addr_range object */ 02220 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02221 ast_free_ha(ha); /* cleanup the tmp ha */ 02222 addr_range->limit = limit; 02223 addr_range->delme = 0; 02224 02225 /* cleanup */ 02226 if (found) { 02227 ao2_unlock(addr_range); 02228 } else { 02229 ao2_link(callno_limits, addr_range); 02230 } 02231 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02232 } 02233 }
| static struct iax2_context* build_context | ( | const char * | context | ) | [static, read] |
Definition at line 11589 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), and iax2_context::context.
Referenced by build_user().
11590 { 11591 struct iax2_context *con; 11592 11593 if ((con = ast_calloc(1, sizeof(*con)))) 11594 ast_copy_string(con->context, context, sizeof(con->context)); 11595 11596 return con; 11597 }
| static void build_ecx_key | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 5767 of file chan_iax2.c.
References ast_aes_decrypt_key, ast_aes_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().
05768 { 05769 /* it is required to hold the corresponding decrypt key to our encrypt key 05770 * in the pvt struct because queued frames occasionally need to be decrypted and 05771 * re-encrypted when updated for a retransmission */ 05772 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 05773 ast_aes_encrypt_key(digest, &pvt->ecx); 05774 ast_aes_decrypt_key(digest, &pvt->mydcx); 05775 }
| static void build_encryption_keys | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 5761 of file chan_iax2.c.
References ast_aes_decrypt_key, build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
05762 { 05763 build_ecx_key(digest, pvt); 05764 ast_aes_decrypt_key(digest, &pvt->dcx); 05765 }
| static struct iax2_peer * build_peer | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | temponly | |||
| ) | [static, read] |
Create peer structure based on configuration.
Definition at line 11737 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, ao2_alloc, ao2_find, ast_append_ha(), ast_callerid_split(), ast_clear_flag, ast_copy_flags, 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_DEL, ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), iax2_peer::authmethods, CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, CALLTOKEN_YES, iax2_peer::capability, cid_name, cid_num, context, iax2_peer::dbsecret, iax2_peer::defaddr, DEFAULT_FREQ_NOTOK, DEFAULT_FREQ_OK, DEFAULT_MAXMS, iax2_peer::dnsmgr, iax2_peer::encmethods, iax2_peer::expire, iax2_peer::expiry, get_auth_methods(), get_encrypt_methods(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_DEFAULT_PORTNO, IAX_DELME, IAX_DYNAMIC, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_peer::inkeys, ast_variable::lineno, LOG_WARNING, iax2_peer::mailbox, mailbox, iax2_peer::mask, iax2_peer::maxcallno, iax2_peer::maxms, mwi_event_cb(), iax2_peer::mwi_event_sub, ast_variable::name, iax2_peer::name, ast_variable::next, OBJ_POINTER, iax2_peer::outkey, peer_destructor(), peer_set_srcaddr(), peer_unref(), peercnt_modify(), iax2_peer::peercontext, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, prefs, iax2_peer::prefs, regexten, S_OR, secret, iax2_peer::smoothing, iax2_peer::sockfd, strsep(), unlink_peer(), ast_variable::value, and zonetag.
Referenced by realtime_peer(), and set_config().
11738 { 11739 struct iax2_peer *peer = NULL; 11740 struct ast_ha *oldha = NULL; 11741 int maskfound = 0; 11742 int found = 0; 11743 int firstpass = 1; 11744 struct iax2_peer tmp_peer = { 11745 .name = name, 11746 }; 11747 11748 if (!temponly) { 11749 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 11750 if (peer && !ast_test_flag(peer, IAX_DELME)) 11751 firstpass = 0; 11752 } 11753 11754 if (peer) { 11755 found++; 11756 if (firstpass) { 11757 oldha = peer->ha; 11758 peer->ha = NULL; 11759 } 11760 unlink_peer(peer); 11761 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 11762 peer->expire = -1; 11763 peer->pokeexpire = -1; 11764 peer->sockfd = defaultsockfd; 11765 if (ast_string_field_init(peer, 32)) 11766 peer = peer_unref(peer); 11767 } 11768 11769 if (peer) { 11770 if (firstpass) { 11771 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 11772 peer->encmethods = iax2_encryption; 11773 peer->adsi = adsi; 11774 ast_string_field_set(peer,secret,""); 11775 if (!found) { 11776 ast_string_field_set(peer, name, name); 11777 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 11778 peer->expiry = min_reg_expire; 11779 } 11780 peer->prefs = prefs; 11781 peer->capability = iax2_capability; 11782 peer->smoothing = 0; 11783 peer->pokefreqok = DEFAULT_FREQ_OK; 11784 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 11785 peer->maxcallno = 0; 11786 peercnt_modify(0, 0, &peer->addr); 11787 peer->calltoken_required = CALLTOKEN_DEFAULT; 11788 ast_string_field_set(peer,context,""); 11789 ast_string_field_set(peer,peercontext,""); 11790 ast_clear_flag(peer, IAX_HASCALLERID); 11791 ast_string_field_set(peer, cid_name, ""); 11792 ast_string_field_set(peer, cid_num, ""); 11793 ast_string_field_set(peer, mohinterpret, mohinterpret); 11794 ast_string_field_set(peer, mohsuggest, mohsuggest); 11795 } 11796 11797 if (!v) { 11798 v = alt; 11799 alt = NULL; 11800 } 11801 while(v) { 11802 if (!strcasecmp(v->name, "secret")) { 11803 ast_string_field_set(peer, secret, v->value); 11804 } else if (!strcasecmp(v->name, "mailbox")) { 11805 ast_string_field_set(peer, mailbox, v->value); 11806 } else if (!strcasecmp(v->name, "hasvoicemail")) { 11807 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 11808 ast_string_field_set(peer, mailbox, name); 11809 } 11810 } else if (!strcasecmp(v->name, "mohinterpret")) { 11811 ast_string_field_set(peer, mohinterpret, v->value); 11812 } else if (!strcasecmp(v->name, "mohsuggest")) { 11813 ast_string_field_set(peer, mohsuggest, v->value); 11814 } else if (!strcasecmp(v->name, "dbsecret")) { 11815 ast_string_field_set(peer, dbsecret, v->value); 11816 } else if (!strcasecmp(v->name, "trunk")) { 11817 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 11818 if (ast_test_flag(peer, IAX_TRUNK) && !timer) { 11819 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 11820 ast_clear_flag(peer, IAX_TRUNK); 11821 } 11822 } else if (!strcasecmp(v->name, "auth")) { 11823 peer->authmethods = get_auth_methods(v->value); 11824 } else if (!strcasecmp(v->name, "encryption")) { 11825 peer->encmethods |= get_encrypt_methods(v->value); 11826 } else if (!strcasecmp(v->name, "transfer")) { 11827 if (!strcasecmp(v->value, "mediaonly")) { 11828 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 11829 } else if (ast_true(v->value)) { 11830 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 11831 } else 11832 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 11833 } else if (!strcasecmp(v->name, "jitterbuffer")) { 11834 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 11835 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 11836 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 11837 } else if (!strcasecmp(v->name, "host")) { 11838 if (!strcasecmp(v->value, "dynamic")) { 11839 /* They'll register with us */ 11840 ast_set_flag(peer, IAX_DYNAMIC); 11841 if (!found) { 11842 /* Initialize stuff iff we're not found, otherwise 11843 we keep going with what we had */ 11844 memset(&peer->addr.sin_addr, 0, 4); 11845 if (peer->addr.sin_port) { 11846 /* If we've already got a port, make it the default rather than absolute */ 11847 peer->defaddr.sin_port = peer->addr.sin_port; 11848 peer->addr.sin_port = 0; 11849 } 11850 } 11851 } else { 11852 /* Non-dynamic. Make sure we become that way if we're not */ 11853 AST_SCHED_DEL(sched, peer->expire); 11854 ast_clear_flag(peer, IAX_DYNAMIC); 11855 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 11856 return peer_unref(peer); 11857 if (!peer->addr.sin_port) 11858 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 11859 } 11860 if (!maskfound) 11861 inet_aton("255.255.255.255", &peer->mask); 11862 } else if (!strcasecmp(v->name, "defaultip")) { 11863 if (ast_get_ip(&peer->defaddr, v->value)) 11864 return peer_unref(peer); 11865 } else if (!strcasecmp(v->name, "sourceaddress")) { 11866 peer_set_srcaddr(peer, v->value); 11867 } else if (!strcasecmp(v->name, "permit") || 11868 !strcasecmp(v->name, "deny")) { 11869 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 11870 } else if (!strcasecmp(v->name, "mask")) { 11871 maskfound++; 11872 inet_aton(v->value, &peer->mask); 11873 } else if (!strcasecmp(v->name, "context")) { 11874 ast_string_field_set(peer, context, v->value); 11875 } else if (!strcasecmp(v->name, "regexten")) { 11876 ast_string_field_set(peer, regexten, v->value); 11877 } else if (!strcasecmp(v->name, "peercontext")) { 11878 ast_string_field_set(peer, peercontext, v->value); 11879 } else if (!strcasecmp(v->name, "port")) { 11880 if (ast_test_flag(peer, IAX_DYNAMIC)) 11881 peer->defaddr.sin_port = htons(atoi(v->value)); 11882 else 11883 peer->addr.sin_port = htons(atoi(v->value)); 11884 } else if (!strcasecmp(v->name, "username")) { 11885 ast_string_field_set(peer, username, v->value); 11886 } else if (!strcasecmp(v->name, "allow")) { 11887 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 11888 } else if (!strcasecmp(v->name, "disallow")) { 11889 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 11890 } else if (!strcasecmp(v->name, "callerid")) { 11891 if (!ast_strlen_zero(v->value)) { 11892 char name2[80]; 11893 char num2[80]; 11894 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 11895 ast_string_field_set(peer, cid_name, name2); 11896 ast_string_field_set(peer, cid_num, num2); 11897 } else { 11898 ast_string_field_set(peer, cid_name, ""); 11899 ast_string_field_set(peer, cid_num, ""); 11900 } 11901 ast_set_flag(peer, IAX_HASCALLERID); 11902 } else if (!strcasecmp(v->name, "fullname")) { 11903 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 11904 ast_set_flag(peer, IAX_HASCALLERID); 11905 } else if (!strcasecmp(v->name, "cid_number")) { 11906 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 11907 ast_set_flag(peer, IAX_HASCALLERID); 11908 } else if (!strcasecmp(v->name, "sendani")) { 11909 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 11910 } else if (!strcasecmp(v->name, "inkeys")) { 11911 ast_string_field_set(peer, inkeys, v->value); 11912 } else if (!strcasecmp(v->name, "outkey")) { 11913 ast_string_field_set(peer, outkey, v->value); 11914 } else if (!strcasecmp(v->name, "qualify")) { 11915 if (!strcasecmp(v->value, "no")) { 11916 peer->maxms = 0; 11917 } else if (!strcasecmp(v->value, "yes")) { 11918 peer->maxms = DEFAULT_MAXMS; 11919 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 11920 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); 11921 peer->maxms = 0; 11922 } 11923 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 11924 peer->smoothing = ast_true(v->value); 11925 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 11926 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 11927 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); 11928 } 11929 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 11930 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 11931 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); 11932 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 11933 } else if (!strcasecmp(v->name, "timezone")) { 11934 ast_string_field_set(peer, zonetag, v->value); 11935 } else if (!strcasecmp(v->name, "adsi")) { 11936 peer->adsi = ast_true(v->value); 11937 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 11938 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 11939 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 11940 } else { 11941 peercnt_modify(1, peer->maxcallno, &peer->addr); 11942 } 11943 } else if (!strcasecmp(v->name, "requirecalltoken")) { 11944 /* default is required unless in optional ip list */ 11945 if (ast_false(v->value)) { 11946 peer->calltoken_required = CALLTOKEN_NO; 11947 } else if (!strcasecmp(v->value, "auto")) { 11948 peer->calltoken_required = CALLTOKEN_AUTO; 11949 } else if (ast_true(v->value)) { 11950 peer->calltoken_required = CALLTOKEN_YES; 11951 } else { 11952 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 11953 } 11954 } /* else if (strcasecmp(v->name,"type")) */ 11955 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 11956 v = v->next; 11957 if (!v) { 11958 v = alt; 11959 alt = NULL; 11960 } 11961 } 11962 if (!peer->authmethods) 11963 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 11964 ast_clear_flag(peer, IAX_DELME); 11965 /* Make sure these are IPv4 addresses */ 11966 peer->addr.sin_family = AF_INET; 11967 } 11968 11969 if (oldha) 11970 ast_free_ha(oldha); 11971 11972 if (!ast_strlen_zero(peer->mailbox)) { 11973 char *mailbox, *context; 11974 context = mailbox = ast_strdupa(peer->mailbox); 11975 strsep(&context, "@"); 11976 if (ast_strlen_zero(context)) 11977 context = "default"; 11978 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL, 11979 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 11980 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 11981 AST_EVENT_IE_END); 11982 } 11983 11984 return peer; 11985 }
| static void build_rand_pad | ( | unsigned char * | buf, | |
| ssize_t | len | |||
| ) | [static] |
Definition at line 5751 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
05752 { 05753 long tmp; 05754 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 05755 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 05756 buf += sizeof(tmp); 05757 len -= sizeof(tmp); 05758 } 05759 }
| static struct iax2_user * build_user | ( | const char * | name, | |
| struct ast_variable * | v, | |||
| struct ast_variable * | alt, | |||
| int | temponly | |||
| ) | [static, read] |
Create in-memory user structure from configuration.
Definition at line 12001 of file chan_iax2.c.
References iax2_user::adsi, iax2_user::amaflags, ao2_alloc, ao2_find, ao2_unlink, ast_append_ha(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_clear_flag, ast_copy_flags, ast_false(), ast_free_ha(), ast_log(), ast_parse_allow_disallow(), ast_set2_flag, ast_set_flag, ast_set_flags_to, ast_strdupa, ast_string_field_build, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_new(), iax2_user::authmethods, build_context(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_user::calltoken_required, CALLTOKEN_YES, iax2_user::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, cleanup(), iax2_user::contexts, iax2_user::curauthreq, iax2_user::dbsecret, iax2_user::encmethods, format, free_context(), get_auth_methods(), get_encrypt_methods(), iax2_user::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DELME, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, ast_variable::lineno, LOG_WARNING, iax2_user::maxauthreq, ast_variable::name, iax2_user::name, ast_variable::next, iax2_context::next, OBJ_POINTER, parkinglot, prefs, iax2_user::prefs, secret, iax2_user::secret, user_destructor(), user_unref(), ast_variable::value, and iax2_user::vars.
Referenced by realtime_user(), and set_config().
12002 { 12003 struct iax2_user *user = NULL; 12004 struct iax2_context *con, *conl = NULL; 12005 struct ast_ha *oldha = NULL; 12006 struct iax2_context *oldcon = NULL; 12007 int format; 12008 int firstpass=1; 12009 int oldcurauthreq = 0; 12010 char *varname = NULL, *varval = NULL; 12011 struct ast_variable *tmpvar = NULL; 12012 struct iax2_user tmp_user = { 12013 .name = name, 12014 }; 12015 12016 if (!temponly) { 12017 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12018 if (user && !ast_test_flag(user, IAX_DELME)) 12019 firstpass = 0; 12020 } 12021 12022 if (user) { 12023 if (firstpass) { 12024 oldcurauthreq = user->curauthreq; 12025 oldha = user->ha; 12026 oldcon = user->contexts; 12027 user->ha = NULL; 12028 user->contexts = NULL; 12029 } 12030 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12031 ao2_unlink(users, user); 12032 } else { 12033 user = ao2_alloc(sizeof(*user), user_destructor); 12034 } 12035 12036 if (user) { 12037 if (firstpass) { 12038 ast_string_field_free_memory(user); 12039 memset(user, 0, sizeof(struct iax2_user)); 12040 if (ast_string_field_init(user, 32)) { 12041 user = user_unref(user); 12042 goto cleanup; 12043 } 12044 user->maxauthreq = maxauthreq; 12045 user->curauthreq = oldcurauthreq; 12046 user->prefs = prefs; 12047 user->capability = iax2_capability; 12048 user->encmethods = iax2_encryption; 12049 user->adsi = adsi; 12050 user->calltoken_required = CALLTOKEN_DEFAULT; 12051 ast_string_field_set(user, name, name); 12052 ast_string_field_set(user, language, language); 12053 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP); 12054 ast_clear_flag(user, IAX_HASCALLERID); 12055 ast_string_field_set(user, cid_name, ""); 12056 ast_string_field_set(user, cid_num, ""); 12057 ast_string_field_set(user, accountcode, accountcode); 12058 ast_string_field_set(user, mohinterpret, mohinterpret); 12059 ast_string_field_set(user, mohsuggest, mohsuggest); 12060 } 12061 if (!v) { 12062 v = alt; 12063 alt = NULL; 12064 } 12065 while(v) { 12066 if (!strcasecmp(v->name, "context")) { 12067 con = build_context(v->value); 12068 if (con) { 12069 if (conl) 12070 conl->next = con; 12071 else 12072 user->contexts = con; 12073 conl = con; 12074 } 12075 } else if (!strcasecmp(v->name, "permit") || 12076 !strcasecmp(v->name, "deny")) { 12077 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12078 } else if (!strcasecmp(v->name, "setvar")) { 12079 varname = ast_strdupa(v->value); 12080 if (varname && (varval = strchr(varname,'='))) { 12081 *varval = '\0'; 12082 varval++; 12083 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12084 tmpvar->next = user->vars; 12085 user->vars = tmpvar; 12086 } 12087 } 12088 } else if (!strcasecmp(v->name, "allow")) { 12089 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12090 } else if (!strcasecmp(v->name, "disallow")) { 12091 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12092 } else if (!strcasecmp(v->name, "trunk")) { 12093 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 12094 if (ast_test_flag(user, IAX_TRUNK) && !timer) { 12095 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12096 ast_clear_flag(user, IAX_TRUNK); 12097 } 12098 } else if (!strcasecmp(v->name, "auth")) { 12099 user->authmethods = get_auth_methods(v->value); 12100 } else if (!strcasecmp(v->name, "encryption")) { 12101 user->encmethods |= get_encrypt_methods(v->value); 12102 } else if (!strcasecmp(v->name, "transfer")) { 12103 if (!strcasecmp(v->value, "mediaonly")) { 12104 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12105 } else if (ast_true(v->value)) { 12106 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12107 } else 12108 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12109 } else if (!strcasecmp(v->name, "codecpriority")) { 12110 if(!strcasecmp(v->value, "caller")) 12111 ast_set_flag(user, IAX_CODEC_USER_FIRST); 12112 else if(!strcasecmp(v->value, "disabled")) 12113 ast_set_flag(user, IAX_CODEC_NOPREFS); 12114 else if(!strcasecmp(v->value, "reqonly")) { 12115 ast_set_flag(user, IAX_CODEC_NOCAP); 12116 ast_set_flag(user, IAX_CODEC_NOPREFS); 12117 } 12118 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12119 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 12120 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12121 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12122 } else if (!strcasecmp(v->name, "dbsecret")) { 12123 ast_string_field_set(user, dbsecret, v->value); 12124 } else if (!strcasecmp(v->name, "secret")) { 12125 if (!ast_strlen_zero(user->secret)) { 12126 char *old = ast_strdupa(user->secret); 12127 12128 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12129 } else 12130 ast_string_field_set(user, secret, v->value); 12131 } else if (!strcasecmp(v->name, "callerid")) { 12132 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12133 char name2[80]; 12134 char num2[80]; 12135 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12136 ast_string_field_set(user, cid_name, name2); 12137 ast_string_field_set(user, cid_num, num2); 12138 ast_set_flag(user, IAX_HASCALLERID); 12139 } else { 12140 ast_clear_flag(user, IAX_HASCALLERID); 12141 ast_string_field_set(user, cid_name, ""); 12142 ast_string_field_set(user, cid_num, ""); 12143 } 12144 } else if (!strcasecmp(v->name, "fullname")) { 12145 if (!ast_strlen_zero(v->value)) { 12146 ast_string_field_set(user, cid_name, v->value); 12147 ast_set_flag(user, IAX_HASCALLERID); 12148 } else { 12149 ast_string_field_set(user, cid_name, ""); 12150 if (ast_strlen_zero(user->cid_num)) 12151 ast_clear_flag(user, IAX_HASCALLERID); 12152 } 12153 } else if (!strcasecmp(v->name, "cid_number")) { 12154 if (!ast_strlen_zero(v->value)) { 12155 ast_string_field_set(user, cid_num, v->value); 12156 ast_set_flag(user, IAX_HASCALLERID); 12157 } else { 12158 ast_string_field_set(user, cid_num, ""); 12159 if (ast_strlen_zero(user->cid_name)) 12160 ast_clear_flag(user, IAX_HASCALLERID); 12161 } 12162 } else if (!strcasecmp(v->name, "accountcode")) { 12163 ast_string_field_set(user, accountcode, v->value); 12164 } else if (!strcasecmp(v->name, "mohinterpret")) { 12165 ast_string_field_set(user, mohinterpret, v->value); 12166 } else if (!strcasecmp(v->name, "mohsuggest")) { 12167 ast_string_field_set(user, mohsuggest, v->value); 12168 } else if (!strcasecmp(v->name, "parkinglot")) { 12169 ast_string_field_set(user, parkinglot, v->value); 12170 } else if (!strcasecmp(v->name, "language")) { 12171 ast_string_field_set(user, language, v->value); 12172 } else if (!strcasecmp(v->name, "amaflags")) { 12173 format = ast_cdr_amaflags2int(v->value); 12174 if (format < 0) { 12175 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12176 } else { 12177 user->amaflags = format; 12178 } 12179 } else if (!strcasecmp(v->name, "inkeys")) { 12180 ast_string_field_set(user, inkeys, v->value); 12181 } else if (!strcasecmp(v->name, "maxauthreq")) { 12182 user->maxauthreq = atoi(v->value); 12183 if (user->maxauthreq < 0) 12184 user->maxauthreq = 0; 12185 } else if (!strcasecmp(v->name, "adsi")) { 12186 user->adsi = ast_true(v->value); 12187 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12188 /* default is required unless in optional ip list */ 12189 if (ast_false(v->value)) { 12190 user->calltoken_required = CALLTOKEN_NO; 12191 } else if (!strcasecmp(v->value, "auto")) { 12192 user->calltoken_required = CALLTOKEN_AUTO; 12193 } else if (ast_true(v->value)) { 12194 user->calltoken_required = CALLTOKEN_YES; 12195 } else { 12196 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12197 } 12198 } /* else if (strcasecmp(v->name,"type")) */ 12199 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12200 v = v->next; 12201 if (!v) { 12202 v = alt; 12203 alt = NULL; 12204 } 12205 } 12206 if (!user->authmethods) { 12207 if (!ast_strlen_zero(user->secret)) { 12208 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12209 if (!ast_strlen_zero(user->inkeys)) 12210 user->authmethods |= IAX_AUTH_RSA; 12211 } else if (!ast_strlen_zero(user->inkeys)) { 12212 user->authmethods = IAX_AUTH_RSA; 12213 } else { 12214 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12215 } 12216 } 12217 ast_clear_flag(user, IAX_DELME); 12218 } 12219 cleanup: 12220 if (oldha) 12221 ast_free_ha(oldha); 12222 if (oldcon) 12223 free_context(oldcon); 12224 return user; 12225 }
| static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 12809 of file chan_iax2.c.
References add_empty_calltoken_ie(), ARRAY_LEN, ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_trylock(), ast_mutex_unlock(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), iax_ie_data::buf, chan_iax2_pvt::capability, parsed_dial_string::context, create_addr(), parsed_dial_string::exten, find_callno_locked(), IAX_CAPABILITY_FULLBANDWIDTH, IAX_COMMAND_NEW, iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, IAX_IE_CAPABILITY, IAX_IE_FORMAT, IAX_IE_USERNAME, IAX_IE_VERSION, IAX_PROTO_VERSION, parsed_dial_string::key, LOG_WARNING, NEW_FORCE, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, iax_ie_data::pos, secret, send_command(), create_addr_info::sockfd, and parsed_dial_string::username.
Referenced by find_cache().
12810 { 12811 struct sockaddr_in sin; 12812 int x; 12813 int callno; 12814 struct iax_ie_data ied; 12815 struct create_addr_info cai; 12816 struct parsed_dial_string pds; 12817 char *tmpstr; 12818 12819 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 12820 /* Look for an *exact match* call. Once a call is negotiated, it can only 12821 look up entries for a single context */ 12822 if (!ast_mutex_trylock(&iaxsl[x])) { 12823 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 12824 return x; 12825 ast_mutex_unlock(&iaxsl[x]); 12826 } 12827 } 12828 12829 /* No match found, we need to create a new one */ 12830 12831 memset(&cai, 0, sizeof(cai)); 12832 memset(&ied, 0, sizeof(ied)); 12833 memset(&pds, 0, sizeof(pds)); 12834 12835 tmpstr = ast_strdupa(data); 12836 parse_dial_string(tmpstr, &pds); 12837 12838 if (ast_strlen_zero(pds.peer)) { 12839 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 12840 return -1; 12841 } 12842 12843 /* Populate our address from the given */ 12844 if (create_addr(pds.peer, NULL, &sin, &cai)) 12845 return -1; 12846 12847 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 12848 pds.peer, pds.username, pds.password, pds.context); 12849 12850 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 12851 if (callno < 1) { 12852 ast_log(LOG_WARNING, "Unable to create call\n"); 12853 return -1; 12854 } 12855 12856 ast_string_field_set(iaxs[callno], dproot, data); 12857 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 12858 12859 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 12860 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 12861 /* the string format is slightly different from a standard dial string, 12862 because the context appears in the 'exten' position 12863 */ 12864 if (pds.exten) 12865 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 12866 if (pds.username) 12867 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 12868 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 12869 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 12870 /* Keep password handy */ 12871 if (pds.password) 12872 ast_string_field_set(iaxs[callno], secret, pds.password); 12873 if (pds.key) 12874 ast_string_field_set(iaxs[callno], outkey, pds.key); 12875 /* Start the call going */ 12876 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 12877 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 12878 12879 return callno; 12880 }
| static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | offset | |||
| ) | [static] |
Definition at line 5603 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().
05604 { 05605 /* Returns where in "receive time" we are. That is, how many ms 05606 since we received (or would have received) the frame with timestamp 0 */ 05607 int ms; 05608 #ifdef IAXTESTS 05609 int jit; 05610 #endif /* IAXTESTS */ 05611 /* Setup rxcore if necessary */ 05612 if (ast_tvzero(p->rxcore)) { 05613 p->rxcore = ast_tvnow(); 05614 if (iaxdebug) 05615 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 05616 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 05617 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 05618 #if 1 05619 if (iaxdebug) 05620 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 05621 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 05622 #endif 05623 } 05624 05625 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 05626 #ifdef IAXTESTS 05627 if (test_jit) { 05628 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 05629 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 05630 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 05631 jit = -jit; 05632 ms += jit; 05633 } 05634 } 05635 if (test_late) { 05636 ms += test_late; 05637 test_late = 0; 05638 } 05639 #endif /* IAXTESTS */ 05640 return ms; 05641 }
| static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | ts, | |||
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 5470 of file chan_iax2.c.
References ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_samp2tv(), ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), chan_iax2_pvt::callno, ast_frame::delivery, ast_frame::frametype, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastsent, MAX_TIMESTAMP_SKEW, chan_iax2_pvt::nextpred, chan_iax2_pvt::notsilenttx, chan_iax2_pvt::offset, chan_iax2_pvt::peercallno, ast_frame::samples, and ast_frame::subclass.
Referenced by iax2_send(), and socket_process().
05471 { 05472 int ms; 05473 int voice = 0; 05474 int genuine = 0; 05475 int adjust; 05476 int rate = ast_format_rate(f->subclass) / 1000; 05477 struct timeval *delivery = NULL; 05478 05479 05480 /* What sort of frame do we have?: voice is self-explanatory 05481 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05482 non-genuine frames are CONTROL frames [ringing etc], DTMF 05483 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05484 the others need a timestamp slaved to the voice frames so that they go in sequence 05485 */ 05486 if (f) { 05487 if (f->frametype == AST_FRAME_VOICE) { 05488 voice = 1; 05489 delivery = &f->delivery; 05490 } else if (f->frametype == AST_FRAME_IAX) { 05491 genuine = 1; 05492 } else if (f->frametype == AST_FRAME_CNG) { 05493 p->notsilenttx = 0; 05494 } 05495 } 05496 if (ast_tvzero(p->offset)) { 05497 p->offset = ast_tvnow(); 05498 /* Round to nearest 20ms for nice looking traces */ 05499 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05500 } 05501 /* If the timestamp is specified, just send it as is */ 05502 if (ts) 05503 return ts; 05504 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05505 if (delivery && !ast_tvzero(*delivery)) { 05506 ms = ast_tvdiff_ms(*delivery, p->offset); 05507 if (ms < 0) { 05508 ms = 0; 05509 } 05510 if (iaxdebug) 05511 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05512 } else { 05513 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05514 if (ms < 0) 05515 ms = 0; 05516 if (voice) { 05517 /* On a voice frame, use predicted values if appropriate */ 05518 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05519 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05520 /* AN EXPLANATION: 05521 When we send voice, we usually send "calculated" timestamps worked out 05522 on the basis of the number of samples sent. When we send other frames, 05523 we usually send timestamps worked out from the real clock. 05524 The problem is that they can tend to drift out of step because the 05525 source channel's clock and our clock may not be exactly at the same rate. 05526 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05527 for this call. Moving it adjusts timestamps for non-voice frames. 05528 We make the adjustment in the style of a moving average. Each time we 05529 adjust p->offset by 10% of the difference between our clock-derived 05530 timestamp and the predicted timestamp. That's why you see "10000" 05531 below even though IAX2 timestamps are in milliseconds. 05532 The use of a moving average avoids offset moving too radically. 05533 Generally, "adjust" roams back and forth around 0, with offset hardly 05534 changing at all. But if a consistent different starts to develop it 05535 will be eliminated over the course of 10 frames (200-300msecs) 05536 */ 05537 adjust = (ms - p->nextpred); 05538 if (adjust < 0) 05539 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05540 else if (adjust > 0) 05541 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05542 05543 if (!p->nextpred) { 05544 p->nextpred = ms; /*f->samples / rate;*/ 05545 if (p->nextpred <= p->lastsent) 05546 p->nextpred = p->lastsent + 3; 05547 } 05548 ms = p->nextpred; 05549 } else { 05550 /* in this case, just use the actual 05551 * time, since we're either way off 05552 * (shouldn't happen), or we're ending a 05553 * silent period -- and seed the next 05554 * predicted time. Also, round ms to the 05555 * next multiple of frame size (so our 05556 * silent periods are multiples of 05557 * frame size too) */ 05558 05559 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05560 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05561 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05562 05563 if (f->samples >= rate) /* check to make sure we dont core dump */ 05564 { 05565 int diff = ms % (f->samples / rate); 05566 if (diff) 05567 ms += f->samples/rate - diff; 05568 } 05569 05570 p->nextpred = ms; 05571 p->notsilenttx = 1; 05572 } 05573 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05574 /* 05575 * IAX2 draft 03 says that timestamps MUST be in order. 05576 * It does not say anything about several frames having the same timestamp 05577 * When transporting video, we can have a frame that spans multiple iax packets 05578 * (so called slices), so it would make sense to use the same timestamp for all of 05579 * them 05580 * We do want to make sure that frames don't go backwards though 05581 */ 05582 if ( (unsigned int)ms < p->lastsent ) 05583 ms = p->lastsent; 05584 } else { 05585 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05586 it's a genuine frame */ 05587 if (genuine) { 05588 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05589 if (ms <= p->lastsent) 05590 ms = p->lastsent + 3; 05591 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05592 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05593 ms = p->lastsent + 3; 05594 } 05595 } 05596 } 05597 p->lastsent = ms; 05598 if (voice) 05599 p->nextpred = p->nextpred + f->samples / rate; 05600 return ms; 05601 }
| static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
| int | sampms, | |||
| struct timeval * | now | |||
| ) | [static] |
Definition at line 5426 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().
05427 { 05428 unsigned long int mssincetx; /* unsigned to handle overflows */ 05429 long int ms, pred; 05430 05431 tpeer->trunkact = *now; 05432 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05433 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05434 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05435 tpeer->txtrunktime = *now; 05436 tpeer->lastsent = 999999; 05437 } 05438 /* Update last transmit time now */ 05439 tpeer->lasttxtime = *now; 05440 05441 /* Calculate ms offset */ 05442 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05443 /* Predict from last value */ 05444 pred = tpeer->lastsent + sampms; 05445 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05446 ms = pred; 05447 05448 /* We never send the same timestamp twice, so fudge a little if we must */ 05449 if (ms == tpeer->lastsent) 05450 ms = tpeer->lastsent + 1; 05451 tpeer->lastsent = ms; 05452 return ms; 05453 }
| static int callno_hash | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2389 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02390 { 02391 return abs(ast_random()); 02392 }
| static int calltoken_required | ( | struct sockaddr_in * | sin, | |
| const char * | name, | |||
| int | subclass | |||
| ) | [static] |
Definition at line 1937 of file chan_iax2.c.
References addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), CALLTOKEN_AUTO, CALLTOKEN_DEFAULT, CALLTOKEN_NO, iax2_peer::calltoken_required, iax2_user::calltoken_required, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), realtime_peer(), realtime_user(), S_OR, and user_unref().
Referenced by handle_call_token().
01938 { 01939 struct addr_range *addr_range; 01940 struct iax2_peer *peer = NULL; 01941 struct iax2_user *user = NULL; 01942 /* if no username is given, check for guest accounts */ 01943 const char *find = S_OR(name, "guest"); 01944 int res = 1; /* required by default */ 01945 int optional = 0; 01946 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 01947 /* There are only two cases in which calltoken validation is not required. 01948 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 01949 * the peer definition has not set the requirecalltoken option. 01950 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 01951 */ 01952 01953 /* ----- Case 1 ----- */ 01954 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 01955 ao2_ref(addr_range, -1); 01956 optional = 1; 01957 } 01958 01959 /* ----- Case 2 ----- */ 01960 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 01961 calltoken_required = user->calltoken_required; 01962 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 01963 calltoken_required = user->calltoken_required; 01964 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 01965 calltoken_required = peer->calltoken_required; 01966 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 01967 calltoken_required = peer->calltoken_required; 01968 } 01969 01970 if (peer) { 01971 peer_unref(peer); 01972 } 01973 if (user) { 01974 user_unref(user); 01975 } 01976 01977 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); 01978 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 01979 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 01980 res = 0; 01981 } 01982 01983 return res; 01984 }
| static int check_access | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7038 of file chan_iax2.c.
References iax2_user::accountcode, iax2_user::adsi, chan_iax2_pvt::adsi, iax_ies::adsicpe, chan_iax2_pvt::amaflags, iax2_user::amaflags, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, apply_context(), ast_apply_ha(), ast_codec_pref_convert(), ast_copy_flags, ast_db_get(), ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, ast_set2_flag, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_variable_new(), iax2_user::authmethods, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, iax_ies::called_context, iax_ies::called_number, iax_ies::calling_ani, iax_ies::calling_name, iax_ies::calling_number, chan_iax2_pvt::calling_pres, iax_ies::calling_pres, chan_iax2_pvt::calling_tns, iax_ies::calling_tns, chan_iax2_pvt::calling_ton, iax_ies::calling_ton, iax2_user::capability, chan_iax2_pvt::capability, iax_ies::capability, iax2_user::cid_name, cid_name, iax2_user::cid_num, cid_num, iax_ies::codec_prefs, iax2_context::context, chan_iax2_pvt::context, context, iax2_user::contexts, iax2_user::dbsecret, DEFAULT_CONTEXT, iax_ies::dnid, iax2_user::encmethods, chan_iax2_pvt::encmethods, exten, ast_variable::file, iax_ies::format, iax2_user::ha, iax2_getpeertrunk(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_MAXAUTHREQ, IAX_NOTRANSFER, IAX_PROTO_VERSION, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, iax2_user::inkeys, iax2_user::language, iax_ies::language, LOG_WARNING, iax2_user::maxauthreq, iax2_user::mohinterpret, iax2_user::mohsuggest, ast_variable::name, iax2_user::name, ast_variable::next, parkinglot, iax2_user::parkinglot, chan_iax2_pvt::peeradsicpe, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_user::prefs, chan_iax2_pvt::prefs, prefs, iax_ies::rdnis, realtime_user(), secret, iax2_user::secret, user_unref(), iax_ies::username, ast_variable::value, chan_iax2_pvt::vars, iax2_user::vars, iax_ies::version, and version.
Referenced by socket_process().
07039 { 07040 /* Start pessimistic */ 07041 int res = -1; 07042 int version = 2; 07043 struct iax2_user *user = NULL, *best = NULL; 07044 int bestscore = 0; 07045 int gotcapability = 0; 07046 struct ast_variable *v = NULL, *tmpvar = NULL; 07047 struct ao2_iterator i; 07048 07049 if (!iaxs[callno]) 07050 return res; 07051 if (ies->called_number) 07052 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07053 if (ies->calling_number) { 07054 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) { 07055 ast_shrink_phone_number(ies->calling_number); 07056 } 07057 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07058 } 07059 if (ies->calling_name) 07060 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07061 if (ies->calling_ani) 07062 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07063 if (ies->dnid) 07064 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07065 if (ies->rdnis) 07066 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07067 if (ies->called_context) 07068 ast_string_field_set(iaxs[callno], context, ies->called_context); 07069 if (ies->language) 07070 ast_string_field_set(iaxs[callno], language, ies->language); 07071 if (ies->username) 07072 ast_string_field_set(iaxs[callno], username, ies->username); 07073 if (ies->calling_ton > -1) 07074 iaxs[callno]->calling_ton = ies->calling_ton; 07075 if (ies->calling_tns > -1) 07076 iaxs[callno]->calling_tns = ies->calling_tns; 07077 if (ies->calling_pres > -1) 07078 iaxs[callno]->calling_pres = ies->calling_pres; 07079 if (ies->format) 07080 iaxs[callno]->peerformat = ies->format; 07081 if (ies->adsicpe) 07082 iaxs[callno]->peeradsicpe = ies->adsicpe; 07083 if (ies->capability) { 07084 gotcapability = 1; 07085 iaxs[callno]->peercapability = ies->capability; 07086 } 07087 if (ies->version) 07088 version = ies->version; 07089 07090 /* Use provided preferences until told otherwise for actual preferences */ 07091 if(ies->codec_prefs) { 07092 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07093 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07094 } 07095 07096 if (!gotcapability) 07097 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07098 if (version > IAX_PROTO_VERSION) { 07099 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07100 ast_inet_ntoa(sin->sin_addr), version); 07101 return res; 07102 } 07103 /* Search the userlist for a compatible entry, and fill in the rest */ 07104 i = ao2_iterator_init(users, 0); 07105 while ((user = ao2_iterator_next(&i))) { 07106 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07107 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07108 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 07109 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07110 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07111 if (!ast_strlen_zero(iaxs[callno]->username)) { 07112 /* Exact match, stop right now. */ 07113 if (best) 07114 user_unref(best); 07115 best = user; 07116 break; 07117 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07118 /* No required authentication */ 07119 if (user->ha) { 07120 /* There was host authentication and we passed, bonus! */ 07121 if (bestscore < 4) { 07122 bestscore = 4; 07123 if (best) 07124 user_unref(best); 07125 best = user; 07126 continue; 07127 } 07128 } else { 07129 /* No host access, but no secret, either, not bad */ 07130 if (bestscore < 3) { 07131 bestscore = 3; 07132 if (best) 07133 user_unref(best); 07134 best = user; 07135 continue; 07136 } 07137 } 07138 } else { 07139 if (user->ha) { 07140 /* Authentication, but host access too, eh, it's something.. */ 07141 if (bestscore < 2) { 07142 bestscore = 2; 07143 if (best) 07144 user_unref(best); 07145 best = user; 07146 continue; 07147 } 07148 } else { 07149 /* Authentication and no host access... This is our baseline */ 07150 if (bestscore < 1) { 07151 bestscore = 1; 07152 if (best) 07153 user_unref(best); 07154 best = user; 07155 continue; 07156 } 07157 } 07158 } 07159 } 07160 user_unref(user); 07161 } 07162 ao2_iterator_destroy(&i); 07163 user = best; 07164 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07165 user = realtime_user(iaxs[callno]->username, sin); 07166 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07167 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 07168 user = user_unref(user); 07169 } 07170 } 07171 if (user) { 07172 /* We found our match (use the first) */ 07173 /* copy vars */ 07174 for (v = user->vars ; v ; v = v->next) { 07175 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07176 tmpvar->next = iaxs[callno]->vars; 07177 iaxs[callno]->vars = tmpvar; 07178 } 07179 } 07180 /* If a max AUTHREQ restriction is in place, activate it */ 07181 if (user->maxauthreq > 0) 07182 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 07183 iaxs[callno]->prefs = user->prefs; 07184 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST); 07185 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOPREFS); 07186 ast_copy_flags(iaxs[callno], user, IAX_CODEC_NOCAP); 07187 iaxs[callno]->encmethods = user->encmethods; 07188 /* Store the requested username if not specified */ 07189 if (ast_strlen_zero(iaxs[callno]->username)) 07190 ast_string_field_set(iaxs[callno], username, user->name); 07191 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07192 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 07193 iaxs[callno]->capability = user->capability; 07194 /* And use the default context */ 07195 if (ast_strlen_zero(iaxs[callno]->context)) { 07196 if (user->contexts) 07197 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07198 else 07199 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07200 } 07201 /* And any input keys */ 07202 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07203 /* And the permitted authentication methods */ 07204 iaxs[callno]->authmethods = user->authmethods; 07205 iaxs[callno]->adsi = user->adsi; 07206 /* If the user has callerid, override the remote caller id. */ 07207 if (ast_test_flag(user, IAX_HASCALLERID)) { 07208 iaxs[callno]->calling_tns = 0; 07209 iaxs[callno]->calling_ton = 0; 07210 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07211 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07212 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07213 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07214 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07215 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07216 } /* else user is allowed to set their own CID settings */ 07217 if (!ast_strlen_zero(user->accountcode)) 07218 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07219 if (!ast_strlen_zero(user->mohinterpret)) 07220 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07221 if (!ast_strlen_zero(user->mohsuggest)) 07222 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07223 if (!ast_strlen_zero(user->parkinglot)) 07224 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07225 if (user->amaflags) 07226 iaxs[callno]->amaflags = user->amaflags; 07227 if (!ast_strlen_zero(user->language)) 07228 ast_string_field_set(iaxs[callno], language, user->language); 07229 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07230 /* Keep this check last */ 07231 if (!ast_strlen_zero(user->dbsecret)) { 07232 char *family, *key=NULL; 07233 char buf[80]; 07234 family = ast_strdupa(user->dbsecret); 07235 key = strchr(family, '/'); 07236 if (key) { 07237 *key = '\0'; 07238 key++; 07239 } 07240 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07241 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07242 else 07243 ast_string_field_set(iaxs[callno], secret, buf); 07244 } else 07245 ast_string_field_set(iaxs[callno], secret, user->secret); 07246 res = 0; 07247 user = user_unref(user); 07248 } else { 07249 /* user was not found, but we should still fake an AUTHREQ. 07250 * Set authmethods to the last known authmethod used by the system 07251 * Set a fake secret, it's not looked at, just required to attempt authentication. 07252 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07253 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07254 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07255 iaxs[callno]->authrej = 1; 07256 if (!ast_strlen_zero(iaxs[callno]->username)) { 07257 /* only send the AUTHREQ if a username was specified. */ 07258 res = 0; 07259 } 07260 } 07261 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07262 return res; 07263 }
| static int check_provisioning | ( | struct sockaddr_in * | sin, | |
| int | sockfd, | |||
| char * | si, | |||
| unsigned int | ver | |||
| ) | [static] |
Definition at line 8824 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
08825 { 08826 unsigned int ourver; 08827 char rsi[80]; 08828 snprintf(rsi, sizeof(rsi), "si-%s", si); 08829 if (iax_provision_version(&ourver, rsi, 1)) 08830 return 0; 08831 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 08832 if (ourver != ver) 08833 iax2_provision(sin, sockfd, NULL, rsi, 1); 08834 return 0; 08835 }
| static int check_srcaddr | ( | struct sockaddr * | sa, | |
| socklen_t | salen | |||
| ) | [static] |
Check if address can be used as packet source.
Definition at line 11615 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
11616 { 11617 int sd; 11618 int res; 11619 11620 sd = socket(AF_INET, SOCK_DGRAM, 0); 11621 if (sd < 0) { 11622 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 11623 return -1; 11624 } 11625 11626 res = bind(sd, sa, salen); 11627 if (res < 0) { 11628 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 11629 close(sd); 11630 return 1; 11631 } 11632 11633 close(sd); 11634 return 0; 11635 }
| static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7809 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().
07810 { 07811 char exten[256] = ""; 07812 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 07813 struct iax2_dpcache *dp = NULL; 07814 07815 if (ies->called_number) 07816 ast_copy_string(exten, ies->called_number, sizeof(exten)); 07817 07818 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 07819 status = CACHE_FLAG_EXISTS; 07820 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 07821 status = CACHE_FLAG_CANEXIST; 07822 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 07823 status = CACHE_FLAG_NONEXISTENT; 07824 07825 if (ies->refresh) 07826 expiry = ies->refresh; 07827 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 07828 matchmore = CACHE_FLAG_MATCHMORE; 07829 07830 AST_LIST_LOCK(&dpcache); 07831 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 07832 if (strcmp(dp->exten, exten)) 07833 continue; 07834 AST_LIST_REMOVE_CURRENT(peer_list); 07835 dp->callno = 0; 07836 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 07837 if (dp->flags & CACHE_FLAG_PENDING) { 07838 dp->flags &= ~CACHE_FLAG_PENDING; 07839 dp->flags |= status; 07840 dp->flags |= matchmore; 07841 } 07842 /* Wake up waiters */ 07843 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 07844 if (dp->waiters[x] > -1) { 07845 if (write(dp->waiters[x], "asdf", 4) < 0) { 07846 } 07847 } 07848 } 07849 } 07850 AST_LIST_TRAVERSE_SAFE_END; 07851 AST_LIST_UNLOCK(&dpcache); 07852 07853 return 0; 07854 }
| static char * complete_iax2_peers | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 3546 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::name, and peer_unref().
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), and handle_cli_iax2_show_peer().
03547 { 03548 int which = 0; 03549 struct iax2_peer *peer; 03550 char *res = NULL; 03551 int wordlen = strlen(word); 03552 struct ao2_iterator i; 03553 03554 i = ao2_iterator_init(peers, 0); 03555 while ((peer = ao2_iterator_next(&i))) { 03556 if (!strncasecmp(peer->name, word, wordlen) && ++which > state) { 03557 res = ast_strdup(peer->name); 03558 peer_unref(peer); 03559 break; 03560 } 03561 peer_unref(peer); 03562 } 03563 ao2_iterator_destroy(&i); 03564 03565 return res; 03566 }
| static char * complete_iax2_unregister | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 6459 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, iax2_peer::expire, iax2_peer::name, and peer_unref().
Referenced by handle_cli_iax2_unregister().
06460 { 06461 int which = 0; 06462 struct iax2_peer *p = NULL; 06463 char *res = NULL; 06464 int wordlen = strlen(word); 06465 06466 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06467 if (pos == 2) { 06468 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06469 while ((p = ao2_iterator_next(&i))) { 06470 if (!strncasecmp(p->name, word, wordlen) && 06471 ++which > state && p->expire > 0) { 06472 res = ast_strdup(p->name); 06473 peer_unref(p); 06474 break; 06475 } 06476 peer_unref(p); 06477 } 06478 ao2_iterator_destroy(&i); 06479 } 06480 06481 return res; 06482 }
| static int complete_transfer | ( | int | callno, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7856 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::aseqno, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), iax_frame::callno, iax_ies::callno, jb_frame::data, DEFAULT_RETRY_TIME, iax2_frame_free(), chan_iax2_pvt::iseqno, chan_iax2_pvt::jb, jb_getall(), JB_OK, jb_reset(), chan_iax2_pvt::lag, chan_iax2_pvt::last, chan_iax2_pvt::lastsent, LOG_WARNING, chan_iax2_pvt::nextpred, chan_iax2_pvt::offset, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, peercnt_add(), peercnt_remove_by_addr(), chan_iax2_pvt::pingtime, remove_by_peercallno(), remove_by_transfercallno(), iax_frame::retries, chan_iax2_pvt::rseqno, chan_iax2_pvt::rxcore, store_by_peercallno(), chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, TRANSFER_NONE, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, chan_iax2_pvt::videoformat, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
07857 { 07858 int peercallno = 0; 07859 struct chan_iax2_pvt *pvt = iaxs[callno]; 07860 struct iax_frame *cur; 07861 jb_frame frame; 07862 07863 if (ies->callno) 07864 peercallno = ies->callno; 07865 07866 if (peercallno < 1) { 07867 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07868 return -1; 07869 } 07870 remove_by_transfercallno(pvt); 07871 /* since a transfer has taken place, the address will change. 07872 * This must be accounted for in the peercnts table. Remove 07873 * the old address and add the new one */ 07874 peercnt_remove_by_addr(&pvt->addr); 07875 peercnt_add(&pvt->transfer); 07876 /* now copy over the new address */ 07877 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 07878 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 07879 /* Reset sequence numbers */ 07880 pvt->oseqno = 0; 07881 pvt->rseqno = 0; 07882 pvt->iseqno = 0; 07883 pvt->aseqno = 0; 07884 07885 if (pvt->peercallno) { 07886 remove_by_peercallno(pvt); 07887 } 07888 pvt->peercallno = peercallno; 07889 /*this is where the transfering call swiches hash tables */ 07890 store_by_peercallno(pvt); 07891 pvt->transferring = TRANSFER_NONE; 07892 pvt->svoiceformat = -1; 07893 pvt->voiceformat = 0; 07894 pvt->svideoformat = -1; 07895 pvt->videoformat = 0; 07896 pvt->transfercallno = -1; 07897 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 07898 memset(&pvt->offset, 0, sizeof(pvt->offset)); 07899 /* reset jitterbuffer */ 07900 while(jb_getall(pvt->jb,&frame) == JB_OK) 07901 iax2_frame_free(frame.data); 07902 jb_reset(pvt->jb); 07903 pvt->lag = 0; 07904 pvt->last = 0; 07905 pvt->lastsent = 0; 07906 pvt->nextpred = 0; 07907 pvt->pingtime = DEFAULT_RETRY_TIME; 07908 AST_LIST_LOCK(&frame_queue); 07909 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 07910 /* We must cancel any packets that would have been transmitted 07911 because now we're talking to someone new. It's okay, they 07912 were transmitted to someone that didn't care anyway. */ 07913 if (callno == cur->callno) 07914 cur->retries = -1; 07915 } 07916 AST_LIST_UNLOCK(&frame_queue); 07917 return 0; 07918 }
| static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1370 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().
01371 { 01372 int x; 01373 int power=-1; 01374 /* If it's 128 or smaller, just return it */ 01375 if (subclass < IAX_FLAG_SC_LOG) 01376 return subclass; 01377 /* Otherwise find its power */ 01378 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01379 if (subclass & (1 << x)) { 01380 if (power > -1) { 01381 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01382 return 0; 01383 } else 01384 power = x; 01385 } 01386 } 01387 return power | IAX_FLAG_SC_LOG; 01388 }
| static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | iep | |||
| ) | [static] |
Definition at line 8837 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().
08838 { 08839 jb_info stats; 08840 jb_getinfo(pvt->jb, &stats); 08841 08842 memset(iep, 0, sizeof(*iep)); 08843 08844 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 08845 if(stats.frames_in == 0) stats.frames_in = 1; 08846 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 08847 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 08848 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 08849 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 08850 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 08851 }
| static int create_addr | ( | const char * | peername, | |
| struct ast_channel * | c, | |||
| struct sockaddr_in * | sin, | |||
| struct create_addr_info * | cai | |||
| ) | [static] |
Definition at line 4235 of file chan_iax2.c.
References iax2_peer::addr, iax2_peer::adsi, create_addr_info::adsi, ast_clear_flag, ast_codec_pref_convert(), ast_codec_pref_prepend(), ast_copy_flags, ast_copy_string(), ast_db_get(), ast_debug, ast_get_ip_or_srv(), ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::capability, create_addr_info::capability, 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_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, 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, create_addr_info::timezone, iax2_peer::username, create_addr_info::username, and iax2_peer::zonetag.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_provision(), and iax2_request().
04236 { 04237 struct iax2_peer *peer; 04238 int res = -1; 04239 struct ast_codec_pref ourprefs; 04240 04241 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 04242 cai->sockfd = defaultsockfd; 04243 cai->maxtime = 0; 04244 sin->sin_family = AF_INET; 04245 04246 if (!(peer = find_peer(peername, 1))) { 04247 cai->found = 0; 04248 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) { 04249 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04250 return -1; 04251 } 04252 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04253 /* use global iax prefs for unknown peer/user */ 04254 /* But move the calling channel's native codec to the top of the preference list */ 04255 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04256 if (c) 04257 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04258 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04259 return 0; 04260 } 04261 04262 cai->found = 1; 04263 04264 /* if the peer has no address (current or default), return failure */ 04265 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 04266 goto return_unref; 04267 04268 /* if the peer is being monitored and is currently unreachable, return failure */ 04269 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04270 goto return_unref; 04271 04272 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 04273 cai->maxtime = peer->maxms; 04274 cai->capability = peer->capability; 04275 cai->encmethods = peer->encmethods; 04276 cai->sockfd = peer->sockfd; 04277 cai->adsi = peer->adsi; 04278 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04279 /* Move the calling channel's native codec to the top of the preference list */ 04280 if (c) { 04281 ast_debug(1, "prepending %x to prefs\n", c->nativeformats); 04282 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04283 } 04284 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04285 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04286 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04287 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04288 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04289 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04290 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04291 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04292 if (ast_strlen_zero(peer->dbsecret)) { 04293 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04294 } else { 04295 char *family; 04296 char *key = NULL; 04297 04298 family = ast_strdupa(peer->dbsecret); 04299 key = strchr(family, '/'); 04300 if (key) 04301 *key++ = '\0'; 04302 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04303 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04304 goto return_unref; 04305 } 04306 } 04307 04308 if (peer->addr.sin_addr.s_addr) { 04309 sin->sin_addr = peer->addr.sin_addr; 04310 sin->sin_port = peer->addr.sin_port; 04311 } else { 04312 sin->sin_addr = peer->defaddr.sin_addr; 04313 sin->sin_port = peer->defaddr.sin_port; 04314 } 04315 04316 res = 0; 04317 04318 return_unref: 04319 peer_unref(peer); 04320 04321 return res; 04322 }
| static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2394 of file chan_iax2.c.
References ao2_alloc, ao2_container_alloc, ao2_link, ao2_ref, callno_entry::callno, callno_hash(), IAX_MAX_CALLS, and TRUNK_CALL_START.
Referenced by load_objects().
02395 { 02396 uint16_t i; 02397 02398 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02399 return -1; 02400 } 02401 02402 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02403 return -1; 02404 } 02405 02406 /* start at 2, 0 and 1 are reserved */ 02407 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02408 struct callno_entry *callno_entry; 02409 02410 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02411 return -1; 02412 } 02413 02414 callno_entry->callno = i; 02415 02416 if (i < TRUNK_CALL_START) { 02417 ao2_link(callno_pool, callno_entry); 02418 } else { 02419 ao2_link(callno_pool_trunk, callno_entry); 02420 } 02421 02422 ao2_ref(callno_entry, -1); 02423 } 02424 02425 return 0; 02426 }
| 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 5825 of file chan_iax2.c.
References ast_debug, AST_FRAME_VIDEO, ast_iax2_full_hdr::csub, ast_iax2_mini_enc_hdr::encdata, ast_iax2_full_enc_hdr::encdata, ast_frame::frametype, IAX_FLAG_FULL, memcpy_decrypt(), ast_iax2_full_hdr::scallno, ast_frame::subclass, ast_iax2_full_hdr::type, and uncompress_subclass().
Referenced by decrypt_frame(), and update_packet().
05826 { 05827 int padding; 05828 unsigned char *workspace; 05829 05830 workspace = alloca(*datalen); 05831 memset(f, 0, sizeof(*f)); 05832 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05833 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05834 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 05835 return -1; 05836 /* Decrypt */ 05837 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 05838 05839 padding = 16 + (workspace[15] & 0x0f); 05840 if (iaxdebug) 05841 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 05842 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 05843 return -1; 05844 05845 *datalen -= padding; 05846 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05847 f->frametype = fh->type; 05848 if (f->frametype == AST_FRAME_VIDEO) { 05849 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 05850 } else { 05851 f->subclass = uncompress_subclass(fh->csub); 05852 } 05853 } else { 05854 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05855 if (iaxdebug) 05856 ast_debug(1, "Decoding mini with length %d\n", *datalen); 05857 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 05858 return -1; 05859 /* Decrypt */ 05860 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 05861 padding = 16 + (workspace[15] & 0x0f); 05862 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 05863 return -1; 05864 *datalen -= padding; 05865 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05866 } 05867 return 0; 05868 }
| static int decrypt_frame | ( | int | callno, | |
| struct ast_iax2_full_hdr * | fh, | |||
| struct ast_frame * | f, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 5911 of file chan_iax2.c.
References ast_set_flag, ast_strdupa, ast_test_flag, build_encryption_keys(), decode_frame(), IAX_KEYPOPULATED, MD5Final(), MD5Init(), MD5Update(), secret, and strsep().
Referenced by socket_process().
05912 { 05913 int res=-1; 05914 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 05915 /* Search for possible keys, given secrets */ 05916 struct MD5Context md5; 05917 unsigned char digest[16]; 05918 char *tmppw, *stringp; 05919 05920 tmppw = ast_strdupa(iaxs[callno]->secret); 05921 stringp = tmppw; 05922 while ((tmppw = strsep(&stringp, ";"))) { 05923 MD5Init(&md5); 05924 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 05925 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 05926 MD5Final(digest, &md5); 05927 build_encryption_keys(digest, iaxs[callno]); 05928 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05929 if (!res) { 05930 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 05931 break; 05932 } 05933 } 05934 } else 05935 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 05936 return res; 05937 }
| 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 8984 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_thread::buf, iax2_pkt_buf::buf, iax2_thread::buf_len, iax2_thread::full_frames, iax2_pkt_buf::len, iax2_thread::lock, and ast_iax2_full_hdr::oseqno.
Referenced by socket_read().
08985 { 08986 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 08987 struct ast_iax2_full_hdr *fh, *cur_fh; 08988 08989 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 08990 return; 08991 08992 pkt_buf->len = from_here->buf_len; 08993 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 08994 08995 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 08996 ast_mutex_lock(&to_here->lock); 08997 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 08998 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 08999 if (fh->oseqno < cur_fh->oseqno) { 09000 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09001 break; 09002 } 09003 } 09004 AST_LIST_TRAVERSE_SAFE_END 09005 09006 if (!cur_pkt_buf) 09007 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09008 09009 ast_mutex_unlock(&to_here->lock); 09010 }
| static void delete_users | ( | void | ) | [static] |
Definition at line 12245 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_DEL, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, iax2_destroy(), peer_delme_cb(), chan_iax2_pvt::reg, and user_delme_cb().
Referenced by __unload_module(), and set_config_destroy().
12246 { 12247 struct iax2_registry *reg; 12248 12249 ao2_callback(users, 0, user_delme_cb, NULL); 12250 12251 AST_LIST_LOCK(®istrations); 12252 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 12253 AST_SCHED_DEL(sched, reg->expire); 12254 if (reg->callno) { 12255 int callno = reg->callno; 12256 ast_mutex_lock(&iaxsl[callno]); 12257 if (iaxs[callno]) { 12258 iaxs[callno]->reg = NULL; 12259 iax2_destroy(callno); 12260 } 12261 ast_mutex_unlock(&iaxsl[callno]); 12262 } 12263 if (reg->dnsmgr) 12264 ast_dnsmgr_release(reg->dnsmgr); 12265 ast_free(reg); 12266 } 12267 AST_LIST_UNLOCK(®istrations); 12268 12269 ao2_callback(peers, 0, peer_delme_cb, NULL); 12270 }
| static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2750 of file chan_iax2.c.
References ast_free, ast_iax2_firmware_header::datalen, iax_firmware::fd, and iax_firmware::fwh.
Referenced by reload_firmware().
| static void dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid, | |||
| int | skiplock | |||
| ) | [static] |
Definition at line 8685 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(), iax_ie_data::buf, IAX_COMMAND_DPREP, IAX_DPSTATUS_CANEXIST, IAX_DPSTATUS_EXISTS, IAX_DPSTATUS_IGNOREPAT, IAX_DPSTATUS_MATCHMORE, IAX_DPSTATUS_NONEXISTENT, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLED_NUMBER, IAX_IE_DPSTATUS, IAX_IE_REFRESH, iax_ie_data::pos, and send_command().
Referenced by dp_lookup_thread(), and socket_process().
08686 { 08687 unsigned short dpstatus = 0; 08688 struct iax_ie_data ied1; 08689 int mm; 08690 08691 memset(&ied1, 0, sizeof(ied1)); 08692 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 08693 /* Must be started */ 08694 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 08695 dpstatus = IAX_DPSTATUS_EXISTS; 08696 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 08697 dpstatus = IAX_DPSTATUS_CANEXIST; 08698 } else { 08699 dpstatus = IAX_DPSTATUS_NONEXISTENT; 08700 } 08701 if (ast_ignore_pattern(context, callednum)) 08702 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 08703 if (mm) 08704 dpstatus |= IAX_DPSTATUS_MATCHMORE; 08705 if (!skiplock) 08706 ast_mutex_lock(&iaxsl[callno]); 08707 if (iaxs[callno]) { 08708 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 08709 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 08710 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 08711 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 08712 } 08713 if (!skiplock) 08714 ast_mutex_unlock(&iaxsl[callno]); 08715 }
| static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 8717 of file chan_iax2.c.
References ast_free, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, and dp_lookup().
Referenced by spawn_dp_lookup().
| static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
| struct ast_iax2_full_hdr * | fh, | |||
| unsigned char * | poo, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 5870 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().
05871 { 05872 int padding; 05873 unsigned char *workspace; 05874 workspace = alloca(*datalen + 32); 05875 if (!workspace) 05876 return -1; 05877 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05878 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05879 if (iaxdebug) 05880 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 05881 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 05882 padding = 16 + (padding & 0xf); 05883 memcpy(workspace, poo, padding); 05884 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05885 workspace[15] &= 0xf0; 05886 workspace[15] |= (padding & 0xf); 05887 if (iaxdebug) 05888 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 05889 *datalen += padding; 05890 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 05891 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 05892 memcpy(poo, workspace + *datalen - 32, 32); 05893 } else { 05894 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05895 if (iaxdebug) 05896 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 05897 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 05898 padding = 16 + (padding & 0xf); 05899 memcpy(workspace, poo, padding); 05900 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05901 workspace[15] &= 0xf0; 05902 workspace[15] |= (padding & 0x0f); 05903 *datalen += padding; 05904 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 05905 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 05906 memcpy(poo, workspace + *datalen - 32, 32); 05907 } 05908 return 0; 05909 }
| static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8116 of file chan_iax2.c.
References __expire_registry(), and schedule_action.
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), realtime_peer(), reg_source_db(), and update_registry().
08117 { 08118 #ifdef SCHED_MULTITHREADED 08119 if (schedule_action(__expire_registry, data)) 08120 #endif 08121 __expire_registry(data); 08122 return 0; 08123 }
| static struct iax2_dpcache* find_cache | ( | struct ast_channel * | chan, | |
| const char * | data, | |||
| const char * | context, | |||
| const char * | exten, | |||
| int | priority | |||
| ) | [static, read] |
Definition at line 12882 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, LOG_WARNING, iax2_dpcache::orig, iax2_dpcache::peercontext, and iax2_dpcache::waiters.
Referenced by iax2_canmatch(), iax2_exec(), iax2_exists(), and iax2_matchmore().
12883 { 12884 struct iax2_dpcache *dp = NULL; 12885 struct timeval now = ast_tvnow(); 12886 int x, com[2], timeout, old = 0, outfd, doabort, callno; 12887 struct ast_channel *c = NULL; 12888 struct ast_frame *f = NULL; 12889 12890 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 12891 if (ast_tvcmp(now, dp->expiry) > 0) { 12892 AST_LIST_REMOVE_CURRENT(cache_list); 12893 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 12894 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 12895 else 12896 ast_free(dp); 12897 continue; 12898 } 12899 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 12900 break; 12901 } 12902 AST_LIST_TRAVERSE_SAFE_END; 12903 12904 if (!dp) { 12905 /* No matching entry. Create a new one. */ 12906 /* First, can we make a callno? */ 12907 if ((callno = cache_get_callno_locked(data)) < 0) { 12908 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 12909 return NULL; 12910 } 12911 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 12912 ast_mutex_unlock(&iaxsl[callno]); 12913 return NULL; 12914 } 12915 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 12916 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 12917 dp->expiry = ast_tvnow(); 12918 dp->orig = dp->expiry; 12919 /* Expires in 30 mins by default */ 12920 dp->expiry.tv_sec += iaxdefaultdpcache; 12921 dp->flags = CACHE_FLAG_PENDING; 12922 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 12923 dp->waiters[x] = -1; 12924 /* Insert into the lists */ 12925 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 12926 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 12927 /* Send the request if we're already up */ 12928 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 12929 iax2_dprequest(dp, callno); 12930 ast_mutex_unlock(&iaxsl[callno]); 12931 } 12932 12933 /* By here we must have a dp */ 12934 if (dp->flags & CACHE_FLAG_PENDING) { 12935 /* Okay, here it starts to get nasty. We need a pipe now to wait 12936 for a reply to come back so long as it's pending */ 12937 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 12938 /* Find an empty slot */ 12939 if (dp->waiters[x] < 0) 12940 break; 12941 } 12942 if (x >= ARRAY_LEN(dp->waiters)) { 12943 ast_log(LOG_WARNING, "No more waiter positions available\n"); 12944 return NULL; 12945 } 12946 if (pipe(com)) { 12947 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 12948 return NULL; 12949 } 12950 dp->waiters[x] = com[1]; 12951 /* Okay, now we wait */ 12952 timeout = iaxdefaulttimeout * 1000; 12953 /* Temporarily unlock */ 12954 AST_LIST_UNLOCK(&dpcache); 12955 /* Defer any dtmf */ 12956 if (chan) 12957 old = ast_channel_defer_dtmf(chan); 12958 doabort = 0; 12959 while(timeout) { 12960 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 12961 if (outfd > -1) 12962 break; 12963 if (!c) 12964 continue; 12965 if (!(f = ast_read(c))) { 12966 doabort = 1; 12967 break; 12968 } 12969 ast_frfree(f); 12970 } 12971 if (!timeout) { 12972 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 12973 } 12974 AST_LIST_LOCK(&dpcache); 12975 dp->waiters[x] = -1; 12976 close(com[1]); 12977 close(com[0]); 12978 if (doabort) { 12979 /* Don't interpret anything, just abort. Not sure what th epoint 12980 of undeferring dtmf on a hung up channel is but hey whatever */ 12981 if (!old && chan) 12982 ast_channel_undefer_dtmf(chan); 12983 return NULL; 12984 } 12985 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 12986 /* Now to do non-independent analysis the results of our wait */ 12987 if (dp->flags & CACHE_FLAG_PENDING) { 12988 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 12989 pending. Don't let it take as long to timeout. */ 12990 dp->flags &= ~CACHE_FLAG_PENDING; 12991 dp->flags |= CACHE_FLAG_TIMEOUT; 12992 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 12993 systems without leaving it unavailable once the server comes back online */ 12994 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 12995 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 12996 if (dp->waiters[x] > -1) { 12997 if (write(dp->waiters[x], "asdf", 4) < 0) { 12998 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 12999 } 13000 } 13001 } 13002 } 13003 } 13004 /* Our caller will obtain the rest */ 13005 if (!old && chan) 13006 ast_channel_undefer_dtmf(chan); 13007 } 13008 return dp; 13009 }
| 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 2650 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02650 { 02651 02652 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02653 }
| 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 2655 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().
02655 { 02656 02657 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02658 }
| static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 1182 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_detached_background, iax2_thread::cond, iax2_thread::ffinfo, iax2_process_thread(), IAX_THREAD_TYPE_DYNAMIC, iaxdynamicthreadcount, iaxdynamicthreadnum, iaxmaxthreadcount, iax2_thread::init_cond, iax2_thread::init_lock, iax2_thread::lock, thread, iax2_thread::threadid, iax2_thread::threadnum, and iax2_thread::type.
Referenced by __schedule_action(), and socket_read().
01183 { 01184 struct iax2_thread *thread = NULL; 01185 01186 /* Pop the head of the idle list off */ 01187 AST_LIST_LOCK(&idle_list); 01188 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01189 AST_LIST_UNLOCK(&idle_list); 01190 01191 /* If we popped a thread off the idle list, just return it */ 01192 if (thread) { 01193 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01194 return thread; 01195 } 01196 01197 /* Pop the head of the dynamic list off */ 01198 AST_LIST_LOCK(&dynamic_list); 01199 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01200 AST_LIST_UNLOCK(&dynamic_list); 01201 01202 /* If we popped a thread off the dynamic list, just return it */ 01203 if (thread) { 01204 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01205 return thread; 01206 } 01207 01208 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01209 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01210 return NULL; 01211 01212 /* Set default values */ 01213 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01214 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01215 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01216 01217 /* Initialize lock and condition */ 01218 ast_mutex_init(&thread->lock); 01219 ast_cond_init(&thread->cond, NULL); 01220 ast_mutex_init(&thread->init_lock); 01221 ast_cond_init(&thread->init_cond, NULL); 01222 ast_mutex_lock(&thread->init_lock); 01223 01224 /* Create thread and send it on it's way */ 01225 if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01226 ast_cond_destroy(&thread->cond); 01227 ast_mutex_destroy(&thread->lock); 01228 ast_free(thread); 01229 return NULL; 01230 } 01231 01232 /* this thread is not processing a full frame (since it is idle), 01233 so ensure that the field for the full frame call number is empty */ 01234 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01235 01236 /* Wait for the thread to be ready before returning it to the caller */ 01237 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01238 01239 /* Done with init_lock */ 01240 ast_mutex_unlock(&thread->init_lock); 01241 01242 return thread; 01243 }
| static struct iax2_peer* find_peer | ( | const char * | name, | |
| int | realtime | |||
| ) | [static, read] |
Definition at line 1448 of file chan_iax2.c.
References ao2_find, iax2_peer::name, OBJ_POINTER, and realtime_peer().
Referenced by calltoken_required(), create_addr(), function_iaxpeer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), handle_cli_iax2_show_peer(), handle_cli_iax2_unregister(), iax2_devicestate(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), and update_registry().
01449 { 01450 struct iax2_peer *peer = NULL; 01451 struct iax2_peer tmp_peer = { 01452 .name = name, 01453 }; 01454 01455 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01456 01457 /* Now go for realtime if applicable */ 01458 if(!peer && realtime) 01459 peer = realtime_peer(name, NULL); 01460 01461 return peer; 01462 }
| static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
| int | fd | |||
| ) | [static, read] |
Definition at line 5643 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_calloc, ast_debug, ast_inet_ntoa(), AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_init(), ast_mutex_lock(), ast_tvnow(), inaddrcmp(), iax2_trunk_peer::lastsent, iax2_trunk_peer::lock, iax2_trunk_peer::sockfd, and iax2_trunk_peer::trunkact.
Referenced by iax2_trunk_queue(), and socket_process_meta().
05644 { 05645 struct iax2_trunk_peer *tpeer = NULL; 05646 05647 /* Finds and locks trunk peer */ 05648 AST_LIST_LOCK(&tpeers); 05649 05650 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 05651 if (!inaddrcmp(&tpeer->addr, sin)) { 05652 ast_mutex_lock(&tpeer->lock); 05653 break; 05654 } 05655 } 05656 05657 if (!tpeer) { 05658 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 05659 ast_mutex_init(&tpeer->lock); 05660 tpeer->lastsent = 9999; 05661 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 05662 tpeer->trunkact = ast_tvnow(); 05663 ast_mutex_lock(&tpeer->lock); 05664 tpeer->sockfd = fd; 05665 #ifdef SO_NO_CHECK 05666 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 05667 #endif 05668 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 05669 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 05670 } 05671 } 05672 05673 AST_LIST_UNLOCK(&tpeers); 05674 05675 return tpeer; 05676 }
| static struct iax2_user* find_user | ( | const char * | name | ) | [static, read] |
Definition at line 1476 of file chan_iax2.c.
References ao2_find, iax2_user::name, and OBJ_POINTER.
Referenced by calltoken_required(), handle_cli_iax2_prune_realtime(), and requirecalltoken_mark_auto().
01477 { 01478 struct iax2_user tmp_user = { 01479 .name = name, 01480 }; 01481 01482 return ao2_find(users, &tmp_user, OBJ_POINTER); 01483 }
| static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
| int | callno, | |||
| unsigned int | ts | |||
| ) | [static] |
Definition at line 5455 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05456 { 05457 long ms; /* NOT unsigned */ 05458 if (ast_tvzero(iaxs[callno]->rxcore)) { 05459 /* Initialize rxcore time if appropriate */ 05460 iaxs[callno]->rxcore = ast_tvnow(); 05461 /* Round to nearest 20ms so traces look pretty */ 05462 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05463 } 05464 /* Calculate difference between trunk and channel */ 05465 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05466 /* Return as the sum of trunk time and the difference between trunk and real time */ 05467 return ms + ts; 05468 }
| static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 11379 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
11380 { 11381 struct iax2_context *conl; 11382 while(con) { 11383 conl = con; 11384 con = con->next; 11385 ast_free(conl); 11386 } 11387 }
| static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1576 of file chan_iax2.c.
References ast_free, ast_frame::data, signaling_queue_entry::f, and ast_frame::ptr.
Referenced by pvt_destructor(), queue_signalling(), and send_signaling().
| static int function_iaxpeer | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 13132 of file chan_iax2.c.
References iax2_peer::addr, iax2_trunk_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strdupa, ast_test_flag, iax2_peer::callno, iax2_peer::capability, iax2_peer::cid_name, iax2_peer::cid_num, iax2_peer::context, iax2_peer::expire, find_peer(), IAX_DYNAMIC, iax2_peer::mailbox, peer_status(), peer_unref(), iax2_peer::prefs, PTR_TO_CALLNO, ast_channel::tech, and ast_channel::tech_pvt.
13133 { 13134 struct iax2_peer *peer; 13135 char *peername, *colname; 13136 13137 peername = ast_strdupa(data); 13138 13139 /* if our channel, return the IP address of the endpoint of current channel */ 13140 if (!strcmp(peername,"CURRENTCHANNEL")) { 13141 unsigned short callno; 13142 if (chan->tech != &iax2_tech) 13143 return -1; 13144 callno = PTR_TO_CALLNO(chan->tech_pvt); 13145 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 13146 return 0; 13147 } 13148 13149 if ((colname = strchr(peername, ','))) 13150 *colname++ = '\0'; 13151 else 13152 colname = "ip"; 13153 13154 if (!(peer = find_peer(peername, 1))) 13155 return -1; 13156 13157 if (!strcasecmp(colname, "ip")) { 13158 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 13159 } else if (!strcasecmp(colname, "status")) { 13160 peer_status(peer, buf, len); 13161 } else if (!strcasecmp(colname, "mailbox")) { 13162 ast_copy_string(buf, peer->mailbox, len); 13163 } else if (!strcasecmp(colname, "context")) { 13164 ast_copy_string(buf, peer->context, len); 13165 } else if (!strcasecmp(colname, "expire")) { 13166 snprintf(buf, len, "%d", peer->expire); 13167 } else if (!strcasecmp(colname, "dynamic")) { 13168 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 13169 } else if (!strcasecmp(colname, "callerid_name")) { 13170 ast_copy_string(buf, peer->cid_name, len); 13171 } else if (!strcasecmp(colname, "callerid_num")) { 13172 ast_copy_string(buf, peer->cid_num, len); 13173 } else if (!strcasecmp(colname, "codecs")) { 13174 ast_getformatname_multiple(buf, len -1, peer->capability); 13175 } else if (!strncasecmp(colname, "codec[", 6)) { 13176 char *codecnum, *ptr; 13177 int codec = 0; 13178 13179 codecnum = strchr(colname, '['); 13180 *codecnum = '\0'; 13181 codecnum++; 13182 if ((ptr = strchr(codecnum, ']'))) { 13183 *ptr = '\0'; 13184 } 13185 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 13186 ast_copy_string(buf, ast_getformatname(codec), len); 13187 } else { 13188 buf[0] = '\0'; 13189 } 13190 } else { 13191 buf[0] = '\0'; 13192 } 13193 13194 peer_unref(peer); 13195 13196 return 0; 13197 }
| static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 11599 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
11600 { 11601 int methods = 0; 11602 if (strstr(value, "rsa")) 11603 methods |= IAX_AUTH_RSA; 11604 if (strstr(value, "md5")) 11605 methods |= IAX_AUTH_MD5; 11606 if (strstr(value, "plaintext")) 11607 methods |= IAX_AUTH_PLAINTEXT; 11608 return methods; 11609 }
| static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1325 of file chan_iax2.c.
References ast_true(), and IAX_ENCRYPT_AES128.
Referenced by build_peer(), build_user(), and set_config().
01326 { 01327 int e; 01328 if (!strcasecmp(s, "aes128")) 01329 e = IAX_ENCRYPT_AES128; 01330 else if (ast_true(s)) 01331 e = IAX_ENCRYPT_AES128; 01332 else 01333 e = 0; 01334 return e; 01335 }
| static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3853 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
03854 { 03855 #ifdef SCHED_MULTITHREADED 03856 if (schedule_action(__get_from_jb, data)) 03857 #endif 03858 __get_from_jb(data); 03859 return 0; 03860 }
| static struct callno_entry * get_unused_callno | ( | int | trunk, | |
| int | validated | |||
| ) | [static, read] |
Definition at line 2327 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().
02328 { 02329 struct callno_entry *callno_entry = NULL; 02330 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02331 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02332 /* Minor optimization for the extreme case. */ 02333 return NULL; 02334 } 02335 02336 /* the callno_pool container is locked here primarily to ensure thread 02337 * safety of the total_nonval_callno_used check and increment */ 02338 ao2_lock(callno_pool); 02339 02340 /* only a certain number of nonvalidated call numbers should be allocated. 02341 * If there ever is an attack, this separates the calltoken validating 02342 * users from the non calltoken validating users. */ 02343 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02344 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02345 ao2_unlock(callno_pool); 02346 return NULL; 02347 } 02348 02349 /* unlink the object from the container, taking over ownership 02350 * of the reference the container had to the object */ 02351 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02352 02353 if (callno_entry) { 02354 callno_entry->validated = validated; 02355 if (!validated) { 02356 total_nonval_callno_used++; 02357 } 02358 } 02359 02360 ao2_unlock(callno_pool); 02361 return callno_entry; 02362 }
| 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 4532 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().
04534 { 04535 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04536 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04537 struct ast_str *buf = ast_str_alloca(256); 04538 time_t t = time(NULL); 04539 char hash[41]; /* 40 char sha1 hash */ 04540 int subclass = uncompress_subclass(fh->csub); 04541 04542 /* ----- Case 1 ----- */ 04543 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04544 struct iax_ie_data ied = { 04545 .buf = { 0 }, 04546 .pos = 0, 04547 }; 04548 04549 /* create the hash with their address data and our timestamp */ 04550 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04551 ast_sha1_hash(hash, ast_str_buffer(buf)); 04552 04553 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04554 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04555 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04556 04557 return 1; 04558 04559 /* ----- Case 2 ----- */ 04560 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04561 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04562 char *rec_ts = NULL; /* received timestamp */ 04563 unsigned int rec_time; /* received time_t */ 04564 04565 /* split the timestamp from the hash data */ 04566 rec_hash = strchr((char *) ies->calltokendata, '?'); 04567 if (rec_hash) { 04568 *rec_hash++ = '\0'; 04569 rec_ts = (char *) ies->calltokendata; 04570 } 04571 04572 /* check that we have valid data before we do any comparisons */ 04573 if (!rec_hash || !rec_ts) { 04574 goto reject; 04575 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04576 goto reject; 04577 } 04578 04579 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04580 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04581 ast_sha1_hash(hash, ast_str_buffer(buf)); 04582 04583 /* compare hashes and then check timestamp delay */ 04584 if (strcmp(hash, rec_hash)) { 04585 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04586 goto reject; /* received hash does not match ours, reject */ 04587 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04588 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04589 goto reject; /* too much delay, reject */ 04590 } 04591 04592 /* at this point the call token is valid, returning 0 04593 * will allow socket_process to continue as usual */ 04594 requirecalltoken_mark_auto(ies->username, subclass); 04595 return 0; 04596 04597 /* ----- Case 3 ----- */ 04598 } else { /* calltokens are not supported for this client, how do we respond? */ 04599 if (calltoken_required(sin, ies->username, subclass)) { 04600 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")); 04601 goto reject; 04602 } 04603 return 0; /* calltoken is not required for this addr, so permit it. */ 04604 } 04605 04606 reject: 04607 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04608 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04609 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04610 } else { 04611 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04612 } 04613 04614 return 1; 04615 }
| static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 11230 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.
11231 { 11232 int force = 0; 11233 int res; 11234 11235 switch (cmd) { 11236 case CLI_INIT: 11237 e->command = "iax2 provision"; 11238 e->usage = 11239 "Usage: iax2 provision <host> <template> [forced]\n" 11240 " Provisions the given peer or IP address using a template\n" 11241 " matching either 'template' or '*' if the template is not\n" 11242 " found. If 'forced' is specified, even empty provisioning\n" 11243 " fields will be provisioned as empty fields.\n"; 11244 return NULL; 11245 case CLI_GENERATE: 11246 if (a->pos == 3) 11247 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 11248 return NULL; 11249 } 11250 11251 if (a->argc < 4) 11252 return CLI_SHOWUSAGE; 11253 if (a->argc > 4) { 11254 if (!strcasecmp(a->argv[4], "forced")) 11255 force = 1; 11256 else 11257 return CLI_SHOWUSAGE; 11258 } 11259 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 11260 if (res < 0) 11261 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 11262 else if (res < 1) 11263 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 11264 else 11265 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 11266 return CLI_SUCCESS; 11267 }
| static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3301 of file chan_iax2.c.
References ao2_unlink, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_set_flag, ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_iax2_peers(), expire_registry(), ast_cli_args::fd, find_peer(), find_user(), IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, ast_cli_args::line, ast_cli_args::n, peer_ref(), peer_unref(), ast_cli_args::pos, prune_peers(), prune_users(), ast_cli_entry::usage, user_unref(), and ast_cli_args::word.
03302 { 03303 struct iax2_peer *peer = NULL; 03304 struct iax2_user *user = NULL; 03305 03306 switch (cmd) { 03307 case CLI_INIT: 03308 e->command = "iax2 prune realtime"; 03309 e->usage = 03310 "Usage: iax2 prune realtime [<peername>|all]\n" 03311 " Prunes object(s) from the cache\n"; 03312 return NULL; 03313 case CLI_GENERATE: 03314 if (a->pos == 3) 03315 return complete_iax2_peers(a->line, a->word, a->pos, a->n); 03316 return NULL; 03317 } 03318 if (a->argc != 4) 03319 return CLI_SHOWUSAGE; 03320 if (!strcmp(a->argv[3], "all")) { 03321 prune_users(); 03322 prune_peers(); 03323 ast_cli(a->fd, "Cache flushed successfully.\n"); 03324 return CLI_SUCCESS; 03325 } 03326 peer = find_peer(a->argv[3], 0); 03327 user = find_user(a->argv[3]); 03328 if (peer || user) { 03329 if (peer) { 03330 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 03331 ast_set_flag(peer, IAX_RTAUTOCLEAR); 03332 expire_registry(peer_ref(peer)); 03333 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03334 } else { 03335 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03336 } 03337 peer_unref(peer); 03338 } 03339 if (user) { 03340 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 03341 ast_set_flag(user, IAX_RTAUTOCLEAR); 03342 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03343 } else { 03344 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03345 } 03346 ao2_unlink(users,user); 03347 user_unref(user); 03348 } 03349 } else { 03350 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03351 } 03352 03353 return CLI_SUCCESS; 03354 }
| static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 12786 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
12787 { 12788 switch (cmd) { 12789 case CLI_INIT: 12790 e->command = "iax2 reload"; 12791 e->usage = 12792 "Usage: iax2 reload\n" 12793 " Reloads IAX configuration from iax.conf\n"; 12794 return NULL; 12795 case CLI_GENERATE: 12796 return NULL; 12797 } 12798 12799 reload_config(); 12800 12801 return CLI_SUCCESS; 12802 }
| static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6839 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(), 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.
06840 { 06841 switch (cmd) { 06842 case CLI_INIT: 06843 e->command = "iax2 set debug {on|off|peer}"; 06844 e->usage = 06845 "Usage: iax2 set debug {on|off|peer peername}\n" 06846 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 06847 return NULL; 06848 case CLI_GENERATE: 06849 if (a->pos == 4) 06850 return complete_iax2_peers(a->line, a->word, a->pos, a->n); 06851 return NULL; 06852 } 06853 06854 if (a->argc < e->args || a->argc > e->args + 1) 06855 return CLI_SHOWUSAGE; 06856 06857 if (!strcasecmp(a->argv[3], "peer")) { 06858 struct iax2_peer *peer; 06859 06860 if (a->argc != e->args + 1) 06861 return CLI_SHOWUSAGE; 06862 06863 peer = find_peer(a->argv[4], 1); 06864 06865 if (!peer) { 06866 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 06867 return CLI_FAILURE; 06868 } 06869 06870 debugaddr.sin_addr = peer->addr.sin_addr; 06871 debugaddr.sin_port = peer->addr.sin_port; 06872 06873 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 06874 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 06875 06876 ao2_ref(peer, -1); 06877 } else if (!strncasecmp(a->argv[3], "on", 2)) { 06878 iaxdebug = 1; 06879 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 06880 } else { 06881 iaxdebug = 0; 06882 memset(&debugaddr, 0, sizeof(debugaddr)); 06883 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 06884 } 06885 return CLI_SUCCESS; 06886 }
| static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6914 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.
06915 { 06916 switch (cmd) { 06917 case CLI_INIT: 06918 e->command = "iax2 set debug jb {on|off}"; 06919 e->usage = 06920 "Usage: iax2 set debug jb {on|off}\n" 06921 " Enables/Disables jitterbuffer debugging information\n"; 06922 return NULL; 06923 case CLI_GENERATE: 06924 return NULL; 06925 } 06926 06927 if (a->argc != e->args) 06928 return CLI_SHOWUSAGE; 06929 06930 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 06931 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 06932 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 06933 } else { 06934 jb_setoutput(jb_error_output, jb_warning_output, NULL); 06935 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 06936 } 06937 return CLI_SUCCESS; 06938 }
| static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6888 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.
06889 { 06890 switch (cmd) { 06891 case CLI_INIT: 06892 e->command = "iax2 set debug trunk {on|off}"; 06893 e->usage = 06894 "Usage: iax2 set debug trunk {on|off}\n" 06895 " Enables/Disables debugging of IAX trunking\n"; 06896 return NULL; 06897 case CLI_GENERATE: 06898 return NULL; 06899 } 06900 06901 if (a->argc != e->args) 06902 return CLI_SHOWUSAGE; 06903 06904 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 06905 iaxtrunkdebug = 1; 06906 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 06907 } else { 06908 iaxtrunkdebug = 0; 06909 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 06910 } 06911 return CLI_SUCCESS; 06912 }
| 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 3612 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.
03613 { 03614 int mtuv; 03615 03616 switch (cmd) { 03617 case CLI_INIT: 03618 e->command = "iax2 set mtu"; 03619 e->usage = 03620 "Usage: iax2 set mtu <value>\n" 03621 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03622 " zero to disable. Disabling means that the operating system\n" 03623 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03624 " packet exceeds the UDP payload size. This is substantially\n" 03625 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03626 " greater for G.711 samples.\n"; 03627 return NULL; 03628 case CLI_GENERATE: 03629 return NULL; 03630 } 03631 03632 if (a->argc != 4) 03633 return CLI_SHOWUSAGE; 03634 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03635 mtuv = MAX_TRUNK_MTU; 03636 else 03637 mtuv = atoi(a->argv[3]); 03638 03639 if (mtuv == 0) { 03640 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03641 global_max_trunk_mtu = 0; 03642 return CLI_SUCCESS; 03643 } 03644 if (mtuv < 172 || mtuv > 4000) { 03645 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03646 return CLI_SHOWUSAGE; 03647 } 03648 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03649 global_max_trunk_mtu = mtuv; 03650 return CLI_SUCCESS; 03651 }
| static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3653 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, s, ast_cli_entry::usage, and iax2_dpcache::waiters.
03654 { 03655 struct iax2_dpcache *dp = NULL; 03656 char tmp[1024], *pc = NULL; 03657 int s, x, y; 03658 struct timeval now = ast_tvnow(); 03659 03660 switch (cmd) { 03661 case CLI_INIT: 03662 e->command = "iax2 show cache"; 03663 e->usage = 03664 "Usage: iax2 show cache\n" 03665 " Display currently cached IAX Dialplan results.\n"; 03666 return NULL; 03667 case CLI_GENERATE: 03668 return NULL; 03669 } 03670 03671 AST_LIST_LOCK(&dpcache); 03672 03673 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03674 03675 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 03676 s = dp->expiry.tv_sec - now.tv_sec; 03677 tmp[0] = '\0'; 03678 if (dp->flags & CACHE_FLAG_EXISTS) 03679 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03680 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03681 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03682 if (dp->flags & CACHE_FLAG_CANEXIST) 03683 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03684 if (dp->flags & CACHE_FLAG_PENDING) 03685 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03686 if (dp->flags & CACHE_FLAG_TIMEOUT) 03687 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03688 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03689 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03690 if (dp->flags & CACHE_FLAG_MATCHMORE) 03691 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03692 if (dp->flags & CACHE_FLAG_UNKNOWN) 03693 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03694 /* Trim trailing pipe */ 03695 if (!ast_strlen_zero(tmp)) { 03696 tmp[strlen(tmp) - 1] = '\0'; 03697 } else { 03698 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03699 } 03700 y = 0; 03701 pc = strchr(dp->peercontext, '@'); 03702 if (!pc) { 03703 pc = dp->peercontext; 03704 } else { 03705 pc++; 03706 } 03707 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 03708 if (dp->waiters[x] > -1) 03709 y++; 03710 } 03711 if (s > 0) { 03712 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03713 } else { 03714 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 03715 } 03716 } 03717 03718 AST_LIST_UNLOCK(&dpcache); 03719 03720 return CLI_SUCCESS; 03721 }
| static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 2280 of file chan_iax2.c.
References peercnt::addr, 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, and ast_cli_entry::usage.
02281 { 02282 struct ao2_iterator i; 02283 struct peercnt *peercnt; 02284 struct sockaddr_in sin; 02285 int found = 0; 02286 02287 switch (cmd) { 02288 case CLI_INIT: 02289 e->command = "iax2 show callnumber usage"; 02290 e->usage = 02291 "Usage: iax2 show callnumber usage <ip address (optional)>\n" 02292 " Shows current ip addresses which are consuming iax2 call numbers\n"; 02293 return NULL; 02294 case CLI_GENERATE: 02295 return NULL; 02296 case CLI_HANDLER: 02297 if (a->argc < 4 || a->argc > 5) 02298 return CLI_SHOWUSAGE; 02299 02300 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02301 i = ao2_iterator_init(peercnts, 0); 02302 while ((peercnt = ao2_iterator_next(&i))) { 02303 sin.sin_addr.s_addr = peercnt->addr; 02304 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) { 02305 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02306 found = 1; 02307 break; 02308 } else { 02309 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02310 } 02311 ao2_ref(peercnt, -1); 02312 } 02313 ao2_iterator_destroy(&i); 02314 02315 if (a->argc == 4) { 02316 ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used); 02317 } else if (a->argc == 5 && !found) { 02318 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] ); 02319 } 02320 02321 return CLI_SUCCESS; 02322 default: 02323 return NULL; 02324 } 02325 }
| static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6666 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_cli_args::argc, ARRAY_LEN, ast_cli(), ast_getformatname(), ast_inet_ntoa(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, 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, jb_getinfo(), jb_info::jitter, MARK_IAX_SUBCLASS_TX, jb_info::min, chan_iax2_pvt::owner, chan_iax2_pvt::remote_rr, S_OR, and ast_cli_entry::usage.
06667 { 06668 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 06669 #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" 06670 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 06671 int x; 06672 int numchans = 0; 06673 char first_message[10] = { 0, }; 06674 char last_message[10] = { 0, }; 06675 06676 switch (cmd) { 06677 case CLI_INIT: 06678 e->command = "iax2 show channels"; 06679 e->usage = 06680 "Usage: iax2 show channels\n" 06681 " Lists all currently active IAX channels.\n"; 06682 return NULL; 06683 case CLI_GENERATE: 06684 return NULL; 06685 } 06686 06687 if (a->argc != 3) 06688 return CLI_SHOWUSAGE; 06689 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 06690 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06691 ast_mutex_lock(&iaxsl[x]); 06692 if (iaxs[x]) { 06693 int lag, jitter, localdelay; 06694 jb_info jbinfo; 06695 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06696 jb_getinfo(iaxs[x]->jb, &jbinfo); 06697 jitter = jbinfo.jitter; 06698 localdelay = jbinfo.current - jbinfo.min; 06699 } else { 06700 jitter = -1; 06701 localdelay = 0; 06702 } 06703 06704 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06705 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06706 lag = iaxs[x]->remote_rr.delay; 06707 ast_cli(a->fd, FORMAT, 06708 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06709 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 06710 S_OR(iaxs[x]->username, "(None)"), 06711 iaxs[x]->callno, iaxs[x]->peercallno, 06712 iaxs[x]->oseqno, iaxs[x]->iseqno, 06713 lag, 06714 jitter, 06715 localdelay, 06716 ast_getformatname(iaxs[x]->voiceformat), 06717 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06718 first_message, 06719 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06720 last_message); 06721 numchans++; 06722 } 06723 ast_mutex_unlock(&iaxsl[x]); 06724 } 06725 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 06726 return CLI_SUCCESS; 06727 #undef FORMAT 06728 #undef FORMAT2 06729 #undef FORMATB 06730 }
| static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6516 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, ast_cli_entry::usage, and ast_iax2_firmware_header::version.
06517 { 06518 struct iax_firmware *cur = NULL; 06519 06520 switch (cmd) { 06521 case CLI_INIT: 06522 e->command = "iax2 show firmware"; 06523 e->usage = 06524 "Usage: iax2 show firmware\n" 06525 " Lists all known IAX firmware images.\n"; 06526 return NULL; 06527 case CLI_GENERATE: 06528 return NULL; 06529 } 06530 06531 if (a->argc != 3 && a->argc != 4) 06532 return CLI_SHOWUSAGE; 06533 06534 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 06535 AST_LIST_LOCK(&firmwares); 06536 AST_LIST_TRAVERSE(&firmwares, cur, list) { 06537 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 06538 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 06539 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 06540 } 06541 } 06542 AST_LIST_UNLOCK(&firmwares); 06543 06544 return CLI_SUCCESS; 06545 }
| static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6816 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.
06817 { 06818 int numchans = 0; 06819 06820 switch (cmd) { 06821 case CLI_INIT: 06822 e->command = "iax2 show netstats"; 06823 e->usage = 06824 "Usage: iax2 show netstats\n" 06825 " Lists network status for all currently active IAX channels.\n"; 06826 return NULL; 06827 case CLI_GENERATE: 06828 return NULL; 06829 } 06830 if (a->argc != 3) 06831 return CLI_SHOWUSAGE; 06832 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 06833 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 06834 numchans = ast_cli_netstats(NULL, a->fd, 1); 06835 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 06836 return CLI_SUCCESS; 06837 }
| 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 3470 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_strlen_zero(), ast_test_flag, 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::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.
03471 { 03472 char status[30]; 03473 char cbuf[256]; 03474 struct iax2_peer *peer; 03475 char codec_buf[512]; 03476 int x = 0, codec = 0, load_realtime = 0; 03477 03478 switch (cmd) { 03479 case CLI_INIT: 03480 e->command = "iax2 show peer"; 03481 e->usage = 03482 "Usage: iax2 show peer <name>\n" 03483 " Display details on specific IAX peer\n"; 03484 return NULL; 03485 case CLI_GENERATE: 03486 if (a->pos == 3) 03487 return complete_iax2_peers(a->line, a->word, a->pos, a->n); 03488 return NULL; 03489 } 03490 03491 if (a->argc < 4) 03492 return CLI_SHOWUSAGE; 03493 03494 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03495 03496 peer = find_peer(a->argv[3], load_realtime); 03497 if (peer) { 03498 ast_cli(a->fd, "\n\n"); 03499 ast_cli(a->fd, " * Name : %s\n", peer->name); 03500 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03501 ast_cli(a->fd, " Context : %s\n", peer->context); 03502 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03503 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03504 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03505 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03506 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03507 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No"); 03508 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03509 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03510 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03511 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)); 03512 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03513 ast_cli(a->fd, " Username : %s\n", peer->username); 03514 ast_cli(a->fd, " Codecs : "); 03515 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03516 ast_cli(a->fd, "%s\n", codec_buf); 03517 03518 ast_cli(a->fd, " Codec Order : ("); 03519 for(x = 0; x < 32 ; x++) { 03520 codec = ast_codec_pref_index(&peer->prefs,x); 03521 if(!codec) 03522 break; 03523 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03524 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03525 ast_cli(a->fd, "|"); 03526 } 03527 03528 if (!x) 03529 ast_cli(a->fd, "none"); 03530 ast_cli(a->fd, ")\n"); 03531 03532 ast_cli(a->fd, " Status : "); 03533 peer_status(peer, status, sizeof(status)); 03534 ast_cli(a->fd, "%s\n",status); 03535 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"); 03536 ast_cli(a->fd, "\n"); 03537 peer_unref(peer); 03538 } else { 03539 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03540 ast_cli(a->fd, "\n"); 03541 } 03542 03543 return CLI_SUCCESS; 03544 }
| static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6484 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.
06485 { 06486 switch (cmd) { 06487 case CLI_INIT: 06488 e->command = "iax2 show peers"; 06489 e->usage = 06490 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06491 " Lists all known IAX2 peers.\n" 06492 " Optional 'registered' argument lists only peers with known addresses.\n" 06493 " Optional regular expression pattern is used to filter the peer list.\n"; 06494 return NULL; 06495 case CLI_GENERATE: 06496 return NULL; 06497 } 06498 06499 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) { 06500 case RESULT_SHOWUSAGE: 06501 return CLI_SHOWUSAGE; 06502 case RESULT_FAILURE: 06503 return CLI_FAILURE; 06504 default: 06505 return CLI_SUCCESS; 06506 } 06507 }
| static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6625 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, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_registry::dnsmgr, ast_cli_args::fd, FORMAT, FORMAT2, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), iax2_registry::us, ast_cli_entry::usage, and iax2_registry::username.
06626 { 06627 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 06628 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 06629 struct iax2_registry *reg = NULL; 06630 char host[80]; 06631 char perceived[80]; 06632 int counter = 0; 06633 06634 switch (cmd) { 06635 case CLI_INIT: 06636 e->command = "iax2 show registry"; 06637 e->usage = 06638 "Usage: iax2 show registry\n" 06639 " Lists all registration requests and status.\n"; 06640 return NULL; 06641 case CLI_GENERATE: 06642 return NULL; 06643 } 06644 if (a->argc != 3) 06645 return CLI_SHOWUSAGE; 06646 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 06647 AST_LIST_LOCK(®istrations); 06648 AST_LIST_TRAVERSE(®istrations, reg, entry) { 06649 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 06650 if (reg->us.sin_addr.s_addr) 06651 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06652 else 06653 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 06654 ast_cli(a->fd, FORMAT, host, 06655 (reg->dnsmgr) ? "Y" : "N", 06656 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 06657 counter++; 06658 } 06659 AST_LIST_UNLOCK(®istrations); 06660 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 06661 return CLI_SUCCESS; 06662 #undef FORMAT 06663 #undef FORMAT2 06664 }
| static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3568 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_frame::final, iax_get_frames(), iax_get_iframes(), iax_get_oframes(), iax_frame::retries, and ast_cli_entry::usage.
03569 { 03570 struct iax_frame *cur; 03571 int cnt = 0, dead = 0, final = 0; 03572 03573 switch (cmd) { 03574 case CLI_INIT: 03575 e->command = "iax2 show stats"; 03576 e->usage = 03577 "Usage: iax2 show stats\n" 03578 " Display statistics on IAX channel driver.\n"; 03579 return NULL; 03580 case CLI_GENERATE: 03581 return NULL; 03582 } 03583 03584 if (a->argc != 3) 03585 return CLI_SHOWUSAGE; 03586 03587 AST_LIST_LOCK(&frame_queue); 03588 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 03589 if (cur->retries < 0) 03590 dead++; 03591 if (cur->final) 03592 final++; 03593 cnt++; 03594 } 03595 AST_LIST_UNLOCK(&frame_queue); 03596 03597 ast_cli(a->fd, " IAX Statistics\n"); 03598 ast_cli(a->fd, "---------------------\n"); 03599 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03600 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03601 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03602 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03603 03604 trunk_timed = trunk_untimed = 0; 03605 if (trunk_maxmtu > trunk_nmaxmtu) 03606 trunk_nmaxmtu = trunk_maxmtu; 03607 03608 return CLI_SUCCESS; 03609 }
| static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6347 of file chan_iax2.c.
References iax2_thread::actions, ast_cli_args::argc, ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax2_thread::checktime, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_thread::curfunc, ast_cli_args::fd, IAX_THREAD_TYPE_DYNAMIC, iaxthreadcount, iax2_thread::iostate, thread, iax2_thread::threadnum, iax2_thread::type, and ast_cli_entry::usage.
06348 { 06349 struct iax2_thread *thread = NULL; 06350 time_t t; 06351 int threadcount = 0, dynamiccount = 0; 06352 char type; 06353 06354 switch (cmd) { 06355 case CLI_INIT: 06356 e->command = "iax2 show threads"; 06357 e->usage = 06358 "Usage: iax2 show threads\n" 06359 " Lists status of IAX helper threads\n"; 06360 return NULL; 06361 case CLI_GENERATE: 06362 return NULL; 06363 } 06364 if (a->argc != 3) 06365 return CLI_SHOWUSAGE; 06366 06367 ast_cli(a->fd, "IAX2 Thread Information\n"); 06368 time(&t); 06369 ast_cli(a->fd, "Idle Threads:\n"); 06370 AST_LIST_LOCK(&idle_list); 06371 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06372 #ifdef DEBUG_SCHED_MULTITHREAD 06373 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06374 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06375 #else 06376 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06377 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06378 #endif 06379 threadcount++; 06380 } 06381 AST_LIST_UNLOCK(&idle_list); 06382 ast_cli(a->fd, "Active Threads:\n"); 06383 AST_LIST_LOCK(&active_list); 06384 AST_LIST_TRAVERSE(&active_list, thread, list) { 06385 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06386 type = 'D'; 06387 else 06388 type = 'P'; 06389 #ifdef DEBUG_SCHED_MULTITHREAD 06390 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06391 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06392 #else 06393 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06394 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06395 #endif 06396 threadcount++; 06397 } 06398 AST_LIST_UNLOCK(&active_list); 06399 ast_cli(a->fd, "Dynamic Threads:\n"); 06400 AST_LIST_LOCK(&dynamic_list); 06401 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06402 #ifdef DEBUG_SCHED_MULTITHREAD 06403 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06404 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06405 #else 06406 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06407 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06408 #endif 06409 dynamiccount++; 06410 } 06411 AST_LIST_UNLOCK(&dynamic_list); 06412 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06413 return CLI_SUCCESS; 06414 }
| static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6144 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_flag, iax2_user::authmethods, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, iax2_context::context, iax2_user::contexts, DEFAULT_CONTEXT, ast_cli_args::fd, FORMAT, FORMAT2, iax2_user::ha, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, iax2_user::inkeys, iax2_user::name, iax2_user::secret, ast_cli_entry::usage, and user_unref().
06145 { 06146 regex_t regexbuf; 06147 int havepattern = 0; 06148 06149 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06150 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06151 06152 struct iax2_user *user = NULL; 06153 char auth[90]; 06154 char *pstr = ""; 06155 struct ao2_iterator i; 06156 06157 switch (cmd) { 06158 case CLI_INIT: 06159 e->command = "iax2 show users [like]"; 06160 e->usage = 06161 "Usage: iax2 show users [like <pattern>]\n" 06162 " Lists all known IAX2 users.\n" 06163 " Optional regular expression pattern is used to filter the user list.\n"; 06164 return NULL; 06165 case CLI_GENERATE: 06166 return NULL; 06167 } 06168 06169 switch (a->argc) { 06170 case 5: 06171 if (!strcasecmp(a->argv[3], "like")) { 06172 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06173 return CLI_SHOWUSAGE; 06174 havepattern = 1; 06175 } else 06176 return CLI_SHOWUSAGE; 06177 case 3: 06178 break; 06179 default: 06180 return CLI_SHOWUSAGE; 06181 } 06182 06183 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06184 i = ao2_iterator_init(users, 0); 06185 for (user = ao2_iterator_next(&i); user; 06186 user_unref(user), user = ao2_iterator_next(&i)) { 06187 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06188 continue; 06189 06190 if (!ast_strlen_zero(user->secret)) { 06191 ast_copy_string(auth,user->secret, sizeof(auth)); 06192 } else if (!ast_strlen_zero(user->inkeys)) { 06193 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06194 } else 06195 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06196 06197 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 06198 pstr = "REQ Only"; 06199 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 06200 pstr = "Disabled"; 06201 else 06202 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06203 06204 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06205 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06206 user->ha ? "Yes" : "No", pstr); 06207 } 06208 ao2_iterator_destroy(&i); 06209 06210 if (havepattern) 06211 regfree(®exbuf); 06212 06213 return CLI_SUCCESS; 06214 #undef FORMAT 06215 #undef FORMAT2 06216 }
| static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3356 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.
03357 { 03358 switch (cmd) { 03359 case CLI_INIT: 03360 e->command = "iax2 test losspct"; 03361 e->usage = 03362 "Usage: iax2 test losspct <percentage>\n" 03363 " For testing, throws away <percentage> percent of incoming packets\n"; 03364 return NULL; 03365 case CLI_GENERATE: 03366 return NULL; 03367 } 03368 if (a->argc != 4) 03369 return CLI_SHOWUSAGE; 03370 03371 test_losspct = atoi(a->argv[3]); 03372 03373 return CLI_SUCCESS; 03374 }
| static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6416 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(), ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.
06417 { 06418 struct iax2_peer *p; 06419 06420 switch (cmd) { 06421 case CLI_INIT: 06422 e->command = "iax2 unregister"; 06423 e->usage = 06424 "Usage: iax2 unregister <peername>\n" 06425 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06426 return NULL; 06427 case CLI_GENERATE: 06428 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06429 } 06430 06431 if (a->argc != 3) 06432 return CLI_SHOWUSAGE; 06433 06434 p = find_peer(a->argv[2], 1); 06435 if (p) { 06436 if (p->expire > 0) { 06437 struct iax2_peer tmp_peer = { 06438 .name = a->argv[2], 06439 }; 06440 struct iax2_peer *peer; 06441 06442 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06443 if (peer) { 06444 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06445 peer_unref(peer); /* ref from ao2_find() */ 06446 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06447 } else { 06448 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06449 } 06450 } else { 06451 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06452 } 06453 } else { 06454 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06455 } 06456 return CLI_SUCCESS; 06457 }
| static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 8954 of file chan_iax2.c.
References ast_free, AST_LIST_REMOVE_HEAD, ast_mutex_lock(), ast_mutex_unlock(), iax2_pkt_buf::buf, iax2_thread::buf, iax2_thread::buf_len, iax2_thread::buf_size, iax2_thread::full_frames, iax2_pkt_buf::len, iax2_thread::lock, and socket_process().
Referenced by iax2_process_thread().
08955 { 08956 struct iax2_pkt_buf *pkt_buf; 08957 08958 ast_mutex_lock(&thread->lock); 08959 08960 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 08961 ast_mutex_unlock(&thread->lock); 08962 08963 thread->buf = pkt_buf->buf; 08964 thread->buf_len = pkt_buf->len; 08965 thread->buf_size = pkt_buf->len + 1; 08966 08967 socket_process(thread); 08968 08969 thread->buf = NULL; 08970 ast_free(pkt_buf); 08971 08972 ast_mutex_lock(&thread->lock); 08973 } 08974 08975 ast_mutex_unlock(&thread->lock); 08976 }
| static int handle_error | ( | void | ) | [static] |
Definition at line 3024 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().
03025 { 03026 /* XXX Ideally we should figure out why an error occurred and then abort those 03027 rather than continuing to try. Unfortunately, the published interface does 03028 not seem to work XXX */ 03029 #if 0 03030 struct sockaddr_in *sin; 03031 int res; 03032 struct msghdr m; 03033 struct sock_extended_err e; 03034 m.msg_name = NULL; 03035 m.msg_namelen = 0; 03036 m.msg_iov = NULL; 03037 m.msg_control = &e; 03038 m.msg_controllen = sizeof(e); 03039 m.msg_flags = 0; 03040 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03041 if (res < 0) 03042 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03043 else { 03044 if (m.msg_controllen) { 03045 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03046 if (sin) 03047 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03048 else 03049 ast_log(LOG_WARNING, "No address detected??\n"); 03050 } else { 03051 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03052 } 03053 } 03054 #endif 03055 return 0; 03056 }
| static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
| struct sockaddr_in * | sin, | |||
| int | callno | |||
| ) | [static] |
Acknowledgment received for OUR registration.
Definition at line 7921 of file chan_iax2.c.
References iax2_registry::addr, iax_ies::apparent_addr, ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_verb, iax_ies::calling_number, EVENT_FLAG_SYSTEM, iax2_registry::expire, iax2_do_register_s(), iax2_sched_replace(), inaddrcmp(), LOG_WARNING, manager_event, iax2_registry::messages, iax_ies::msgcount, iax_ies::refresh, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGISTERED, iax2_registry::regstate, iax2_registry::us, and iax_ies::username.
Referenced by socket_process().
07922 { 07923 struct iax2_registry *reg; 07924 /* Start pessimistic */ 07925 char peer[256] = ""; 07926 char msgstatus[60]; 07927 int refresh = 60; 07928 char ourip[256] = "<Unspecified>"; 07929 struct sockaddr_in oldus; 07930 struct sockaddr_in us; 07931 int oldmsgs; 07932 07933 memset(&us, 0, sizeof(us)); 07934 if (ies->apparent_addr) 07935 memmove(&us, ies->apparent_addr, sizeof(us)); 07936 if (ies->username) 07937 ast_copy_string(peer, ies->username, sizeof(peer)); 07938 if (ies->refresh) 07939 refresh = ies->refresh; 07940 if (ies->calling_number) { 07941 /* We don't do anything with it really, but maybe we should */ 07942 } 07943 reg = iaxs[callno]->reg; 07944 if (!reg) { 07945 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 07946 return -1; 07947 } 07948 memcpy(&oldus, ®->us, sizeof(oldus)); 07949 oldmsgs = reg->messages; 07950 if (inaddrcmp(®->addr, sin)) { 07951 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 07952 return -1; 07953 } 07954 memcpy(®->us, &us, sizeof(reg->us)); 07955 if (ies->msgcount >= 0) 07956 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 07957 /* always refresh the registration at the interval requested by the server 07958 we are registering to 07959 */ 07960 reg->refresh = refresh; 07961 reg->expire = iax2_sched_replace(reg->expire, sched, 07962 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 07963 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 07964 if (reg->messages > 255) 07965 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 07966 else if (reg->messages > 1) 07967 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 07968 else if (reg->messages > 0) 07969 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus)); 07970 else 07971 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus)); 07972 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 07973 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 07974 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 07975 } 07976 reg->regstate = REG_STATE_REGISTERED; 07977 return 0; 07978 }
| static int attribute_pure iax2_allow_new | ( | int | frametype, | |
| int | subclass, | |||
| int | inbound | |||
| ) | [inline, static] |
Definition at line 2463 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().
02464 { 02465 if (frametype != AST_FRAME_IAX) { 02466 return 0; 02467 } 02468 switch (subclass) { 02469 case IAX_COMMAND_NEW: 02470 case IAX_COMMAND_REGREQ: 02471 case IAX_COMMAND_FWDOWNL: 02472 case IAX_COMMAND_REGREL: 02473 return 1; 02474 case IAX_COMMAND_POKE: 02475 if (!inbound) { 02476 return 1; 02477 } 02478 break; 02479 } 02480 return 0; 02481 }
| 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 1110 of file chan_iax2.c.
References chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, chan_iax2_pvt::owner, chan_iax2_pvt::peer, and chan_iax2_pvt::peercallno.
Referenced by ast_iax2_new(), and iax2_answer().
01111 { 01112 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01113 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01114 pvt->owner ? pvt->owner->name : "", 01115 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01116 }
| static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5219 of file chan_iax2.c.
References AST_CONTROL_ANSWER, ast_debug, AST_FRAME_CONTROL, ast_mutex_lock(), ast_mutex_unlock(), iax2_ami_channelupdate(), PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05220 { 05221 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05222 ast_debug(1, "Answering IAX2 call\n"); 05223 ast_mutex_lock(&iaxsl[callno]); 05224 if (iaxs[callno]) 05225 iax2_ami_channelupdate(iaxs[callno]); 05226 ast_mutex_unlock(&iaxsl[callno]); 05227 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05228 }
| static int iax2_append_register | ( | const char * | hostname, | |
| const char * | username, | |||
| const char * | secret, | |||
| const char * | porta | |||
| ) | [static] |
Definition at line 7980 of file chan_iax2.c.
References iax2_registry::addr, ast_calloc, ast_copy_string(), ast_dnsmgr_lookup(), ast_free, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, iax2_registry::dnsmgr, iax2_registry::expire, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, iax2_registry::refresh, iax2_registry::secret, and iax2_registry::username.
Referenced by iax2_register().
07982 { 07983 struct iax2_registry *reg; 07984 07985 if (!(reg = ast_calloc(1, sizeof(*reg)))) 07986 return -1; 07987 07988 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 07989 ast_free(reg); 07990 return -1; 07991 } 07992 07993 ast_copy_string(reg->username, username, sizeof(reg->username)); 07994 07995 if (secret) 07996 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 07997 07998 reg->expire = -1; 07999 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08000 reg->addr.sin_family = AF_INET; 08001 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 08002 08003 AST_LIST_LOCK(®istrations); 08004 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08005 AST_LIST_UNLOCK(®istrations); 08006 08007 return 0; 08008 }
| 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 5064 of file chan_iax2.c.
References ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_CONTROL_SRCUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_IMAGE, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname_multiple(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_read(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_tvnow(), ast_tvzero(), ast_verb, ast_waitfor_n(), ast_write(), chan_iax2_pvt::bridgecallno, f, ast_frame::frametype, iax2_start_transfer(), IAX_LINGER_TIMEOUT, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, lock_both(), LOG_WARNING, ast_channel::nativeformats, PTR_TO_CALLNO, ast_frame::subclass, ast_channel::tech, ast_channel::tech_pvt, TRANSFER_RELEASED, and unlock_both().
05065 { 05066 struct ast_channel *cs[3]; 05067 struct ast_channel *who, *other; 05068 int to = -1; 05069 int res = -1; 05070 int transferstarted=0; 05071 struct ast_frame *f; 05072 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05073 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05074 struct timeval waittimer = {0, 0}; 05075 05076 /* We currently do not support native bridging if a timeoutms value has been provided */ 05077 if (timeoutms > 0) { 05078 return AST_BRIDGE_FAILED; 05079 } 05080 05081 timeoutms = -1; 05082 05083 lock_both(callno0, callno1); 05084 if (!iaxs[callno0] || !iaxs[callno1]) { 05085 unlock_both(callno0, callno1); 05086 return AST_BRIDGE_FAILED; 05087 } 05088 /* Put them in native bridge mode */ 05089 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05090 iaxs[callno0]->bridgecallno = callno1; 05091 iaxs[callno1]->bridgecallno = callno0; 05092 } 05093 unlock_both(callno0, callno1); 05094 05095 /* If not, try to bridge until we can execute a transfer, if we can */ 05096 cs[0] = c0; 05097 cs[1] = c1; 05098 for (/* ever */;;) { 05099 /* Check in case we got masqueraded into */ 05100 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05101 ast_verb(3, "Can't masquerade, we're different...\n"); 05102 /* Remove from native mode */ 05103 if (c0->tech == &iax2_tech) { 05104 ast_mutex_lock(&iaxsl[callno0]); 05105 iaxs[callno0]->bridgecallno = 0; 05106 ast_mutex_unlock(&iaxsl[callno0]); 05107 } 05108 if (c1->tech == &iax2_tech) { 05109 ast_mutex_lock(&iaxsl[callno1]); 05110 iaxs[callno1]->bridgecallno = 0; 05111 ast_mutex_unlock(&iaxsl[callno1]); 05112 } 05113 return AST_BRIDGE_FAILED_NOWARN; 05114 } 05115 if (c0->nativeformats != c1->nativeformats) { 05116 char buf0[255]; 05117 char buf1[255]; 05118 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 05119 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 05120 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 05121 /* Remove from native mode */ 05122 lock_both(callno0, callno1); 05123 if (iaxs[callno0]) 05124 iaxs[callno0]->bridgecallno = 0; 05125 if (iaxs[callno1]) 05126 iaxs[callno1]->bridgecallno = 0; 05127 unlock_both(callno0, callno1); 05128 return AST_BRIDGE_FAILED_NOWARN; 05129 } 05130 /* check if transfered and if we really want native bridging */ 05131 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 05132 /* Try the transfer */ 05133 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05134 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 05135 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05136 transferstarted = 1; 05137 } 05138 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05139 /* Call has been transferred. We're no longer involved */ 05140 struct timeval now = ast_tvnow(); 05141 if (ast_tvzero(waittimer)) { 05142 waittimer = now; 05143 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05144 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05145 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05146 *fo = NULL; 05147 *rc = c0; 05148 res = AST_BRIDGE_COMPLETE; 05149 break; 05150 } 05151 } 05152 to = 1000; 05153 who = ast_waitfor_n(cs, 2, &to); 05154 if (timeoutms > -1) { 05155 timeoutms -= (1000 - to); 05156 if (timeoutms < 0) 05157 timeoutms = 0; 05158 } 05159 if (!who) { 05160 if (!timeoutms) { 05161 res = AST_BRIDGE_RETRY; 05162 break; 05163 } 05164 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05165 res = AST_BRIDGE_FAILED; 05166 break; 05167 } 05168 continue; 05169 } 05170 f = ast_read(who); 05171 if (!f) { 05172 *fo = NULL; 05173 *rc = who; 05174 res = AST_BRIDGE_COMPLETE; 05175 break; 05176 } 05177 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) { 05178 *fo = f; 05179 *rc = who; 05180 res = AST_BRIDGE_COMPLETE; 05181 break; 05182 } 05183 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05184 if ((f->frametype == AST_FRAME_VOICE) || 05185 (f->frametype == AST_FRAME_TEXT) || 05186 (f->frametype == AST_FRAME_VIDEO) || 05187 (f->frametype == AST_FRAME_IMAGE) || 05188 (f->frametype == AST_FRAME_DTMF) || 05189 (f->frametype == AST_FRAME_CONTROL)) { 05190 /* monitored dtmf take out of the bridge. 05191 * check if we monitor the specific source. 05192 */ 05193 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05194 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 05195 *rc = who; 05196 *fo = f; 05197 res = AST_BRIDGE_COMPLETE; 05198 /* Remove from native mode */ 05199 break; 05200 } 05201 /* everything else goes to the other side */ 05202 ast_write(other, f); 05203 } 05204 ast_frfree(f); 05205 /* Swap who gets priority */ 05206 cs[2] = cs[0]; 05207 cs[0] = cs[1]; 05208 cs[1] = cs[2]; 05209 } 05210 lock_both(callno0, callno1); 05211 if(iaxs[callno0]) 05212 iaxs[callno0]->bridgecallno = 0; 05213 if(iaxs[callno1]) 05214 iaxs[callno1]->bridgecallno = 0; 05215 unlock_both(callno0, callno1); 05216 return res; 05217 }
| static int iax2_call | ( | struct ast_channel * | c, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 4675 of file chan_iax2.c.
References ast_channel::_state, add_empty_calltoken_ie(), create_addr_info::adsi, chan_iax2_pvt::adsi, ast_channel::adsicpe, ast_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_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_flag, ast_var_name(), ast_var_value(), auto_congest(), iax_ie_data::buf, CALLNO_TO_PTR, capability, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_callerid::cid_tns, ast_callerid::cid_ton, context, create_addr_info::context, ast_channel::context, parsed_dial_string::context, create_addr(), ast_datastore::data, chan_iax2_pvt::encmethods, create_addr_info::encmethods, parsed_dial_string::exten, iax2_datetime(), iax2_sched_add(), IAX_COMMAND_NEW, 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_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_CODEC_PREFS, IAX_IE_DATETIME, IAX_IE_DNID, IAX_IE_ENCRYPTION, IAX_IE_FORMAT, 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, chan_iax2_pvt::initid, parsed_dial_string::key, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::nativeformats, parsed_dial_string::options, chan_iax2_pvt::osptoken, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, parsed_dial_string::port, iax_ie_data::pos, create_addr_info::prefs, PTR_TO_CALLNO, secret, create_addr_info::secret, send_command(), create_addr_info::sockfd, chan_iax2_pvt::sockfd, ast_channel::tech_pvt, create_addr_info::timezone, create_addr_info::username, parsed_dial_string::username, and var.
04676 { 04677 struct sockaddr_in sin; 04678 char *l=NULL, *n=NULL, *tmpstr; 04679 struct iax_ie_data ied; 04680 char *defaultrdest = "s"; 04681 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04682 struct parsed_dial_string pds; 04683 struct create_addr_info cai; 04684 struct ast_var_t *var; 04685 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 04686 const char* osp_token_ptr; 04687 unsigned int osp_token_length; 04688 unsigned char osp_block_index; 04689 unsigned int osp_block_length; 04690 unsigned char osp_buffer[256]; 04691 04692 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 04693 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 04694 return -1; 04695 } 04696 04697 memset(&cai, 0, sizeof(cai)); 04698 cai.encmethods = iax2_encryption; 04699 04700 memset(&pds, 0, sizeof(pds)); 04701 tmpstr = ast_strdupa(dest); 04702 parse_dial_string(tmpstr, &pds); 04703 04704 if (ast_strlen_zero(pds.peer)) { 04705 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 04706 return -1; 04707 } 04708 04709 if (!pds.exten) { 04710 pds.exten = defaultrdest; 04711 } 04712 04713 if (create_addr(pds.peer, c, &sin, &cai)) { 04714 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 04715 return -1; 04716 } 04717 04718 if (!pds.username && !ast_strlen_zero(cai.username)) 04719 pds.username = cai.username; 04720 if (!pds.password && !ast_strlen_zero(cai.secret)) 04721 pds.password = cai.secret; 04722 if (!pds.key && !ast_strlen_zero(cai.outkey)) 04723 pds.key = cai.outkey; 04724 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 04725 pds.context = cai.peercontext; 04726 04727 /* Keep track of the context for outgoing calls too */ 04728 ast_copy_string(c->context, cai.context, sizeof(c->context)); 04729 04730 if (pds.port) 04731 sin.sin_port = htons(atoi(pds.port)); 04732 04733 l = c->cid.cid_num; 04734 n = c->cid.cid_name; 04735 04736 /* Now build request */ 04737 memset(&ied, 0, sizeof(ied)); 04738 04739 /* On new call, first IE MUST be IAX version of caller */ 04740 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 04741 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 04742 if (pds.options && strchr(pds.options, 'a')) { 04743 /* Request auto answer */ 04744 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 04745 } 04746 04747 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 04748 04749 if (l) { 04750 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 04751 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04752 } else { 04753 if (n) 04754 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04755 else 04756 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 04757 } 04758 04759 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 04760 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 04761 04762 if (n) 04763 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 04764 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 04765 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 04766 04767 if (!ast_strlen_zero(c->language)) 04768 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 04769 if (!ast_strlen_zero(c->cid.cid_dnid)) 04770 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 04771 if (!ast_strlen_zero(c->cid.cid_rdnis)) 04772 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 04773 04774 if (pds.context) 04775 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 04776 04777 if (pds.username) 04778 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 04779 04780 if (cai.encmethods) 04781 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 04782 04783 ast_mutex_lock(&iaxsl[callno]); 04784 04785 if (!ast_strlen_zero(c->context)) 04786 ast_string_field_set(iaxs[callno], context, c->context); 04787 04788 if (pds.username) 04789 ast_string_field_set(iaxs[callno], username, pds.username); 04790 04791 iaxs[callno]->encmethods = cai.encmethods; 04792 04793 iaxs[callno]->adsi = cai.adsi; 04794 04795 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 04796 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 04797 04798 if (pds.key) 04799 ast_string_field_set(iaxs[callno], outkey, pds.key); 04800 if (pds.password) 04801 ast_string_field_set(iaxs[callno], secret, pds.password); 04802 04803 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 04804 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 04805 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 04806 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 04807 04808 if (iaxs[callno]->maxtime) { 04809 /* Initialize pingtime and auto-congest time */ 04810 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 04811 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 04812 } else if (autokill) { 04813 iaxs[callno]->pingtime = autokill / 2; 04814 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 04815 } 04816 04817 /* Check if there is an OSP token set by IAXCHANINFO function */ 04818 osp_token_ptr = iaxs[callno]->osptoken; 04819 if (!ast_strlen_zero(osp_token_ptr)) { 04820 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 04821 osp_block_index = 0; 04822 while (osp_token_length > 0) { 04823 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 04824 osp_buffer[0] = osp_block_index; 04825 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 04826 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 04827 osp_block_index++; 04828 osp_token_ptr += osp_block_length; 04829 osp_token_length -= osp_block_length; 04830 } 04831 } else 04832 ast_log(LOG_WARNING, "OSP token is too long\n"); 04833 } else if (iaxdebug) 04834 ast_debug(1, "OSP token is undefined\n"); 04835 04836 /* send the command using the appropriate socket for this peer */ 04837 iaxs[callno]->sockfd = cai.sockfd; 04838 04839 /* Add remote vars */ 04840 if (variablestore) { 04841 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 04842 ast_debug(1, "Found an IAX variable store on this channel\n"); 04843 AST_LIST_LOCK(variablelist); 04844 AST_LIST_TRAVERSE(variablelist, var, entries) { 04845 char tmp[256]; 04846 int i; 04847 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 04848 /* Automatically divide the value up into sized chunks */ 04849 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 04850 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 04851 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 04852 } 04853 } 04854 AST_LIST_UNLOCK(variablelist); 04855 } 04856 04857 /* Transmit the string in a "NEW" request */ 04858 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 04859 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 04860 04861 ast_mutex_unlock(&iaxsl[callno]); 04862 ast_setstate(c, AST_STATE_RINGING); 04863 04864 return 0; 04865 }
| 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 13035 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.
13036 { 13037 int res = 0; 13038 struct iax2_dpcache *dp = NULL; 13039 #if 0 13040 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13041 #endif 13042 if ((priority != 1) && (priority != 2)) 13043 return 0; 13044 13045 AST_LIST_LOCK(&dpcache); 13046 if ((dp = find_cache(chan, data, context, exten, priority))) { 13047 if (dp->flags & CACHE_FLAG_CANEXIST) 13048 res = 1; 13049 } else { 13050 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13051 } 13052 AST_LIST_UNLOCK(&dpcache); 13053 13054 return res; 13055 }
| static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4346 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().
04347 { 04348 struct timeval t = ast_tvnow(); 04349 struct ast_tm tm; 04350 unsigned int tmp; 04351 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04352 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04353 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04354 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04355 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04356 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04357 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04358 return tmp; 04359 }
| static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3130 of file chan_iax2.c.
References ao2_ref, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_queue_hangup(), DEADLOCK_AVOIDANCE, iax2_destroy_helper(), 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().
03131 { 03132 struct chan_iax2_pvt *pvt = NULL; 03133 struct ast_channel *owner = NULL; 03134 03135 retry: 03136 if ((pvt = iaxs[callno])) { 03137 iax2_destroy_helper(pvt); 03138 } 03139 03140 owner = pvt ? pvt->owner : NULL; 03141 03142 if (owner) { 03143 if (ast_channel_trylock(owner)) { 03144 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03145 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03146 goto retry; 03147 } 03148 } 03149 03150 if (!owner) { 03151 iaxs[callno] = NULL; 03152 } 03153 03154 if (pvt) { 03155 if (!owner) { 03156 pvt->owner = NULL; 03157 } else { 03158 /* If there's an owner, prod it to give up */ 03159 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03160 * because we already hold the owner channel lock. */ 03161 ast_queue_hangup(owner); 03162 } 03163 03164 if (pvt->peercallno) { 03165 remove_by_peercallno(pvt); 03166 } 03167 03168 if (pvt->transfercallno) { 03169 remove_by_transfercallno(pvt); 03170 } 03171 03172 if (!owner) { 03173 ao2_ref(pvt, -1); 03174 pvt = NULL; 03175 } 03176 } 03177 03178 if (owner) { 03179 ast_channel_unlock(owner); 03180 } 03181 03182 if (callno & 0x4000) { 03183 update_max_trunk(); 03184 } 03185 }
| static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1529 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag, AST_SCHED_DEL, AST_SCHED_DEL_SPINLOCK, ast_test_flag, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::callno, iax2_user::curauthreq, IAX_MAXAUTHREQ, 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, user_unref(), and chan_iax2_pvt::username.
Referenced by iax2_destroy(), iax2_predestroy(), pvt_destructor(), and stop_stuff().
01530 { 01531 /* Decrement AUTHREQ count if needed */ 01532 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01533 struct iax2_user *user; 01534 struct iax2_user tmp_user = { 01535 .name = pvt->username, 01536 }; 01537 01538 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01539 if (user) { 01540 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01541 user_unref(user); 01542 } 01543 01544 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01545 } 01546 /* No more pings or lagrq's */ 01547 AST_SCHED_DEL_SPINLOCK(sched, pvt->pingid, &iaxsl[pvt->callno]); 01548 AST_SCHED_DEL_SPINLOCK(sched, pvt->lagid, &iaxsl[pvt->callno]); 01549 AST_SCHED_DEL(sched, pvt->autoid); 01550 AST_SCHED_DEL(sched, pvt->authid); 01551 AST_SCHED_DEL(sched, pvt->initid); 01552 AST_SCHED_DEL(sched, pvt->jbid); 01553 AST_SCHED_DEL(sched, pvt->keyrotateid); 01554 }
| static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 13282 of file chan_iax2.c.
References iax2_peer::addr, ast_debug, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), ast_strdupa, ast_strlen_zero(), iax2_peer::defaddr, find_peer(), iax2_peer::historicms, iax2_peer::lastms, LOG_WARNING, iax2_peer::maxms, parse_dial_string(), parsed_dial_string::peer, and peer_unref().
13283 { 13284 struct parsed_dial_string pds; 13285 char *tmp = ast_strdupa(data); 13286 struct iax2_peer *p; 13287 int res = AST_DEVICE_INVALID; 13288 13289 memset(&pds, 0, sizeof(pds)); 13290 parse_dial_string(tmp, &pds); 13291 13292 if (ast_strlen_zero(pds.peer)) { 13293 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 13294 return res; 13295 } 13296 13297 ast_debug(3, "Checking device state for device %s\n", pds.peer); 13298 13299 /* SLD: FIXME: second call to find_peer during registration */ 13300 if (!(p = find_peer(pds.peer, 1))) 13301 return res; 13302 13303 res = AST_DEVICE_UNAVAILABLE; 13304 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 13305 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 13306 13307 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 13308 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 13309 /* Peer is registered, or have default IP address 13310 and a valid registration */ 13311 if (p->historicms == 0 || p->historicms <= p->maxms) 13312 /* let the core figure out whether it is in use or not */ 13313 res = AST_DEVICE_UNKNOWN; 13314 } 13315 13316 peer_unref(p); 13317 13318 return res; 13319 }
| static int iax2_digit_begin | ( | struct ast_channel * | c, | |
| char | digit | |||
| ) | [static] |
Definition at line 3970 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03971 { 03972 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 03973 }
| static int iax2_digit_end | ( | struct ast_channel * | c, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 3975 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03976 { 03977 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 03978 }
| static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11088 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(), iax_ie_data::buf, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, find_callno_locked(), iax2_destroy(), iax2_do_register_s(), iax2_sched_replace(), IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, LOG_WARNING, NEW_FORCE, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_REGSENT, REG_STATE_TIMEOUT, iax2_registry::regstate, send_command(), and iax2_registry::username.
Referenced by __iax2_do_register_s(), load_module(), and reload_config().
11089 { 11090 struct iax_ie_data ied; 11091 if (iaxdebug) 11092 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11093 11094 if (reg->dnsmgr && 11095 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 11096 /* Maybe the IP has changed, force DNS refresh */ 11097 ast_dnsmgr_refresh(reg->dnsmgr); 11098 } 11099 11100 /* 11101 * if IP has Changed, free allocated call to create a new one with new IP 11102 * call has the pointer to IP and must be updated to the new one 11103 */ 11104 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11105 int callno = reg->callno; 11106 ast_mutex_lock(&iaxsl[callno]); 11107 iax2_destroy(callno); 11108 ast_mutex_unlock(&iaxsl[callno]); 11109 reg->callno = 0; 11110 } 11111 if (!reg->addr.sin_addr.s_addr) { 11112 if (iaxdebug) 11113 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11114 /* Setup the next registration attempt */ 11115 reg->expire = iax2_sched_replace(reg->expire, sched, 11116 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11117 return -1; 11118 } 11119 11120 if (!reg->callno) { 11121 ast_debug(3, "Allocate call number\n"); 11122 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 11123 if (reg->callno < 1) { 11124 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11125 return -1; 11126 } else 11127 ast_debug(3, "Registration created on call %d\n", reg->callno); 11128 iaxs[reg->callno]->reg = reg; 11129 ast_mutex_unlock(&iaxsl[reg->callno]); 11130 } 11131 /* Setup the next registration a little early */ 11132 reg->expire = iax2_sched_replace(reg->expire, sched, 11133 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11134 /* Send the request */ 11135 memset(&ied, 0, sizeof(ied)); 11136 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11137 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11138 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11139 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11140 reg->regstate = REG_STATE_REGSENT; 11141 return 0; 11142 }
| static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7770 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
07771 { 07772 #ifdef SCHED_MULTITHREADED 07773 if (schedule_action(__iax2_do_register_s, data)) 07774 #endif 07775 __iax2_do_register_s(data); 07776 return 0; 07777 }
| static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
| int | callno | |||
| ) | [static] |
Definition at line 8515 of file chan_iax2.c.
References AST_FRAME_IAX, auto_hangup(), chan_iax2_pvt::autoid, iax_ie_data::buf, CACHE_FLAG_TRANSMITTED, iax2_dpcache::exten, iax2_dpcache::flags, iax2_sched_replace(), IAX_COMMAND_DPREQ, iax_ie_append_str(), IAX_IE_CALLED_NUMBER, iax_ie_data::pos, and send_command().
Referenced by find_cache(), and socket_process().
08516 { 08517 struct iax_ie_data ied; 08518 /* Auto-hangup with 30 seconds of inactivity */ 08519 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 08520 sched, 30000, auto_hangup, (void *)(long)callno); 08521 memset(&ied, 0, sizeof(ied)); 08522 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 08523 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 08524 dp->flags |= CACHE_FLAG_TRANSMITTED; 08525 }
| static void * iax2_dup_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1125 of file chan_iax2.c.
References ast_calloc, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_name(), ast_var_value(), and LOG_ERROR.
01126 { 01127 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01128 struct ast_var_t *oldvar, *newvar; 01129 01130 newlist = ast_calloc(sizeof(*newlist), 1); 01131 if (!newlist) { 01132 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01133 return NULL; 01134 } 01135 01136 AST_LIST_HEAD_INIT(newlist); 01137 AST_LIST_LOCK(oldlist); 01138 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01139 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01140 if (newvar) 01141 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01142 else 01143 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01144 } 01145 AST_LIST_UNLOCK(oldlist); 01146 return newlist; 01147 }
| 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 13081 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().
13082 { 13083 char odata[256]; 13084 char req[256]; 13085 char *ncontext; 13086 struct iax2_dpcache *dp = NULL; 13087 struct ast_app *dial = NULL; 13088 #if 0 13089 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); 13090 #endif 13091 if (priority == 2) { 13092 /* Indicate status, can be overridden in dialplan */ 13093 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13094 if (dialstatus) { 13095 dial = pbx_findapp(dialstatus); 13096 if (dial) 13097 pbx_exec(chan, dial, ""); 13098 } 13099 return -1; 13100 } else if (priority != 1) 13101 return -1; 13102 13103 AST_LIST_LOCK(&dpcache); 13104 if ((dp = find_cache(chan, data, context, exten, priority))) { 13105 if (dp->flags & CACHE_FLAG_EXISTS) { 13106 ast_copy_string(odata, data, sizeof(odata)); 13107 ncontext = strchr(odata, '/'); 13108 if (ncontext) { 13109 *ncontext = '\0'; 13110 ncontext++; 13111 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13112 } else { 13113 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13114 } 13115 ast_verb(3, "Executing Dial('%s')\n", req); 13116 } else { 13117 AST_LIST_UNLOCK(&dpcache); 13118 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13119 return -1; 13120 } 13121 } 13122 AST_LIST_UNLOCK(&dpcache); 13123 13124 if ((dial = pbx_findapp("Dial"))) 13125 return pbx_exec(chan, dial, req); 13126 else 13127 ast_log(LOG_WARNING, "No dial application registered\n"); 13128 13129 return -1; 13130 }
| 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 13012 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.
13013 { 13014 int res = 0; 13015 struct iax2_dpcache *dp = NULL; 13016 #if 0 13017 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13018 #endif 13019 if ((priority != 1) && (priority != 2)) 13020 return 0; 13021 13022 AST_LIST_LOCK(&dpcache); 13023 if ((dp = find_cache(chan, data, context, exten, priority))) { 13024 if (dp->flags & CACHE_FLAG_EXISTS) 13025 res = 1; 13026 } else { 13027 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13028 } 13029 AST_LIST_UNLOCK(&dpcache); 13030 13031 return res; 13032 }
| static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 3997 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), LOG_WARNING, chan_iax2_pvt::owner, PTR_TO_CALLNO, and ast_channel::tech_pvt.
03998 { 03999 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04000 ast_mutex_lock(&iaxsl[callno]); 04001 if (iaxs[callno]) 04002 iaxs[callno]->owner = newchan; 04003 else 04004 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04005 ast_mutex_unlock(&iaxsl[callno]); 04006 return 0; 04007 }
| static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1556 of file chan_iax2.c.
References AST_SCHED_DEL, iax_frame_free(), and iax_frame::retrans.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), resend_with_token(), and schedule_delivery().
01557 { 01558 AST_SCHED_DEL(sched, fr->retrans); 01559 iax_frame_free(fr); 01560 }
| static void iax2_free_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1149 of file chan_iax2.c.
References ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, and AST_LIST_UNLOCK.
01150 { 01151 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01152 struct ast_var_t *oldvar; 01153 01154 AST_LIST_LOCK(oldlist); 01155 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01156 ast_free(oldvar); 01157 } 01158 AST_LIST_UNLOCK(oldlist); 01159 AST_LIST_HEAD_DESTROY(oldlist); 01160 ast_free(oldlist); 01161 }
| static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
| char * | host, | |||
| int | len | |||
| ) | [static] |
Definition at line 1496 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_copy_string(), iax2_peer::name, peer_unref(), and realtime_peer().
Referenced by __find_callno().
01497 { 01498 struct iax2_peer *peer = NULL; 01499 int res = 0; 01500 struct ao2_iterator i; 01501 01502 i = ao2_iterator_init(peers, 0); 01503 while ((peer = ao2_iterator_next(&i))) { 01504 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01505 (peer->addr.sin_port == sin.sin_port)) { 01506 ast_copy_string(host, peer->name, len); 01507 peer_unref(peer); 01508 res = 1; 01509 break; 01510 } 01511 peer_unref(peer); 01512 } 01513 ao2_iterator_destroy(&i); 01514 01515 if (!peer) { 01516 peer = realtime_peer(NULL, &sin); 01517 if (peer) { 01518 ast_copy_string(host, peer->name, len); 01519 peer_unref(peer); 01520 res = 1; 01521 } 01522 } 01523 01524 return res; 01525 }
| static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5287 of file chan_iax2.c.
References iax2_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag, IAX_TRUNK, and peer_unref().
Referenced by check_access().
05288 { 05289 struct iax2_peer *peer; 05290 int res = 0; 05291 struct ao2_iterator i; 05292 05293 i = ao2_iterator_init(peers, 0); 05294 while ((peer = ao2_iterator_next(&i))) { 05295 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05296 (peer->addr.sin_port == sin.sin_port)) { 05297 res = ast_test_flag(peer, IAX_TRUNK); 05298 peer_unref(peer); 05299 break; 05300 } 05301 peer_unref(peer); 05302 } 05303 ao2_iterator_destroy(&i); 05304 05305 return res; 05306 }
| static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4867 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_add(), ast_test_flag, ast_verb, iax_ie_data::buf, CALLNO_TO_PTR, ast_channel::hangupcause, iax2_destroy(), iax2_predestroy(), IAX_ALREADYGONE, IAX_COMMAND_HANGUP, iax_ie_append_byte(), IAX_IE_CAUSECODE, LOG_ERROR, LOG_WARNING, iax_ie_data::pos, PTR_TO_CALLNO, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.
04868 { 04869 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04870 struct iax_ie_data ied; 04871 int alreadygone; 04872 memset(&ied, 0, sizeof(ied)); 04873 ast_mutex_lock(&iaxsl[callno]); 04874 if (callno && iaxs[callno]) { 04875 ast_debug(1, "We're hanging up %s now...\n", c->name); 04876 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 04877 /* Send the hangup unless we have had a transmission error or are already gone */ 04878 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 04879 if (!iaxs[callno]->error && !alreadygone) { 04880 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 04881 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 04882 } 04883 if (!iaxs[callno]) { 04884 ast_mutex_unlock(&iaxsl[callno]); 04885 return 0; 04886 } 04887 } 04888 /* Explicitly predestroy it */ 04889 iax2_predestroy(callno); 04890 /* If we were already gone to begin with, destroy us now */ 04891 if (iaxs[callno] && alreadygone) { 04892 ast_debug(1, "Really destroying %s now...\n", c->name); 04893 iax2_destroy(callno); 04894 } else if (iaxs[callno]) { 04895 if (ast_sched_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 04896 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 04897 iax2_destroy(callno); 04898 } 04899 } 04900 } else if (c->tech_pvt) { 04901 /* If this call no longer exists, but the channel still 04902 * references it we need to set the channel's tech_pvt to null 04903 * to avoid ast_channel_free() trying to free it. 04904 */ 04905 c->tech_pvt = NULL; 04906 } 04907 ast_mutex_unlock(&iaxsl[callno]); 04908 ast_verb(3, "Hungup '%s'\n", c->name); 04909 return 0; 04910 }
| static int iax2_indicate | ( | struct ast_channel * | c, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 5230 of file chan_iax2.c.
References AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_debug, AST_FRAME_CONTROL, ast_moh_start(), ast_moh_stop(), ast_mutex_lock(), ast_mutex_unlock(), chan_iax2_pvt::mohinterpret, PTR_TO_CALLNO, send_command(), ast_channel::tech_pvt, and wait_for_peercallno().
05231 { 05232 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05233 struct chan_iax2_pvt *pvt; 05234 int res = 0; 05235 05236 if (iaxdebug) 05237 ast_debug(1, "Indicating condition %d\n", condition); 05238 05239 ast_mutex_lock(&iaxsl[callno]); 05240 pvt = iaxs[callno]; 05241 05242 if (wait_for_peercallno(pvt)) { 05243 res = -1; 05244 goto done; 05245 } 05246 05247 switch (condition) { 05248 case AST_CONTROL_HOLD: 05249 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05250 ast_moh_start(c, data, pvt->mohinterpret); 05251 goto done; 05252 } 05253 break; 05254 case AST_CONTROL_UNHOLD: 05255 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05256 ast_moh_stop(c); 05257 goto done; 05258 } 05259 } 05260 05261 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05262 05263 done: 05264 ast_mutex_unlock(&iaxsl[callno]); 05265 05266 return res; 05267 }
| static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 4982 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_sched_add(), iax_ie_data::buf, build_ecx_key(), chan_iax2_pvt::callno, IAX_COMMAND_RTKEY, IAX_DEBUGDIGEST, iax_ie_append_raw(), IAX_IE_CHALLENGE, chan_iax2_pvt::keyrotateid, MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, and send_command().
Referenced by iax2_send().
04983 { 04984 int res = 0; 04985 struct chan_iax2_pvt *pvt = (void *) vpvt; 04986 struct MD5Context md5; 04987 char key[17] = ""; 04988 struct iax_ie_data ied = { 04989 .pos = 0, 04990 }; 04991 04992 ast_mutex_lock(&iaxsl[pvt->callno]); 04993 pvt->keyrotateid = 04994 ast_sched_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 04995 04996 snprintf(key, sizeof(key), "%lX", ast_random()); 04997 04998 MD5Init(&md5); 04999 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05000 MD5Final((unsigned char *) key, &md5); 05001 05002 IAX_DEBUGDIGEST("Sending", key); 05003 05004 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05005 05006 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05007 05008 build_ecx_key((unsigned char *) key, pvt); 05009 05010 ast_mutex_unlock(&iaxsl[pvt->callno]); 05011 05012 return res; 05013 }
| 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 13058 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.
13059 { 13060 int res = 0; 13061 struct iax2_dpcache *dp = NULL; 13062 #if 0 13063 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13064 #endif 13065 if ((priority != 1) && (priority != 2)) 13066 return 0; 13067 13068 AST_LIST_LOCK(&dpcache); 13069 if ((dp = find_cache(chan, data, context, exten, priority))) { 13070 if (dp->flags & CACHE_FLAG_MATCHMORE) 13071 res = 1; 13072 } else { 13073 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13074 } 13075 AST_LIST_UNLOCK(&dpcache); 13076 13077 return res; 13078 }
| static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11292 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
11293 { 11294 struct iax2_peer *peer = (struct iax2_peer *)data; 11295 peer->pokeexpire = -1; 11296 #ifdef SCHED_MULTITHREADED 11297 if (schedule_action(__iax2_poke_noanswer, data)) 11298 #endif 11299 __iax2_poke_noanswer(data); 11300 peer_unref(peer); 11301 return 0; 11302 }
| static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
| int | heldcall | |||
| ) | [static] |
Definition at line 11313 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_del(), 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, 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, 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().
11314 { 11315 int callno; 11316 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 11317 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 11318 immediately after clearing things out */ 11319 peer->lastms = 0; 11320 peer->historicms = 0; 11321 peer->pokeexpire = -1; 11322 peer->callno = 0; 11323 return 0; 11324 } 11325 11326 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 11327 if ((callno = peer->callno) > 0) { 11328 ast_log(LOG_NOTICE, "Still have a callno...\n"); 11329 ast_mutex_lock(&iaxsl[callno]); 11330 iax2_destroy(callno); 11331 ast_mutex_unlock(&iaxsl[callno]); 11332 } 11333 if (heldcall) 11334 ast_mutex_unlock(&iaxsl[heldcall]); 11335 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 11336 if (heldcall) 11337 ast_mutex_lock(&iaxsl[heldcall]); 11338 if (peer->callno < 1) { 11339 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 11340 return -1; 11341 } 11342 11343 /* Speed up retransmission times for this qualify call */ 11344 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 11345 iaxs[peer->callno]->peerpoke = peer; 11346 11347 if (peer->pokeexpire > -1) { 11348 if (!ast_sched_del(sched, peer->pokeexpire)) { 11349 peer->pokeexpire = -1; 11350 peer_unref(peer); 11351 } 11352 } 11353 11354 /* Queue up a new task to handle no reply */ 11355 /* If the host is already unreachable then use the unreachable interval instead */ 11356 if (peer->lastms < 0) 11357 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 11358 else 11359 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 11360 11361 if (peer->pokeexpire == -1) 11362 peer_unref(peer); 11363 11364 /* And send the poke */ 11365 ast_mutex_lock(&iaxsl[callno]); 11366 if (iaxs[callno]) { 11367 struct iax_ie_data ied = { 11368 .buf = { 0 }, 11369 .pos = 0, 11370 }; 11371 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 11372 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 11373 } 11374 ast_mutex_unlock(&iaxsl[callno]); 11375 11376 return 0; 11377 }
| static int iax2_poke_peer_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 11304 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
11305 { 11306 struct iax2_peer *peer = obj; 11307 11308 iax2_poke_peer(peer, 0); 11309 11310 return 0; 11311 }
| static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 8555 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
08556 { 08557 struct iax2_peer *peer = (struct iax2_peer *)data; 08558 peer->pokeexpire = -1; 08559 #ifdef SCHED_MULTITHREADED 08560 if (schedule_action(__iax2_poke_peer_s, data)) 08561 #endif 08562 __iax2_poke_peer_s(data); 08563 return 0; 08564 }
| static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3107 of file chan_iax2.c.
References ast_module_unref(), ast_set_flag, ast_test_flag, iax2_destroy_helper(), iax2_queue_hangup(), IAX_ALREADYGONE, chan_iax2_pvt::owner, and ast_channel::tech_pvt.
Referenced by iax2_hangup(), and send_command_final().
03108 { 03109 struct ast_channel *c = NULL; 03110 struct chan_iax2_pvt *pvt = iaxs[callno]; 03111 03112 if (!pvt) 03113 return -1; 03114 03115 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 03116 iax2_destroy_helper(pvt); 03117 ast_set_flag(pvt, IAX_ALREADYGONE); 03118 } 03119 03120 if ((c = pvt->owner)) { 03121 c->tech_pvt = NULL; 03122 iax2_queue_hangup(callno); 03123 pvt->owner = NULL; 03124 ast_module_unref(ast_module_info->self); 03125 } 03126 03127 return 0; 03128 }
| static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 10959 of file chan_iax2.c.
References iax2_thread::actions, ast_atomic_fetchadd_int(), ast_cond_timedwait(), ast_cond_wait(), AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_tvadd(), ast_tvnow(), iax2_thread::checktime, iax2_thread::cond, iax2_thread::curfunc, handle_deferred_full_frames(), iax2_process_thread_cleanup(), IAX_IOSTATE_IDLE, IAX_IOSTATE_PROCESSING, IAX_IOSTATE_READY, IAX_IOSTATE_SCHEDREADY, IAX_THREAD_TYPE_DYNAMIC, iaxactivethreadcount, iaxdynamicthreadcount, iax2_thread::init_cond, iax2_thread::init_lock, insert_idle_thread(), iax2_thread::iostate, iax2_thread::lock, iax2_thread::scheddata, iax2_thread::schedfunc, signal_condition(), socket_process(), thread, and iax2_thread::type.
Referenced by find_idle_thread(), and start_network_thread().
10960 { 10961 struct iax2_thread *thread = data; 10962 struct timeval wait; 10963 struct timespec ts; 10964 int put_into_idle = 0; 10965 int first_time = 1; 10966 10967 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 10968 pthread_cleanup_push(iax2_process_thread_cleanup, data); 10969 for(;;) { 10970 /* Wait for something to signal us to be awake */ 10971 ast_mutex_lock(&thread->lock); 10972 10973 /* Flag that we're ready to accept signals */ 10974 if (first_time) { 10975 signal_condition(&thread->init_lock, &thread->init_cond); 10976 first_time = 0; 10977 } 10978 10979 /* Put into idle list if applicable */ 10980 if (put_into_idle) 10981 insert_idle_thread(thread); 10982 10983 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 10984 struct iax2_thread *t = NULL; 10985 /* Wait to be signalled or time out */ 10986 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 10987 ts.tv_sec = wait.tv_sec; 10988 ts.tv_nsec = wait.tv_usec * 1000; 10989 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 10990 /* This thread was never put back into the available dynamic 10991 * thread list, so just go away. */ 10992 if (!put_into_idle) { 10993 ast_mutex_unlock(&thread->lock); 10994 break; 10995 } 10996 AST_LIST_LOCK(&dynamic_list); 10997 /* Account for the case where this thread is acquired *right* after a timeout */ 10998 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 10999 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11000 AST_LIST_UNLOCK(&dynamic_list); 11001 if (t) { 11002 /* This dynamic thread timed out waiting for a task and was 11003 * not acquired immediately after the timeout, 11004 * so it's time to go away. */ 11005 ast_mutex_unlock(&thread->lock); 11006 break; 11007 } 11008 /* Someone grabbed our thread *right* after we timed out. 11009 * Wait for them to set us up with something to do and signal 11010 * us to continue. */ 11011 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11012 ts.tv_sec = wait.tv_sec; 11013 ts.tv_nsec = wait.tv_usec * 1000; 11014 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 11015 { 11016 ast_mutex_unlock(&thread->lock); 11017 break; 11018 } 11019 } 11020 } else { 11021 ast_cond_wait(&thread->cond, &thread->lock); 11022 } 11023 11024 /* Go back into our respective list */ 11025 put_into_idle = 1; 11026 11027 ast_mutex_unlock(&thread->lock); 11028 11029 if (thread->iostate == IAX_IOSTATE_IDLE) 11030 continue; 11031 11032 /* Add ourselves to the active list now */ 11033 AST_LIST_LOCK(&active_list); 11034 AST_LIST_INSERT_HEAD(&active_list, thread, list); 11035 AST_LIST_UNLOCK(&active_list); 11036 11037 /* See what we need to do */ 11038 switch(thread->iostate) { 11039 case IAX_IOSTATE_READY: 11040 thread->actions++; 11041 thread->iostate = IAX_IOSTATE_PROCESSING; 11042 socket_process(thread); 11043 handle_deferred_full_frames(thread); 11044 break; 11045 case IAX_IOSTATE_SCHEDREADY: 11046 thread->actions++; 11047 thread->iostate = IAX_IOSTATE_PROCESSING; 11048 #ifdef SCHED_MULTITHREADED 11049 thread->schedfunc(thread->scheddata); 11050 #endif 11051 default: 11052 break; 11053 } 11054 time(&thread->checktime); 11055 thread->iostate = IAX_IOSTATE_IDLE; 11056 #ifdef DEBUG_SCHED_MULTITHREAD 11057 thread->curfunc[0]='\0'; 11058 #endif 11059 11060 /* Now... remove ourselves from the active list, and return to the idle list */ 11061 AST_LIST_LOCK(&active_list); 11062 AST_LIST_REMOVE(&active_list, thread, list); 11063 AST_LIST_UNLOCK(&active_list); 11064 11065 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11066 handle_deferred_full_frames(thread); 11067 } 11068 11069 /*!\note For some reason, idle threads are exiting without being removed 11070 * from an idle list, which is causing memory corruption. Forcibly remove 11071 * it from the list, if it's there. 11072 */ 11073 AST_LIST_LOCK(&idle_list); 11074 AST_LIST_REMOVE(&idle_list, thread, list); 11075 AST_LIST_UNLOCK(&idle_list); 11076 11077 AST_LIST_LOCK(&dynamic_list); 11078 AST_LIST_REMOVE(&dynamic_list, thread, list); 11079 AST_LIST_UNLOCK(&dynamic_list); 11080 11081 /* I am exiting here on my own volition, I need to clean up my own data structures 11082 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11083 */ 11084 pthread_cleanup_pop(1); 11085 return NULL; 11086 }
| static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 10948 of file chan_iax2.c.
References ast_atomic_dec_and_test(), ast_cond_destroy(), ast_free, ast_mutex_destroy(), iax2_thread::cond, iaxactivethreadcount, iax2_thread::init_cond, iax2_thread::init_lock, iax2_thread::lock, and thread.
Referenced by iax2_process_thread().
10949 { 10950 struct iax2_thread *thread = data; 10951 ast_mutex_destroy(&thread->lock); 10952 ast_cond_destroy(&thread->cond); 10953 ast_mutex_destroy(&thread->init_lock); 10954 ast_cond_destroy(&thread->init_cond); 10955 ast_free(thread); 10956 ast_atomic_dec_and_test(&iaxactivethreadcount); 10957 }
| static int iax2_provision | ( | struct sockaddr_in * | end, | |
| int | sockfd, | |||
| char * | dest, | |||
| const char * | template, | |||
| int | force | |||
| ) | [static] |
Definition at line 11144 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_mutex_unlock(), ast_set_flag, 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(), NEW_FORCE, iax_ie_data::pos, send_command(), and create_addr_info::sockfd.
Referenced by check_provisioning(), handle_cli_iax2_provision(), and iax2_prov_app().
11145 { 11146 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11147 is found for template */ 11148 struct iax_ie_data provdata; 11149 struct iax_ie_data ied; 11150 unsigned int sig; 11151 struct sockaddr_in sin; 11152 int callno; 11153 struct create_addr_info cai; 11154 11155 memset(&cai, 0, sizeof(cai)); 11156 11157 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11158 11159 if (iax_provision_build(&provdata, &sig, template, force)) { 11160 ast_debug(1, "No provisioning found for template '%s'\n", template); 11161 return 0; 11162 } 11163 11164 if (end) { 11165 memcpy(&sin, end, sizeof(sin)); 11166 cai.sockfd = sockfd; 11167 } else if (create_addr(dest, NULL, &sin, &cai)) 11168 return -1; 11169 11170 /* Build the rest of the message */ 11171 memset(&ied, 0, sizeof(ied)); 11172 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11173 11174 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11175 if (!callno) 11176 return -1; 11177 11178 if (iaxs[callno]) { 11179 /* Schedule autodestruct in case they don't ever give us anything back */ 11180 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11181 sched, 15000, auto_hangup, (void *)(long)callno); 11182 ast_set_flag(iaxs[callno], IAX_PROVISION); 11183 /* Got a call number now, so go ahead and send the provisioning information */ 11184 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11185 } 11186 ast_mutex_unlock(&iaxsl[callno]); 11187 11188 return 1; 11189 }
| 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 2732 of file chan_iax2.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_control_data(), and DEADLOCK_AVOIDANCE.
Referenced by socket_process().
02734 { 02735 for (;;) { 02736 if (iaxs[callno] && iaxs[callno]->owner) { 02737 if (ast_channel_trylock(iaxs[callno]->owner)) { 02738 /* Avoid deadlock by pausing and trying again */ 02739 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02740 } else { 02741 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 02742 ast_channel_unlock(iaxs[callno]->owner); 02743 break; 02744 } 02745 } else 02746 break; 02747 } 02748 return 0; 02749 }
| 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 2670 of file chan_iax2.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_frame(), and DEADLOCK_AVOIDANCE.
Referenced by __attempt_transmit(), __auto_congest(), __do_deliver(), __get_from_jb(), and socket_process().
02671 { 02672 for (;;) { 02673 if (iaxs[callno] && iaxs[callno]->owner) { 02674 if (ast_channel_trylock(iaxs[callno]->owner)) { 02675 /* Avoid deadlock by pausing and trying again */ 02676 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02677 } else { 02678 ast_queue_frame(iaxs[callno]->owner, f); 02679 ast_channel_unlock(iaxs[callno]->owner); 02680 break; 02681 } 02682 } else 02683 break; 02684 } 02685 return 0; 02686 }
| 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 2701 of file chan_iax2.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_hangup(), and DEADLOCK_AVOIDANCE.
Referenced by iax2_predestroy().
02702 { 02703 for (;;) { 02704 if (iaxs[callno] && iaxs[callno]->owner) { 02705 if (ast_channel_trylock(iaxs[callno]->owner)) { 02706 /* Avoid deadlock by pausing and trying again */ 02707 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02708 } else { 02709 ast_queue_hangup(iaxs[callno]->owner); 02710 ast_channel_unlock(iaxs[callno]->owner); 02711 break; 02712 } 02713 } else 02714 break; 02715 } 02716 return 0; 02717 }
| static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 4976 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
04977 { 04978 ast_log(LOG_NOTICE, "I should never be called!\n"); 04979 return &ast_null_frame; 04980 }
| static int iax2_register | ( | const char * | value, | |
| int | lineno | |||
| ) | [static] |
Definition at line 8010 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().
08011 { 08012 char copy[256]; 08013 char *username, *hostname, *secret; 08014 char *porta; 08015 char *stringp=NULL; 08016 08017 if (!value) 08018 return -1; 08019 08020 ast_copy_string(copy, value, sizeof(copy)); 08021 stringp = copy; 08022 username = strsep(&stringp, "@"); 08023 hostname = strsep(&stringp, "@"); 08024 08025 if (!hostname) { 08026 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08027 return -1; 08028 } 08029 08030 stringp = username; 08031 username = strsep(&stringp, ":"); 08032 secret = strsep(&stringp, ":"); 08033 stringp = hostname; 08034 hostname = strsep(&stringp, ":"); 08035 porta = strsep(&stringp, ":"); 08036 08037 if (porta && !atoi(porta)) { 08038 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08039 return -1; 08040 } 08041 08042 return iax2_append_register(hostname, username, secret, porta); 08043 }
| static struct ast_channel * iax2_request | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Definition at line 11389 of file chan_iax2.c.
References ast_best_codec(), AST_CAUSE_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_flags, 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_flag, ast_translator_best_choice(), create_addr_info::capability, create_addr(), find_callno_locked(), create_addr_info::found, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_SENDANI, IAX_TRANSFERMEDIA, IAX_TRUNK, IAX_USEJITTERBUF, LOG_WARNING, make_trunk(), create_addr_info::maxtime, chan_iax2_pvt::maxtime, ast_channel::nativeformats, NEW_FORCE, parse_dial_string(), parsed_dial_string::peer, parsed_dial_string::port, ast_channel::readformat, create_addr_info::sockfd, and ast_channel::writeformat.
11390 { 11391 int callno; 11392 int res; 11393 int fmt, native; 11394 struct sockaddr_in sin; 11395 struct ast_channel *c; 11396 struct parsed_dial_string pds; 11397 struct create_addr_info cai; 11398 char *tmpstr; 11399 11400 memset(&pds, 0, sizeof(pds)); 11401 tmpstr = ast_strdupa(data); 11402 parse_dial_string(tmpstr, &pds); 11403 11404 if (ast_strlen_zero(pds.peer)) { 11405 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 11406 return NULL; 11407 } 11408 11409 memset(&cai, 0, sizeof(cai)); 11410 cai.capability = iax2_capability; 11411 11412 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 11413 11414 /* Populate our address from the given */ 11415 if (create_addr(pds.peer, NULL, &sin, &cai)) { 11416 *cause = AST_CAUSE_UNREGISTERED; 11417 return NULL; 11418 } 11419 11420 if (pds.port) 11421 sin.sin_port = htons(atoi(pds.port)); 11422 11423 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11424 if (callno < 1) { 11425 ast_log(LOG_WARNING, "Unable to create call\n"); 11426 *cause = AST_CAUSE_CONGESTION; 11427 return NULL; 11428 } 11429 11430 /* If this is a trunk, update it now */ 11431 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 11432 if (ast_test_flag(&cai, IAX_TRUNK)) { 11433 int new_callno; 11434 if ((new_callno = make_trunk(callno, 1)) != -1) 11435 callno = new_callno; 11436 } 11437 iaxs[callno]->maxtime = cai.maxtime; 11438 if (cai.found) 11439 ast_string_field_set(iaxs[callno], host, pds.peer); 11440 11441 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 11442 11443 ast_mutex_unlock(&iaxsl[callno]); 11444 11445 if (c) { 11446 /* Choose a format we can live with */ 11447 if (c->nativeformats & format) 11448 c->nativeformats &= format; 11449 else { 11450 native = c->nativeformats; 11451 fmt = format; 11452 res = ast_translator_best_choice(&fmt, &native); 11453 if (res < 0) { 11454 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 11455 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 11456 ast_hangup(c); 11457 return NULL; 11458 } 11459 c->nativeformats = native; 11460 } 11461 c->readformat = ast_best_codec(c->nativeformats); 11462 c->writeformat = c->readformat; 11463 } 11464 11465 return c; 11466 }
| static int iax2_sched_add | ( | struct sched_context * | con, | |
| int | when, | |||
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 1282 of file chan_iax2.c.
References ast_sched_add(), sched_lock, and signal_condition().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_poke_peer(), make_trunk(), network_thread(), realtime_peer(), reg_source_db(), sched_delay_remove(), socket_process(), and update_registry().
01283 { 01284 int res; 01285 01286 res = ast_sched_add(con, when, callback, data); 01287 signal_condition(&sched_lock, &sched_cond); 01288 01289 return res; 01290 }
| static int iax2_sched_replace | ( | int | id, | |
| struct sched_context * | con, | |||
| int | when, | |||
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 1274 of file chan_iax2.c.
References AST_SCHED_REPLACE, sched_lock, and signal_condition().
Referenced by auth_fail(), iax2_ack_registry(), iax2_do_register(), iax2_dprequest(), iax2_provision(), and update_jbsched().
01275 { 01276 AST_SCHED_REPLACE(id, con, when, callback, data); 01277 signal_condition(&sched_lock, &sched_cond); 01278 01279 return id; 01280 }
| 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 5939 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_log(), ast_test_flag, calc_timestamp(), ast_iax2_mini_hdr::callno, ast_iax2_video_hdr::callno, chan_iax2_pvt::callno, iax_frame::callno, compress_subclass(), ast_iax2_full_hdr::csub, iax_frame::data, ast_frame::data, iax_frame::datalen, ast_frame::datalen, ast_iax2_full_hdr::dcallno, iax_frame::dcallno, DIRECTION_OUTGRESS, iax_frame::ecx, chan_iax2_pvt::ecx, chan_iax2_pvt::encmethods, iax_frame::encmethods, encrypt_frame(), iax_frame::final, chan_iax2_pvt::first_iax_message, ast_frame::frametype, iax2_key_rotate(), iax2_transmit(), iax2_trunk_queue(), IAX_CALLENCRYPTED, IAX_COMMAND_ACK, IAX_ENCRYPTED, IAX_FLAG_FULL, iax_frame_new(), iax_frame_wrap(), IAX_KEYPOPULATED, iax_outputframe(), IAX_TRUNK, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::last_iax_message, chan_iax2_pvt::lastsent, iax2_trunk_peer::lastsent, chan_iax2_pvt::lastvsent, LOG_NOTICE, LOG_WARNING, MARK_IAX_SUBCLASS_TX, MAX_RETRY_TIME, MIN_RETRY_TIME, chan_iax2_pvt::mydcx, iax_frame::mydcx, ast_iax2_full_hdr::oseqno, chan_iax2_pvt::oseqno, iax_frame::oseqno, chan_iax2_pvt::peercallno, chan_iax2_pvt::pingtime, ast_frame::ptr, iax_frame::retries, iax_frame::retrytime, ast_iax2_full_hdr::scallno, iax_frame::semirand, chan_iax2_pvt::semirand, send_packet(), ast_frame::subclass, chan_iax2_pvt::svideoformat, chan_iax2_pvt::svoiceformat, chan_iax2_pvt::transfer, iax_frame::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, chan_iax2_pvt::transferring, ast_iax2_mini_hdr::ts, ast_iax2_video_hdr::ts, ast_iax2_full_hdr::ts, iax_frame::ts, ast_iax2_full_hdr::type, and ast_iax2_video_hdr::zeros.
Referenced by __send_command(), iax2_write(), send_signaling(), and socket_process().
05940 { 05941 /* Queue a packet for delivery on a given private structure. Use "ts" for 05942 timestamp, or calculate if ts is 0. Send immediately without retransmission 05943 or delayed, with retransmission */ 05944 struct ast_iax2_full_hdr *fh; 05945 struct ast_iax2_mini_hdr *mh; 05946 struct ast_iax2_video_hdr *vh; 05947 struct { 05948 struct iax_frame fr2; 05949 unsigned char buffer[4096]; 05950 } frb; 05951 struct iax_frame *fr; 05952 int res; 05953 int sendmini=0; 05954 unsigned int lastsent; 05955 unsigned int fts; 05956 05957 frb.fr2.afdatalen = sizeof(frb.buffer); 05958 05959 if (!pvt) { 05960 ast_log(LOG_WARNING, "No private structure for packet?\n"); 05961 return -1; 05962 } 05963 05964 lastsent = pvt->lastsent; 05965 05966 /* Calculate actual timestamp */ 05967 fts = calc_timestamp(pvt, ts, f); 05968 05969 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 05970 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 05971 * increment the "predicted timestamps" for voice, if we're predicting */ 05972 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 05973 return 0; 05974 #if 0 05975 ast_log(LOG_NOTICE, 05976 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 05977 *("=!" + (f->frametype == AST_FRAME_VOICE)), 05978 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 05979 pvt->keyrotateid != -1 ? "" : "no " 05980 ); 05981 #endif 05982 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 05983 iax2_key_rotate(pvt); 05984 } 05985 05986 if ((ast_test_flag(pvt, IAX_TRUNK) || 05987 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 05988 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 05989 /* High two bytes are the same on timestamp, or sending on a trunk */ && 05990 (f->frametype == AST_FRAME_VOICE) 05991 /* is a voice frame */ && 05992 (f->subclass == pvt->svoiceformat) 05993 /* is the same type */ ) { 05994 /* Force immediate rather than delayed transmission */ 05995 now = 1; 05996 /* Mark that mini-style frame is appropriate */ 05997 sendmini = 1; 05998 } 05999 if ( f->frametype == AST_FRAME_VIDEO ) { 06000 /* 06001 * If the lower 15 bits of the timestamp roll over, or if 06002 * the video format changed then send a full frame. 06003 * Otherwise send a mini video frame 06004 */ 06005 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06006 ((f->subclass & ~0x1) == pvt->svideoformat) 06007 ) { 06008 now = 1; 06009 sendmini = 1; 06010 } else { 06011 now = 0; 06012 sendmini = 0; 06013 } 06014 pvt->lastvsent = fts; 06015 } 06016 if (f->frametype == AST_FRAME_IAX) { 06017 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06018 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX; 06019 if (!pvt->first_iax_message) { 06020 pvt->first_iax_message = pvt->last_iax_message; 06021 } 06022 } 06023 /* Allocate an iax_frame */ 06024 if (now) { 06025 fr = &frb.fr2; 06026 } else 06027 fr = iax_frame_new(DIRECTION_OUTGRESS, ast_test_flag(pvt, IAX_ENCRYPTED) ? f->datalen + 32 : f->datalen, (f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_VIDEO)); 06028 if (!fr) { 06029 ast_log(LOG_WARNING, "Out of memory\n"); 06030 return -1; 06031 } 06032 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06033 iax_frame_wrap(fr, f); 06034 06035 fr->ts = fts; 06036 fr->callno = pvt->callno; 06037 fr->transfer = transfer; 06038 fr->final = final; 06039 fr->encmethods = 0; 06040 if (!sendmini) { 06041 /* We need a full frame */ 06042 if (seqno > -1) 06043 fr->oseqno = seqno; 06044 else 06045 fr->oseqno = pvt->oseqno++; 06046 fr->iseqno = pvt->iseqno; 06047 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06048 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06049 fh->ts = htonl(fr->ts); 06050 fh->oseqno = fr->oseqno; 06051 if (transfer) { 06052 fh->iseqno = 0; 06053 } else 06054 fh->iseqno = fr->iseqno; 06055 /* Keep track of the last thing we've acknowledged */ 06056 if (!transfer) 06057 pvt->aseqno = fr->iseqno; 06058 fh->type = fr->af.frametype & 0xFF; 06059 if (fr->af.frametype == AST_FRAME_VIDEO) 06060 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 06061 else 06062 fh->csub = compress_subclass(fr->af.subclass); 06063 if (transfer) { 06064 fr->dcallno = pvt->transfercallno; 06065 } else 06066 fr->dcallno = pvt->peercallno; 06067 fh->dcallno = htons(fr->dcallno); 06068 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06069 fr->data = fh; 06070 fr->retries = 0; 06071 /* Retry after 2x the ping time has passed */ 06072 fr->retrytime = pvt->pingtime * 2; 06073 if (fr->retrytime < MIN_RETRY_TIME) 06074 fr->retrytime = MIN_RETRY_TIME; 06075 if (fr->retrytime > MAX_RETRY_TIME) 06076 fr->retrytime = MAX_RETRY_TIME; 06077 /* Acks' don't get retried */ 06078 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 06079 fr->retries = -1; 06080 else if (f->frametype == AST_FRAME_VOICE) 06081 pvt->svoiceformat = f->subclass; 06082 else if (f->frametype == AST_FRAME_VIDEO) 06083 pvt->svideoformat = f->subclass & ~0x1; 06084 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 06085 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 06086 if (fr->transfer) 06087 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06088 else 06089 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06090 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06091 fr->encmethods = pvt->encmethods; 06092 fr->ecx = pvt->ecx; 06093 fr->mydcx = pvt->mydcx; 06094 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06095 } else 06096 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06097 } 06098 06099 if (now) { 06100 res = send_packet(fr); 06101 } else 06102 res = iax2_transmit(fr); 06103 } else { 06104 if (ast_test_flag(pvt, IAX_TRUNK)) { 06105 iax2_trunk_queue(pvt, fr); 06106 res = 0; 06107 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06108 /* Video frame have no sequence number */ 06109 fr->oseqno = -1; 06110 fr->iseqno = -1; 06111 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06112 vh->zeros = 0; 06113 vh->callno = htons(0x8000 | fr->callno); 06114 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 06115 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06116 fr->data = vh; 06117 fr->retries = -1; 06118 res = send_packet(fr); 06119 } else { 06120 /* Mini-frames have no sequence number */ 06121 fr->oseqno = -1; 06122 fr->iseqno = -1; 06123 /* Mini frame will do */ 06124 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06125 mh->callno = htons(fr->callno); 06126 mh->ts = htons(fr->ts & 0xFFFF); 06127 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06128 fr->data = mh; 06129 fr->retries = -1; 06130 if (pvt->transferring == TRANSFER_MEDIAPASS) 06131 fr->transfer = 1; 06132 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 06133 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 06134 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06135 } else 06136 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06137 } 06138 res = send_packet(fr); 06139 } 06140 } 06141 return res; 06142 }
| static int iax2_sendhtml | ( | struct ast_channel * | c, | |
| int | subclass, | |||
| const char * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 3992 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03993 { 03994 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 03995 }
| static int iax2_sendimage | ( | struct ast_channel * | c, | |
| struct ast_frame * | img | |||
| ) | [static] |
Definition at line 3987 of file chan_iax2.c.
References AST_FRAME_IMAGE, ast_frame::data, ast_frame::datalen, ast_frame::ptr, PTR_TO_CALLNO, send_command_locked(), ast_frame::subclass, and ast_channel::tech_pvt.
03988 { 03989 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1); 03990 }
| static int iax2_sendtext | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 3980 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
03981 { 03982 03983 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 03984 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 03985 }
| static int iax2_setoption | ( | struct ast_channel * | c, | |
| int | option, | |||
| void * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 4934 of file chan_iax2.c.
References AST_CONTROL_OPTION, AST_FRAME_CONTROL, ast_free, ast_malloc, ast_mutex_lock(), ast_mutex_unlock(), AST_OPTION_FLAG_REQUEST, AST_OPTION_RXGAIN, AST_OPTION_TXGAIN, ast_option_header::data, errno, PTR_TO_CALLNO, send_command_locked(), ast_channel::tech_pvt, and wait_for_peercallno().
04935 { 04936 struct ast_option_header *h; 04937 int res; 04938 04939 switch (option) { 04940 case AST_OPTION_TXGAIN: 04941 case AST_OPTION_RXGAIN: 04942 /* these two cannot be sent, because they require a result */ 04943 errno = ENOSYS; 04944 return -1; 04945 default: 04946 { 04947 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04948 struct chan_iax2_pvt *pvt; 04949 04950 ast_mutex_lock(&iaxsl[callno]); 04951 pvt = iaxs[callno]; 04952 04953 if (wait_for_peercallno(pvt)) { 04954 ast_mutex_unlock(&iaxsl[callno]); 04955 return -1; 04956 } 04957 04958 ast_mutex_unlock(&iaxsl[callno]); 04959 04960 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 04961 return -1; 04962 } 04963 04964 h->flag = AST_OPTION_FLAG_REQUEST; 04965 h->option = htons(option); 04966 memcpy(h->data, data, datalen); 04967 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 04968 AST_CONTROL_OPTION, 0, (unsigned char *) h, 04969 datalen + sizeof(*h), -1); 04970 ast_free(h); 04971 return res; 04972 } 04973 } 04974 }
| static int iax2_start_transfer | ( | unsigned short | callno0, | |
| unsigned short | callno1, | |||
| int | mediaonly | |||
| ) | [static] |
Definition at line 5015 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, AST_FRAME_IAX, ast_random(), ast_set_flag, iax_ie_data::buf, IAX_CALLENCRYPTED, IAX_COMMAND_TXREQ, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), IAX_IE_CALLNO, IAX_IE_TRANSFERID, IAX_NOTRANSFER, iax_ie_data::pos, send_command(), TRANSFER_BEGIN, TRANSFER_MBEGIN, and chan_iax2_pvt::transferring.
Referenced by iax2_bridge().
05016 { 05017 int res; 05018 struct iax_ie_data ied0; 05019 struct iax_ie_data ied1; 05020 unsigned int transferid = (unsigned int)ast_random(); 05021 05022 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05023 ast_debug(1, "transfers are not supported for encrypted calls at this time"); 05024 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER); 05025 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER); 05026 return 0; 05027 } 05028 05029 memset(&ied0, 0, sizeof(ied0)); 05030 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05031 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05032 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05033 05034 memset(&ied1, 0, sizeof(ied1)); 05035 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05036 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05037 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05038 05039 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05040 if (res) 05041 return -1; 05042 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05043 if (res) 05044 return -1; 05045 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05046 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05047 return 0; 05048 }
| static int iax2_transfer | ( | struct ast_channel * | c, | |
| const char * | dest | |||
| ) | [static] |
Definition at line 5269 of file chan_iax2.c.
References ast_copy_string(), ast_debug, AST_FRAME_IAX, iax_ie_data::buf, chan_iax2_pvt::callno, context, IAX_COMMAND_TRANSFER, iax_ie_append_str(), IAX_IE_CALLED_CONTEXT, IAX_IE_CALLED_NUMBER, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05270 { 05271 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05272 struct iax_ie_data ied = { "", }; 05273 char tmp[256], *context; 05274 ast_copy_string(tmp, dest, sizeof(tmp)); 05275 context = strchr(tmp, '@'); 05276 if (context) { 05277 *context = '\0'; 05278 context++; 05279 } 05280 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05281 if (context) 05282 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05283 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05284 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05285 }
| static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3952 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, sched_lock, iax_frame::sentyet, and signal_condition().
Referenced by iax2_send().
03953 { 03954 /* Lock the queue and place this packet at the end */ 03955 /* By setting this to 0, the network thread will send it for us, and 03956 queue retransmission if necessary */ 03957 fr->sentyet = 0; 03958 AST_LIST_LOCK(&frame_queue); 03959 AST_LIST_INSERT_TAIL(&frame_queue, fr, list); 03960 AST_LIST_UNLOCK(&frame_queue); 03961 /* Wake up the network and scheduler thread */ 03962 if (netthreadid != AST_PTHREADT_NULL) 03963 pthread_kill(netthreadid, SIGURG); 03964 signal_condition(&sched_lock, &sched_cond); 03965 return 0; 03966 }
| static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [inline, static] |
Definition at line 8609 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
08610 { 08611 /* Drop when trunk is about 5 seconds idle */ 08612 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 08613 return 1; 08614 return 0; 08615 }
| static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_frame * | fr | |||
| ) | [static] |
Definition at line 5678 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_flag, ast_tvnow(), ast_iax2_meta_trunk_entry::callno, chan_iax2_pvt::callno, ast_iax2_mini_hdr::callno, iax2_trunk_peer::calls, ast_frame::data, ast_frame::datalen, DEFAULT_TRUNKDATA, f, find_tpeer(), IAX2_TRUNK_PREFACE, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_iax2_meta_trunk_mini::mini, ast_frame::ptr, send_trunk(), chan_iax2_pvt::sockfd, iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdataalloc, iax2_trunk_peer::trunkdatalen, iax_frame::ts, and ast_iax2_mini_hdr::ts.
Referenced by iax2_send().
05679 { 05680 struct ast_frame *f; 05681 struct iax2_trunk_peer *tpeer; 05682 void *tmp, *ptr; 05683 struct timeval now; 05684 int res; 05685 struct ast_iax2_meta_trunk_entry *met; 05686 struct ast_iax2_meta_trunk_mini *mtm; 05687 05688 f = &fr->af; 05689 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 05690 if (tpeer) { 05691 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 05692 /* Need to reallocate space */ 05693 if (tpeer->trunkdataalloc < trunkmaxsize) { 05694 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 05695 ast_mutex_unlock(&tpeer->lock); 05696 return -1; 05697 } 05698 05699 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 05700 tpeer->trunkdata = tmp; 05701 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); 05702 } else { 05703 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)); 05704 ast_mutex_unlock(&tpeer->lock); 05705 return -1; 05706 } 05707 } 05708 05709 /* Append to meta frame */ 05710 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 05711 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 05712 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 05713 mtm->len = htons(f->datalen); 05714 mtm->mini.callno = htons(pvt->callno); 05715 mtm->mini.ts = htons(0xffff & fr->ts); 05716 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 05717 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 05718 } else { 05719 met = (struct ast_iax2_meta_trunk_entry *)ptr; 05720 /* Store call number and length in meta header */ 05721 met->callno = htons(pvt->callno); 05722 met->len = htons(f->datalen); 05723 /* Advance pointers/decrease length past trunk entry header */ 05724 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 05725 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 05726 } 05727 /* Copy actual trunk data */ 05728 memcpy(ptr, f->data.ptr, f->datalen); 05729 tpeer->trunkdatalen += f->datalen; 05730 05731 tpeer->calls++; 05732 05733 /* track the largest mtu we actually have sent */ 05734 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 05735 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 05736 05737 /* if we have enough for a full MTU, ship it now without waiting */ 05738 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 05739 now = ast_tvnow(); 05740 res = send_trunk(tpeer, &now); 05741 trunk_untimed ++; 05742 } 05743 05744 ast_mutex_unlock(&tpeer->lock); 05745 } 05746 return 0; 05747 }
| static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 8527 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate().
Referenced by socket_process(), and socket_process_meta().
08528 { 08529 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 08530 }
| static int iax2_write | ( | struct ast_channel * | c, | |
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 6940 of file chan_iax2.c.
References ast_debug, AST_FRAME_NULL, AST_FRAME_VOICE, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, iax2_peer::callno, errno, ast_frame::frametype, iax2_send(), IAX_ALREADYGONE, IAX_QUELCH, IAX_STATE_STARTED, PTR_TO_CALLNO, and ast_channel::tech_pvt.
06941 { 06942 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 06943 int res = -1; 06944 ast_mutex_lock(&iaxsl[callno]); 06945 if (iaxs[callno]) { 06946 /* If there's an outstanding error, return failure now */ 06947 if (!iaxs[callno]->error) { 06948 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 06949 res = 0; 06950 /* Don't waste bandwidth sending null frames */ 06951 else if (f->frametype == AST_FRAME_NULL) 06952 res = 0; 06953 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 06954 res = 0; 06955 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 06956 res = 0; 06957 else 06958 /* Simple, just queue for transmission */ 06959 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 06960 } else { 06961 ast_debug(1, "Write error: %s\n", strerror(errno)); 06962 } 06963 } 06964 /* If it's already gone, just return */ 06965 ast_mutex_unlock(&iaxsl[callno]); 06966 return res; 06967 }
| static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 2899 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, and ast_iax2_firmware_header::version.
Referenced by update_registry().
02900 { 02901 int res = 0; 02902 struct iax_firmware *cur = NULL; 02903 02904 if (ast_strlen_zero(dev)) 02905 return 0; 02906 02907 AST_LIST_LOCK(&firmwares); 02908 AST_LIST_TRAVERSE(&firmwares, cur, list) { 02909 if (!strcmp(dev, (char *)cur->fwh->devname)) { 02910 res = ntohs(cur->fwh->version); 02911 break; 02912 } 02913 } 02914 AST_LIST_UNLOCK(&firmwares); 02915 02916 return res; 02917 }
| static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 978 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
00979 { 00980 if (iaxdebug) 00981 ast_verbose("%s", data); 00982 }
| static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 984 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
00985 { 00986 ast_log(LOG_WARNING, "%s", data); 00987 }
| static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
| const unsigned char * | dev, | |||
| unsigned int | desc | |||
| ) | [static] |
Definition at line 2919 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, and IAX_IE_FWBLOCKDESC.
Referenced by socket_process().
02920 { 02921 int res = -1; 02922 unsigned int bs = desc & 0xff; 02923 unsigned int start = (desc >> 8) & 0xffffff; 02924 unsigned int bytes; 02925 struct iax_firmware *cur; 02926 02927 if (ast_strlen_zero((char *)dev) || !bs) 02928 return -1; 02929 02930 start *= bs; 02931 02932 AST_LIST_LOCK(&firmwares); 02933 AST_LIST_TRAVERSE(&firmwares, cur, list) { 02934 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 02935 continue; 02936 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 02937 if (start < ntohl(cur->fwh->datalen)) { 02938 bytes = ntohl(cur->fwh->datalen) - start; 02939 if (bytes > bs) 02940 bytes = bs; 02941 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 02942 } else { 02943 bytes = 0; 02944 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 02945 } 02946 if (bytes == bs) 02947 res = 0; 02948 else 02949 res = 1; 02950 break; 02951 } 02952 AST_LIST_UNLOCK(&firmwares); 02953 02954 return res; 02955 }
| 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 961 of file chan_iax2.c.
References debugaddr, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), and socket_process().
00962 { 00963 if (iaxdebug || 00964 (sin && debugaddr.sin_addr.s_addr && 00965 (!ntohs(debugaddr.sin_port) || 00966 debugaddr.sin_port == sin->sin_port) && 00967 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 00968 if (iaxdebug) { 00969 iax_showframe(f, fhi, rx, sin, datalen); 00970 } else { 00971 iaxdebug = 1; 00972 iax_showframe(f, fhi, rx, sin, datalen); 00973 iaxdebug = 0; 00974 } 00975 } 00976 }
| static int iax_park | ( | struct ast_channel * | chan1, | |
| struct ast_channel * | chan2 | |||
| ) | [static] |
Definition at line 8771 of file chan_iax2.c.
References ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, iax_dual::chan1, iax_dual::chan2, ast_channel::context, ast_channel::exten, iax_park_thread(), LOG_WARNING, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
08772 { 08773 struct iax_dual *d; 08774 struct ast_channel *chan1m, *chan2m; 08775 pthread_t th; 08776 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 08777 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 08778 if (chan2m && chan1m) { 08779 /* Make formats okay */ 08780 chan1m->readformat = chan1->readformat; 08781 chan1m->writeformat = chan1->writeformat; 08782 ast_channel_masquerade(chan1m, chan1); 08783 /* Setup the extensions and such */ 08784 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 08785 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 08786 chan1m->priority = chan1->priority; 08787 08788 /* We make a clone of the peer channel too, so we can play 08789 back the announcement */ 08790 /* Make formats okay */ 08791 chan2m->readformat = chan2->readformat; 08792 chan2m->writeformat = chan2->writeformat; 08793 ast_channel_masquerade(chan2m, chan2); 08794 /* Setup the extensions and such */ 08795 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 08796 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 08797 chan2m->priority = chan2->priority; 08798 if (ast_do_masquerade(chan2m)) { 08799 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 08800 ast_hangup(chan2m); 08801 return -1; 08802 } 08803 } else { 08804 if (chan1m) 08805 ast_hangup(chan1m); 08806 if (chan2m) 08807 ast_hangup(chan2m); 08808 return -1; 08809 } 08810 if ((d = ast_calloc(1, sizeof(*d)))) { 08811 d->chan1 = chan1m; 08812 d->chan2 = chan2m; 08813 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) { 08814 return 0; 08815 } 08816 ast_free(d); 08817 } 08818 return -1; 08819 }
| static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 8751 of file chan_iax2.c.
References ast_free, ast_frfree, ast_hangup(), ast_log(), ast_park_call(), ast_read(), iax_dual::chan1, iax_dual::chan2, ext, f, and LOG_NOTICE.
Referenced by iax_park().
08752 { 08753 struct ast_channel *chan1, *chan2; 08754 struct iax_dual *d; 08755 struct ast_frame *f; 08756 int ext; 08757 int res; 08758 d = stuff; 08759 chan1 = d->chan1; 08760 chan2 = d->chan2; 08761 ast_free(d); 08762 f = ast_read(chan1); 08763 if (f) 08764 ast_frfree(f); 08765 res = ast_park_call(chan1, chan2, 0, &ext); 08766 ast_hangup(chan2); 08767 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 08768 return NULL; 08769 }
Definition at line 1711 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().
01712 { 01713 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01714 if (new) { 01715 size_t afdatalen = new->afdatalen; 01716 memcpy(new, fr, sizeof(*new)); 01717 iax_frame_wrap(new, &fr->af); 01718 new->afdatalen = afdatalen; 01719 new->data = NULL; 01720 new->datalen = 0; 01721 new->direction = DIRECTION_INGRESS; 01722 new->retrans = -1; 01723 } 01724 return new; 01725 }
| static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1167 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, IAX_THREAD_TYPE_DYNAMIC, and iax2_thread::type.
Referenced by iax2_process_thread().
01168 { 01169 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01170 AST_LIST_LOCK(&dynamic_list); 01171 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01172 AST_LIST_UNLOCK(&dynamic_list); 01173 } else { 01174 AST_LIST_LOCK(&idle_list); 01175 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01176 AST_LIST_UNLOCK(&idle_list); 01177 } 01178 01179 return; 01180 }
| static void jb_debug_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1013 of file chan_iax2.c.
References ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01014 { 01015 va_list args; 01016 char buf[1024]; 01017 01018 va_start(args, fmt); 01019 vsnprintf(buf, sizeof(buf), fmt, args); 01020 va_end(args); 01021 01022 ast_verbose("%s", buf); 01023 }
| static void jb_error_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 989 of file chan_iax2.c.
References ast_log(), and LOG_ERROR.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
| static void jb_warning_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1001 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01002 { 01003 va_list args; 01004 char buf[1024]; 01005 01006 va_start(args, fmt); 01007 vsnprintf(buf, sizeof(buf), fmt, args); 01008 va_end(args); 01009 01010 ast_log(LOG_WARNING, "%s", buf); 01011 }
| static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 13665 of file chan_iax2.c.
References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), ast_cond_init(), ast_custom_function_register, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_manager_register, 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, ast_register_switch(), ast_timer_close(), ast_timer_open(), ast_timer_set_rate(), ast_verb, config, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, iax2_do_register(), iax2_poke_peer_cb(), iax2_prov_app(), iax_debug_output(), iax_error_output(), iax_provision_reload(), iax_set_error(), iax_set_output(), 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(), peer_set_sock_cb(), reload_firmware(), RQ_CHAR, RQ_UINTEGER2, sched_context_create(), sched_context_destroy(), SENTINEL, set_config(), and start_network_thread().
13666 { 13667 13668 static const char config[] = "iax.conf"; 13669 int x = 0; 13670 struct iax2_registry *reg = NULL; 13671 13672 if (load_objects()) { 13673 return AST_MODULE_LOAD_FAILURE; 13674 } 13675 13676 randomcalltokendata = ast_random(); 13677 ast_custom_function_register(&iaxpeer_function); 13678 ast_custom_function_register(&iaxvar_function); 13679 13680 iax_set_output(iax_debug_output); 13681 iax_set_error(iax_error_output); 13682 jb_setoutput(jb_error_output, jb_warning_output, NULL); 13683 13684 memset(iaxs, 0, sizeof(iaxs)); 13685 13686 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 13687 ast_mutex_init(&iaxsl[x]); 13688 } 13689 13690 ast_cond_init(&sched_cond, NULL); 13691 13692 if (!(sched = sched_context_create())) { 13693 ast_log(LOG_ERROR, "Failed to create scheduler context\n"); 13694 return AST_MODULE_LOAD_FAILURE; 13695 } 13696 13697 if (!(io = io_context_create())) { 13698 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 13699 sched_context_destroy(sched); 13700 return AST_MODULE_LOAD_FAILURE; 13701 } 13702 13703 if (!(netsock = ast_netsock_list_alloc())) { 13704 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 13705 io_context_destroy(io); 13706 sched_context_destroy(sched); 13707 return AST_MODULE_LOAD_FAILURE; 13708 } 13709 ast_netsock_init(netsock); 13710 13711 outsock = ast_netsock_list_alloc(); 13712 if (!outsock) { 13713 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13714 io_context_destroy(io); 13715 sched_context_destroy(sched); 13716 return AST_MODULE_LOAD_FAILURE; 13717 } 13718 ast_netsock_init(outsock); 13719 13720 ast_cli_register_multiple(cli_iax2, sizeof(cli_iax2) / sizeof(struct ast_cli_entry)); 13721 13722 ast_register_application(papp, iax2_prov_app, psyn, pdescrip); 13723 13724 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" ); 13725 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" ); 13726 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" ); 13727 13728 if ((timer = ast_timer_open())) { 13729 ast_timer_set_rate(timer, trunkfreq); 13730 } 13731 13732 if (set_config(config, 0) == -1) { 13733 if (timer) { 13734 ast_timer_close(timer); 13735 } 13736 return AST_MODULE_LOAD_DECLINE; 13737 } 13738 13739 if (ast_channel_register(&iax2_tech)) { 13740 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 13741 __unload_module(); 13742 return AST_MODULE_LOAD_FAILURE; 13743 } 13744 13745 if (ast_register_switch(&iax2_switch)) 13746 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 13747 13748 if (start_network_thread()) { 13749 ast_log(LOG_ERROR, "Unable to start network thread\n"); 13750 __unload_module(); 13751 return AST_MODULE_LOAD_FAILURE; 13752 } else 13753 ast_verb(2, "IAX Ready and Listening\n"); 13754 13755 AST_LIST_LOCK(®istrations); 13756 AST_LIST_TRAVERSE(®istrations, reg, entry) 13757 iax2_do_register(reg); 13758 AST_LIST_UNLOCK(®istrations); 13759 13760 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 13761 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 13762 13763 13764 reload_firmware(0); 13765 iax_provision_reload(0); 13766 13767 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 13768 13769 return AST_MODULE_LOAD_SUCCESS; 13770 }
| static int load_objects | ( | void | ) | [static] |
Definition at line 13606 of file chan_iax2.c.
References addr_range_cmp_cb(), addr_range_hash_cb(), ao2_container_alloc, ao2_ref, AST_MODULE_LOAD_FAILURE, create_callno_pools(), IAX_MAX_CALLS, MAX_PEER_BUCKETS, MAX_USER_BUCKETS, peer_cmp_cb(), peer_hash_cb(), peercnt_cmp_cb(), peercnt_hash_cb(), pvt_cmp_cb(), pvt_hash_cb(), transfercallno_pvt_cmp_cb(), transfercallno_pvt_hash_cb(), user_cmp_cb(), and user_hash_cb().
Referenced by load_module().
13607 { 13608 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 13609 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 13610 13611 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 13612 goto container_fail; 13613 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 13614 goto container_fail; 13615 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 13616 goto container_fail; 13617 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 13618 goto container_fail; 13619 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 13620 goto container_fail; 13621 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 13622 goto container_fail; 13623 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 13624 goto container_fail; 13625 } else if (create_callno_pools()) { 13626 goto container_fail; 13627 } 13628 13629 return 0; 13630 13631 container_fail: 13632 if (peers) { 13633 ao2_ref(peers, -1); 13634 } 13635 if (users) { 13636 ao2_ref(users, -1); 13637 } 13638 if (iax_peercallno_pvts) { 13639 ao2_ref(iax_peercallno_pvts, -1); 13640 } 13641 if (iax_transfercallno_pvts) { 13642 ao2_ref(iax_transfercallno_pvts, -1); 13643 } 13644 if (peercnts) { 13645 ao2_ref(peercnts, -1); 13646 } 13647 if (callno_limits) { 13648 ao2_ref(callno_limits, -1); 13649 } 13650 if (calltoken_ignores) { 13651 ao2_ref(calltoken_ignores, -1); 13652 } 13653 if (callno_pool) { 13654 ao2_ref(callno_pool, -1); 13655 } 13656 if (callno_pool_trunk) { 13657 ao2_ref(callno_pool_trunk, -1); 13658 } 13659 return AST_MODULE_LOAD_FAILURE; 13660 }
| static void lock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5050 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), and DEADLOCK_AVOIDANCE.
Referenced by iax2_bridge().
05051 { 05052 ast_mutex_lock(&iaxsl[callno0]); 05053 while (ast_mutex_trylock(&iaxsl[callno1])) { 05054 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05055 } 05056 }
| static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 8894 of file chan_iax2.c.
References ast_debug, ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, 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, 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().
08895 { 08896 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 08897 jb_info jbinfo; 08898 08899 ast_mutex_lock(&iaxsl[callno]); 08900 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 08901 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) { 08902 jb_getinfo(iaxs[callno]->jb, &jbinfo); 08903 localjitter = jbinfo.jitter; 08904 localdelay = jbinfo.current - jbinfo.min; 08905 locallost = jbinfo.frames_lost; 08906 locallosspct = jbinfo.losspct/1000; 08907 localdropped = jbinfo.frames_dropped; 08908 localooo = jbinfo.frames_ooo; 08909 localpackets = jbinfo.frames_in; 08910 } 08911 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", 08912 iaxs[callno]->owner->name, 08913 iaxs[callno]->pingtime, 08914 localjitter, 08915 localdelay, 08916 locallost, 08917 locallosspct, 08918 localdropped, 08919 localooo, 08920 localpackets, 08921 iaxs[callno]->remote_rr.jitter, 08922 iaxs[callno]->remote_rr.delay, 08923 iaxs[callno]->remote_rr.losscnt, 08924 iaxs[callno]->remote_rr.losspct/1000, 08925 iaxs[callno]->remote_rr.dropped, 08926 iaxs[callno]->remote_rr.ooo, 08927 iaxs[callno]->remote_rr.packets); 08928 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", 08929 iaxs[callno]->owner->name, 08930 iaxs[callno]->pingtime, 08931 localjitter, 08932 localdelay, 08933 locallost, 08934 locallosspct, 08935 localdropped, 08936 localooo, 08937 localpackets, 08938 iaxs[callno]->remote_rr.jitter, 08939 iaxs[callno]->remote_rr.delay, 08940 iaxs[callno]->remote_rr.losscnt, 08941 iaxs[callno]->remote_rr.losspct/1000, 08942 iaxs[callno]->remote_rr.dropped, 08943 iaxs[callno]->remote_rr.ooo, 08944 iaxs[callno]->remote_rr.packets); 08945 } 08946 ast_mutex_unlock(&iaxsl[callno]); 08947 }
| static int make_trunk | ( | unsigned short | callno, | |
| int | locked | |||
| ) | [static] |
Definition at line 1791 of file chan_iax2.c.
References ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL, chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), iax2_sched_add(), chan_iax2_pvt::lagid, LOG_WARNING, MIN_REUSE_TIME, chan_iax2_pvt::pingid, replace_callno(), send_lagrq(), send_ping(), TRUNK_CALL_START, update_max_nontrunk(), update_max_trunk(), and callno_entry::validated.
Referenced by iax2_request(), and socket_process().
01792 { 01793 int x; 01794 int res= 0; 01795 struct callno_entry *callno_entry; 01796 if (iaxs[callno]->oseqno) { 01797 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01798 return -1; 01799 } 01800 if (callno & TRUNK_CALL_START) { 01801 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01802 return -1; 01803 } 01804 01805 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 01806 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01807 return -1; 01808 } 01809 01810 x = callno_entry->callno; 01811 ast_mutex_lock(&iaxsl[x]); 01812 01813 /*! 01814 * \note We delete these before switching the slot, because if 01815 * they fire in the meantime, they will generate a warning. 01816 */ 01817 AST_SCHED_DEL(sched, iaxs[callno]->pingid); 01818 AST_SCHED_DEL(sched, iaxs[callno]->lagid); 01819 iaxs[x] = iaxs[callno]; 01820 iaxs[x]->callno = x; 01821 01822 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 01823 * before assigning the new one */ 01824 if (iaxs[x]->callno_entry) { 01825 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 01826 } 01827 iaxs[x]->callno_entry = callno_entry; 01828 01829 iaxs[callno] = NULL; 01830 /* Update the two timers that should have been started */ 01831 iaxs[x]->pingid = iax2_sched_add(sched, 01832 ping_time * 1000, send_ping, (void *)(long)x); 01833 iaxs[x]->lagid = iax2_sched_add(sched, 01834 lagrq_time * 1000, send_lagrq, (void *)(long)x); 01835 01836 if (locked) 01837 ast_mutex_unlock(&iaxsl[callno]); 01838 res = x; 01839 if (!locked) 01840 ast_mutex_unlock(&iaxsl[x]); 01841 01842 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 01843 /* We move this call from a non-trunked to a trunked call */ 01844 update_max_trunk(); 01845 update_max_nontrunk(); 01846 return res; 01847 }
| static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 6509 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
06510 { 06511 ast_cli_netstats(s, -1, 0); 06512 astman_append(s, "\r\n"); 06513 return RESULT_SUCCESS; 06514 }
| 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 6561 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_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), IAX_DYNAMIC, iax2_peer::mask, iax2_peer::name, peer_status(), peer_unref(), RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by load_module().
06562 { 06563 struct iax2_peer *peer = NULL; 06564 int peer_count = 0; 06565 char nm[20]; 06566 char status[20]; 06567 const char *id = astman_get_header(m,"ActionID"); 06568 char idtext[256] = ""; 06569 struct ao2_iterator i; 06570 06571 if (!ast_strlen_zero(id)) 06572 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06573 06574 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 06575 06576 06577 i = ao2_iterator_init(peers, 0); 06578 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) { 06579 06580 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 06581 if (!ast_strlen_zero(peer->username)) { 06582 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 06583 } else { 06584 astman_append(s, "ObjectName: %s\r\n", peer->name); 06585 } 06586 astman_append(s, "ChanObjectType: peer\r\n"); 06587 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-"); 06588 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06589 astman_append(s, "Mask: %s\r\n", nm); 06590 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port)); 06591 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No"); 06592 peer_status(peer, status, sizeof(status)); 06593 astman_append(s, "Status: %s\r\n\r\n", status); 06594 peer_count++; 06595 } 06596 ao2_iterator_destroy(&i); 06597 06598 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 06599 return RESULT_SUCCESS; 06600 }
| static int manager_iax2_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
callback to display iax peers in manager
Definition at line 6548 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_get_header(), and astman_send_ack().
Referenced by load_module().
06549 { 06550 char *a[] = { "iax2", "show", "users" }; 06551 const char *id = astman_get_header(m,"ActionID"); 06552 char idtext[256] = ""; 06553 06554 if (!ast_strlen_zero(id)) 06555 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06556 astman_send_ack(s, m, "Peer status list will follow"); 06557 return __iax2_show_peers(1, -1, s, 3, a ); 06558 }
| 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 1740 of file chan_iax2.c.
References chan_iax2_pvt::addr, chan_iax2_pvt::callno, chan_iax2_pvt::peercallno, chan_iax2_pvt::transfer, TRANSFER_MEDIAPASS, chan_iax2_pvt::transfercallno, and chan_iax2_pvt::transferring.
Referenced by __ao2_callback(), __find_callno(), ast_parse_device_state(), check_blacklist(), find_command(), handle_updates(), lua_find_extension(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and transfercallno_pvt_cmp_cb().
01741 { 01742 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01743 (cur->addr.sin_port == sin->sin_port)) { 01744 /* This is the main host */ 01745 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01746 (check_dcallno ? dcallno == cur->callno : 1) ) { 01747 /* That's us. Be sure we keep track of the peer call number */ 01748 return 1; 01749 } 01750 } 01751 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01752 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01753 /* We're transferring */ 01754 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01755 return 1; 01756 } 01757 return 0; 01758 }
| static void memcpy_decrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_decrypt_key * | dcx | |||
| ) | [static] |
Definition at line 5777 of file chan_iax2.c.
References ast_aes_decrypt, ast_log(), and LOG_WARNING.
Referenced by decode_frame().
05778 { 05779 #if 0 05780 /* Debug with "fake encryption" */ 05781 int x; 05782 if (len % 16) 05783 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05784 for (x=0;x<len;x++) 05785 dst[x] = src[x] ^ 0xff; 05786 #else 05787 unsigned char lastblock[16] = { 0 }; 05788 int x; 05789 while(len > 0) { 05790 ast_aes_decrypt(src, dst, dcx); 05791 for (x=0;x<16;x++) 05792 dst[x] ^= lastblock[x]; 05793 memcpy(lastblock, src, sizeof(lastblock)); 05794 dst += 16; 05795 src += 16; 05796 len -= 16; 05797 } 05798 #endif 05799 }
| static void memcpy_encrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_encrypt_key * | ecx | |||
| ) | [static] |
Definition at line 5801 of file chan_iax2.c.
References ast_aes_encrypt, ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
05802 { 05803 #if 0 05804 /* Debug with "fake encryption" */ 05805 int x; 05806 if (len % 16) 05807 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05808 for (x=0;x<len;x++) 05809 dst[x] = src[x] ^ 0xff; 05810 #else 05811 unsigned char curblock[16] = { 0 }; 05812 int x; 05813 while(len > 0) { 05814 for (x=0;x<16;x++) 05815 curblock[x] ^= src[x]; 05816 ast_aes_encrypt(curblock, dst, ecx); 05817 memcpy(curblock, dst, sizeof(curblock)); 05818 dst += 16; 05819 src += 16; 05820 len -= 16; 05821 } 05822 #endif 05823 }
| static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | enc | |||
| ) | [static] |
Definition at line 7284 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().
07285 { 07286 /* Select exactly one common encryption if there are any */ 07287 p->encmethods &= enc; 07288 if (p->encmethods) { 07289 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07290 p->keyrotateid = -2; 07291 } 07292 if (p->encmethods & IAX_ENCRYPT_AES128) 07293 p->encmethods = IAX_ENCRYPT_AES128; 07294 else 07295 p->encmethods = 0; 07296 } 07297 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 1101 of file chan_iax2.c.
Referenced by build_peer().
| static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 11496 of file chan_iax2.c.
References ast_debug, ast_io_add(), AST_IO_IN, AST_IO_PRI, ast_io_wait(), AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_mutex_trylock(), ast_mutex_unlock(), ast_timer_fd(), attempt_transmit(), iax_frame::callno, f, iax2_sched_add(), iax_frame_free(), iax_frame::retrans, iax_frame::retries, iax_frame::retrytime, send_packet(), iax_frame::sentyet, and timing_read().
Referenced by start_network_thread().
11497 { 11498 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 11499 from the network, and queue them for delivery to the channels */ 11500 int res, count, wakeup; 11501 struct iax_frame *f; 11502 11503 if (timer) 11504 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 11505 11506 for(;;) { 11507 pthread_testcancel(); 11508 11509 /* Go through the queue, sending messages which have not yet been 11510 sent, and scheduling retransmissions if appropriate */ 11511 AST_LIST_LOCK(&frame_queue); 11512 count = 0; 11513 wakeup = -1; 11514 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) { 11515 if (f->sentyet) 11516 continue; 11517 11518 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 11519 if (ast_mutex_trylock(&iaxsl[f->callno])) { 11520 wakeup = 1; 11521 continue; 11522 } 11523 11524 f->sentyet = 1; 11525 11526 if (iaxs[f->callno]) { 11527 send_packet(f); 11528 count++; 11529 } 11530 11531 ast_mutex_unlock(&iaxsl[f->callno]); 11532 11533 if (f->retries < 0) { 11534 /* This is not supposed to be retransmitted */ 11535 AST_LIST_REMOVE_CURRENT(list); 11536 /* Free the iax frame */ 11537 iax_frame_free(f); 11538 } else { 11539 /* We need reliable delivery. Schedule a retransmission */ 11540 f->retries++; 11541 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 11542 } 11543 } 11544 AST_LIST_TRAVERSE_SAFE_END; 11545 AST_LIST_UNLOCK(&frame_queue); 11546 11547 pthread_testcancel(); 11548 if (count >= 20) 11549 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 11550 11551 /* Now do the IO, and run scheduled tasks */ 11552 res = ast_io_wait(io, wakeup); 11553 if (res >= 0) { 11554 if (res >= 20) 11555 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 11556 } 11557 } 11558 return NULL; 11559 }
| static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
| const char * | host | |||
| ) | [static, read] |
Definition at line 1669 of file chan_iax2.c.
References ao2_alloc, ao2_ref, AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, ast_string_field_set, chan_iax2_pvt::authid, chan_iax2_pvt::autoid, chan_iax2_pvt::dpentries, exten, chan_iax2_pvt::hold_signaling, chan_iax2_pvt::initid, chan_iax2_pvt::jb, jb_new(), jb_setconf(), chan_iax2_pvt::jbid, chan_iax2_pvt::keyrotateid, chan_iax2_pvt::lagid, jb_conf::max_contig_interp, jb_conf::max_jitterbuf, chan_iax2_pvt::pingid, prefs, chan_iax2_pvt::prefs, pvt_destructor(), jb_conf::resync_threshold, chan_iax2_pvt::signaling_queue, and jb_conf::target_extra.
Referenced by __find_callno().
01670 { 01671 struct chan_iax2_pvt *tmp; 01672 jb_conf jbconf; 01673 01674 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01675 return NULL; 01676 } 01677 01678 if (ast_string_field_init(tmp, 32)) { 01679 ao2_ref(tmp, -1); 01680 tmp = NULL; 01681 return NULL; 01682 } 01683 01684 tmp->prefs = prefs; 01685 tmp->pingid = -1; 01686 tmp->lagid = -1; 01687 tmp->autoid = -1; 01688 tmp->authid = -1; 01689 tmp->initid = -1; 01690 tmp->keyrotateid = -1; 01691 01692 ast_string_field_set(tmp,exten, "s"); 01693 ast_string_field_set(tmp,host, host); 01694 01695 tmp->jb = jb_new(); 01696 tmp->jbid = -1; 01697 jbconf.max_jitterbuf = maxjitterbuffer; 01698 jbconf.resync_threshold = resyncthreshold; 01699 jbconf.max_contig_interp = maxjitterinterps; 01700 jbconf.target_extra = jittertargetextra; 01701 jb_setconf(tmp->jb,&jbconf); 01702 01703 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 01704 01705 tmp->hold_signaling = 1; 01706 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 01707 01708 return tmp; 01709 }
| static void parse_dial_string | ( | char * | data, | |
| struct parsed_dial_string * | pds | |||
| ) | [static] |
Parses an IAX dial string into its component parts.
| data | the string to be parsed | |
| pds | pointer to a struct parsed_dial_string to be filled in |
This function parses the string and fills the structure with pointers to its component parts. The input string will be modified.
Definition at line 4635 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().
04636 { 04637 if (ast_strlen_zero(data)) 04638 return; 04639 04640 pds->peer = strsep(&data, "/"); 04641 pds->exten = strsep(&data, "/"); 04642 pds->options = data; 04643 04644 if (pds->exten) { 04645 data = pds->exten; 04646 pds->exten = strsep(&data, "@"); 04647 pds->context = data; 04648 } 04649 04650 if (strchr(pds->peer, '@')) { 04651 data = pds->peer; 04652 pds->username = strsep(&data, "@"); 04653 pds->peer = data; 04654 } 04655 04656 if (pds->username) { 04657 data = pds->username; 04658 pds->username = strsep(&data, ":"); 04659 pds->password = data; 04660 } 04661 04662 data = pds->peer; 04663 pds->peer = strsep(&data, ":"); 04664 pds->port = data; 04665 04666 /* check for a key name wrapped in [] in the secret position, if found, 04667 move it to the key field instead 04668 */ 04669 if (pds->password && (pds->password[0] == '[')) { 04670 pds->key = ast_strip_quoted(pds->password, "[", "]"); 04671 pds->password = NULL; 04672 } 04673 }
| static int peer_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1417 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and iax2_peer::name.
Referenced by load_objects().
| static int peer_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 12227 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
12228 { 12229 struct iax2_peer *peer = obj; 12230 12231 ast_set_flag(peer, IAX_DELME); 12232 12233 return 0; 12234 }
| static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 11712 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(), iax2_peer::mwi_event_sub, and register_peer_exten().
Referenced by build_peer().
11713 { 11714 struct iax2_peer *peer = obj; 11715 int callno = peer->callno; 11716 11717 ast_free_ha(peer->ha); 11718 11719 if (callno > 0) { 11720 ast_mutex_lock(&iaxsl[callno]); 11721 iax2_destroy(callno); 11722 ast_mutex_unlock(&iaxsl[callno]); 11723 } 11724 11725 register_peer_exten(peer, 0); 11726 11727 if (peer->dnsmgr) 11728 ast_dnsmgr_release(peer->dnsmgr); 11729 11730 if (peer->mwi_event_sub) 11731 ast_event_unsubscribe(peer->mwi_event_sub); 11732 11733 ast_string_field_free_memory(peer); 11734 }
| static int peer_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1407 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_objects().
01408 { 01409 const struct iax2_peer *peer = obj; 01410 01411 return ast_str_hash(peer->name); 01412 }
Definition at line 1464 of file chan_iax2.c.
References ao2_ref.
Referenced by __iax2_poke_noanswer(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_unregister(), iax2_poke_peer(), realtime_peer(), reg_source_db(), socket_process(), and update_registry().
01465 { 01466 ao2_ref(peer, +1); 01467 return peer; 01468 }
| static int peer_set_sock_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 13560 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
13561 { 13562 struct iax2_peer *peer = obj; 13563 13564 if (peer->sockfd < 0) 13565 peer->sockfd = defaultsockfd; 13566 13567 return 0; 13568 }
| 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 11640 of file chan_iax2.c.
References iax2_trunk_peer::addr, ast_debug, ast_get_ip(), ast_log(), ast_netsock_bind(), ast_netsock_find(), ast_netsock_sockfd(), ast_netsock_unref(), ast_strdupa, check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_WARNING, iax2_peer::name, qos, socket_read(), iax2_peer::sockfd, iax2_trunk_peer::sockfd, and strsep().
Referenced by build_peer().
11641 { 11642 struct sockaddr_in sin; 11643 int nonlocal = 1; 11644 int port = IAX_DEFAULT_PORTNO; 11645 int sockfd = defaultsockfd; 11646 char *tmp; 11647 char *addr; 11648 char *portstr; 11649 11650 if (!(tmp = ast_strdupa(srcaddr))) 11651 return -1; 11652 11653 addr = strsep(&tmp, ":"); 11654 portstr = tmp; 11655 11656 if (portstr) { 11657 port = atoi(portstr); 11658 if (port < 1) 11659 port = IAX_DEFAULT_PORTNO; 11660 } 11661 11662 if (!ast_get_ip(&sin, addr)) { 11663 struct ast_netsock *sock; 11664 int res; 11665 11666 sin.sin_port = 0; 11667 sin.sin_family = AF_INET; 11668 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 11669 if (res == 0) { 11670 /* ip address valid. */ 11671 sin.sin_port = htons(port); 11672 if (!(sock = ast_netsock_find(netsock, &sin))) 11673 sock = ast_netsock_find(outsock, &sin); 11674 if (sock) { 11675 sockfd = ast_netsock_sockfd(sock); 11676 nonlocal = 0; 11677 } else { 11678 unsigned int orig_saddr = sin.sin_addr.s_addr; 11679 /* INADDR_ANY matches anyway! */ 11680 sin.sin_addr.s_addr = INADDR_ANY; 11681 if (ast_netsock_find(netsock, &sin)) { 11682 sin.sin_addr.s_addr = orig_saddr; 11683 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 11684 if (sock) { 11685 sockfd = ast_netsock_sockfd(sock); 11686 ast_netsock_unref(sock); 11687 nonlocal = 0; 11688 } else { 11689 nonlocal = 2; 11690 } 11691 } 11692 } 11693 } 11694 } 11695 11696 peer->sockfd = sockfd; 11697 11698 if (nonlocal == 1) { 11699 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 11700 srcaddr, peer->name); 11701 return -1; 11702 } else if (nonlocal == 2) { 11703 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 11704 srcaddr, peer->name); 11705 return -1; 11706 } else { 11707 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 11708 return 0; 11709 } 11710 }
| static int peer_status | ( | struct iax2_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
peer_status: Report Peer status in character string
Definition at line 3447 of file chan_iax2.c.
References ast_copy_string(), iax2_peer::lastms, and iax2_peer::maxms.
Referenced by __iax2_show_peers(), function_iaxpeer(), handle_cli_iax2_show_peer(), and manager_iax2_show_peer_list().
03448 { 03449 int res = 0; 03450 if (peer->maxms) { 03451 if (peer->lastms < 0) { 03452 ast_copy_string(status, "UNREACHABLE", statuslen); 03453 } else if (peer->lastms > peer->maxms) { 03454 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03455 res = 1; 03456 } else if (peer->lastms) { 03457 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03458 res = 1; 03459 } else { 03460 ast_copy_string(status, "UNKNOWN", statuslen); 03461 } 03462 } else { 03463 ast_copy_string(status, "Unmonitored", statuslen); 03464 res = -1; 03465 } 03466 return res; 03467 }
Definition at line 1470 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(), poke_all_peers(), prune_peers(), realtime_peer(), reg_source_db(), register_verify(), registry_authrequest(), requirecalltoken_mark_auto(), set_config(), socket_process(), unlink_peer(), and update_registry().
01471 { 01472 ao2_ref(peer, -1); 01473 return NULL; 01474 }
| static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2075 of file chan_iax2.c.
References peercnt::addr, iax2_trunk_peer::addr, ao2_alloc, ao2_find, ao2_link, ao2_lock(), ao2_ref, ao2_unlock(), ast_debug, ast_inet_ntoa(), ast_log(), peercnt::cur, peercnt::limit, LOG_ERROR, OBJ_POINTER, and set_peercnt_limit().
Referenced by __find_callno(), and complete_transfer().
02076 { 02077 struct peercnt *peercnt; 02078 unsigned long addr = sin->sin_addr.s_addr; 02079 int res = 0; 02080 struct peercnt tmp = { 02081 .addr = addr, 02082 }; 02083 02084 /* Reasoning for peercnts container lock: Two identical ip addresses 02085 * could be added by different threads at the "same time". Without the container 02086 * lock, both threads could alloc space for the same object and attempt 02087 * to link to table. With the lock, one would create the object and link 02088 * to table while the other would find the already created peercnt object 02089 * rather than creating a new one. */ 02090 ao2_lock(peercnts); 02091 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02092 ao2_lock(peercnt); 02093 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02094 ao2_lock(peercnt); 02095 /* create and set defaults */ 02096 peercnt->addr = addr; 02097 set_peercnt_limit(peercnt); 02098 /* guarantees it does not go away after unlocking table 02099 * ao2_find automatically adds this */ 02100 ao2_link(peercnts, peercnt); 02101 } else { 02102 ao2_unlock(peercnts); 02103 return -1; 02104 } 02105 02106 /* check to see if the address has hit its callno limit. If not increment cur. */ 02107 if (peercnt->limit > peercnt->cur) { 02108 peercnt->cur++; 02109 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02110 } else { /* max num call numbers for this peer has been reached! */ 02111 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02112 res = -1; 02113 } 02114 02115 /* clean up locks and ref count */ 02116 ao2_unlock(peercnt); 02117 ao2_unlock(peercnts); 02118 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02119 02120 return res; 02121 }
| static int peercnt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1915 of file chan_iax2.c.
References peercnt::addr, CMP_MATCH, and CMP_STOP.
Referenced by load_objects().
| static int peercnt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1909 of file chan_iax2.c.
References peercnt::addr.
Referenced by load_objects().
| static void peercnt_modify | ( | unsigned char | reg, | |
| uint16_t | limit, | |||
| struct sockaddr_in * | sin | |||
| ) | [static] |
Definition at line 2047 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, ast_debug, ast_inet_ntoa(), peercnt::limit, OBJ_POINTER, peercnt::reg, and set_peercnt_limit().
Referenced by __expire_registry(), build_peer(), and update_registry().
02048 { 02049 /* this function turns off and on custom callno limits set by peer registration */ 02050 struct peercnt *peercnt; 02051 struct peercnt tmp = { 02052 .addr = sin->sin_addr.s_addr, 02053 }; 02054 02055 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02056 peercnt->reg = reg; 02057 if (limit) { 02058 peercnt->limit = limit; 02059 } else { 02060 set_peercnt_limit(peercnt); 02061 } 02062 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg); 02063 ao2_ref(peercnt, -1); /* decrement ref from find */ 02064 } 02065 }
| static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2127 of file chan_iax2.c.
References peercnt::addr, ao2_lock(), ao2_unlink, ao2_unlock(), ast_debug, ast_inet_ntoa(), and peercnt::cur.
Referenced by peercnt_remove_by_addr(), and peercnt_remove_cb().
02128 { 02129 struct sockaddr_in sin = { 02130 .sin_addr.s_addr = peercnt->addr, 02131 }; 02132 02133 if (peercnt) { 02134 /* Container locked here since peercnt may be unlinked from list. If left unlocked, 02135 * peercnt_add could try and grab this entry from the table and modify it at the 02136 * "same time" this thread attemps to unlink it.*/ 02137 ao2_lock(peercnts); 02138 peercnt->cur--; 02139 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02140 /* if this was the last connection from the peer remove it from table */ 02141 if (peercnt->cur == 0) { 02142 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02143 } 02144 ao2_unlock(peercnts); 02145 } 02146 }
| static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2166 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, OBJ_POINTER, and peercnt_remove().
Referenced by __find_callno(), and complete_transfer().
02167 { 02168 struct peercnt *peercnt; 02169 struct peercnt tmp = { 02170 .addr = sin->sin_addr.s_addr, 02171 }; 02172 02173 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02174 peercnt_remove(peercnt); 02175 ao2_ref(peercnt, -1); /* decrement ref from find */ 02176 } 02177 return 0; 02178 }
| static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2152 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02153 { 02154 struct peercnt *peercnt = (struct peercnt *) obj; 02155 02156 peercnt_remove(peercnt); 02157 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02158 02159 return 0; 02160 }
| static void poke_all_peers | ( | void | ) | [static] |
Definition at line 12743 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, iax2_poke_peer(), and peer_unref().
Referenced by reload_config().
12744 { 12745 struct ao2_iterator i; 12746 struct iax2_peer *peer; 12747 12748 i = ao2_iterator_init(peers, 0); 12749 while ((peer = ao2_iterator_next(&i))) { 12750 iax2_poke_peer(peer, 0); 12751 peer_unref(peer); 12752 } 12753 ao2_iterator_destroy(&i); 12754 }
| static int prune_addr_range_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2036 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02037 { 02038 struct addr_range *addr_range = obj; 02039 02040 return addr_range->delme ? CMP_MATCH : 0; 02041 }
| static void prune_peers | ( | void | ) | [static] |
Definition at line 12288 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, peer_unref(), and unlink_peer().
Referenced by handle_cli_iax2_prune_realtime(), and reload_config().
12289 { 12290 struct iax2_peer *peer; 12291 struct ao2_iterator i; 12292 12293 i = ao2_iterator_init(peers, 0); 12294 while ((peer = ao2_iterator_next(&i))) { 12295 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 12296 unlink_peer(peer); 12297 } 12298 peer_unref(peer); 12299 } 12300 ao2_iterator_destroy(&i); 12301 }
| static void prune_users | ( | void | ) | [static] |
Definition at line 12272 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_unlink, ast_test_flag, IAX_DELME, IAX_RTCACHEFRIENDS, and user_unref().
Referenced by handle_cli_iax2_prune_realtime(), and reload_config().
12273 { 12274 struct iax2_user *user; 12275 struct ao2_iterator i; 12276 12277 i = ao2_iterator_init(users, 0); 12278 while ((user = ao2_iterator_next(&i))) { 12279 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 12280 ao2_unlink(users, user); 12281 } 12282 user_unref(user); 12283 } 12284 ao2_iterator_destroy(&i); 12285 }
| static int pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 13577 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
13578 { 13579 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 13580 13581 /* The frames_received field is used to hold whether we're matching 13582 * against a full frame or not ... */ 13583 13584 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 13585 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 13586 }
| static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1621 of file chan_iax2.c.
References chan_iax2_pvt::addr, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_string_field_free_memory, ast_variables_destroy(), iax2_registry::callno, iax_frame::callno, chan_iax2_pvt::callno, chan_iax2_pvt::callno_entry, jb_frame::data, free_signaling_queue_entry(), iax2_destroy_helper(), iax2_frame_free(), IAX_ALREADYGONE, chan_iax2_pvt::jb, jb_destroy(), jb_getall(), JB_OK, chan_iax2_pvt::owner, chan_iax2_pvt::reg, iax_frame::retries, s, sched_delay_remove(), chan_iax2_pvt::signaling_queue, and chan_iax2_pvt::vars.
Referenced by new_iax().
01622 { 01623 struct chan_iax2_pvt *pvt = obj; 01624 struct iax_frame *cur = NULL; 01625 struct signaling_queue_entry *s = NULL; 01626 01627 ast_mutex_lock(&iaxsl[pvt->callno]); 01628 iax2_destroy_helper(pvt); 01629 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01630 pvt->callno_entry = NULL; 01631 ast_mutex_unlock(&iaxsl[pvt->callno]); 01632 01633 /* Already gone */ 01634 ast_set_flag(pvt, IAX_ALREADYGONE); 01635 01636 AST_LIST_LOCK(&frame_queue); 01637 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 01638 /* Cancel any pending transmissions */ 01639 if (cur->callno == pvt->callno) { 01640 cur->retries = -1; 01641 } 01642 } 01643 AST_LIST_UNLOCK(&frame_queue); 01644 01645 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01646 free_signaling_queue_entry(s); 01647 } 01648 01649 if (pvt->reg) { 01650 pvt->reg->callno = 0; 01651 } 01652 01653 if (!pvt->owner) { 01654 jb_frame frame; 01655 if (pvt->vars) { 01656 ast_variables_destroy(pvt->vars); 01657 pvt->vars = NULL; 01658 } 01659 01660 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01661 iax2_frame_free(frame.data); 01662 } 01663 01664 jb_destroy(pvt->jb); 01665 ast_string_field_free_memory(pvt); 01666 } 01667 }
| static int pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 13570 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_objects().
13571 { 13572 const struct chan_iax2_pvt *pvt = obj; 13573 13574 return pvt->peercallno; 13575 }
| 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 1597 of file chan_iax2.c.
References ast_calloc, AST_FRAME_IAX, AST_LIST_INSERT_TAIL, ast_frame::data, ast_frame::frametype, free_signaling_queue_entry(), chan_iax2_pvt::hold_signaling, ast_frame::ptr, and chan_iax2_pvt::signaling_queue.
Referenced by __send_command().
01598 { 01599 struct signaling_queue_entry *new; 01600 01601 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01602 return 1; /* do not queue this frame */ 01603 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01604 return -1; /* out of memory */ 01605 } 01606 01607 memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */ 01608 01609 if (new->f.datalen) { /* if there is data in this frame copy it over as well */ 01610 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) { 01611 free_signaling_queue_entry(new); 01612 return -1; 01613 } 01614 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr)); 01615 } 01616 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next); 01617 01618 return 0; 01619 }
| static int raw_hangup | ( | struct sockaddr_in * | sin, | |
| unsigned short | src, | |||
| unsigned short | dst, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 7265 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().
07266 { 07267 struct ast_iax2_full_hdr fh; 07268 fh.scallno = htons(src | IAX_FLAG_FULL); 07269 fh.dcallno = htons(dst); 07270 fh.ts = 0; 07271 fh.oseqno = 0; 07272 fh.iseqno = 0; 07273 fh.type = AST_FRAME_IAX; 07274 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07275 iax_outputframe(NULL, &fh, 0, sin, 0); 07276 #if 0 07277 if (option_debug) 07278 #endif 07279 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07280 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07281 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07282 }
| static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4013 of file chan_iax2.c.
References iax2_peer::addr, ao2_link, ast_copy_flags, ast_debug, ast_get_time_t(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_sched_del(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_peer(), iax2_peer::expire, expire_registry(), hp, iax2_sched_add(), IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_TEMPONLY, iax2_peer::name, ast_variable::name, ast_variable::next, peer_ref(), peer_unref(), realtime_update_peer(), reg_source_db(), SENTINEL, ast_variable::value, and var.
Referenced by authenticate_reply(), calltoken_required(), find_peer(), and iax2_getpeername().
04014 { 04015 struct ast_variable *var = NULL; 04016 struct ast_variable *tmp; 04017 struct iax2_peer *peer=NULL; 04018 time_t regseconds = 0, nowtime; 04019 int dynamic=0; 04020 04021 if (peername) { 04022 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04023 if (!var && sin) 04024 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04025 } else if (sin) { 04026 char porta[25]; 04027 sprintf(porta, "%d", ntohs(sin->sin_port)); 04028 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04029 if (var) { 04030 /* We'll need the peer name in order to build the structure! */ 04031 for (tmp = var; tmp; tmp = tmp->next) { 04032 if (!strcasecmp(tmp->name, "name")) 04033 peername = tmp->value; 04034 } 04035 } 04036 } 04037 if (!var && peername) { /* Last ditch effort */ 04038 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04039 /*!\note 04040 * If this one loaded something, then we need to ensure that the host 04041 * field matched. The only reason why we can't have this as a criteria 04042 * is because we only have the IP address and the host field might be 04043 * set as a name (and the reverse PTR might not match). 04044 */ 04045 if (var && sin) { 04046 for (tmp = var; tmp; tmp = tmp->next) { 04047 if (!strcasecmp(tmp->name, "host")) { 04048 struct ast_hostent ahp; 04049 struct hostent *hp; 04050 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04051 /* No match */ 04052 ast_variables_destroy(var); 04053 var = NULL; 04054 } 04055 break; 04056 } 04057 } 04058 } 04059 } 04060 if (!var) 04061 return NULL; 04062 04063 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04064 04065 if (!peer) { 04066 ast_variables_destroy(var); 04067 return NULL; 04068 } 04069 04070 for (tmp = var; tmp; tmp = tmp->next) { 04071 /* Make sure it's not a user only... */ 04072 if (!strcasecmp(tmp->name, "type")) { 04073 if (strcasecmp(tmp->value, "friend") && 04074 strcasecmp(tmp->value, "peer")) { 04075 /* Whoops, we weren't supposed to exist! */ 04076 peer = peer_unref(peer); 04077 break; 04078 } 04079 } else if (!strcasecmp(tmp->name, "regseconds")) { 04080 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04081 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04082 inet_aton(tmp->value, &(peer->addr.sin_addr)); 04083 } else if (!strcasecmp(tmp->name, "port")) { 04084 peer->addr.sin_port = htons(atoi(tmp->value)); 04085 } else if (!strcasecmp(tmp->name, "host")) { 04086 if (!strcasecmp(tmp->value, "dynamic")) 04087 dynamic = 1; 04088 } 04089 } 04090 04091 ast_variables_destroy(var); 04092 04093 if (!peer) 04094 return NULL; 04095 04096 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 04097 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04098 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 04099 if (peer->expire > -1) { 04100 if (!ast_sched_del(sched, peer->expire)) { 04101 peer->expire = -1; 04102 peer_unref(peer); 04103 } 04104 } 04105 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04106 if (peer->expire == -1) 04107 peer_unref(peer); 04108 } 04109 ao2_link(peers, peer); 04110 if (ast_test_flag(peer, IAX_DYNAMIC)) 04111 reg_source_db(peer); 04112 } else { 04113 ast_set_flag(peer, IAX_TEMPONLY); 04114 } 04115 04116 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04117 time(&nowtime); 04118 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04119 memset(&peer->addr, 0, sizeof(peer->addr)); 04120 realtime_update_peer(peer->name, &peer->addr, 0); 04121 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04122 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04123 } 04124 else { 04125 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04126 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04127 } 04128 } 04129 04130 return peer; 04131 }
| static void realtime_update_peer | ( | const char * | peername, | |
| struct sockaddr_in * | sin, | |||
| time_t | regtime | |||
| ) | [static] |
Definition at line 4204 of file chan_iax2.c.
References ast_inet_ntoa(), ast_update_realtime(), and SENTINEL.
Referenced by __expire_registry(), realtime_peer(), and update_registry().
04205 { 04206 char port[10]; 04207 char regseconds[20]; 04208 04209 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04210 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 04211 ast_update_realtime("iaxpeers", "name", peername, 04212 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 04213 "regseconds", regseconds, SENTINEL); 04214 }
| static struct iax2_user * realtime_user | ( | const char * | username, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4133 of file chan_iax2.c.
References ao2_link, ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_set_flag, ast_test_flag, ast_variables_destroy(), build_user(), hp, IAX_RTCACHEFRIENDS, IAX_TEMPONLY, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.
Referenced by calltoken_required(), and check_access().
04134 { 04135 struct ast_variable *var; 04136 struct ast_variable *tmp; 04137 struct iax2_user *user=NULL; 04138 04139 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04140 if (!var) 04141 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04142 if (!var && sin) { 04143 char porta[6]; 04144 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04145 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04146 if (!var) 04147 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04148 } 04149 if (!var) { /* Last ditch effort */ 04150 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04151 /*!\note 04152 * If this one loaded something, then we need to ensure that the host 04153 * field matched. The only reason why we can't have this as a criteria 04154 * is because we only have the IP address and the host field might be 04155 * set as a name (and the reverse PTR might not match). 04156 */ 04157 if (var) { 04158 for (tmp = var; tmp; tmp = tmp->next) { 04159 if (!strcasecmp(tmp->name, "host")) { 04160 struct ast_hostent ahp; 04161 struct hostent *hp; 04162 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04163 /* No match */ 04164 ast_variables_destroy(var); 04165 var = NULL; 04166 } 04167 break; 04168 } 04169 } 04170 } 04171 } 04172 if (!var) 04173 return NULL; 04174 04175 tmp = var; 04176 while(tmp) { 04177 /* Make sure it's not a peer only... */ 04178 if (!strcasecmp(tmp->name, "type")) { 04179 if (strcasecmp(tmp->value, "friend") && 04180 strcasecmp(tmp->value, "user")) { 04181 return NULL; 04182 } 04183 } 04184 tmp = tmp->next; 04185 } 04186 04187 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 04188 04189 ast_variables_destroy(var); 04190 04191 if (!user) 04192 return NULL; 04193 04194 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 04195 ast_set_flag(user, IAX_RTCACHEFRIENDS); 04196 ao2_link(users, user); 04197 } else { 04198 ast_set_flag(user, IAX_TEMPONLY); 04199 } 04200 04201 return user; 04202 }
| static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8127 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_inet_ntoa(), ast_sched_del(), ast_test_flag, ast_verb, iax2_peer::expire, expire_registry(), iax2_peer::expiry, iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), IAX_TEMPONLY, iax2_peer::name, peer_ref(), peer_unref(), and register_peer_exten().
Referenced by realtime_peer(), and set_config().
08128 { 08129 char data[80]; 08130 struct in_addr in; 08131 char *c, *d; 08132 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 08133 c = strchr(data, ':'); 08134 if (c) { 08135 *c = '\0'; 08136 c++; 08137 if (inet_aton(data, &in)) { 08138 d = strchr(c, ':'); 08139 if (d) { 08140 *d = '\0'; 08141 d++; 08142 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name, 08143 ast_inet_ntoa(in), atoi(c), atoi(d)); 08144 iax2_poke_peer(p, 0); 08145 p->expiry = atoi(d); 08146 memset(&p->addr, 0, sizeof(p->addr)); 08147 p->addr.sin_family = AF_INET; 08148 p->addr.sin_addr = in; 08149 p->addr.sin_port = htons(atoi(c)); 08150 if (p->expire > -1) { 08151 if (!ast_sched_del(sched, p->expire)) { 08152 p->expire = -1; 08153 peer_unref(p); 08154 } 08155 } 08156 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08157 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08158 if (p->expire == -1) 08159 peer_unref(p); 08160 if (iax2_regfunk) 08161 iax2_regfunk(p->name, 1); 08162 register_peer_exten(p, 1); 08163 } 08164 08165 } 08166 } 08167 } 08168 }
| static void register_peer_exten | ( | struct iax2_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Definition at line 8046 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(), peer_destructor(), reg_source_db(), and update_registry().
08047 { 08048 char multi[256]; 08049 char *stringp, *ext; 08050 if (!ast_strlen_zero(regcontext)) { 08051 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08052 stringp = multi; 08053 while((ext = strsep(&stringp, "&"))) { 08054 if (onoff) { 08055 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08056 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08057 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08058 } else 08059 ast_context_remove_extension(regcontext, ext, 1, NULL); 08060 } 08061 } 08062 }
| static int register_verify | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Verify inbound registration.
Definition at line 7436 of file chan_iax2.c.
References ast_apply_ha(), ast_check_signature, ast_clear_flag, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_inet_ntoa(), ast_key_get, AST_KEY_PUBLIC, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, iax2_peer::authmethods, chan_iax2_pvt::expiry, find_peer(), iax2_peer::ha, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_DYNAMIC, IAX_STATE_AUTHENTICATED, iax2_peer::inkeys, LOG_NOTICE, LOG_WARNING, iax_ies::md5_result, MD5Final(), MD5Init(), MD5Update(), iax2_peer::name, iax_ies::password, peer_unref(), iax_ies::refresh, iax_ies::rsa_result, iax2_peer::secret, secret, strsep(), and iax_ies::username.
Referenced by socket_process().
07437 { 07438 char requeststr[256] = ""; 07439 char peer[256] = ""; 07440 char md5secret[256] = ""; 07441 char rsasecret[256] = ""; 07442 char secret[256] = ""; 07443 struct iax2_peer *p = NULL; 07444 struct ast_key *key; 07445 char *keyn; 07446 int x; 07447 int expire = 0; 07448 int res = -1; 07449 07450 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07451 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 07452 if (ies->username) 07453 ast_copy_string(peer, ies->username, sizeof(peer)); 07454 if (ies->password) 07455 ast_copy_string(secret, ies->password, sizeof(secret)); 07456 if (ies->md5_result) 07457 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07458 if (ies->rsa_result) 07459 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07460 if (ies->refresh) 07461 expire = ies->refresh; 07462 07463 if (ast_strlen_zero(peer)) { 07464 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 07465 return -1; 07466 } 07467 07468 /* SLD: first call to lookup peer during registration */ 07469 ast_mutex_unlock(&iaxsl[callno]); 07470 p = find_peer(peer, 1); 07471 ast_mutex_lock(&iaxsl[callno]); 07472 if (!p || !iaxs[callno]) { 07473 if (iaxs[callno]) { 07474 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 07475 /* Anything, as long as it's non-blank */ 07476 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07477 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 07478 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 07479 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 07480 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 07481 * to be plaintext, indicating it is an authmethod used by other peers on the system. 07482 * 07483 * If none of these cases exist, res will be returned as 0 without authentication indicating 07484 * an AUTHREQ needs to be sent out. */ 07485 07486 if (ast_strlen_zero(iaxs[callno]->challenge) && 07487 !(!ast_strlen_zero(secret) && plaintext)) { 07488 /* by setting res to 0, an REGAUTH will be sent */ 07489 res = 0; 07490 } 07491 } 07492 if (authdebug && !p) 07493 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07494 goto return_unref; 07495 } 07496 07497 if (!ast_test_flag(p, IAX_DYNAMIC)) { 07498 if (authdebug) 07499 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07500 goto return_unref; 07501 } 07502 07503 if (!ast_apply_ha(p->ha, sin)) { 07504 if (authdebug) 07505 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 07506 goto return_unref; 07507 } 07508 ast_string_field_set(iaxs[callno], secret, p->secret); 07509 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 07510 /* Check secret against what we have on file */ 07511 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 07512 if (!ast_strlen_zero(p->inkeys)) { 07513 char tmpkeys[256]; 07514 char *stringp=NULL; 07515 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 07516 stringp=tmpkeys; 07517 keyn = strsep(&stringp, ":"); 07518 while(keyn) { 07519 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07520 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 07521 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07522 break; 07523 } else if (!key) 07524 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 07525 keyn = strsep(&stringp, ":"); 07526 } 07527 if (!keyn) { 07528 if (authdebug) 07529 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 07530 goto return_unref; 07531 } 07532 } else { 07533 if (authdebug) 07534 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 07535 goto return_unref; 07536 } 07537 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 07538 struct MD5Context md5; 07539 unsigned char digest[16]; 07540 char *tmppw, *stringp; 07541 07542 tmppw = ast_strdupa(p->secret); 07543 stringp = tmppw; 07544 while((tmppw = strsep(&stringp, ";"))) { 07545 MD5Init(&md5); 07546 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 07547 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07548 MD5Final(digest, &md5); 07549 for (x=0;x<16;x++) 07550 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07551 if (!strcasecmp(requeststr, md5secret)) 07552 break; 07553 } 07554 if (tmppw) { 07555 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07556 } else { 07557 if (authdebug) 07558 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 07559 goto return_unref; 07560 } 07561 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 07562 /* They've provided a plain text password and we support that */ 07563 if (strcmp(secret, p->secret)) { 07564 if (authdebug) 07565 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 07566 goto return_unref; 07567 } else 07568 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07569 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 07570 /* if challenge has been sent, but no challenge response if given, reject. */ 07571 goto return_unref; 07572 } 07573 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 07574 07575 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 07576 res = 0; 07577 07578 return_unref: 07579 if (iaxs[callno]) { 07580 ast_string_field_set(iaxs[callno], peer, peer); 07581 07582 /* Choose lowest expiry number */ 07583 if (expire && (expire < iaxs[callno]->expiry)) { 07584 iaxs[callno]->expiry = expire; 07585 } 07586 } 07587 07588 if (p) { 07589 peer_unref(p); 07590 } 07591 return res; 07592 }
| static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8335 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_strdupa, ast_string_field_set, chan_iax2_pvt::authmethods, iax2_peer::authmethods, iax_ie_data::buf, find_peer(), IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_COMMAND_REGAUTH, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_AUTHMETHODS, IAX_IE_CHALLENGE, IAX_IE_USERNAME, peer_unref(), iax_ie_data::pos, and send_command().
Referenced by socket_process().
08336 { 08337 struct iax_ie_data ied; 08338 struct iax2_peer *p; 08339 char challenge[10]; 08340 const char *peer_name; 08341 int sentauthmethod; 08342 08343 peer_name = ast_strdupa(iaxs[callno]->peer); 08344 08345 /* SLD: third call to find_peer in registration */ 08346 ast_mutex_unlock(&iaxsl[callno]); 08347 if ((p = find_peer(peer_name, 1))) { 08348 last_authmethod = p->authmethods; 08349 } 08350 08351 ast_mutex_lock(&iaxsl[callno]); 08352 if (!iaxs[callno]) 08353 goto return_unref; 08354 08355 memset(&ied, 0, sizeof(ied)); 08356 /* The selection of which delayed reject is sent may leak information, 08357 * if it sets a static response. For example, if a host is known to only 08358 * use MD5 authentication, then an RSA response would indicate that the 08359 * peer does not exist, and vice-versa. 08360 * Therefore, we use whatever the last peer used (which may vary over the 08361 * course of a server, which should leak minimal information). */ 08362 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08363 if (!p) { 08364 iaxs[callno]->authmethods = sentauthmethod; 08365 } 08366 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08367 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08368 /* Build the challenge */ 08369 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08370 ast_string_field_set(iaxs[callno], challenge, challenge); 08371 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08372 } 08373 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08374 08375 return_unref: 08376 if (p) { 08377 peer_unref(p); 08378 } 08379 08380 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08381 }
| static int registry_rerequest | ( | struct iax_ies * | ies, | |
| int | callno, | |||
| struct sockaddr_in * | sin | |||
| ) | [static] |
Definition at line 8383 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_strlen_zero(), authenticate(), iax_ies::authmethods, iax_ie_data::buf, iax_ies::challenge, IAX_COMMAND_REGREQ, iax_ie_append_short(), iax_ie_append_str(), IAX_IE_REFRESH, IAX_IE_USERNAME, inaddrcmp(), LOG_NOTICE, LOG_WARNING, iax_ie_data::pos, iax2_registry::refresh, chan_iax2_pvt::reg, REG_STATE_AUTHSENT, REG_STATE_NOAUTH, iax2_registry::regstate, iax2_registry::secret, send_command(), iax2_registry::username, and iax_ies::username.
Referenced by socket_process().
08384 { 08385 struct iax2_registry *reg; 08386 /* Start pessimistic */ 08387 struct iax_ie_data ied; 08388 char peer[256] = ""; 08389 char challenge[256] = ""; 08390 int res; 08391 int authmethods = 0; 08392 if (ies->authmethods) 08393 authmethods = ies->authmethods; 08394 if (ies->username) 08395 ast_copy_string(peer, ies->username, sizeof(peer)); 08396 if (ies->challenge) 08397 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 08398 memset(&ied, 0, sizeof(ied)); 08399 reg = iaxs[callno]->reg; 08400 if (reg) { 08401 if (inaddrcmp(®->addr, sin)) { 08402 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08403 return -1; 08404 } 08405 if (ast_strlen_zero(reg->secret)) { 08406 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 08407 reg->regstate = REG_STATE_NOAUTH; 08408 return -1; 08409 } 08410 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08411 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08412 if (reg->secret[0] == '[') { 08413 char tmpkey[256]; 08414 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 08415 tmpkey[strlen(tmpkey) - 1] = '\0'; 08416 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 08417 } else 08418 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 08419 if (!res) { 08420 reg->regstate = REG_STATE_AUTHSENT; 08421 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 08422 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08423 } else 08424 return -1; 08425 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 08426 } else 08427 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 08428 return -1; 08429 }
| static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 6603 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_cli_iax2_show_registry().
06604 { 06605 switch(regstate) { 06606 case REG_STATE_UNREGISTERED: 06607 return "Unregistered"; 06608 case REG_STATE_REGSENT: 06609 return "Request Sent"; 06610 case REG_STATE_AUTHSENT: 06611 return "Auth. Sent"; 06612 case REG_STATE_REGISTERED: 06613 return "Registered"; 06614 case REG_STATE_REJECTED: 06615 return "Rejected"; 06616 case REG_STATE_TIMEOUT: 06617 return "Timeout"; 06618 case REG_STATE_NOAUTH: 06619 return "No Authentication"; 06620 default: 06621 return "Unknown"; 06622 } 06623 }
| static int reload | ( | void | ) | [static] |
Definition at line 12804 of file chan_iax2.c.
References reload_config().
12805 { 12806 return reload_config(); 12807 }
| static int reload_config | ( | void | ) | [static] |
Definition at line 12755 of file chan_iax2.c.
References ao2_callback, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_unload_realtime(), config, debugaddr, iax2_do_register(), iax_provision_reload(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, poke_all_peers(), prune_addr_range_cb(), prune_peers(), prune_users(), reload_firmware(), set_config(), and set_peercnt_limit_all_cb().
Referenced by handle_cli_iax2_reload(), and reload().
12756 { 12757 static const char config[] = "iax.conf"; 12758 struct iax2_registry *reg; 12759 12760 if (set_config(config, 1) > 0) { 12761 prune_peers(); 12762 prune_users(); 12763 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 12764 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 12765 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 12766 trunk_timed = trunk_untimed = 0; 12767 trunk_nmaxmtu = trunk_maxmtu = 0; 12768 memset(&debugaddr, '\0', sizeof(debugaddr)); 12769 12770 AST_LIST_LOCK(®istrations); 12771 AST_LIST_TRAVERSE(®istrations, reg, entry) 12772 iax2_do_register(reg); 12773 AST_LIST_UNLOCK(®istrations); 12774 12775 /* Qualify hosts, too */ 12776 poke_all_peers(); 12777 } 12778 12779 reload_firmware(0); 12780 iax_provision_reload(1); 12781 ast_unload_realtime("iaxpeers"); 12782 12783 return 0; 12784 }
| static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 2958 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(), dir, errno, LOG_WARNING, and try_firmware().
Referenced by __unload_module(), load_module(), and reload_config().
02959 { 02960 struct iax_firmware *cur = NULL; 02961 DIR *fwd; 02962 struct dirent *de; 02963 char dir[256], fn[256]; 02964 02965 AST_LIST_LOCK(&firmwares); 02966 02967 /* Mark all as dead */ 02968 AST_LIST_TRAVERSE(&firmwares, cur, list) 02969 cur->dead = 1; 02970 02971 /* Now that we have marked them dead... load new ones */ 02972 if (!unload) { 02973 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 02974 fwd = opendir(dir); 02975 if (fwd) { 02976 while((de = readdir(fwd))) { 02977 if (de->d_name[0] != '.') { 02978 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 02979 if (!try_firmware(fn)) { 02980 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 02981 } 02982 } 02983 } 02984 closedir(fwd); 02985 } else 02986 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 02987 } 02988 02989 /* Clean up leftovers */ 02990 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 02991 if (!cur->dead) 02992 continue; 02993 AST_LIST_REMOVE_CURRENT(list); 02994 destroy_firmware(cur); 02995 } 02996 AST_LIST_TRAVERSE_SAFE_END; 02997 02998 AST_LIST_UNLOCK(&firmwares); 02999 }
| static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1878 of file chan_iax2.c.
References ao2_unlink, ast_log(), LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by complete_transfer(), iax2_destroy(), resend_with_token(), and socket_process().
01879 { 01880 if (!pvt->peercallno) { 01881 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01882 return; 01883 } 01884 01885 ao2_unlink(iax_peercallno_pvts, pvt); 01886 }
| static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1859 of file chan_iax2.c.
References ao2_unlink, ast_log(), LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by complete_transfer(), and iax2_destroy().
01860 { 01861 if (!pvt->transfercallno) { 01862 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01863 return; 01864 } 01865 01866 ao2_unlink(iax_transfercallno_pvts, pvt); 01867 }
| static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2364 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().
02365 { 02366 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02367 02368 /* the callno_pool container is locked here primarily to ensure thread 02369 * safety of the total_nonval_callno_used check and decrement */ 02370 ao2_lock(callno_pool); 02371 02372 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02373 total_nonval_callno_used--; 02374 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02375 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02376 } 02377 02378 if (callno_entry->callno < TRUNK_CALL_START) { 02379 ao2_link(callno_pool, callno_entry); 02380 } else { 02381 ao2_link(callno_pool_trunk, callno_entry); 02382 } 02383 ao2_ref(callno_entry, -1); /* only container ref remains */ 02384 02385 ao2_unlock(callno_pool); 02386 return 0; 02387 }
| static void requirecalltoken_mark_auto | ( | const char * | name, | |
| int | subclass | |||
| ) | [static] |
Definition at line 4492 of file chan_iax2.c.
References ast_strlen_zero(), CALLTOKEN_AUTO, iax2_peer::calltoken_required, iax2_user::calltoken_required, CALLTOKEN_YES, find_peer(), find_user(), IAX_COMMAND_NEW, peer_unref(), and user_unref().
Referenced by handle_call_token().
04493 { 04494 struct iax2_user *user = NULL; 04495 struct iax2_peer *peer = NULL; 04496 04497 if (ast_strlen_zero(name)) { 04498 return; /* no username given */ 04499 } 04500 04501 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04502 user->calltoken_required = CALLTOKEN_YES; 04503 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04504 peer->calltoken_required = CALLTOKEN_YES; 04505 } 04506 04507 if (peer) { 04508 peer_unref(peer); 04509 } 04510 if (user) { 04511 user_unref(user); 04512 } 04513 }
| static void resend_with_token | ( | int | callno, | |
| struct iax_frame * | f, | |||
| const char * | newtoken | |||
| ) | [static] |
Definition at line 4408 of file chan_iax2.c.
References iax_frame::af, chan_iax2_pvt::aseqno, AST_FRAME_IAX, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, iax_ie_data::buf, chan_iax2_pvt::calltoken_ie_len, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, iax_frame::encmethods, ast_frame::frametype, iax2_allow_new(), iax2_frame_free(), iax_ie_append_str(), IAX_IE_CALLTOKEN, chan_iax2_pvt::iseqno, chan_iax2_pvt::oseqno, chan_iax2_pvt::peercallno, remove_by_peercallno(), chan_iax2_pvt::rseqno, send_command(), and ast_frame::subclass.
Referenced by socket_process().
04409 { 04410 struct chan_iax2_pvt *pvt = iaxs[callno]; 04411 int frametype = f->af.frametype; 04412 int subclass = f->af.subclass; 04413 struct { 04414 struct ast_iax2_full_hdr fh; 04415 struct iax_ie_data ied; 04416 } data = { 04417 .ied.buf = { 0 }, 04418 .ied.pos = 0, 04419 }; 04420 /* total len - header len gives us the frame's IE len */ 04421 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04422 04423 if (!pvt) { 04424 return; /* this should not be possible if called from socket_process() */ 04425 } 04426 04427 /* 04428 * Check to make sure last frame sent is valid for call token resend 04429 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04430 * 2. Frame should _NOT_ already have a destination callno 04431 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04432 * 4. Pvt must have a calltoken_ie_len which represents the number of 04433 * bytes at the end of the frame used for the previous calltoken ie. 04434 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04435 * 6. Total length of f->data must be _LESS_ than size of our data struct 04436 * because f->data must be able to fit within data. 04437 */ 04438 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04439 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04440 (f->datalen > sizeof(data))) { 04441 04442 return; /* ignore resend, token was not valid for the dialog */ 04443 } 04444 04445 /* token is valid 04446 * 1. Copy frame data over 04447 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04448 * NOTE: Having the ie always be last is not protocol specified, 04449 * it is only an implementation choice. Since we only expect the ie to 04450 * be last for frames we have sent, this can no way be affected by 04451 * another end point. 04452 * 3. Remove frame from queue 04453 * 4. Free old frame 04454 * 5. Clear previous seqnos 04455 * 6. Resend with CALLTOKEN ie. 04456 */ 04457 04458 /* ---1.--- */ 04459 memcpy(&data, f->data, f->datalen); 04460 data.ied.pos = ie_data_pos; 04461 04462 /* ---2.--- */ 04463 /* move to the beginning of the calltoken ie so we can write over it */ 04464 data.ied.pos -= pvt->calltoken_ie_len; 04465 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04466 04467 /* make sure to update token length incase it ever has to be stripped off again */ 04468 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04469 04470 /* ---3.--- */ 04471 AST_LIST_LOCK(&frame_queue); 04472 AST_LIST_REMOVE(&frame_queue, f, list); 04473 AST_LIST_UNLOCK(&frame_queue); 04474 04475 /* ---4.--- */ 04476 iax2_frame_free(f); 04477 04478 /* ---5.--- */ 04479 pvt->oseqno = 0; 04480 pvt->rseqno = 0; 04481 pvt->iseqno = 0; 04482 pvt->aseqno = 0; 04483 if (pvt->peercallno) { 04484 remove_by_peercallno(pvt); 04485 pvt->peercallno = 0; 04486 } 04487 04488 /* ---6.--- */ 04489 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04490 }
Definition at line 8864 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, iax_ies::ospblocklength, and iax_ies::osptokenblock.
Referenced by socket_process().
08865 { 08866 int i; 08867 unsigned int length, offset = 0; 08868 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 08869 08870 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 08871 length = ies->ospblocklength[i]; 08872 if (length != 0) { 08873 if (length > IAX_MAX_OSPBLOCK_SIZE) { 08874 /* OSP token block length wrong, clear buffer */ 08875 offset = 0; 08876 break; 08877 } else { 08878 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 08879 offset += length; 08880 } 08881 } else { 08882 break; 08883 } 08884 } 08885 *(full_osptoken + offset) = '\0'; 08886 if (strlen(full_osptoken) != offset) { 08887 /* OSP token length wrong, clear buffer */ 08888 *full_osptoken = '\0'; 08889 } 08890 08891 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 08892 }
Definition at line 8853 of file chan_iax2.c.
References iax_frame::callno, iax_rr::delay, iax_rr::dropped, 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().
08854 { 08855 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 08856 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 08857 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 08858 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 08859 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 08860 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 08861 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 08862 }
| static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
| struct callno_entry * | callno_entry | |||
| ) | [static] |
Definition at line 2436 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(), and replace_callno().
Referenced by pvt_destructor().
02437 { 02438 int i; 02439 struct peercnt *peercnt; 02440 struct peercnt tmp = { 02441 .addr = sin->sin_addr.s_addr, 02442 }; 02443 02444 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02445 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02446 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02447 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02448 if (i == -1) { 02449 ao2_ref(peercnt, -1); 02450 } 02451 } 02452 02453 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02454 }
| static void* sched_thread | ( | void * | ignore | ) | [static] |
Definition at line 11468 of file chan_iax2.c.
References ast_cond_timedwait(), ast_debug, ast_mutex_lock(), ast_mutex_unlock(), ast_samp2tv(), ast_sched_runq(), ast_sched_wait(), ast_tvadd(), ast_tvnow(), and sched_lock.
Referenced by start_network_thread().
11469 { 11470 int count; 11471 int res; 11472 struct timeval wait; 11473 struct timespec ts; 11474 11475 for (;;) { 11476 pthread_testcancel(); 11477 ast_mutex_lock(&sched_lock); 11478 res = ast_sched_wait(sched); 11479 if ((res > 1000) || (res < 0)) 11480 res = 1000; 11481 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(res, 1000)); 11482 ts.tv_sec = wait.tv_sec; 11483 ts.tv_nsec = wait.tv_usec * 1000; 11484 ast_cond_timedwait(&sched_cond, &sched_lock, &ts); 11485 ast_mutex_unlock(&sched_lock); 11486 pthread_testcancel(); 11487 11488 count = ast_sched_runq(sched); 11489 if (count >= 20) 11490 ast_debug(1, "chan_iax2: ast_sched_runq ran %d scheduled tasks all at once\n", count); 11491 } 11492 11493 return NULL; 11494 }
| static int schedule_delivery | ( | struct iax_frame * | fr, | |
| int | updatehistory, | |||
| int | fromtrunk, | |||
| unsigned int * | tsout | |||
| ) | [static] |
Definition at line 3868 of file chan_iax2.c.
References __do_deliver(), iax_frame::af, ast_bridged_channel(), AST_CHAN_TP_WANTSJITTER, ast_codec_get_samples(), ast_debug, ast_format_rate(), AST_FRAME_CNG, AST_FRAME_VOICE, ast_samp2tv(), AST_SCHED_DEL, ast_test_flag, ast_tv(), ast_tvadd(), ast_tvzero(), calc_rxstamp(), iax_frame::callno, jb_frame::data, ast_frame::delivery, ast_frame::frametype, iax2_frame_free(), IAX_FORCEJITTERBUF, IAX_USEJITTERBUF, chan_iax2_pvt::jb, JB_DROP, jb_getall(), JB_OK, jb_put(), jb_reset(), JB_SCHED, JB_TYPE_CONTROL, JB_TYPE_SILENCE, JB_TYPE_VOICE, chan_iax2_pvt::jbid, chan_iax2_pvt::owner, ast_channel_tech::properties, chan_iax2_pvt::rxcore, ast_frame::subclass, ast_channel::tech, iax_frame::ts, unwrap_timestamp(), and update_jbsched().
Referenced by socket_process(), and socket_process_meta().
03869 { 03870 int type, len; 03871 int ret; 03872 int needfree = 0; 03873 struct ast_channel *owner = NULL; 03874 struct ast_channel *bridge = NULL; 03875 03876 /* Attempt to recover wrapped timestamps */ 03877 unwrap_timestamp(fr); 03878 03879 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 03880 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 03881 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 03882 else { 03883 #if 0 03884 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 03885 #endif 03886 fr->af.delivery = ast_tv(0,0); 03887 } 03888 03889 type = JB_TYPE_CONTROL; 03890 len = 0; 03891 03892 if(fr->af.frametype == AST_FRAME_VOICE) { 03893 type = JB_TYPE_VOICE; 03894 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000); 03895 } else if(fr->af.frametype == AST_FRAME_CNG) { 03896 type = JB_TYPE_SILENCE; 03897 } 03898 03899 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 03900 if (tsout) 03901 *tsout = fr->ts; 03902 __do_deliver(fr); 03903 return -1; 03904 } 03905 03906 if ((owner = iaxs[fr->callno]->owner)) 03907 bridge = ast_bridged_channel(owner); 03908 03909 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 03910 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 03911 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 03912 jb_frame frame; 03913 03914 /* deliver any frames in the jb */ 03915 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 03916 __do_deliver(frame.data); 03917 /* __do_deliver() can make the call disappear */ 03918 if (!iaxs[fr->callno]) 03919 return -1; 03920 } 03921 03922 jb_reset(iaxs[fr->callno]->jb); 03923 03924 AST_SCHED_DEL(sched, iaxs[fr->callno]->jbid); 03925 03926 /* deliver this frame now */ 03927 if (tsout) 03928 *tsout = fr->ts; 03929 __do_deliver(fr); 03930 return -1; 03931 } 03932 03933 /* insert into jitterbuffer */ 03934 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 03935 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 03936 calc_rxstamp(iaxs[fr->callno],fr->ts)); 03937 if (ret == JB_DROP) { 03938 needfree++; 03939 } else if (ret == JB_SCHED) { 03940 update_jbsched(iaxs[fr->callno]); 03941 } 03942 if (tsout) 03943 *tsout = fr->ts; 03944 if (needfree) { 03945 /* Free our iax frame */ 03946 iax2_frame_free(fr); 03947 return -1; 03948 } 03949 return 0; 03950 }
| static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1562 of file chan_iax2.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), iax2_destroy(), LOG_DEBUG, option_debug, and PTR_TO_CALLNO.
Referenced by iax2_hangup().
01563 { 01564 unsigned short callno = PTR_TO_CALLNO(vid); 01565 ast_mutex_lock(&iaxsl[callno]); 01566 if (iaxs[callno]) { 01567 if (option_debug) { 01568 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01569 } 01570 iax2_destroy(callno); 01571 } 01572 ast_mutex_unlock(&iaxsl[callno]); 01573 return 0; 01574 }
| 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 4372 of file chan_iax2.c.
References AST_FRAME_IAX, iax_ie_data::buf, compress_subclass(), and iax_ie_data::pos.
Referenced by handle_call_token(), and socket_process().
04375 { 04376 struct { 04377 struct ast_iax2_full_hdr f; 04378 struct iax_ie_data ied; 04379 } data; 04380 size_t size = sizeof(struct ast_iax2_full_hdr); 04381 04382 if (ied) { 04383 size += ied->pos; 04384 memcpy(&data.ied, ied->buf, ied->pos); 04385 } 04386 04387 data.f.scallno = htons(0x8000 | callno); 04388 data.f.dcallno = htons(dcallno); 04389 data.f.ts = htonl(ts); 04390 data.f.iseqno = seqno; 04391 data.f.oseqno = 0; 04392 data.f.type = AST_FRAME_IAX; 04393 data.f.csub = compress_subclass(command); 04394 04395 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04396 }
| static int send_command | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 6988 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().
06989 { 06990 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 06991 }
| 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 7007 of file chan_iax2.c.
References __send_command(), chan_iax2_pvt::callno, and iax2_predestroy().
Referenced by __auth_reject(), __auto_hangup(), authenticate_request(), iax2_hangup(), socket_process(), and update_registry().
07008 { 07009 int call_num = i->callno; 07010 /* It is assumed that the callno has already been locked */ 07011 iax2_predestroy(i->callno); 07012 if (!iaxs[call_num]) 07013 return -1; 07014 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07015 }
| static int send_command_immediate | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 7017 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07018 { 07019 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07020 }
| static int send_command_locked | ( | unsigned short | callno, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen, | |||
| int | seqno | |||
| ) | [static] |
Definition at line 6993 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_unlock(), and send_command().
Referenced by iax2_answer(), iax2_digit_begin(), iax2_digit_end(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), and iax2_transfer().
06994 { 06995 int res; 06996 ast_mutex_lock(&iaxsl[callno]); 06997 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 06998 ast_mutex_unlock(&iaxsl[callno]); 06999 return res; 07000 }
| static int send_command_transfer | ( | struct chan_iax2_pvt * | i, | |
| char | type, | |||
| int | command, | |||
| unsigned int | ts, | |||
| const unsigned char * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 7022 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07023 { 07024 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07025 }
| static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1360 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01361 { 01362 #ifdef SCHED_MULTITHREADED 01363 if (schedule_action(__send_lagrq, data)) 01364 #endif 01365 __send_lagrq(data); 01366 01367 return 0; 01368 }
| static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3071 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax2_trunk_peer::addr, ast_debug, ast_inet_ntoa(), iax_frame::callno, iax_frame::data, iax_frame::datalen, errno, handle_error(), iax_showframe(), chan_iax2_pvt::peercallno, iax2_trunk_peer::sockfd, chan_iax2_pvt::transfer, transfer, iax_frame::transfer, and iax_frame::ts.
Referenced by __attempt_transmit(), iax2_send(), network_thread(), and vnak_retransmit().
03072 { 03073 int res; 03074 int callno = f->callno; 03075 03076 /* Don't send if there was an error, but return error instead */ 03077 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03078 return -1; 03079 03080 /* Called with iaxsl held */ 03081 if (iaxdebug) 03082 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)); 03083 03084 if (f->transfer) { 03085 if (iaxdebug) 03086 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03087 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03088 } else { 03089 if (iaxdebug) 03090 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03091 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03092 } 03093 if (res < 0) { 03094 if (iaxdebug) 03095 ast_debug(1, "Received error: %s\n", strerror(errno)); 03096 handle_error(); 03097 } else 03098 res = 0; 03099 03100 return res; 03101 }
| static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1315 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01316 { 01317 #ifdef SCHED_MULTITHREADED 01318 if (schedule_action(__send_ping, data)) 01319 #endif 01320 __send_ping(data); 01321 01322 return 0; 01323 }
| 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 1584 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(), s, and chan_iax2_pvt::signaling_queue.
Referenced by socket_process().
01585 { 01586 struct signaling_queue_entry *s = NULL; 01587 01588 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01589 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01590 free_signaling_queue_entry(s); 01591 } 01592 pvt->hold_signaling = 0; 01593 }
| static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [static] |
Definition at line 8566 of file chan_iax2.c.
References iax2_trunk_peer::addr, iax_frame::afdata, ast_debug, ast_inet_ntoa(), ast_test_flag, calc_txpeerstamp(), iax2_trunk_peer::calls, ast_iax2_meta_hdr::cmddata, iax_frame::data, ast_iax2_meta_hdr::data, iax_frame::datalen, iax_frame::direction, DIRECTION_OUTGRESS, IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_TRUNKTIMESTAMPS, ast_iax2_meta_hdr::metacmd, iax_frame::retrans, iax2_trunk_peer::sockfd, iax_frame::transfer, transmit_trunk(), iax2_trunk_peer::trunkdata, iax2_trunk_peer::trunkdatalen, ast_iax2_meta_trunk_hdr::ts, and ast_iax2_meta_hdr::zeros.
Referenced by iax2_trunk_queue(), and timing_read().
08567 { 08568 int res = 0; 08569 struct iax_frame *fr; 08570 struct ast_iax2_meta_hdr *meta; 08571 struct ast_iax2_meta_trunk_hdr *mth; 08572 int calls = 0; 08573 08574 /* Point to frame */ 08575 fr = (struct iax_frame *)tpeer->trunkdata; 08576 /* Point to meta data */ 08577 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 08578 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 08579 if (tpeer->trunkdatalen) { 08580 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 08581 meta->zeros = 0; 08582 meta->metacmd = IAX_META_TRUNK; 08583 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 08584 meta->cmddata = IAX_META_TRUNK_MINI; 08585 else 08586 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 08587 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 08588 /* And the rest of the ast_iax2 header */ 08589 fr->direction = DIRECTION_OUTGRESS; 08590 fr->retrans = -1; 08591 fr->transfer = 0; 08592 /* Any appropriate call will do */ 08593 fr->data = fr->afdata; 08594 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 08595 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 08596 calls = tpeer->calls; 08597 #if 0 08598 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)); 08599 #endif 08600 /* Reset transmit trunk side data */ 08601 tpeer->trunkdatalen = 0; 08602 tpeer->calls = 0; 08603 } 08604 if (res < 0) 08605 return res; 08606 return calls; 08607 }
| static int set_config | ( | const char * | config_file, | |
| int | reload | |||
| ) | [static] |
Load configuration.
Definition at line 12322 of file chan_iax2.c.
References add_calltoken_ignore(), ao2_link, ast_category_browse(), ast_cdr_amaflags2int(), ast_clear_flag, 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_flag, ast_set_flag, ast_set_flags_to, ast_str2cos(), ast_str2tos(), ast_strlen_zero(), ast_test_flag, ast_true(), ast_variable_browse(), ast_variable_retrieve(), ast_verb, build_callno_limits(), build_peer(), build_user(), capability, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_ENCRYPT_KEYROTATE, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_RTAUTOCLEAR, IAX_RTCACHEFRIENDS, IAX_RTIGNOREREGEXPIRE, IAX_RTUPDATE, IAX_SHRINKCALLERID, IAX_TRANSFERMEDIA, IAX_TRUNKTIMESTAMPS, IAX_USEJITTERBUF, iaxmaxthreadcount, iaxthreadcount, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, MAX_TRUNK_MTU, MAX_TRUNKDATA, ast_variable::name, ast_variable::next, peer_unref(), prefs, qos, reg_source_db(), secret, set_config_destroy(), socket_read(), user_unref(), and ast_variable::value.
Referenced by load_module(), and reload_config().
12323 { 12324 struct ast_config *cfg, *ucfg; 12325 int capability=iax2_capability; 12326 struct ast_variable *v; 12327 char *cat; 12328 const char *utype; 12329 const char *tosval; 12330 int format; 12331 int portno = IAX_DEFAULT_PORTNO; 12332 int x; 12333 int mtuv; 12334 struct iax2_user *user; 12335 struct iax2_peer *peer; 12336 struct ast_netsock *ns; 12337 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 12338 #if 0 12339 static unsigned short int last_port=0; 12340 #endif 12341 12342 cfg = ast_config_load(config_file, config_flags); 12343 12344 if (!cfg) { 12345 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 12346 return -1; 12347 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 12348 ucfg = ast_config_load("users.conf", config_flags); 12349 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 12350 return 0; 12351 /* Otherwise we need to reread both files */ 12352 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12353 cfg = ast_config_load(config_file, config_flags); 12354 } else { /* iax.conf changed, gotta reread users.conf, too */ 12355 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12356 ucfg = ast_config_load("users.conf", config_flags); 12357 } 12358 12359 if (reload) { 12360 set_config_destroy(); 12361 } 12362 12363 /* Reset global codec prefs */ 12364 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 12365 12366 /* Reset Global Flags */ 12367 memset(&globalflags, 0, sizeof(globalflags)); 12368 ast_set_flag(&globalflags, IAX_RTUPDATE); 12369 ast_set_flag(&globalflags, IAX_SHRINKCALLERID); 12370 12371 /* Turns on support for key rotation during encryption. */ 12372 iax2_encryption |= IAX_ENCRYPT_KEYROTATE; 12373 #ifdef SO_NO_CHECK 12374 nochecksums = 0; 12375 #endif 12376 /* Reset default parking lot */ 12377 default_parkinglot[0] = '\0'; 12378 12379 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12380 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12381 global_max_trunk_mtu = MAX_TRUNK_MTU; 12382 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 12383 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 12384 12385 maxauthreq = 3; 12386 12387 srvlookup = 0; 12388 12389 v = ast_variable_browse(cfg, "general"); 12390 12391 /* Seed initial tos value */ 12392 tosval = ast_variable_retrieve(cfg, "general", "tos"); 12393 if (tosval) { 12394 if (ast_str2tos(tosval, &qos.tos)) 12395 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 12396 } 12397 /* Seed initial cos value */ 12398 tosval = ast_variable_retrieve(cfg, "general", "cos"); 12399 if (tosval) { 12400 if (ast_str2cos(tosval, &qos.cos)) 12401 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 12402 } 12403 while(v) { 12404 if (!strcasecmp(v->name, "bindport")){ 12405 if (reload) 12406 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 12407 else 12408 portno = atoi(v->value); 12409 } else if (!strcasecmp(v->name, "pingtime")) 12410 ping_time = atoi(v->value); 12411 else if (!strcasecmp(v->name, "iaxthreadcount")) { 12412 if (reload) { 12413 if (atoi(v->value) != iaxthreadcount) 12414 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 12415 } else { 12416 iaxthreadcount = atoi(v->value); 12417 if (iaxthreadcount < 1) { 12418 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 12419 iaxthreadcount = 1; 12420 } else if (iaxthreadcount > 256) { 12421 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 12422 iaxthreadcount = 256; 12423 } 12424 } 12425 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 12426 if (reload) { 12427 AST_LIST_LOCK(&dynamic_list); 12428 iaxmaxthreadcount = atoi(v->value); 12429 AST_LIST_UNLOCK(&dynamic_list); 12430 } else { 12431 iaxmaxthreadcount = atoi(v->value); 12432 if (iaxmaxthreadcount < 0) { 12433 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 12434 iaxmaxthreadcount = 0; 12435 } else if (iaxmaxthreadcount > 256) { 12436 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 12437 iaxmaxthreadcount = 256; 12438 } 12439 } 12440 } else if (!strcasecmp(v->name, "nochecksums")) { 12441 #ifdef SO_NO_CHECK 12442 if (ast_true(v->value)) 12443 nochecksums = 1; 12444 else 12445 nochecksums = 0; 12446 #else 12447 if (ast_true(v->value)) 12448 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 12449 #endif 12450 } 12451 else if (!strcasecmp(v->name, "maxjitterbuffer")) 12452 maxjitterbuffer = atoi(v->value); 12453 else if (!strcasecmp(v->name, "resyncthreshold")) 12454 resyncthreshold = atoi(v->value); 12455 else if (!strcasecmp(v->name, "maxjitterinterps")) 12456 maxjitterinterps = atoi(v->value); 12457 else if (!strcasecmp(v->name, "jittertargetextra")) 12458 jittertargetextra = atoi(v->value); 12459 else if (!strcasecmp(v->name, "lagrqtime")) 12460 lagrq_time = atoi(v->value); 12461 else if (!strcasecmp(v->name, "maxregexpire")) 12462 max_reg_expire = atoi(v->value); 12463 else if (!strcasecmp(v->name, "minregexpire")) 12464 min_reg_expire = atoi(v->value); 12465 else if (!strcasecmp(v->name, "bindaddr")) { 12466 if (reload) { 12467 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 12468 } else { 12469 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 12470 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 12471 } else { 12472 if (strchr(v->value, ':')) 12473 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 12474 else 12475 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 12476 if (defaultsockfd < 0) 12477 defaultsockfd = ast_netsock_sockfd(ns); 12478 ast_netsock_unref(ns); 12479 } 12480 } 12481 } else if (!strcasecmp(v->name, "authdebug")) 12482 authdebug = ast_true(v->value); 12483 else if (!strcasecmp(v->name, "encryption")) 12484 iax2_encryption |= get_encrypt_methods(v->value); 12485 else if (!strcasecmp(v->name, "transfer")) { 12486 if (!strcasecmp(v->value, "mediaonly")) { 12487 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12488 } else if (ast_true(v->value)) { 12489 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12490 } else 12491 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12492 } else if (!strcasecmp(v->name, "codecpriority")) { 12493 if(!strcasecmp(v->value, "caller")) 12494 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 12495 else if(!strcasecmp(v->value, "disabled")) 12496 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 12497 else if(!strcasecmp(v->value, "reqonly")) { 12498 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 12499 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 12500 } 12501 } else if (!strcasecmp(v->name, "jitterbuffer")) 12502 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 12503 else if (!strcasecmp(v->name, "forcejitterbuffer")) 12504 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 12505 else if (!strcasecmp(v->name, "delayreject")) 12506 delayreject = ast_true(v->value); 12507 else if (!strcasecmp(v->name, "allowfwdownload")) 12508 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 12509 else if (!strcasecmp(v->name, "rtcachefriends")) 12510 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 12511 else if (!strcasecmp(v->name, "rtignoreregexpire")) 12512 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 12513 else if (!strcasecmp(v->name, "rtupdate")) 12514 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 12515 else if (!strcasecmp(v->name, "trunktimestamps")) 12516 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 12517 else if (!strcasecmp(v->name, "rtautoclear")) { 12518 int i = atoi(v->value); 12519 if(i > 0) 12520 global_rtautoclear = i; 12521 else 12522 i = 0; 12523 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 12524 } else if (!strcasecmp(v->name, "trunkfreq")) { 12525 trunkfreq = atoi(v->value); 12526 if (trunkfreq < 10) 12527 trunkfreq = 10; 12528 } else if (!strcasecmp(v->name, "trunkmtu")) { 12529 mtuv = atoi(v->value); 12530 if (mtuv == 0 ) 12531 global_max_trunk_mtu = 0; 12532 else if (mtuv >= 172 && mtuv < 4000) 12533 global_max_trunk_mtu = mtuv; 12534 else 12535 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 12536 mtuv, v->lineno); 12537 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 12538 trunkmaxsize = atoi(v->value); 12539 if (trunkmaxsize == 0) 12540 trunkmaxsize = MAX_TRUNKDATA; 12541 } else if (!strcasecmp(v->name, "autokill")) { 12542 if (sscanf(v->value, "%30d", &x) == 1) { 12543 if (x >= 0) 12544 autokill = x; 12545 else 12546 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 12547 } else if (ast_true(v->value)) { 12548 autokill = DEFAULT_MAXMS; 12549 } else { 12550 autokill = 0; 12551 } 12552 } else if (!strcasecmp(v->name, "bandwidth")) { 12553 if (!strcasecmp(v->value, "low")) { 12554 capability = IAX_CAPABILITY_LOWBANDWIDTH; 12555 } else if (!strcasecmp(v->value, "medium")) { 12556 capability = IAX_CAPABILITY_MEDBANDWIDTH; 12557 } else if (!strcasecmp(v->value, "high")) { 12558 capability = IAX_CAPABILITY_FULLBANDWIDTH; 12559 } else 12560 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 12561 } else if (!strcasecmp(v->name, "allow")) { 12562 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 12563 } else if (!strcasecmp(v->name, "disallow")) { 12564 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 12565 } else if (!strcasecmp(v->name, "register")) { 12566 iax2_register(v->value, v->lineno); 12567 } else if (!strcasecmp(v->name, "iaxcompat")) { 12568 iaxcompat = ast_true(v->value); 12569 } else if (!strcasecmp(v->name, "regcontext")) { 12570 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 12571 /* Create context if it doesn't exist already */ 12572 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 12573 } else if (!strcasecmp(v->name, "tos")) { 12574 if (ast_str2tos(v->value, &qos.tos)) 12575 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 12576 } else if (!strcasecmp(v->name, "cos")) { 12577 if (ast_str2cos(v->value, &qos.cos)) 12578 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 12579 } else if (!strcasecmp(v->name, "parkinglot")) { 12580 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 12581 } else if (!strcasecmp(v->name, "accountcode")) { 12582 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 12583 } else if (!strcasecmp(v->name, "mohinterpret")) { 12584 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 12585 } else if (!strcasecmp(v->name, "mohsuggest")) { 12586 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 12587 } else if (!strcasecmp(v->name, "amaflags")) { 12588 format = ast_cdr_amaflags2int(v->value); 12589 if (format < 0) { 12590 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12591 } else { 12592 amaflags = format; 12593 } 12594 } else if (!strcasecmp(v->name, "language")) { 12595 ast_copy_string(language, v->value, sizeof(language)); 12596 } else if (!strcasecmp(v->name, "maxauthreq")) { 12597 maxauthreq = atoi(v->value); 12598 if (maxauthreq < 0) 12599 maxauthreq = 0; 12600 } else if (!strcasecmp(v->name, "adsi")) { 12601 adsi = ast_true(v->value); 12602 } else if (!strcasecmp(v->name, "srvlookup")) { 12603 srvlookup = ast_true(v->value); 12604 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12605 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 12606 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 12607 } 12608 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 12609 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 12610 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); 12611 } 12612 } else if (!strcasecmp(v->name, "calltokenoptional")) { 12613 if (add_calltoken_ignore(v->value)) { 12614 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 12615 } 12616 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 12617 if (ast_true(v->value)) { 12618 ast_set_flag((&globalflags), IAX_SHRINKCALLERID); 12619 } else if (ast_false(v->value)) { 12620 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID); 12621 } else { 12622 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 12623 } 12624 }/*else if (strcasecmp(v->name,"type")) */ 12625 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12626 v = v->next; 12627 } 12628 12629 if (defaultsockfd < 0) { 12630 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 12631 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 12632 } else { 12633 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 12634 defaultsockfd = ast_netsock_sockfd(ns); 12635 ast_netsock_unref(ns); 12636 } 12637 } 12638 if (reload) { 12639 ast_netsock_release(outsock); 12640 outsock = ast_netsock_list_alloc(); 12641 if (!outsock) { 12642 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 12643 return -1; 12644 } 12645 ast_netsock_init(outsock); 12646 } 12647 12648 if (min_reg_expire > max_reg_expire) { 12649 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 12650 min_reg_expire, max_reg_expire, max_reg_expire); 12651 min_reg_expire = max_reg_expire; 12652 } 12653 iax2_capability = capability; 12654 12655 if (ucfg) { 12656 struct ast_variable *gen; 12657 int genhasiax; 12658 int genregisteriax; 12659 const char *hasiax, *registeriax; 12660 12661 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 12662 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 12663 gen = ast_variable_browse(ucfg, "general"); 12664 cat = ast_category_browse(ucfg, NULL); 12665 while (cat) { 12666 if (strcasecmp(cat, "general")) { 12667 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 12668 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 12669 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 12670 /* Start with general parameters, then specific parameters, user and peer */ 12671 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 12672 if (user) { 12673 ao2_link(users, user); 12674 user = user_unref(user); 12675 } 12676 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 12677 if (peer) { 12678 if (ast_test_flag(peer, IAX_DYNAMIC)) 12679 reg_source_db(peer); 12680 ao2_link(peers, peer); 12681 peer = peer_unref(peer); 12682 } 12683 } 12684 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 12685 char tmp[256]; 12686 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 12687 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 12688 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 12689 if (!host) 12690 host = ast_variable_retrieve(ucfg, "general", "host"); 12691 if (!username) 12692 username = ast_variable_retrieve(ucfg, "general", "username"); 12693 if (!secret) 12694 secret = ast_variable_retrieve(ucfg, "general", "secret"); 12695 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 12696 if (!ast_strlen_zero(secret)) 12697 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 12698 else 12699 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 12700 iax2_register(tmp, 0); 12701 } 12702 } 12703 } 12704 cat = ast_category_browse(ucfg, cat); 12705 } 12706 ast_config_destroy(ucfg); 12707 } 12708 12709 cat = ast_category_browse(cfg, NULL); 12710 while(cat) { 12711 if (strcasecmp(cat, "general")) { 12712 utype = ast_variable_retrieve(cfg, cat, "type"); 12713 if (!strcasecmp(cat, "callnumberlimits")) { 12714 build_callno_limits(ast_variable_browse(cfg, cat)); 12715 } else if (utype) { 12716 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 12717 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 12718 if (user) { 12719 ao2_link(users, user); 12720 user = user_unref(user); 12721 } 12722 } 12723 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 12724 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 12725 if (peer) { 12726 if (ast_test_flag(peer, IAX_DYNAMIC)) 12727 reg_source_db(peer); 12728 ao2_link(peers, peer); 12729 peer = peer_unref(peer); 12730 } 12731 } else if (strcasecmp(utype, "user")) { 12732 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 12733 } 12734 } else 12735 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 12736 } 12737 cat = ast_category_browse(cfg, cat); 12738 } 12739 ast_config_destroy(cfg); 12740 return 1; 12741 }
| static void set_config_destroy | ( | void | ) | [static] |
Definition at line 12303 of file chan_iax2.c.
References addr_range_delme_cb(), ao2_callback, ast_clear_flag, delete_users(), IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_TRANSFERMEDIA, IAX_USEJITTERBUF, MAX_TRUNKDATA, and OBJ_NODATA.
Referenced by set_config().
12304 { 12305 strcpy(accountcode, ""); 12306 strcpy(language, ""); 12307 strcpy(mohinterpret, "default"); 12308 strcpy(mohsuggest, ""); 12309 trunkmaxsize = MAX_TRUNKDATA; 12310 amaflags = 0; 12311 delayreject = 0; 12312 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 12313 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 12314 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 12315 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 12316 delete_users(); 12317 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 12318 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 12319 }
| static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 1996 of file chan_iax2.c.
References peercnt::addr, addr_range_match_address_cb(), ao2_callback, ao2_ref, ast_debug, ast_inet_ntoa(), addr_range::limit, peercnt::limit, and peercnt::reg.
Referenced by peercnt_add(), peercnt_modify(), and set_peercnt_limit_all_cb().
01997 { 01998 uint16_t limit = global_maxcallno; 01999 struct addr_range *addr_range; 02000 struct sockaddr_in sin = { 02001 .sin_addr.s_addr = peercnt->addr, 02002 }; 02003 02004 02005 if (peercnt->reg && peercnt->limit) { 02006 return; /* this peercnt has a custom limit set by a registration */ 02007 } 02008 02009 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02010 limit = addr_range->limit; 02011 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02012 ao2_ref(addr_range, -1); 02013 } 02014 02015 peercnt->limit = limit; 02016 }
| static int set_peercnt_limit_all_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2022 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02023 { 02024 struct peercnt *peercnt = obj; 02025 02026 set_peercnt_limit(peercnt); 02027 ast_debug(1, "Reset limits for peercnts table\n"); 02028 02029 return 0; 02030 }
| static void signal_condition | ( | ast_mutex_t * | lock, | |
| ast_cond_t * | cond | |||
| ) | [static] |
Definition at line 910 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_process_thread(), iax2_sched_add(), iax2_sched_replace(), iax2_transmit(), and socket_read().
00911 { 00912 ast_mutex_lock(lock); 00913 ast_cond_signal(cond); 00914 ast_mutex_unlock(lock); 00915 }
| static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 9290 of file chan_iax2.c.
References chan_iax2_pvt::addr, iax_frame::af, iax_frame::afdatalen, chan_iax2_pvt::aseqno, ast_aes_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_trylock, ast_channel_unlock, ast_clear_flag, ast_codec_choose(), ast_codec_get_samples(), ast_codec_pref_convert(), ast_codec_pref_index(), ast_codec_pref_string(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, 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_iax2_new(), ast_inet_ntoa(), AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_parking_ext(), ast_sched_del(), AST_SCHED_DEL, ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_var_assign(), ast_variables_destroy(), ast_verb, auth_fail(), authenticate_reply(), authenticate_request(), authenticate_verify(), chan_iax2_pvt::authmethods, iax_ie_data::buf, iax2_thread::buf, iax2_thread::buf_len, CACHE_FLAG_TRANSMITTED, iax_frame::cacheable, calc_timestamp(), iax_ies::called_number, iax2_peer::callno, chan_iax2_pvt::callno, iax_frame::callno, iax_ies::calltoken, iax_ies::calltokendata, chan_iax2_pvt::capability, iax_ies::cause, iax_ies::causecode, iax_ies::challenge, check_access(), check_provisioning(), chan_iax2_pvt::chosenformat, chan_iax2_pvt::cid_num, cid_num, iax_ies::codec_prefs, complete_dpreply(), complete_transfer(), construct_rr(), context, chan_iax2_pvt::context, ast_iax2_full_hdr::csub, ast_datastore::data, ast_frame::data, ast_frame::datalen, DATASTORE_INHERIT_FOREVER, ast_iax2_full_hdr::dcallno, DEADLOCK_AVOIDANCE, decrypt_frame(), iax_ies::devicetype, dp_lookup(), chan_iax2_pvt::encmethods, iax_ies::encmethods, chan_iax2_pvt::error, EVENT_FLAG_CALL, EVENT_FLAG_SYSTEM, exists(), exten, chan_iax2_pvt::exten, iax_frame::final, find_callno(), chan_iax2_pvt::first_iax_message, iax2_dpcache::flags, iax_ies::format, format, chan_iax2_pvt::frames_received, ast_frame::frametype, iax_ies::fwdesc, handle_call_token(), ast_channel::hangupcause, iax2_peer::historicms, chan_iax2_pvt::hold_signaling, iax2_ack_registry(), iax2_allow_new(), iax2_destroy(), iax2_dprequest(), iax2_poke_peer_s(), iax2_queue_control_data(), iax2_queue_frame(), iax2_sched_add(), iax2_send(), 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_frame_wrap(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLNO, IAX_IE_CAUSE, IAX_IE_CAUSECODE, IAX_IE_FORMAT, IAX_IE_IAX_UNKNOWN, iax_outputframe(), iax_park(), iax_parse_ies(), IAX_PROVISION, IAX_QUELCH, IAX_STATE_AUTHENTICATED, IAX_STATE_STARTED, IAX_STATE_TBD, IAX_TRUNK, iax_ies::iax_unknown, iaxfrdup2(), chan_iax2_pvt::iaxvars, inaddrcmp(), ast_datastore::inheritance, chan_iax2_pvt::initid, chan_iax2_pvt::inkeys, iax2_thread::iofd, iax2_thread::iosin, chan_iax2_pvt::iseqno, iax_frame::iseqno, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::last, chan_iax2_pvt::last_iax_message, iax2_peer::lastms, ast_frame::len, LOG_ERROR, log_jitterstats(), LOG_NOTICE, LOG_WARNING, make_trunk(), ast_frame::mallocd, manager_event, iax2_peer::maxms, merge_encryption(), ast_iax2_meta_hdr::metacmd, chan_iax2_pvt::mohsuggest, iax_ies::musiconhold, iax2_peer::name, ast_variable::name, ast_channel::nativeformats, NEW_ALLOW, NEW_ALLOW_CALLTOKEN_VALIDATED, NEW_PREVENT, ast_variable::next, ast_frame::offset, chan_iax2_pvt::oseqno, iax_frame::oseqno, ast_iax2_full_hdr::oseqno, iax_frame::outoforder, chan_iax2_pvt::owner, pbx_builtin_setvar_helper(), peer_ref(), peer_unref(), chan_iax2_pvt::peercallno, chan_iax2_pvt::peercapability, chan_iax2_pvt::peerformat, iax2_peer::pokeexpire, iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, iax_ie_data::pos, chan_iax2_pvt::prefs, iax_ies::provver, iax_ies::provverpres, ast_frame::ptr, raw_hangup(), ast_channel::readformat, iax_ies::refresh, REG_STATE_REJECTED, register_verify(), registry_authrequest(), registry_rerequest(), remove_by_peercallno(), resend_with_token(), iax_frame::retries, chan_iax2_pvt::rprefs, chan_iax2_pvt::rseqno, S_OR, ast_frame::samples, save_osptoken(), save_rr(), ast_iax2_full_hdr::scallno, schedule_delivery(), chan_iax2_pvt::secret, send_apathetic_reply(), send_command(), send_command_final(), send_command_immediate(), send_command_transfer(), send_signaling(), iax_ies::serviceident, iax2_peer::smoothing, socket_process_meta(), spawn_dp_lookup(), ast_frame::src, chan_iax2_pvt::state, stop_stuff(), store_by_peercallno(), ast_frame::subclass, iax_frame::transfer, TRANSFER_BEGIN, TRANSFER_MBEGIN, TRANSFER_MEDIA, TRANSFER_MEDIAPASS, TRANSFER_MREADY, TRANSFER_READY, TRANSFER_RELEASED, chan_iax2_pvt::transferring, try_transfer(), iax_frame::ts, ast_iax2_full_hdr::ts, ast_iax2_full_hdr::type, uncompress_subclass(), update_registry(), iax_ies::username, ast_variable::value, var, iax_ies::vars, VERBOSE_PREFIX_4, chan_iax2_pvt::videoformat, vnak_retransmit(), chan_iax2_pvt::voiceformat, and ast_iax2_meta_hdr::zeros.
Referenced by handle_deferred_full_frames(), and iax2_process_thread().
09291 { 09292 struct sockaddr_in sin; 09293 int res; 09294 int updatehistory=1; 09295 int new = NEW_PREVENT; 09296 int dcallno = 0; 09297 char decrypted = 0; 09298 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09299 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09300 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09301 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09302 struct iax_frame *fr; 09303 struct iax_frame *cur; 09304 struct ast_frame f = { 0, }; 09305 struct ast_channel *c = NULL; 09306 struct iax2_dpcache *dp; 09307 struct iax2_peer *peer; 09308 struct iax_ies ies; 09309 struct iax_ie_data ied0, ied1; 09310 int format; 09311 int fd; 09312 int exists; 09313 int minivid = 0; 09314 char empty[32]=""; /* Safety measure */ 09315 struct iax_frame *duped_fr; 09316 char host_pref_buf[128]; 09317 char caller_pref_buf[128]; 09318 struct ast_codec_pref pref; 09319 char *using_prefs = "mine"; 09320 09321 /* allocate an iax_frame with 4096 bytes of data buffer */ 09322 fr = alloca(sizeof(*fr) + 4096); 09323 memset(fr, 0, sizeof(*fr)); 09324 fr->afdatalen = 4096; /* From alloca() above */ 09325 09326 /* Copy frequently used parameters to the stack */ 09327 res = thread->buf_len; 09328 fd = thread->iofd; 09329 memcpy(&sin, &thread->iosin, sizeof(sin)); 09330 09331 if (res < sizeof(*mh)) { 09332 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09333 return 1; 09334 } 09335 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09336 if (res < sizeof(*vh)) { 09337 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)); 09338 return 1; 09339 } 09340 09341 /* This is a video frame, get call number */ 09342 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 09343 minivid = 1; 09344 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 09345 return socket_process_meta(res, meta, &sin, fd, fr); 09346 09347 #ifdef DEBUG_SUPPORT 09348 if (res >= sizeof(*fh)) 09349 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 09350 #endif 09351 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09352 if (res < sizeof(*fh)) { 09353 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)); 09354 return 1; 09355 } 09356 09357 /* Get the destination call number */ 09358 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 09359 09360 09361 /* check to make sure this full frame isn't encrypted before we attempt 09362 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 09363 * callno is not found here, that just means one hasn't been allocated for 09364 * this connection yet. */ 09365 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 09366 ast_mutex_lock(&iaxsl[fr->callno]); 09367 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 09368 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09369 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09370 ast_mutex_unlock(&iaxsl[fr->callno]); 09371 return 1; 09372 } 09373 decrypted = 1; 09374 } 09375 ast_mutex_unlock(&iaxsl[fr->callno]); 09376 } 09377 09378 /* Retrieve the type and subclass */ 09379 f.frametype = fh->type; 09380 if (f.frametype == AST_FRAME_VIDEO) { 09381 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 09382 } else { 09383 f.subclass = uncompress_subclass(fh->csub); 09384 } 09385 09386 /* Deal with POKE/PONG without allocating a callno */ 09387 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 09388 /* Reply back with a PONG, but don't care about the result. */ 09389 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09390 return 1; 09391 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 09392 /* Ignore */ 09393 return 1; 09394 } 09395 09396 f.datalen = res - sizeof(*fh); 09397 if (f.datalen) { 09398 if (f.frametype == AST_FRAME_IAX) { 09399 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 09400 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 09401 return 1; 09402 } 09403 f.data.ptr = NULL; 09404 f.datalen = 0; 09405 } else { 09406 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 09407 memset(&ies, 0, sizeof(ies)); 09408 } 09409 } else { 09410 if (f.frametype == AST_FRAME_IAX) 09411 f.data.ptr = NULL; 09412 else 09413 f.data.ptr = empty; 09414 memset(&ies, 0, sizeof(ies)); 09415 } 09416 09417 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) { 09418 /* only set NEW_ALLOW if calltoken checks out */ 09419 if (handle_call_token(fh, &ies, &sin, fd)) { 09420 return 1; 09421 } 09422 09423 if (ies.calltoken && ies.calltokendata) { 09424 /* if we've gotten this far, and the calltoken ie data exists, 09425 * then calltoken validation _MUST_ have taken place. If calltoken 09426 * data is provided, it is always validated reguardless of any 09427 * calltokenoptional or requirecalltoken options */ 09428 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 09429 } else { 09430 new = NEW_ALLOW; 09431 } 09432 } 09433 } else { 09434 /* Don't know anything about it yet */ 09435 f.frametype = AST_FRAME_NULL; 09436 f.subclass = 0; 09437 } 09438 09439 if (!fr->callno) { 09440 int check_dcallno = 0; 09441 09442 /* 09443 * We enforce accurate destination call numbers for ACKs. This forces the other 09444 * end to know the destination call number before call setup can complete. 09445 * 09446 * Discussed in the following thread: 09447 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 09448 */ 09449 09450 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) { 09451 check_dcallno = 1; 09452 } 09453 09454 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 09455 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) { 09456 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09457 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) { 09458 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09459 } 09460 return 1; 09461 } 09462 } 09463 09464 if (fr->callno > 0) 09465 ast_mutex_lock(&iaxsl[fr->callno]); 09466 09467 if (!fr->callno || !iaxs[fr->callno]) { 09468 /* A call arrived for a nonexistent destination. Unless it's an "inval" 09469 frame, reply with an inval */ 09470 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09471 /* We can only raw hangup control frames */ 09472 if (((f.subclass != IAX_COMMAND_INVAL) && 09473 (f.subclass != IAX_COMMAND_TXCNT) && 09474 (f.subclass != IAX_COMMAND_TXACC) && 09475 (f.subclass != IAX_COMMAND_FWDOWNL))|| 09476 (f.frametype != AST_FRAME_IAX)) 09477 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 09478 fd); 09479 } 09480 if (fr->callno > 0) 09481 ast_mutex_unlock(&iaxsl[fr->callno]); 09482 return 1; 09483 } 09484 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 09485 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09486 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09487 ast_mutex_unlock(&iaxsl[fr->callno]); 09488 return 1; 09489 } 09490 decrypted = 1; 09491 } 09492 #ifdef DEBUG_SUPPORT 09493 if (decrypted) { 09494 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 09495 } 09496 #endif 09497 09498 /* count this frame */ 09499 iaxs[fr->callno]->frames_received++; 09500 09501 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 09502 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 09503 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 09504 unsigned short new_peercallno; 09505 09506 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 09507 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 09508 if (iaxs[fr->callno]->peercallno) { 09509 remove_by_peercallno(iaxs[fr->callno]); 09510 } 09511 iaxs[fr->callno]->peercallno = new_peercallno; 09512 store_by_peercallno(iaxs[fr->callno]); 09513 } 09514 } 09515 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09516 if (iaxdebug) 09517 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 09518 /* Check if it's out of order (and not an ACK or INVAL) */ 09519 fr->oseqno = fh->oseqno; 09520 fr->iseqno = fh->iseqno; 09521 fr->ts = ntohl(fh->ts); 09522 #ifdef IAXTESTS 09523 if (test_resync) { 09524 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 09525 fr->ts += test_resync; 09526 } 09527 #endif /* IAXTESTS */ 09528 #if 0 09529 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 09530 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 09531 (f.subclass == IAX_COMMAND_NEW || 09532 f.subclass == IAX_COMMAND_AUTHREQ || 09533 f.subclass == IAX_COMMAND_ACCEPT || 09534 f.subclass == IAX_COMMAND_REJECT)) ) ) 09535 #endif 09536 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 09537 updatehistory = 0; 09538 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 09539 (iaxs[fr->callno]->iseqno || 09540 ((f.subclass != IAX_COMMAND_TXCNT) && 09541 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 09542 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 09543 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 09544 (f.subclass != IAX_COMMAND_TXACC)) || 09545 (f.frametype != AST_FRAME_IAX))) { 09546 if ( 09547 ((f.subclass != IAX_COMMAND_ACK) && 09548 (f.subclass != IAX_COMMAND_INVAL) && 09549 (f.subclass != IAX_COMMAND_TXCNT) && 09550 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 09551 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 09552 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 09553 (f.subclass != IAX_COMMAND_TXACC) && 09554 (f.subclass != IAX_COMMAND_VNAK)) || 09555 (f.frametype != AST_FRAME_IAX)) { 09556 /* If it's not an ACK packet, it's out of order. */ 09557 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 09558 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 09559 /* Check to see if we need to request retransmission, 09560 * and take sequence number wraparound into account */ 09561 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 09562 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 09563 if ((f.frametype != AST_FRAME_IAX) || 09564 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 09565 ast_debug(1, "Acking anyway\n"); 09566 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 09567 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 09568 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09569 } 09570 } else { 09571 /* Send a VNAK requesting retransmission */ 09572 iax2_vnak(fr->callno); 09573 } 09574 ast_mutex_unlock(&iaxsl[fr->callno]); 09575 return 1; 09576 } 09577 } else { 09578 /* Increment unless it's an ACK or VNAK */ 09579 if (((f.subclass != IAX_COMMAND_ACK) && 09580 (f.subclass != IAX_COMMAND_INVAL) && 09581 (f.subclass != IAX_COMMAND_TXCNT) && 09582 (f.subclass != IAX_COMMAND_TXACC) && 09583 (f.subclass != IAX_COMMAND_VNAK)) || 09584 (f.frametype != AST_FRAME_IAX)) 09585 iaxs[fr->callno]->iseqno++; 09586 } 09587 /* Ensure text frames are NULL-terminated */ 09588 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 09589 if (res < thread->buf_size) 09590 thread->buf[res++] = '\0'; 09591 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 09592 thread->buf[res - 1] = '\0'; 09593 } 09594 09595 /* Handle implicit ACKing unless this is an INVAL, and only if this is 09596 from the real peer, not the transfer peer */ 09597 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 09598 ((f.subclass != IAX_COMMAND_INVAL) || 09599 (f.frametype != AST_FRAME_IAX))) { 09600 unsigned char x; 09601 int call_to_destroy; 09602 /* First we have to qualify that the ACKed value is within our window */ 09603 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 09604 x = fr->iseqno; 09605 else 09606 x = iaxs[fr->callno]->oseqno; 09607 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 09608 /* The acknowledgement is within our window. Time to acknowledge everything 09609 that it says to */ 09610 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 09611 /* Ack the packet with the given timestamp */ 09612 if (iaxdebug) 09613 ast_debug(1, "Cancelling transmission of packet %d\n", x); 09614 call_to_destroy = 0; 09615 AST_LIST_LOCK(&frame_queue); 09616 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 09617 /* If it's our call, and our timestamp, mark -1 retries */ 09618 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 09619 cur->retries = -1; 09620 /* Destroy call if this is the end */ 09621 if (cur->final) 09622 call_to_destroy = fr->callno; 09623 } 09624 } 09625 AST_LIST_UNLOCK(&frame_queue); 09626 if (call_to_destroy) { 09627 if (iaxdebug) 09628 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 09629 ast_mutex_lock(&iaxsl[call_to_destroy]); 09630 iax2_destroy(call_to_destroy); 09631 ast_mutex_unlock(&iaxsl[call_to_destroy]); 09632 } 09633 } 09634 /* Note how much we've received acknowledgement for */ 09635 if (iaxs[fr->callno]) 09636 iaxs[fr->callno]->rseqno = fr->iseqno; 09637 else { 09638 /* Stop processing now */ 09639 ast_mutex_unlock(&iaxsl[fr->callno]); 09640 return 1; 09641 } 09642 } else { 09643 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 09644 } 09645 } 09646 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 09647 ((f.frametype != AST_FRAME_IAX) || 09648 ((f.subclass != IAX_COMMAND_TXACC) && 09649 (f.subclass != IAX_COMMAND_TXCNT)))) { 09650 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 09651 ast_mutex_unlock(&iaxsl[fr->callno]); 09652 return 1; 09653 } 09654 09655 /* when we receive the first full frame for a new incoming channel, 09656 it is safe to start the PBX on the channel because we have now 09657 completed a 3-way handshake with the peer */ 09658 if ((f.frametype == AST_FRAME_VOICE) || 09659 (f.frametype == AST_FRAME_VIDEO) || 09660 (f.frametype == AST_FRAME_IAX)) { 09661 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 09662 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 09663 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 09664 ast_mutex_unlock(&iaxsl[fr->callno]); 09665 return 1; 09666 } 09667 } 09668 09669 if (ies.vars) { 09670 struct ast_datastore *variablestore = NULL; 09671 struct ast_variable *var, *prev = NULL; 09672 AST_LIST_HEAD(, ast_var_t) *varlist; 09673 if ((c = iaxs[fr->callno]->owner)) { 09674 varlist = ast_calloc(1, sizeof(*varlist)); 09675 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09676 09677 if (variablestore && varlist) { 09678 variablestore->data = varlist; 09679 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09680 AST_LIST_HEAD_INIT(varlist); 09681 ast_debug(1, "I can haz IAX vars?\n"); 09682 for (var = ies.vars; var; var = var->next) { 09683 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 09684 if (prev) { 09685 ast_free(prev); 09686 } 09687 prev = var; 09688 if (!newvar) { 09689 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 09690 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 09691 } else { 09692 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 09693 } 09694 } 09695 if (prev) { 09696 ast_free(prev); 09697 } 09698 ies.vars = NULL; 09699 ast_channel_datastore_add(c, variablestore); 09700 } else { 09701 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 09702 if (variablestore) { 09703 ast_datastore_free(variablestore); 09704 } 09705 if (varlist) { 09706 ast_free(varlist); 09707 } 09708 } 09709 } else { 09710 /* No channel yet, so transfer the variables directly over to the pvt, 09711 * for later inheritance. */ 09712 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 09713 for (var = ies.vars; var && var->next; var = var->next); 09714 if (var) { 09715 var->next = iaxs[fr->callno]->iaxvars; 09716 iaxs[fr->callno]->iaxvars = ies.vars; 09717 ies.vars = NULL; 09718 } 09719 } 09720 } 09721 09722 if (ies.vars) { 09723 ast_debug(1, "I have IAX variables, but they were not processed\n"); 09724 } 09725 } 09726 09727 /* once we receive our first IAX Full Frame that is not CallToken related, send all 09728 * queued signaling frames that were being held. */ 09729 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 09730 send_signaling(iaxs[fr->callno]); 09731 } 09732 09733 if (f.frametype == AST_FRAME_VOICE) { 09734 if (f.subclass != iaxs[fr->callno]->voiceformat) { 09735 iaxs[fr->callno]->voiceformat = f.subclass; 09736 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass); 09737 if (iaxs[fr->callno]->owner) { 09738 int orignative; 09739 retryowner: 09740 if (ast_channel_trylock(iaxs[fr->callno]->owner)) { 09741 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 09742 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 09743 } 09744 if (iaxs[fr->callno]) { 09745 if (iaxs[fr->callno]->owner) { 09746 orignative = iaxs[fr->callno]->owner->nativeformats; 09747 iaxs[fr->callno]->owner->nativeformats = f.subclass; 09748 if (iaxs[fr->callno]->owner->readformat) 09749 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 09750 iaxs[fr->callno]->owner->nativeformats = orignative; 09751 ast_channel_unlock(iaxs[fr->callno]->owner); 09752 } 09753 } else { 09754 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 09755 /* Free remote variables (if any) */ 09756 if (ies.vars) { 09757 ast_variables_destroy(ies.vars); 09758 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 09759 ies.vars = NULL; 09760 } 09761 ast_mutex_unlock(&iaxsl[fr->callno]); 09762 return 1; 09763 } 09764 } 09765 } 09766 } 09767 if (f.frametype == AST_FRAME_VIDEO) { 09768 if (f.subclass != iaxs[fr->callno]->videoformat) { 09769 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 09770 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 09771 } 09772 } 09773 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 09774 if (f.subclass == AST_CONTROL_BUSY) { 09775 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 09776 } else if (f.subclass == AST_CONTROL_CONGESTION) { 09777 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 09778 } 09779 } 09780 if (f.frametype == AST_FRAME_IAX) { 09781 AST_SCHED_DEL(sched, iaxs[fr->callno]->initid); 09782 /* Handle the IAX pseudo frame itself */ 09783 if (iaxdebug) 09784 ast_debug(1, "IAX subclass %d received\n", f.subclass); 09785 09786 /* Update last ts unless the frame's timestamp originated with us. */ 09787 if (iaxs[fr->callno]->last < fr->ts && 09788 f.subclass != IAX_COMMAND_ACK && 09789 f.subclass != IAX_COMMAND_PONG && 09790 f.subclass != IAX_COMMAND_LAGRP) { 09791 iaxs[fr->callno]->last = fr->ts; 09792 if (iaxdebug) 09793 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 09794 } 09795 iaxs[fr->callno]->last_iax_message = f.subclass; 09796 if (!iaxs[fr->callno]->first_iax_message) { 09797 iaxs[fr->callno]->first_iax_message = f.subclass; 09798 } 09799 switch(f.subclass) { 09800 case IAX_COMMAND_ACK: 09801 /* Do nothing */ 09802 break; 09803 case IAX_COMMAND_QUELCH: 09804 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09805 /* Generate Manager Hold event, if necessary*/ 09806 if (iaxs[fr->callno]->owner) { 09807 manager_event(EVENT_FLAG_CALL, "Hold", 09808 "Status: On\r\n" 09809 "Channel: %s\r\n" 09810 "Uniqueid: %s\r\n", 09811 iaxs[fr->callno]->owner->name, 09812 iaxs[fr->callno]->owner->uniqueid); 09813 } 09814 09815 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 09816 if (ies.musiconhold) { 09817 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 09818 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 09819 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 09820 S_OR(moh_suggest, NULL), 09821 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 09822 if (!iaxs[fr->callno]) { 09823 ast_mutex_unlock(&iaxsl[fr->callno]); 09824 return 1; 09825 } 09826 } 09827 } 09828 } 09829 break; 09830 case IAX_COMMAND_UNQUELCH: 09831 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09832 /* Generate Manager Unhold event, if necessary*/ 09833 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 09834 manager_event(EVENT_FLAG_CALL, "Hold", 09835 "Status: Off\r\n" 09836 "Channel: %s\r\n" 09837 "Uniqueid: %s\r\n", 09838 iaxs[fr->callno]->owner->name, 09839 iaxs[fr->callno]->owner->uniqueid); 09840 } 09841 09842 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 09843 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 09844 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 09845 if (!iaxs[fr->callno]) { 09846 ast_mutex_unlock(&iaxsl[fr->callno]); 09847 return 1; 09848 } 09849 } 09850 } 09851 break; 09852 case IAX_COMMAND_TXACC: 09853 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 09854 /* Ack the packet with the given timestamp */ 09855 AST_LIST_LOCK(&frame_queue); 09856 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 09857 /* Cancel any outstanding txcnt's */ 09858 if ((fr->callno == cur->callno) && (cur->transfer)) 09859 cur->retries = -1; 09860 } 09861 AST_LIST_UNLOCK(&frame_queue); 09862 memset(&ied1, 0, sizeof(ied1)); 09863 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 09864 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 09865 iaxs[fr->callno]->transferring = TRANSFER_READY; 09866 } 09867 break; 09868 case IAX_COMMAND_NEW: 09869 /* Ignore if it's already up */ 09870 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 09871 break; 09872 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 09873 ast_mutex_unlock(&iaxsl[fr->callno]); 09874 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 09875 ast_mutex_lock(&iaxsl[fr->callno]); 09876 if (!iaxs[fr->callno]) { 09877 ast_mutex_unlock(&iaxsl[fr->callno]); 09878 return 1; 09879 } 09880 } 09881 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 09882 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 09883 int new_callno; 09884 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 09885 fr->callno = new_callno; 09886 } 09887 /* For security, always ack immediately */ 09888 if (delayreject) 09889 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09890 if (check_access(fr->callno, &sin, &ies)) { 09891 /* They're not allowed on */ 09892 auth_fail(fr->callno, IAX_COMMAND_REJECT); 09893 if (authdebug) 09894 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); 09895 break; 09896 } 09897 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 09898 const char *context, *exten, *cid_num; 09899 09900 context = ast_strdupa(iaxs[fr->callno]->context); 09901 exten = ast_strdupa(iaxs[fr->callno]->exten); 09902 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 09903 09904 /* This might re-enter the IAX code and need the lock */ 09905 ast_mutex_unlock(&iaxsl[fr->callno]); 09906 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 09907 ast_mutex_lock(&iaxsl[fr->callno]); 09908 09909 if (!iaxs[fr->callno]) { 09910 ast_mutex_unlock(&iaxsl[fr->callno]); 09911 return 1; 09912 } 09913 } else 09914 exists = 0; 09915 /* Get OSP token if it does exist */ 09916 save_osptoken(fr, &ies); 09917 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 09918 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 09919 memset(&ied0, 0, sizeof(ied0)); 09920 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 09921 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 09922 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09923 if (!iaxs[fr->callno]) { 09924 ast_mutex_unlock(&iaxsl[fr->callno]); 09925 return 1; 09926 } 09927 if (authdebug) 09928 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); 09929 } else { 09930 /* Select an appropriate format */ 09931 09932 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09933 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09934 using_prefs = "reqonly"; 09935 } else { 09936 using_prefs = "disabled"; 09937 } 09938 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 09939 memset(&pref, 0, sizeof(pref)); 09940 strcpy(caller_pref_buf, "disabled"); 09941 strcpy(host_pref_buf, "disabled"); 09942 } else { 09943 using_prefs = "mine"; 09944 /* If the information elements are in here... use them */ 09945 if (ies.codec_prefs) 09946 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 09947 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09948 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 09949 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09950 pref = iaxs[fr->callno]->rprefs; 09951 using_prefs = "caller"; 09952 } else { 09953 pref = iaxs[fr->callno]->prefs; 09954 } 09955 } else 09956 pref = iaxs[fr->callno]->prefs; 09957 09958 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 09959 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 09960 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 09961 } 09962 if (!format) { 09963 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09964 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 09965 if (!format) { 09966 memset(&ied0, 0, sizeof(ied0)); 09967 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 09968 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 09969 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 09970 if (!iaxs[fr->callno]) { 09971 ast_mutex_unlock(&iaxsl[fr->callno]); 09972 return 1; 09973 } 09974 if (authdebug) { 09975 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 09976 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 09977 else 09978 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 09979 } 09980 } else { 09981 /* Pick one... */ 09982 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 09983 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 09984 format = 0; 09985 } else { 09986 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 09987 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 09988 memset(&pref, 0, sizeof(pref)); 09989 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 09990 strcpy(caller_pref_buf,"disabled"); 09991 strcpy(host_pref_buf,"disabled"); 09992 } else { 09993 using_prefs = "mine"; 09994 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 09995 /* Do the opposite of what we tried above. */ 09996 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 09997 pref = iaxs[fr->callno]->prefs; 09998 } else { 09999 pref = iaxs[fr->callno]->rprefs; 10000 using_prefs = "caller"; 10001 } 10002 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10003 10004 } else /* if no codec_prefs IE do it the old way */ 10005 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10006 } 10007 } 10008 10009 if (!format) { 10010 memset(&ied0, 0, sizeof(ied0)); 10011 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10012 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10013 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10014 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10015 if (!iaxs[fr->callno]) { 10016 ast_mutex_unlock(&iaxsl[fr->callno]); 10017 return 1; 10018 } 10019 if (authdebug) 10020 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 10021 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 10022 break; 10023 } 10024 } 10025 } 10026 if (format) { 10027 /* No authentication required, let them in */ 10028 memset(&ied1, 0, sizeof(ied1)); 10029 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10030 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10031 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10032 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10033 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10034 "%srequested format = %s,\n" 10035 "%srequested prefs = %s,\n" 10036 "%sactual format = %s,\n" 10037 "%shost prefs = %s,\n" 10038 "%spriority = %s\n", 10039 ast_inet_ntoa(sin.sin_addr), 10040 VERBOSE_PREFIX_4, 10041 ast_getformatname(iaxs[fr->callno]->peerformat), 10042 VERBOSE_PREFIX_4, 10043 caller_pref_buf, 10044 VERBOSE_PREFIX_4, 10045 ast_getformatname(format), 10046 VERBOSE_PREFIX_4, 10047 host_pref_buf, 10048 VERBOSE_PREFIX_4, 10049 using_prefs); 10050 10051 iaxs[fr->callno]->chosenformat = format; 10052 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 10053 } else { 10054 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10055 /* If this is a TBD call, we're ready but now what... */ 10056 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10057 } 10058 } 10059 } 10060 break; 10061 } 10062 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10063 merge_encryption(iaxs[fr->callno],ies.encmethods); 10064 else 10065 iaxs[fr->callno]->encmethods = 0; 10066 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10067 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10068 if (!iaxs[fr->callno]) { 10069 ast_mutex_unlock(&iaxsl[fr->callno]); 10070 return 1; 10071 } 10072 break; 10073 case IAX_COMMAND_DPREQ: 10074 /* Request status in the dialplan */ 10075 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10076 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10077 if (iaxcompat) { 10078 /* Spawn a thread for the lookup */ 10079 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10080 } else { 10081 /* Just look it up */ 10082 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10083 } 10084 } 10085 break; 10086 case IAX_COMMAND_HANGUP: 10087 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 10088 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10089 /* Set hangup cause according to remote */ 10090 if (ies.causecode && iaxs[fr->callno]->owner) 10091 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 10092 /* Send ack immediately, before we destroy */ 10093 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10094 iax2_destroy(fr->callno); 10095 break; 10096 case IAX_COMMAND_REJECT: 10097 /* Set hangup cause according to remote */ 10098 if (ies.causecode && iaxs[fr->callno]->owner) 10099 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 10100 10101 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 10102 if (iaxs[fr->callno]->owner && authdebug) 10103 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10104 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10105 ies.cause ? ies.cause : "<Unknown>"); 10106 ast_debug(1, "Immediately destroying %d, having received reject\n", 10107 fr->callno); 10108 } 10109 /* Send ack immediately, before we destroy */ 10110 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10111 fr->ts, NULL, 0, fr->iseqno); 10112 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 10113 iaxs[fr->callno]->error = EPERM; 10114 iax2_destroy(fr->callno); 10115 break; 10116 case IAX_COMMAND_TRANSFER: 10117 { 10118 struct ast_channel *bridged_chan; 10119 10120 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 10121 /* Set BLINDTRANSFER channel variables */ 10122 10123 ast_mutex_unlock(&iaxsl[fr->callno]); 10124 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 10125 ast_mutex_lock(&iaxsl[fr->callno]); 10126 if (!iaxs[fr->callno]) { 10127 ast_mutex_unlock(&iaxsl[fr->callno]); 10128 return 1; 10129 } 10130 10131 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 10132 if (!strcmp(ies.called_number, ast_parking_ext())) { 10133 struct ast_channel *saved_channel = iaxs[fr->callno]->owner; 10134 ast_mutex_unlock(&iaxsl[fr->callno]); 10135 if (iax_park(bridged_chan, saved_channel)) { 10136 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 10137 } else { 10138 ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 10139 } 10140 ast_mutex_lock(&iaxsl[fr->callno]); 10141 } else { 10142 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 10143 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 10144 ies.called_number, iaxs[fr->callno]->context); 10145 else { 10146 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 10147 ies.called_number, iaxs[fr->callno]->context); 10148 } 10149 } 10150 } else { 10151 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10152 } 10153 10154 break; 10155 } 10156 case IAX_COMMAND_ACCEPT: 10157 /* Ignore if call is already up or needs authentication or is a TBD */ 10158 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10159 break; 10160 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 10161 /* Send ack immediately, before we destroy */ 10162 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10163 iax2_destroy(fr->callno); 10164 break; 10165 } 10166 if (ies.format) { 10167 iaxs[fr->callno]->peerformat = ies.format; 10168 } else { 10169 if (iaxs[fr->callno]->owner) 10170 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10171 else 10172 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10173 } 10174 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)); 10175 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10176 memset(&ied0, 0, sizeof(ied0)); 10177 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10178 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10179 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10180 if (!iaxs[fr->callno]) { 10181 ast_mutex_unlock(&iaxsl[fr->callno]); 10182 return 1; 10183 } 10184 if (authdebug) 10185 ast_log(LOG_NOTICE, "Rejected call to %s, format 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 10186 } else { 10187 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10188 if (iaxs[fr->callno]->owner) { 10189 /* Switch us to use a compatible format */ 10190 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 10191 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 10192 retryowner2: 10193 if (ast_channel_trylock(iaxs[fr->callno]->owner)) { 10194 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 10195 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 10196 } 10197 10198 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10199 /* Setup read/write formats properly. */ 10200 if (iaxs[fr->callno]->owner->writeformat) 10201 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 10202 if (iaxs[fr->callno]->owner->readformat) 10203 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10204 ast_channel_unlock(iaxs[fr->callno]->owner); 10205 } 10206 } 10207 } 10208 if (iaxs[fr->callno]) { 10209 AST_LIST_LOCK(&dpcache); 10210 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10211 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10212 iax2_dprequest(dp, fr->callno); 10213 AST_LIST_UNLOCK(&dpcache); 10214 } 10215 break; 10216 case IAX_COMMAND_POKE: 10217 /* Send back a pong packet with the original timestamp */ 10218 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10219 if (!iaxs[fr->callno]) { 10220 ast_mutex_unlock(&iaxsl[fr->callno]); 10221 return 1; 10222 } 10223 break; 10224 case IAX_COMMAND_PING: 10225 { 10226 struct iax_ie_data pingied; 10227 construct_rr(iaxs[fr->callno], &pingied); 10228 /* Send back a pong packet with the original timestamp */ 10229 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10230 } 10231 break; 10232 case IAX_COMMAND_PONG: 10233 /* Calculate ping time */ 10234 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10235 /* save RR info */ 10236 save_rr(fr, &ies); 10237 10238 /* Good time to write jb stats for this call */ 10239 log_jitterstats(fr->callno); 10240 10241 if (iaxs[fr->callno]->peerpoke) { 10242 peer = iaxs[fr->callno]->peerpoke; 10243 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10244 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10245 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10246 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); 10247 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */ 10248 } 10249 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10250 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10251 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10252 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); 10253 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 10254 } 10255 } 10256 peer->lastms = iaxs[fr->callno]->pingtime; 10257 if (peer->smoothing && (peer->lastms > -1)) 10258 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10259 else if (peer->smoothing && peer->lastms < 0) 10260 peer->historicms = (0 + peer->historicms) / 2; 10261 else 10262 peer->historicms = iaxs[fr->callno]->pingtime; 10263 10264 /* Remove scheduled iax2_poke_noanswer */ 10265 if (peer->pokeexpire > -1) { 10266 if (!ast_sched_del(sched, peer->pokeexpire)) { 10267 peer_unref(peer); 10268 peer->pokeexpire = -1; 10269 } 10270 } 10271 /* Schedule the next cycle */ 10272 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 10273 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10274 else 10275 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 10276 if (peer->pokeexpire == -1) 10277 peer_unref(peer); 10278 /* and finally send the ack */ 10279 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10280 /* And wrap up the qualify call */ 10281 iax2_destroy(fr->callno); 10282 peer->callno = 0; 10283 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 10284 } 10285 break; 10286 case IAX_COMMAND_LAGRQ: 10287 case IAX_COMMAND_LAGRP: 10288 f.src = "LAGRQ"; 10289 f.mallocd = 0; 10290 f.offset = 0; 10291 f.samples = 0; 10292 iax_frame_wrap(fr, &f); 10293 if(f.subclass == IAX_COMMAND_LAGRQ) { 10294 /* Received a LAGRQ - echo back a LAGRP */ 10295 fr->af.subclass = IAX_COMMAND_LAGRP; 10296 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 10297 } else { 10298 /* Received LAGRP in response to our LAGRQ */ 10299 unsigned int ts; 10300 /* This is a reply we've been given, actually measure the difference */ 10301 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 10302 iaxs[fr->callno]->lag = ts - fr->ts; 10303 if (iaxdebug) 10304 ast_debug(1, "Peer %s lag measured as %dms\n", 10305 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 10306 } 10307 break; 10308 case IAX_COMMAND_AUTHREQ: 10309 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10310 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>"); 10311 break; 10312 } 10313 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 10314 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 10315 .subclass = AST_CONTROL_HANGUP, 10316 }; 10317 ast_log(LOG_WARNING, 10318 "I don't know how to authenticate %s to %s\n", 10319 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 10320 iax2_queue_frame(fr->callno, &hangup_fr); 10321 } 10322 if (!iaxs[fr->callno]) { 10323 ast_mutex_unlock(&iaxsl[fr->callno]); 10324 return 1; 10325 } 10326 break; 10327 case IAX_COMMAND_AUTHREP: 10328 /* For security, always ack immediately */ 10329 if (delayreject) 10330 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10331 /* Ignore once we've started */ 10332 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10333 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>"); 10334 break; 10335 } 10336 if (authenticate_verify(iaxs[fr->callno], &ies)) { 10337 if (authdebug) 10338 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); 10339 memset(&ied0, 0, sizeof(ied0)); 10340 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10341 break; 10342 } 10343 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10344 /* This might re-enter the IAX code and need the lock */ 10345 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 10346 } else 10347 exists = 0; 10348 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10349 if (authdebug) 10350 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); 10351 memset(&ied0, 0, sizeof(ied0)); 10352 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10353 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10354 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10355 if (!iaxs[fr->callno]) { 10356 ast_mutex_unlock(&iaxsl[fr->callno]); 10357 return 1; 10358 } 10359 } else { 10360 /* Select an appropriate format */ 10361 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10362 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10363 using_prefs = "reqonly"; 10364 } else { 10365 using_prefs = "disabled"; 10366 } 10367 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10368 memset(&pref, 0, sizeof(pref)); 10369 strcpy(caller_pref_buf, "disabled"); 10370 strcpy(host_pref_buf, "disabled"); 10371 } else { 10372 using_prefs = "mine"; 10373 if (ies.codec_prefs) 10374 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10375 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10376 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10377 pref = iaxs[fr->callno]->rprefs; 10378 using_prefs = "caller"; 10379 } else { 10380 pref = iaxs[fr->callno]->prefs; 10381 } 10382 } else /* if no codec_prefs IE do it the old way */ 10383 pref = iaxs[fr->callno]->prefs; 10384 10385 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10386 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10387 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10388 } 10389 if (!format) { 10390 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10391 ast_debug(1, "We don't do requested format %s, falling back to peer capability %d\n", ast_getformatname(iaxs[fr->callno]->peerformat), iaxs[fr->callno]->peercapability); 10392 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10393 } 10394 if (!format) { 10395 if (authdebug) { 10396 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10397 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 10398 else 10399 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 10400 } 10401 memset(&ied0, 0, sizeof(ied0)); 10402 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10403 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10404 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10405 if (!iaxs[fr->callno]) { 10406 ast_mutex_unlock(&iaxsl[fr->callno]); 10407 return 1; 10408 } 10409 } else { 10410 /* Pick one... */ 10411 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10412 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10413 format = 0; 10414 } else { 10415 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10416 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10417 memset(&pref, 0, sizeof(pref)); 10418 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 10419 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10420 strcpy(caller_pref_buf,"disabled"); 10421 strcpy(host_pref_buf,"disabled"); 10422 } else { 10423 using_prefs = "mine"; 10424 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10425 /* Do the opposite of what we tried above. */ 10426 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10427 pref = iaxs[fr->callno]->prefs; 10428 } else { 10429 pref = iaxs[fr->callno]->rprefs; 10430 using_prefs = "caller"; 10431 } 10432 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10433 } else /* if no codec_prefs IE do it the old way */ 10434 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10435 } 10436 } 10437 if (!format) { 10438 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10439 if (authdebug) { 10440 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10441 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested 0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->capability); 10442 else 10443 ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability 0x%x/0x%x incompatible with our capability 0x%x.\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat, iaxs[fr->callno]->peercapability, iaxs[fr->callno]->capability); 10444 } 10445 memset(&ied0, 0, sizeof(ied0)); 10446 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10447 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10448 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10449 if (!iaxs[fr->callno]) { 10450 ast_mutex_unlock(&iaxsl[fr->callno]); 10451 return 1; 10452 } 10453 } 10454 } 10455 } 10456 if (format) { 10457 /* Authentication received */ 10458 memset(&ied1, 0, sizeof(ied1)); 10459 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10460 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10461 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10462 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10463 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 10464 "%srequested format = %s,\n" 10465 "%srequested prefs = %s,\n" 10466 "%sactual format = %s,\n" 10467 "%shost prefs = %s,\n" 10468 "%spriority = %s\n", 10469 ast_inet_ntoa(sin.sin_addr), 10470 VERBOSE_PREFIX_4, 10471 ast_getformatname(iaxs[fr->callno]->peerformat), 10472 VERBOSE_PREFIX_4, 10473 caller_pref_buf, 10474 VERBOSE_PREFIX_4, 10475 ast_getformatname(format), 10476 VERBOSE_PREFIX_4, 10477 host_pref_buf, 10478 VERBOSE_PREFIX_4, 10479 using_prefs); 10480 10481 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10482 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 10483 iax2_destroy(fr->callno); 10484 else if (ies.vars) { 10485 struct ast_datastore *variablestore; 10486 struct ast_variable *var, *prev = NULL; 10487 AST_LIST_HEAD(, ast_var_t) *varlist; 10488 varlist = ast_calloc(1, sizeof(*varlist)); 10489 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10490 if (variablestore && varlist) { 10491 variablestore->data = varlist; 10492 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10493 AST_LIST_HEAD_INIT(varlist); 10494 ast_debug(1, "I can haz IAX vars? w00t\n"); 10495 for (var = ies.vars; var; var = var->next) { 10496 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10497 if (prev) 10498 ast_free(prev); 10499 prev = var; 10500 if (!newvar) { 10501 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10502 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10503 } else { 10504 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10505 } 10506 } 10507 if (prev) 10508 ast_free(prev); 10509 ies.vars = NULL; 10510 ast_channel_datastore_add(c, variablestore); 10511 } else { 10512 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10513 if (variablestore) 10514 ast_datastore_free(variablestore); 10515 if (varlist) 10516 ast_free(varlist); 10517 } 10518 } 10519 } else { 10520 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10521 /* If this is a TBD call, we're ready but now what... */ 10522 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10523 } 10524 } 10525 } 10526 break; 10527 case IAX_COMMAND_DIAL: 10528 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 10529 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10530 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 10531 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 10532 if (authdebug) 10533 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); 10534 memset(&ied0, 0, sizeof(ied0)); 10535 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10536 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10537 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10538 if (!iaxs[fr->callno]) { 10539 ast_mutex_unlock(&iaxsl[fr->callno]); 10540 return 1; 10541 } 10542 } else { 10543 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10544 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 10545 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10546 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 10547 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 10548 iax2_destroy(fr->callno); 10549 else if (ies.vars) { 10550 struct ast_datastore *variablestore; 10551 struct ast_variable *var, *prev = NULL; 10552 AST_LIST_HEAD(, ast_var_t) *varlist; 10553 varlist = ast_calloc(1, sizeof(*varlist)); 10554 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10555 ast_debug(1, "I can haz IAX vars? w00t\n"); 10556 if (variablestore && varlist) { 10557 variablestore->data = varlist; 10558 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10559 AST_LIST_HEAD_INIT(varlist); 10560 for (var = ies.vars; var; var = var->next) { 10561 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10562 if (prev) 10563 ast_free(prev); 10564 prev = var; 10565 if (!newvar) { 10566 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10567 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10568 } else { 10569 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10570 } 10571 } 10572 if (prev) 10573 ast_free(prev); 10574 ies.vars = NULL; 10575 ast_channel_datastore_add(c, variablestore); 10576 } else { 10577 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10578 if (variablestore) 10579 ast_datastore_free(variablestore); 10580 if (varlist) 10581 ast_free(varlist); 10582 } 10583 } 10584 } 10585 } 10586 break; 10587 case IAX_COMMAND_INVAL: 10588 iaxs[fr->callno]->error = ENOTCONN; 10589 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 10590 iax2_destroy(fr->callno); 10591 ast_debug(1, "Destroying call %d\n", fr->callno); 10592 break; 10593 case IAX_COMMAND_VNAK: 10594 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 10595 /* Force retransmission */ 10596 vnak_retransmit(fr->callno, fr->iseqno); 10597 break; 10598 case IAX_COMMAND_REGREQ: 10599 case IAX_COMMAND_REGREL: 10600 /* For security, always ack immediately */ 10601 if (delayreject) 10602 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10603 if (register_verify(fr->callno, &sin, &ies)) { 10604 if (!iaxs[fr->callno]) { 10605 ast_mutex_unlock(&iaxsl[fr->callno]); 10606 return 1; 10607 } 10608 /* Send delayed failure */ 10609 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 10610 break; 10611 } 10612 if (!iaxs[fr->callno]) { 10613 ast_mutex_unlock(&iaxsl[fr->callno]); 10614 return 1; 10615 } 10616 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 10617 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 10618 10619 if (f.subclass == IAX_COMMAND_REGREL) 10620 memset(&sin, 0, sizeof(sin)); 10621 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 10622 ast_log(LOG_WARNING, "Registry error\n"); 10623 if (!iaxs[fr->callno]) { 10624 ast_mutex_unlock(&iaxsl[fr->callno]); 10625 return 1; 10626 } 10627 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10628 ast_mutex_unlock(&iaxsl[fr->callno]); 10629 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10630 ast_mutex_lock(&iaxsl[fr->callno]); 10631 if (!iaxs[fr->callno]) { 10632 ast_mutex_unlock(&iaxsl[fr->callno]); 10633 return 1; 10634 } 10635 } 10636 break; 10637 } 10638 registry_authrequest(fr->callno); 10639 if (!iaxs[fr->callno]) { 10640 ast_mutex_unlock(&iaxsl[fr->callno]); 10641 return 1; 10642 } 10643 break; 10644 case IAX_COMMAND_REGACK: 10645 if (iax2_ack_registry(&ies, &sin, fr->callno)) 10646 ast_log(LOG_WARNING, "Registration failure\n"); 10647 /* Send ack immediately, before we destroy */ 10648 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10649 iax2_destroy(fr->callno); 10650 break; 10651 case IAX_COMMAND_REGREJ: 10652 if (iaxs[fr->callno]->reg) { 10653 if (authdebug) { 10654 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)); 10655 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>"); 10656 } 10657 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 10658 } 10659 /* Send ack immediately, before we destroy */ 10660 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10661 iax2_destroy(fr->callno); 10662 break; 10663 case IAX_COMMAND_REGAUTH: 10664 /* Authentication request */ 10665 if (registry_rerequest(&ies, fr->callno, &sin)) { 10666 memset(&ied0, 0, sizeof(ied0)); 10667 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 10668 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 10669 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10670 if (!iaxs[fr->callno]) { 10671 ast_mutex_unlock(&iaxsl[fr->callno]); 10672 return 1; 10673 } 10674 } 10675 break; 10676 case IAX_COMMAND_TXREJ: 10677 iaxs[fr->callno]->transferring = 0; 10678 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 10679 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 10680 if (iaxs[fr->callno]->bridgecallno) { 10681 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 10682 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 10683 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 10684 } 10685 } 10686 break; 10687 case IAX_COMMAND_TXREADY: 10688 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 10689 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 10690 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 10691 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 10692 else 10693 iaxs[fr->callno]->transferring = TRANSFER_READY; 10694 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 10695 if (iaxs[fr->callno]->bridgecallno) { 10696 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 10697 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 10698 /* They're both ready, now release them. */ 10699 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 10700 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 10701 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 10702 10703 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 10704 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 10705 10706 memset(&ied0, 0, sizeof(ied0)); 10707 memset(&ied1, 0, sizeof(ied1)); 10708 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 10709 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 10710 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 10711 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 10712 } else { 10713 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 10714 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 10715 10716 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 10717 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 10718 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 10719 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 10720 10721 /* Stop doing lag & ping requests */ 10722 stop_stuff(fr->callno); 10723 stop_stuff(iaxs[fr->callno]->bridgecallno); 10724 10725 memset(&ied0, 0, sizeof(ied0)); 10726 memset(&ied1, 0, sizeof(ied1)); 10727 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 10728 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 10729 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 10730 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 10731 } 10732 10733 } 10734 } 10735 } 10736 break; 10737 case IAX_COMMAND_TXREQ: 10738 try_transfer(iaxs[fr->callno], &ies); 10739 break; 10740 case IAX_COMMAND_TXCNT: 10741 if (iaxs[fr->callno]->transferring) 10742 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 10743 break; 10744 case IAX_COMMAND_TXREL: 10745 /* Send ack immediately, rather than waiting until we've changed addresses */ 10746 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10747 complete_transfer(fr->callno, &ies); 10748 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 10749 break; 10750 case IAX_COMMAND_TXMEDIA: 10751 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 10752 AST_LIST_LOCK(&frame_queue); 10753 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 10754 /* Cancel any outstanding frames and start anew */ 10755 if ((fr->callno == cur->callno) && (cur->transfer)) 10756 cur->retries = -1; 10757 } 10758 AST_LIST_UNLOCK(&frame_queue); 10759 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 10760 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 10761 } 10762 break; 10763 case IAX_COMMAND_RTKEY: 10764 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 10765 ast_log(LOG_WARNING, 10766 "we've been told to rotate our encryption key, " 10767 "but this isn't an encrypted call. bad things will happen.\n" 10768 ); 10769 break; 10770 } 10771 10772 IAX_DEBUGDIGEST("Receiving", ies.challenge); 10773 10774 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 10775 break; 10776 case IAX_COMMAND_DPREP: 10777 complete_dpreply(iaxs[fr->callno], &ies); 10778 break; 10779 case IAX_COMMAND_UNSUPPORT: 10780 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 10781 break; 10782 case IAX_COMMAND_FWDOWNL: 10783 /* Firmware download */ 10784 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 10785 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 10786 break; 10787 } 10788 memset(&ied0, 0, sizeof(ied0)); 10789 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 10790 if (res < 0) 10791 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10792 else if (res > 0) 10793 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 10794 else 10795 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 10796 if (!iaxs[fr->callno]) { 10797 ast_mutex_unlock(&iaxsl[fr->callno]); 10798 return 1; 10799 } 10800 break; 10801 case IAX_COMMAND_CALLTOKEN: 10802 { 10803 struct iax_frame *cur; 10804 int found = 0; 10805 AST_LIST_LOCK(&frame_queue); 10806 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 10807 /* find the last sent frame in our frame queue for this callno. 10808 * There are many things to take into account before resending this frame. 10809 * All of these are taken care of in resend_with_token() */ 10810 if (cur->callno == fr->callno) { 10811 found = 1; 10812 break; 10813 } 10814 } 10815 AST_LIST_UNLOCK(&frame_queue); 10816 10817 /* find last sent frame */ 10818 if (cur && found && ies.calltoken && ies.calltokendata) { 10819 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 10820 } 10821 break; 10822 } 10823 default: 10824 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 10825 memset(&ied0, 0, sizeof(ied0)); 10826 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 10827 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 10828 } 10829 /* Free remote variables (if any) */ 10830 if (ies.vars) { 10831 ast_variables_destroy(ies.vars); 10832 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 10833 ies.vars = NULL; 10834 } 10835 10836 /* Don't actually pass these frames along */ 10837 if ((f.subclass != IAX_COMMAND_ACK) && 10838 (f.subclass != IAX_COMMAND_TXCNT) && 10839 (f.subclass != IAX_COMMAND_TXACC) && 10840 (f.subclass != IAX_COMMAND_INVAL) && 10841 (f.subclass != IAX_COMMAND_VNAK)) { 10842 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 10843 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10844 } 10845 ast_mutex_unlock(&iaxsl[fr->callno]); 10846 return 1; 10847 } 10848 /* Unless this is an ACK or INVAL frame, ack it */ 10849 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 10850 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10851 } else if (minivid) { 10852 f.frametype = AST_FRAME_VIDEO; 10853 if (iaxs[fr->callno]->videoformat > 0) 10854 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 10855 else { 10856 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 10857 iax2_vnak(fr->callno); 10858 ast_mutex_unlock(&iaxsl[fr->callno]); 10859 return 1; 10860 } 10861 f.datalen = res - sizeof(*vh); 10862 if (f.datalen) 10863 f.data.ptr = thread->buf + sizeof(*vh); 10864 else 10865 f.data.ptr = NULL; 10866 #ifdef IAXTESTS 10867 if (test_resync) { 10868 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 10869 } else 10870 #endif /* IAXTESTS */ 10871 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 10872 } else { 10873 /* A mini frame */ 10874 f.frametype = AST_FRAME_VOICE; 10875 if (iaxs[fr->callno]->voiceformat > 0) 10876 f.subclass = iaxs[fr->callno]->voiceformat; 10877 else { 10878 ast_debug(1, "Received mini frame before first full voice frame\n"); 10879 iax2_vnak(fr->callno); 10880 ast_mutex_unlock(&iaxsl[fr->callno]); 10881 return 1; 10882 } 10883 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 10884 if (f.datalen < 0) { 10885 ast_log(LOG_WARNING, "Datalen < 0?\n"); 10886 ast_mutex_unlock(&iaxsl[fr->callno]); 10887 return 1; 10888 } 10889 if (f.datalen) 10890 f.data.ptr = thread->buf + sizeof(*mh); 10891 else 10892 f.data.ptr = NULL; 10893 #ifdef IAXTESTS 10894 if (test_resync) { 10895 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 10896 } else 10897 #endif /* IAXTESTS */ 10898 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 10899 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 10900 } 10901 /* Don't pass any packets until we're started */ 10902 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10903 ast_mutex_unlock(&iaxsl[fr->callno]); 10904 return 1; 10905 } 10906 /* Common things */ 10907 f.src = "IAX2"; 10908 f.mallocd = 0; 10909 f.offset = 0; 10910 f.len = 0; 10911 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 10912 f.samples = ast_codec_get_samples(&f); 10913 /* We need to byteswap incoming slinear samples from network byte order */ 10914 if (f.subclass == AST_FORMAT_SLINEAR) 10915 ast_frame_byteswap_be(&f); 10916 } else 10917 f.samples = 0; 10918 iax_frame_wrap(fr, &f); 10919 10920 /* If this is our most recent packet, use it as our basis for timestamping */ 10921 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 10922 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 10923 fr->outoforder = 0; 10924 } else { 10925 if (iaxdebug && iaxs[fr->callno]) 10926 ast_debug(1, "Received out of order packet... (type=%d, subclass %d, ts = %d, last = %d)\n", f.frametype, f.subclass, fr->ts, iaxs[fr->callno]->last); 10927 fr->outoforder = -1; 10928 } 10929 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 10930 duped_fr = iaxfrdup2(fr); 10931 if (duped_fr) { 10932 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 10933 } 10934 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 10935 iaxs[fr->callno]->last = fr->ts; 10936 #if 1 10937 if (iaxdebug) 10938 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 10939 #endif 10940 } 10941 10942 /* Always run again */ 10943 ast_mutex_unlock(&iaxsl[fr->callno]); 10944 return 1; 10945 }
| 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 9090 of file chan_iax2.c.
References ast_codec_get_samples(), AST_FRAME_VOICE, ast_inet_ntoa(), ast_log(), ast_mutex_unlock(), ast_test_flag, ast_tvnow(), ast_tvzero(), iax_frame::callno, ast_iax2_meta_trunk_entry::callno, ast_iax2_mini_hdr::callno, ast_iax2_meta_hdr::cmddata, ast_frame::data, ast_iax2_meta_trunk_hdr::data, ast_iax2_meta_hdr::data, ast_frame::datalen, find_callno_locked(), find_tpeer(), fix_peerts(), ast_frame::frametype, iax2_vnak(), IAX_FLAG_FULL, iax_frame_wrap(), IAX_META_TRUNK, IAX_META_TRUNK_MINI, IAX_META_TRUNK_SUPERMINI, IAX_STATE_STARTED, iaxfrdup2(), chan_iax2_pvt::last, ast_iax2_meta_trunk_entry::len, ast_iax2_meta_trunk_mini::len, iax2_trunk_peer::lock, LOG_WARNING, ast_frame::mallocd, ast_iax2_meta_hdr::metacmd, ast_iax2_meta_trunk_mini::mini, NEW_PREVENT, ast_frame::offset, iax_frame::outoforder, ast_frame::ptr, iax2_trunk_peer::rxtrunktime, ast_frame::samples, schedule_delivery(), ast_frame::src, chan_iax2_pvt::state, ast_frame::subclass, iax2_trunk_peer::trunkact, iax_frame::ts, ast_iax2_mini_hdr::ts, ast_iax2_meta_trunk_hdr::ts, and chan_iax2_pvt::voiceformat.
Referenced by socket_process().
09092 { 09093 unsigned char metatype; 09094 struct ast_iax2_meta_trunk_mini *mtm; 09095 struct ast_iax2_meta_trunk_hdr *mth; 09096 struct ast_iax2_meta_trunk_entry *mte; 09097 struct iax2_trunk_peer *tpeer; 09098 unsigned int ts; 09099 void *ptr; 09100 struct timeval rxtrunktime; 09101 struct ast_frame f = { 0, }; 09102 09103 if (packet_len < sizeof(*meta)) { 09104 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09105 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09106 return 1; 09107 } 09108 09109 if (meta->metacmd != IAX_META_TRUNK) 09110 return 1; 09111 09112 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09113 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09114 (int) (sizeof(*meta) + sizeof(*mth))); 09115 return 1; 09116 } 09117 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09118 ts = ntohl(mth->ts); 09119 metatype = meta->cmddata; 09120 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09121 ptr = mth->data; 09122 tpeer = find_tpeer(sin, sockfd); 09123 if (!tpeer) { 09124 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09125 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09126 return 1; 09127 } 09128 tpeer->trunkact = ast_tvnow(); 09129 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09130 tpeer->rxtrunktime = tpeer->trunkact; 09131 rxtrunktime = tpeer->rxtrunktime; 09132 ast_mutex_unlock(&tpeer->lock); 09133 while (packet_len >= sizeof(*mte)) { 09134 /* Process channels */ 09135 unsigned short callno, trunked_ts, len; 09136 09137 if (metatype == IAX_META_TRUNK_MINI) { 09138 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09139 ptr += sizeof(*mtm); 09140 packet_len -= sizeof(*mtm); 09141 len = ntohs(mtm->len); 09142 callno = ntohs(mtm->mini.callno); 09143 trunked_ts = ntohs(mtm->mini.ts); 09144 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09145 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09146 ptr += sizeof(*mte); 09147 packet_len -= sizeof(*mte); 09148 len = ntohs(mte->len); 09149 callno = ntohs(mte->callno); 09150 trunked_ts = 0; 09151 } else { 09152 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09153 break; 09154 } 09155 /* Stop if we don't have enough data */ 09156 if (len > packet_len) 09157 break; 09158 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09159 if (!fr->callno) 09160 continue; 09161 09162 /* If it's a valid call, deliver the contents. If not, we 09163 drop it, since we don't have a scallno to use for an INVAL */ 09164 /* Process as a mini frame */ 09165 memset(&f, 0, sizeof(f)); 09166 f.frametype = AST_FRAME_VOICE; 09167 if (!iaxs[fr->callno]) { 09168 /* drop it */ 09169 } else if (iaxs[fr->callno]->voiceformat == 0) { 09170 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09171 iax2_vnak(fr->callno); 09172 } else { 09173 f.subclass = iaxs[fr->callno]->voiceformat; 09174 f.datalen = len; 09175 if (f.datalen >= 0) { 09176 if (f.datalen) 09177 f.data.ptr = ptr; 09178 else 09179 f.data.ptr = NULL; 09180 if (trunked_ts) 09181 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09182 else 09183 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09184 /* Don't pass any packets until we're started */ 09185 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09186 struct iax_frame *duped_fr; 09187 09188 /* Common things */ 09189 f.src = "IAX2"; 09190 f.mallocd = 0; 09191 f.offset = 0; 09192 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09193 f.samples = ast_codec_get_samples(&f); 09194 else 09195 f.samples = 0; 09196 fr->outoforder = 0; 09197 iax_frame_wrap(fr, &f); 09198 duped_fr = iaxfrdup2(fr); 09199 if (duped_fr) 09200 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09201 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09202 iaxs[fr->callno]->last = fr->ts; 09203 } 09204 } else { 09205 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09206 } 09207 } 09208 ast_mutex_unlock(&iaxsl[fr->callno]); 09209 ptr += len; 09210 packet_len -= len; 09211 } 09212 09213 return 1; 09214 }
| static int socket_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 9012 of file chan_iax2.c.
References ast_copy_string(), ast_debug, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_random(), iax2_thread::buf, iax2_thread::buf_len, iax2_thread::buf_size, iax2_thread::callno, iax2_thread::cond, ast_iax2_full_hdr::csub, iax2_thread::csub, iax2_thread::curfunc, defer_full_frame(), errno, iax2_thread::ffinfo, find_idle_thread(), handle_error(), IAX_FLAG_FULL, IAX_IOSTATE_IDLE, IAX_IOSTATE_READY, inaddrcmp(), iax2_thread::iofd, iax2_thread::iosin, iax2_thread::iostate, iax2_thread::lock, LOG_WARNING, iax2_thread::readbuf, ast_iax2_full_hdr::scallno, signal_condition(), iax2_thread::sin, thread, ast_iax2_full_hdr::type, and iax2_thread::type.
Referenced by peer_set_srcaddr(), and set_config().
09013 { 09014 struct iax2_thread *thread; 09015 socklen_t len; 09016 time_t t; 09017 static time_t last_errtime = 0; 09018 struct ast_iax2_full_hdr *fh; 09019 09020 if (!(thread = find_idle_thread())) { 09021 time(&t); 09022 if (t != last_errtime) 09023 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09024 last_errtime = t; 09025 usleep(1); 09026 return 1; 09027 } 09028 09029 len = sizeof(thread->iosin); 09030 thread->iofd = fd; 09031 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09032 thread->buf_size = sizeof(thread->readbuf); 09033 thread->buf = thread->readbuf; 09034 if (thread->buf_len < 0) { 09035 if (errno != ECONNREFUSED && errno != EAGAIN) 09036 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09037 handle_error(); 09038 thread->iostate = IAX_IOSTATE_IDLE; 09039 signal_condition(&thread->lock, &thread->cond); 09040 return 1; 09041 } 09042 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09043 thread->iostate = IAX_IOSTATE_IDLE; 09044 signal_condition(&thread->lock, &thread->cond); 09045 return 1; 09046 } 09047 09048 /* Determine if this frame is a full frame; if so, and any thread is currently 09049 processing a full frame for the same callno from this peer, then drop this 09050 frame (and the peer will retransmit it) */ 09051 fh = (struct ast_iax2_full_hdr *) thread->buf; 09052 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09053 struct iax2_thread *cur = NULL; 09054 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09055 09056 AST_LIST_LOCK(&active_list); 09057 AST_LIST_TRAVERSE(&active_list, cur, list) { 09058 if ((cur->ffinfo.callno == callno) && 09059 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09060 break; 09061 } 09062 if (cur) { 09063 /* we found another thread processing a full frame for this call, 09064 so queue it up for processing later. */ 09065 defer_full_frame(thread, cur); 09066 AST_LIST_UNLOCK(&active_list); 09067 thread->iostate = IAX_IOSTATE_IDLE; 09068 signal_condition(&thread->lock, &thread->cond); 09069 return 1; 09070 } else { 09071 /* this thread is going to process this frame, so mark it */ 09072 thread->ffinfo.callno = callno; 09073 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09074 thread->ffinfo.type = fh->type; 09075 thread->ffinfo.csub = fh->csub; 09076 } 09077 AST_LIST_UNLOCK(&active_list); 09078 } 09079 09080 /* Mark as ready and send on its way */ 09081 thread->iostate = IAX_IOSTATE_READY; 09082 #ifdef DEBUG_SCHED_MULTITHREAD 09083 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09084 #endif 09085 signal_condition(&thread->lock, &thread->cond); 09086 09087 return 1; 09088 }
| static void spawn_dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid | |||
| ) | [static] |
Definition at line 8728 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), ast_log(), ast_pthread_create_detached, ast_strdup, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, dp_lookup_thread(), and LOG_WARNING.
Referenced by socket_process().
08729 { 08730 pthread_t newthread; 08731 struct dpreq_data *dpr; 08732 08733 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 08734 return; 08735 08736 dpr->callno = callno; 08737 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 08738 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 08739 if (callerid) 08740 dpr->callerid = ast_strdup(callerid); 08741 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 08742 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 08743 } 08744 }
| static int start_network_thread | ( | void | ) | [static] |
Definition at line 11561 of file chan_iax2.c.
References ast_calloc, ast_cond_init(), ast_free, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_mutex_init(), ast_pthread_create_background, ast_pthread_create_detached, ast_verb, iax2_thread::cond, iax2_process_thread(), IAX_THREAD_TYPE_POOL, iaxthreadcount, iax2_thread::lock, LOG_WARNING, network_thread(), sched_thread(), thread, iax2_thread::threadid, iax2_thread::threadnum, and iax2_thread::type.
Referenced by load_module().
11562 { 11563 struct iax2_thread *thread; 11564 int threadcount = 0; 11565 int x; 11566 for (x = 0; x < iaxthreadcount; x++) { 11567 thread = ast_calloc(1, sizeof(*thread)); 11568 if (thread) { 11569 thread->type = IAX_THREAD_TYPE_POOL; 11570 thread->threadnum = ++threadcount; 11571 ast_mutex_init(&thread->lock); 11572 ast_cond_init(&thread->cond, NULL); 11573 if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) { 11574 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 11575 ast_free(thread); 11576 thread = NULL; 11577 } 11578 AST_LIST_LOCK(&idle_list); 11579 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 11580 AST_LIST_UNLOCK(&idle_list); 11581 } 11582 } 11583 ast_pthread_create_background(&schedthreadid, NULL, sched_thread, NULL); 11584 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 11585 ast_verb(2, "%d helper threads started\n", threadcount); 11586 return 0; 11587 }
| static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 8431 of file chan_iax2.c.
References iax2_destroy_helper().
Referenced by socket_process().
08432 { 08433 iax2_destroy_helper(iaxs[callno]); 08434 }
| static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1868 of file chan_iax2.c.
References ao2_link, ast_log(), LOG_ERROR, and chan_iax2_pvt::peercallno.
Referenced by __find_callno(), complete_transfer(), and socket_process().
01869 { 01870 if (!pvt->peercallno) { 01871 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01872 return; 01873 } 01874 01875 ao2_link(iax_peercallno_pvts, pvt); 01876 }
| static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1849 of file chan_iax2.c.
References ao2_link, ast_log(), LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
01850 { 01851 if (!pvt->transfercallno) { 01852 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01853 return; 01854 } 01855 01856 ao2_link(iax_transfercallno_pvts, pvt); 01857 }
| static int timing_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 8617 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(), totalcalls, iax2_trunk_peer::trunkdataalloc, and iax2_trunk_peer::trunkdatalen.
Referenced by network_thread().
08618 { 08619 int res, processed = 0, totalcalls = 0; 08620 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 08621 struct timeval now = ast_tvnow(); 08622 08623 if (iaxtrunkdebug) 08624 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 08625 08626 if (timer) { 08627 ast_timer_ack(timer, 1); 08628 } 08629 08630 /* For each peer that supports trunking... */ 08631 AST_LIST_LOCK(&tpeers); 08632 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 08633 processed++; 08634 res = 0; 08635 ast_mutex_lock(&tpeer->lock); 08636 /* We can drop a single tpeer per pass. That makes all this logic 08637 substantially easier */ 08638 if (!drop && iax2_trunk_expired(tpeer, &now)) { 08639 /* Take it out of the list, but don't free it yet, because it 08640 could be in use */ 08641 AST_LIST_REMOVE_CURRENT(list); 08642 drop = tpeer; 08643 } else { 08644 res = send_trunk(tpeer, &now); 08645 trunk_timed++; 08646 if (iaxtrunkdebug) 08647 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); 08648 } 08649 totalcalls += res; 08650 res = 0; 08651 ast_mutex_unlock(&tpeer->lock); 08652 } 08653 AST_LIST_TRAVERSE_SAFE_END; 08654 AST_LIST_UNLOCK(&tpeers); 08655 08656 if (drop) { 08657 ast_mutex_lock(&drop->lock); 08658 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 08659 because by the time they could get tpeerlock, we've already grabbed it */ 08660 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 08661 if (drop->trunkdata) { 08662 ast_free(drop->trunkdata); 08663 drop->trunkdata = NULL; 08664 } 08665 ast_mutex_unlock(&drop->lock); 08666 ast_mutex_destroy(&drop->lock); 08667 ast_free(drop); 08668 08669 } 08670 08671 if (iaxtrunkdebug) 08672 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 08673 iaxtrunkdebug = 0; 08674 08675 return 1; 08676 }
| static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 13595 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
13596 { 13597 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 13598 13599 /* The frames_received field is used to hold whether we're matching 13600 * against a full frame or not ... */ 13601 13602 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 13603 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 13604 }
| static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 13588 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
13589 { 13590 const struct chan_iax2_pvt *pvt = obj; 13591 13592 return pvt->transfercallno; 13593 }
| static int transmit_trunk | ( | struct iax_frame * | f, | |
| struct sockaddr_in * | sin, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 3058 of file chan_iax2.c.
References ast_debug, iax_frame::data, iax_frame::datalen, errno, and handle_error().
Referenced by send_trunk().
03059 { 03060 int res; 03061 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03062 sizeof(*sin)); 03063 if (res < 0) { 03064 ast_debug(1, "Received error: %s\n", strerror(errno)); 03065 handle_error(); 03066 } else 03067 res = 0; 03068 return res; 03069 }
| static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 2760 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, LOG_WARNING, ast_iax2_firmware_header::magic, MD5Final(), MD5Init(), MD5Update(), iax_firmware::mmaplen, and ast_iax2_firmware_header::version.
Referenced by reload_firmware().
02761 { 02762 struct stat stbuf; 02763 struct iax_firmware *cur = NULL; 02764 int ifd, fd, res, len, chunk; 02765 struct ast_iax2_firmware_header *fwh, fwh2; 02766 struct MD5Context md5; 02767 unsigned char sum[16], buf[1024]; 02768 char *s2, *last; 02769 02770 if (!(s2 = alloca(strlen(s) + 100))) { 02771 ast_log(LOG_WARNING, "Alloca failed!\n"); 02772 return -1; 02773 } 02774 02775 last = strrchr(s, '/'); 02776 if (last) 02777 last++; 02778 else 02779 last = s; 02780 02781 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 02782 02783 if ((res = stat(s, &stbuf) < 0)) { 02784 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 02785 return -1; 02786 } 02787 02788 /* Make sure it's not a directory */ 02789 if (S_ISDIR(stbuf.st_mode)) 02790 return -1; 02791 ifd = open(s, O_RDONLY); 02792 if (ifd < 0) { 02793 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 02794 return -1; 02795 } 02796 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 02797 if (fd < 0) { 02798 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 02799 close(ifd); 02800 return -1; 02801 } 02802 /* Unlink our newly created file */ 02803 unlink(s2); 02804 02805 /* Now copy the firmware into it */ 02806 len = stbuf.st_size; 02807 while(len) { 02808 chunk = len; 02809 if (chunk > sizeof(buf)) 02810 chunk = sizeof(buf); 02811 res = read(ifd, buf, chunk); 02812 if (res != chunk) { 02813 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02814 close(ifd); 02815 close(fd); 02816 return -1; 02817 } 02818 res = write(fd, buf, chunk); 02819 if (res != chunk) { 02820 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02821 close(ifd); 02822 close(fd); 02823 return -1; 02824 } 02825 len -= chunk; 02826 } 02827 close(ifd); 02828 /* Return to the beginning */ 02829 lseek(fd, 0, SEEK_SET); 02830 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 02831 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 02832 close(fd); 02833 return -1; 02834 } 02835 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 02836 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 02837 close(fd); 02838 return -1; 02839 } 02840 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 02841 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 02842 close(fd); 02843 return -1; 02844 } 02845 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 02846 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 02847 close(fd); 02848 return -1; 02849 } 02850 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 02851 if (fwh == MAP_FAILED) { 02852 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 02853 close(fd); 02854 return -1; 02855 } 02856 MD5Init(&md5); 02857 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 02858 MD5Final(sum, &md5); 02859 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 02860 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 02861 munmap((void*)fwh, stbuf.st_size); 02862 close(fd); 02863 return -1; 02864 } 02865 02866 AST_LIST_TRAVERSE(&firmwares, cur, list) { 02867 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 02868 /* Found a candidate */ 02869 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 02870 /* The version we have on loaded is older, load this one instead */ 02871 break; 02872 /* This version is no newer than what we have. Don't worry about it. 02873 We'll consider it a proper load anyhow though */ 02874 munmap((void*)fwh, stbuf.st_size); 02875 close(fd); 02876 return 0; 02877 } 02878 } 02879 02880 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 02881 cur->fd = -1; 02882 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 02883 } 02884 02885 if (cur) { 02886 if (cur->fwh) 02887 munmap((void*)cur->fwh, cur->mmaplen); 02888 if (cur->fd > -1) 02889 close(cur->fd); 02890 cur->fwh = fwh; 02891 cur->fd = fd; 02892 cur->mmaplen = stbuf.st_size; 02893 cur->dead = 0; 02894 } 02895 02896 return 0; 02897 }
| static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7779 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, iax_ie_data::pos, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
07780 { 07781 int newcall = 0; 07782 char newip[256]; 07783 struct iax_ie_data ied; 07784 struct sockaddr_in new; 07785 07786 07787 memset(&ied, 0, sizeof(ied)); 07788 if (ies->apparent_addr) 07789 memmove(&new, ies->apparent_addr, sizeof(new)); 07790 if (ies->callno) 07791 newcall = ies->callno; 07792 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 07793 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07794 return -1; 07795 } 07796 pvt->transfercallno = newcall; 07797 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 07798 inet_aton(newip, &pvt->transfer.sin_addr); 07799 pvt->transfer.sin_family = AF_INET; 07800 pvt->transferring = TRANSFER_BEGIN; 07801 pvt->transferid = ies->transferid; 07802 store_by_transfercallno(pvt); 07803 if (ies->transferid) 07804 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 07805 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 07806 return 0; 07807 }
| static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1390 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01391 { 01392 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01393 if (csub & IAX_FLAG_SC_LOG) { 01394 /* special case for 'compressed' -1 */ 01395 if (csub == 0xff) 01396 return -1; 01397 else 01398 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01399 } 01400 else 01401 return csub; 01402 }
| static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8065 of file chan_iax2.c.
References ao2_unlink, ast_sched_del(), iax2_peer::expire, peer_unref(), and iax2_peer::pokeexpire.
Referenced by __expire_registry(), build_peer(), and prune_peers().
08066 { 08067 if (peer->expire > -1) { 08068 if (!ast_sched_del(sched, peer->expire)) { 08069 peer->expire = -1; 08070 peer_unref(peer); 08071 } 08072 } 08073 08074 if (peer->pokeexpire > -1) { 08075 if (!ast_sched_del(sched, peer->pokeexpire)) { 08076 peer->pokeexpire = -1; 08077 peer_unref(peer); 08078 } 08079 } 08080 08081 ao2_unlink(peers, peer); 08082 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 13553 of file chan_iax2.c.
References __unload_module(), and ast_custom_function_unregister().
13554 { 13555 ast_custom_function_unregister(&iaxpeer_function); 13556 ast_custom_function_unregister(&iaxvar_function); 13557 return __unload_module(); 13558 }
| static void unlock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5058 of file chan_iax2.c.
References ast_mutex_unlock().
Referenced by iax2_bridge().
05059 { 05060 ast_mutex_unlock(&iaxsl[callno1]); 05061 ast_mutex_unlock(&iaxsl[callno0]); 05062 }
| static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3725 of file chan_iax2.c.
References iax_frame::af, ast_debug, AST_FRAME_VIDEO, iax_frame::callno, ast_frame::frametype, chan_iax2_pvt::last, and iax_frame::ts.
Referenced by schedule_delivery().
03726 { 03727 /* Video mini frames only encode the lower 15 bits of the session 03728 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 03729 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 03730 const int lower_mask = (1 << ts_shift) - 1; 03731 const int upper_mask = ~lower_mask; 03732 const int last_upper = iaxs[fr->callno]->last & upper_mask; 03733 03734 if ( (fr->ts & upper_mask) == last_upper ) { 03735 const int x = fr->ts - iaxs[fr->callno]->last; 03736 const int threshold = (ts_shift == 15) ? 25000 : 50000; 03737 03738 if (x < -threshold) { 03739 /* Sudden big jump backwards in timestamp: 03740 What likely happened here is that miniframe timestamp has circled but we haven't 03741 gotten the update from the main packet. We'll just pretend that we did, and 03742 update the timestamp appropriately. */ 03743 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 03744 if (iaxdebug) 03745 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 03746 } else if (x > threshold) { 03747 /* Sudden apparent big jump forwards in timestamp: 03748 What's likely happened is this is an old miniframe belonging to the previous 03749 top 15 or 16-bit timestamp that has turned up out of order. 03750 Adjust the timestamp appropriately. */ 03751 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 03752 if (iaxdebug) 03753 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 03754 } 03755 } 03756 }
| static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 3760 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), chan_iax2_pvt::callno, CALLNO_TO_PTR, get_from_jb(), iax2_sched_replace(), chan_iax2_pvt::jb, jb_next(), chan_iax2_pvt::jbid, and chan_iax2_pvt::rxcore.
Referenced by __get_from_jb(), and schedule_delivery().
03761 { 03762 int when; 03763 03764 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 03765 03766 when = jb_next(pvt->jb) - when; 03767 03768 if (when <= 0) { 03769 /* XXX should really just empty until when > 0.. */ 03770 when = 1; 03771 } 03772 03773 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 03774 CALLNO_TO_PTR(pvt->callno)); 03775 }
| static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1777 of file chan_iax2.c.
References ast_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01778 { 01779 int max = 1; 01780 int x; 01781 /* XXX Prolly don't need locks here XXX */ 01782 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01783 if (iaxs[x]) 01784 max = x + 1; 01785 } 01786 maxnontrunkcall = max; 01787 if (iaxdebug) 01788 ast_debug(1, "New max nontrunk callno is %d\n", max); 01789 }
| static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1760 of file chan_iax2.c.
References ARRAY_LEN, ast_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01761 { 01762 int max = TRUNK_CALL_START; 01763 int x; 01764 01765 /* XXX Prolly don't need locks here XXX */ 01766 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01767 if (iaxs[x]) { 01768 max = x + 1; 01769 } 01770 } 01771 01772 maxtrunkcall = max; 01773 if (iaxdebug) 01774 ast_debug(1, "New max trunk callno is %d\n", max); 01775 }
| static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3187 of file chan_iax2.c.
References build_rand_pad(), iax_frame::callno, iax_frame::data, iax_frame::datalen, iax_frame::dcallno, ast_iax2_full_hdr::dcallno, decode_frame(), iax_frame::ecx, iax_frame::encmethods, encrypt_frame(), IAX_FLAG_RETRANS, ast_iax2_full_hdr::iseqno, chan_iax2_pvt::iseqno, iax_frame::iseqno, iax_frame::mydcx, and iax_frame::semirand.
Referenced by __attempt_transmit().
03188 { 03189 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03190 struct ast_iax2_full_hdr *fh = f->data; 03191 struct ast_frame af; 03192 03193 /* if frame is encrypted. decrypt before updating it. */ 03194 if (f->encmethods) { 03195 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03196 } 03197 /* Mark this as a retransmission */ 03198 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03199 /* Update iseqno */ 03200 f->iseqno = iaxs[f->callno]->iseqno; 03201 fh->iseqno = f->iseqno; 03202 03203 /* Now re-encrypt the frame */ 03204 if (f->encmethods) { 03205 /* since this is a retransmit frame, create a new random padding 03206 * before re-encrypting. */ 03207 build_rand_pad(f->semirand, sizeof(f->semirand)); 03208 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03209 } 03210 return 0; 03211 }
| static int update_registry | ( | struct sockaddr_in * | sin, | |
| int | callno, | |||
| char * | devtype, | |||
| int | fd, | |||
| unsigned short | refresh | |||
| ) | [static] |
Definition at line 8176 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_del(), ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_verb, iax_ie_data::buf, iax2_peer::cid_name, iax2_peer::cid_num, context, EVENT_FLAG_SYSTEM, iax2_peer::expire, expire_registry(), iax2_peer::expiry, find_peer(), iax2_datetime(), iax2_poke_peer(), iax2_regfunk, iax2_sched_add(), iax_check_version(), IAX_COMMAND_REGACK, IAX_HASCALLERID, IAX_IE_APPARENT_ADDR, iax_ie_append_addr(), iax_ie_append_int(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_CALLING_NAME, IAX_IE_CALLING_NUMBER, IAX_IE_DATETIME, IAX_IE_FIRMWAREVER, IAX_IE_MSGCOUNT, IAX_IE_REFRESH, IAX_IE_USERNAME, IAX_RTCACHEFRIENDS, IAX_RTUPDATE, IAX_STATE_AUTHENTICATED, IAX_TEMPONLY, inaddrcmp(), 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(), send_command_final(), iax2_peer::sockfd, strsep(), version, and iax2_peer::zonetag.
Referenced by socket_process().
08177 { 08178 /* Called from IAX thread only, with proper iaxsl lock */ 08179 struct iax_ie_data ied; 08180 struct iax2_peer *p; 08181 int msgcount; 08182 char data[80]; 08183 int version; 08184 const char *peer_name; 08185 int res = -1; 08186 08187 memset(&ied, 0, sizeof(ied)); 08188 08189 peer_name = ast_strdupa(iaxs[callno]->peer); 08190 08191 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08192 ast_mutex_unlock(&iaxsl[callno]); 08193 if (!(p = find_peer(peer_name, 1))) { 08194 ast_mutex_lock(&iaxsl[callno]); 08195 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08196 return -1; 08197 } 08198 ast_mutex_lock(&iaxsl[callno]); 08199 if (!iaxs[callno]) 08200 goto return_unref; 08201 08202 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08203 if (sin->sin_addr.s_addr) { 08204 time_t nowtime; 08205 time(&nowtime); 08206 realtime_update_peer(peer_name, sin, nowtime); 08207 } else { 08208 realtime_update_peer(peer_name, sin, 0); 08209 } 08210 } 08211 if (inaddrcmp(&p->addr, sin)) { 08212 if (iax2_regfunk) 08213 iax2_regfunk(p->name, 1); 08214 08215 /* modify entry in peercnts table as _not_ registered */ 08216 peercnt_modify(0, 0, &p->addr); 08217 08218 /* Stash the IP address from which they registered */ 08219 memcpy(&p->addr, sin, sizeof(p->addr)); 08220 08221 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08222 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08223 ast_db_put("IAX/Registry", p->name, data); 08224 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08225 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08226 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08227 register_peer_exten(p, 1); 08228 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08229 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 08230 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08231 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08232 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08233 register_peer_exten(p, 0); 08234 ast_db_del("IAX/Registry", p->name); 08235 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */ 08236 } 08237 /* Update the host */ 08238 /* Verify that the host is really there */ 08239 iax2_poke_peer(p, callno); 08240 } 08241 08242 /* modify entry in peercnts table as registered */ 08243 if (p->maxcallno) { 08244 peercnt_modify(1, p->maxcallno, &p->addr); 08245 } 08246 08247 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08248 if (!iaxs[callno]) { 08249 res = -1; 08250 goto return_unref; 08251 } 08252 08253 /* Store socket fd */ 08254 p->sockfd = fd; 08255 /* Setup the expiry */ 08256 if (p->expire > -1) { 08257 if (!ast_sched_del(sched, p->expire)) { 08258 p->expire = -1; 08259 peer_unref(p); 08260 } 08261 } 08262 /* treat an unspecified refresh interval as the minimum */ 08263 if (!refresh) 08264 refresh = min_reg_expire; 08265 if (refresh > max_reg_expire) { 08266 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08267 p->name, max_reg_expire, refresh); 08268 p->expiry = max_reg_expire; 08269 } else if (refresh < min_reg_expire) { 08270 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08271 p->name, min_reg_expire, refresh); 08272 p->expiry = min_reg_expire; 08273 } else { 08274 p->expiry = refresh; 08275 } 08276 if (p->expiry && sin->sin_addr.s_addr) { 08277 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08278 if (p->expire == -1) 08279 peer_unref(p); 08280 } 08281 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08282 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08283 if (sin->sin_addr.s_addr) { 08284 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08285 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 08286 if (!ast_strlen_zero(p->mailbox)) { 08287 struct ast_event *event; 08288 int new, old; 08289 char *mailbox, *context; 08290 08291 context = mailbox = ast_strdupa(p->mailbox); 08292 strsep(&context, "@"); 08293 if (ast_strlen_zero(context)) 08294 context = "default"; 08295 08296 event = ast_event_get_cached(AST_EVENT_MWI, 08297 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08298 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08299 AST_EVENT_IE_END); 08300 if (event) { 08301 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08302 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08303 ast_event_destroy(event); 08304 } else { /* Fall back on checking the mailbox directly */ 08305 ast_app_inboxcount(p->mailbox, &new, &old); 08306 } 08307 08308 if (new > 255) { 08309 new = 255; 08310 } 08311 if (old > 255) { 08312 old = 255; 08313 } 08314 msgcount = (old << 8) | new; 08315 08316 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08317 } 08318 if (ast_test_flag(p, IAX_HASCALLERID)) { 08319 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08320 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08321 } 08322 } 08323 version = iax_check_version(devtype); 08324 if (version) 08325 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08326 08327 res = 0; 08328 08329 return_unref: 08330 peer_unref(p); 08331 08332 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08333 }
| static int user_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1437 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, and iax2_user::name.
Referenced by load_objects().
| static int user_delme_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 12236 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
12237 { 12238 struct iax2_user *user = obj; 12239 12240 ast_set_flag(user, IAX_DELME); 12241 12242 return 0; 12243 }
| static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 11987 of file chan_iax2.c.
References ast_free_ha(), ast_string_field_free_memory, ast_variables_destroy(), iax2_user::contexts, free_context(), iax2_user::ha, and iax2_user::vars.
Referenced by build_user().
11988 { 11989 struct iax2_user *user = obj; 11990 11991 ast_free_ha(user->ha); 11992 free_context(user->contexts); 11993 if(user->vars) { 11994 ast_variables_destroy(user->vars); 11995 user->vars = NULL; 11996 } 11997 ast_string_field_free_memory(user); 11998 }
| static int user_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1427 of file chan_iax2.c.
References ast_str_hash(), and iax2_user::name.
Referenced by load_objects().
01428 { 01429 const struct iax2_user *user = obj; 01430 01431 return ast_str_hash(user->name); 01432 }
Definition at line 1484 of file chan_iax2.c.
References ao2_ref.
01485 { 01486 ao2_ref(user, +1); 01487 return user; 01488 }
Definition at line 1490 of file chan_iax2.c.
References ao2_ref.
Referenced by authenticate_request(), authenticate_verify(), build_user(), calltoken_required(), check_access(), handle_cli_iax2_prune_realtime(), handle_cli_iax2_show_users(), iax2_destroy_helper(), prune_users(), requirecalltoken_mark_auto(), and set_config().
01491 { 01492 ao2_ref(user, -1); 01493 return NULL; 01494 }
| static void vnak_retransmit | ( | int | callno, | |
| int | last | |||
| ) | [static] |
Definition at line 8532 of file chan_iax2.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, iax_frame::callno, f, iax_frame::oseqno, iax_frame::retries, and send_packet().
Referenced by socket_process().
08533 { 08534 struct iax_frame *f; 08535 08536 AST_LIST_LOCK(&frame_queue); 08537 AST_LIST_TRAVERSE(&frame_queue, f, list) { 08538 /* Send a copy immediately */ 08539 if ((f->callno == callno) && iaxs[f->callno] && 08540 ((unsigned char ) (f->oseqno - last) < 128) && 08541 (f->retries >= 0)) { 08542 send_packet(f); 08543 } 08544 } 08545 AST_LIST_UNLOCK(&frame_queue); 08546 }
| static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 4915 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
04916 { 04917 unsigned short callno = pvt->callno; 04918 04919 if (!pvt->peercallno) { 04920 /* We don't know the remote side's call number, yet. :( */ 04921 int count = 10; 04922 while (count-- && pvt && !pvt->peercallno) { 04923 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 04924 pvt = iaxs[callno]; 04925 } 04926 if (!pvt->peercallno) { 04927 return -1; 04928 } 04929 } 04930 04931 return 0; 04932 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 13776 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 243 of file chan_iax2.c.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_call_forward(), ast_cdr_setaccount(), begin_dial_channel(), check_peer_ok(), dahdi_new(), dial_exec_full(), disa_exec(), do_forward(), findmeexec(), gtalk_new(), jingle_new(), local_call(), sip_new(), tds_log(), and wait_for_answer().
int adsi = 0 [static] |
Definition at line 247 of file chan_iax2.c.
int amaflags = 0 [static] |
Definition at line 246 of file chan_iax2.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 13776 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 159 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 160 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 753 of file chan_iax2.c.
struct ao2_container* callno_pool [static] |
table of available call numbers
Definition at line 712 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 717 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 715 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 756 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
Definition at line 13435 of file chan_iax2.c.
| unsigned int cos |
Definition at line 170 of file chan_iax2.c.
struct sockaddr_in debugaddr [static] |
Definition at line 959 of file chan_iax2.c.
Referenced by handle_cli_iax2_set_debug(), iax_outputframe(), and reload_config().
uint16_t DEFAULT_MAXCALLNO_LIMIT = 2048 [static] |
Definition at line 758 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 760 of file chan_iax2.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Definition at line 140 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 182 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 248 of file chan_iax2.c.
int global_max_trunk_mtu [static] |
Maximum MTU, 0 if not used
Definition at line 135 of file chan_iax2.c.
uint16_t global_maxcallno [static] |
Definition at line 762 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 765 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 302 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 251 of file chan_iax2.c.
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 229 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 249 of file chan_iax2.c.
| int(* iax2_regfunk)(const char *username, int onoff) = NULL |
Referenced by __expire_registry(), reg_source_db(), and update_registry().
struct ast_switch iax2_switch [static] |
Definition at line 13321 of file chan_iax2.c.
struct ast_channel_tech iax2_tech [static] |
Definition at line 1074 of file chan_iax2.c.
struct ast_datastore_info iax2_variable_datastore_info [static] |
{
.type = "IAX2_VARIABLE",
.duplicate = iax2_dup_variable_datastore,
.destroy = iax2_free_variable_datastore,
}
Definition at line 1119 of file chan_iax2.c.
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 936 of file chan_iax2.c.
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 952 of file chan_iax2.c.
int iaxactivethreadcount = 0 [static] |
Definition at line 501 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 161 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 231 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 164 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 166 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 499 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxdynamicthreadnum = 0 [static] |
Definition at line 500 of file chan_iax2.c.
Referenced by find_idle_thread().
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
Definition at line 498 of file chan_iax2.c.
Referenced by find_idle_thread(), and set_config().
Definition at line 13199 of file chan_iax2.c.
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS] [static] |
an array of iax2 pvt structures
The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.
Definition at line 925 of file chan_iax2.c.
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 945 of file chan_iax2.c.
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 497 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 233 of file chan_iax2.c.
struct ast_custom_function iaxvar_function [static] |
Definition at line 9282 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 226 of file chan_iax2.c.
int jittertargetextra = 40 [static] |
Definition at line 152 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 148 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 142 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 162 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 730 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 174 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 146 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 145 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 149 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 151 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 1026 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 1025 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 173 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 244 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 245 of file chan_iax2.c.
Referenced by check_peer_ok(), create_addr_from_peer(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 180 of file chan_iax2.c.
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 253 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 181 of file chan_iax2.c.
char* papp = "IAX2Provision" [static] |
Definition at line 11191 of file chan_iax2.c.
char* pdescrip [static] |
" IAX2Provision([template]): Provisions the calling IAXy (assuming\n" "the calling entity is in fact an IAXy) with the given template or\n" "default if one is not specified. Returns -1 on error or 0 on success.\n"
Definition at line 11193 of file chan_iax2.c.
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 750 of file chan_iax2.c.
struct ao2_container* peers [static] |
Definition at line 744 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 147 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 126 of file chan_iax2.c.
Referenced by ast_best_codec(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), and set_config().
char* psyn = "Provision a calling IAXy with a given template" [static] |
Definition at line 11192 of file chan_iax2.c.
struct { ... } qos [static] |
Referenced by peer_set_srcaddr(), and set_config().
int randomcalltokendata [static] |
Definition at line 728 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 143 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 150 of file chan_iax2.c.
struct sched_context* sched [static] |
Definition at line 227 of file chan_iax2.c.
ast_cond_t sched_cond [static] |
Definition at line 256 of file chan_iax2.c.
ast_mutex_t sched_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static] |
Definition at line 255 of file chan_iax2.c.
Referenced by __unload_module(), iax2_sched_add(), iax2_sched_replace(), iax2_transmit(), and sched_thread().
pthread_t schedthreadid = AST_PTHREADT_NULL [static] |
Definition at line 254 of file chan_iax2.c.
int srvlookup = 0 [static] |
Definition at line 176 of file chan_iax2.c.
Referenced by build_peer().
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 128 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 235 of file chan_iax2.c.
Definition at line 178 of file chan_iax2.c.
Referenced by find_timer(), process_dahdi(), pthread_timer_ack(), pthread_timer_close(), pthread_timer_destructor(), pthread_timer_disable_continuous(), pthread_timer_enable_continuous(), pthread_timer_get_event(), pthread_timer_hash(), pthread_timer_open(), pthread_timer_set_rate(), run_timer(), and timing_test().
| unsigned int tos |
Definition at line 169 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 767 of file chan_iax2.c.
int trunk_maxmtu [static] |
Definition at line 136 of file chan_iax2.c.
int trunk_nmaxmtu [static] |
Trunk MTU statistics
Definition at line 136 of file chan_iax2.c.
int trunk_timed [static] |
Definition at line 136 of file chan_iax2.c.
int trunk_untimed [static] |
Definition at line 136 of file chan_iax2.c.
int trunkfreq = 20 [static] |
Definition at line 156 of file chan_iax2.c.
int trunkmaxsize = MAX_TRUNKDATA [static] |
Definition at line 157 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 747 of file chan_iax2.c.
1.6.1