Implementation of Inter-Asterisk eXchange Version 2 as specified in RFC 5456. More...
#include "asterisk.h"#include <sys/mman.h>#include <dirent.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <sys/time.h>#include <sys/signal.h>#include <signal.h>#include <strings.h>#include <netdb.h>#include <fcntl.h>#include <sys/stat.h>#include <regex.h>#include "asterisk/paths.h"#include "asterisk/lock.h"#include "asterisk/frame.h"#include "asterisk/channel.h"#include "asterisk/module.h"#include "asterisk/pbx.h"#include "asterisk/sched.h"#include "asterisk/io.h"#include "asterisk/config.h"#include "asterisk/cli.h"#include "asterisk/translate.h"#include "asterisk/md5.h"#include "asterisk/cdr.h"#include "asterisk/crypto.h"#include "asterisk/acl.h"#include "asterisk/manager.h"#include "asterisk/callerid.h"#include "asterisk/app.h"#include "asterisk/astdb.h"#include "asterisk/musiconhold.h"#include "asterisk/features.h"#include "asterisk/utils.h"#include "asterisk/causes.h"#include "asterisk/localtime.h"#include "asterisk/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 |
| #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 IAX_MAX_CALLS / 2 |
| #define | TS_GAP_FOR_JB_RESYNC 5000 |
Enumerations | |
| enum | { CACHE_FLAG_EXISTS = (1 << 0), CACHE_FLAG_NONEXISTENT = (1 << 1), CACHE_FLAG_CANEXIST = (1 << 2), CACHE_FLAG_PENDING = (1 << 3), CACHE_FLAG_TIMEOUT = (1 << 4), CACHE_FLAG_TRANSMITTED = (1 << 5), CACHE_FLAG_UNKNOWN = (1 << 6), CACHE_FLAG_MATCHMORE = (1 << 7) } |
| enum | { NEW_PREVENT = 0, NEW_ALLOW = 1, NEW_FORCE = 2, NEW_ALLOW_CALLTOKEN_VALIDATED = 3 } |
| enum | calltoken_peer_enum { CALLTOKEN_DEFAULT = 0, CALLTOKEN_YES = 1, CALLTOKEN_AUTO = 2, CALLTOKEN_NO = 3 } |
Call token validation settings. More... | |
| enum | iax2_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_IMMEDIATE = (1 << 27), IAX_FORCE_ENCRYPT = (1 << 28), IAX_SHRINKCALLERID = (1 << 29) } |
| 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_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, int flags) |
| static char * | complete_iax2_unregister (const char *line, const char *word, int pos, int state) |
| static int | complete_transfer (int callno, struct iax_ies *ies) |
| static unsigned char | compress_subclass (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 void | encmethods_to_str (int e, struct ast_str *buf) |
| static int | encrypt_frame (ast_aes_encrypt_key *ecx, struct ast_iax2_full_hdr *fh, unsigned char *poo, int *datalen) |
| static int | expire_registry (const void *data) |
| static struct iax2_dpcache * | find_cache (struct ast_channel *chan, const char *data, const char *context, const char *exten, int priority) |
| static int | find_callno (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
| static int | find_callno_locked (unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int sockfd, int full_frame) |
| static struct iax2_thread * | find_idle_thread (void) |
| static struct iax2_peer * | find_peer (const char *name, int realtime) |
| static struct iax2_trunk_peer * | find_tpeer (struct sockaddr_in *sin, int fd) |
| static struct iax2_user * | find_user (const char *name) |
| static unsigned int | fix_peerts (struct timeval *rxtrunktime, int callno, unsigned int ts) |
| static void | free_context (struct iax2_context *con) |
| static void | free_signaling_queue_entry (struct signaling_queue_entry *s) |
| static int | function_iaxpeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len) |
| static int | get_auth_methods (const char *value) |
| static int | get_encrypt_methods (const char *s) |
| static int | get_from_jb (const void *p) |
| static struct callno_entry * | get_unused_callno (int trunk, int validated) |
| static int | handle_call_token (struct ast_iax2_full_hdr *fh, struct iax_ies *ies, struct sockaddr_in *sin, int fd) |
| static char * | handle_cli_iax2_provision (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_set_debug_jb (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_set_debug_trunk (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_set_mtu (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Set trunk MTU from CLI. | |
| static char * | handle_cli_iax2_show_cache (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_callno_limits (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_firmware (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_netstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| Show one peer in detail. | |
| static char * | handle_cli_iax2_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_threads (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_test_losspct (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static char * | handle_cli_iax2_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) |
| static void | handle_deferred_full_frames (struct iax2_thread *thread) |
| Handle any deferred full frames for this thread. | |
| static int | handle_error (void) |
| static int | iax2_ack_registry (struct iax_ies *ies, struct sockaddr_in *sin, int callno) |
| Acknowledgment received for OUR registration. | |
| static int attribute_pure | iax2_allow_new (int frametype, int subclass, int inbound) |
| static void | iax2_ami_channelupdate (struct chan_iax2_pvt *pvt) |
| Send manager event at call setup to link between Asterisk channel name and IAX2 call identifiers. | |
| static int | iax2_answer (struct ast_channel *c) |
| static int | iax2_append_register (const char *hostname, const char *username, const char *secret, const char *porta) |
| static enum ast_bridge_result | iax2_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
| static int | iax2_call (struct ast_channel *c, char *dest, int timeout) |
| static int | iax2_canmatch (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| part of the IAX2 dial plan switch interface | |
| static unsigned int | iax2_datetime (const char *tz) |
| static void | iax2_destroy (int callno) |
| static void | iax2_destroy_helper (struct chan_iax2_pvt *pvt) |
| static int | iax2_devicestate (void *data) |
| Part of the device state notification system ---. | |
| static int | iax2_digit_begin (struct ast_channel *c, char digit) |
| static int | iax2_digit_end (struct ast_channel *c, char digit, unsigned int duration) |
| static int | iax2_do_register (struct iax2_registry *reg) |
| static int | iax2_do_register_s (const void *data) |
| static void | iax2_dprequest (struct iax2_dpcache *dp, int callno) |
| static void * | iax2_dup_variable_datastore (void *) |
| static int | iax2_exec (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| Execute IAX2 dialplan switch. | |
| static int | iax2_exists (struct ast_channel *chan, const char *context, const char *exten, int priority, const char *callerid, const char *data) |
| Part of the IAX2 switch interface. | |
| static int | iax2_fixup (struct ast_channel *oldchannel, struct ast_channel *newchan) |
| static void | iax2_frame_free (struct iax_frame *fr) |
| static void | iax2_free_variable_datastore (void *) |
| static int | iax2_getpeername (struct sockaddr_in sin, char *host, int len) |
| static int | iax2_getpeertrunk (struct sockaddr_in sin) |
| static int | iax2_hangup (struct ast_channel *c) |
| static int | iax2_indicate (struct ast_channel *c, int condition, const void *data, size_t datalen) |
| static int | iax2_key_rotate (const void *vpvt) |
| static 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 ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
| static int | iax2_sched_replace (int id, struct ast_sched_thread *st, int when, ast_sched_cb callback, const void *data) |
| static int | iax2_send (struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final) |
| static int | iax2_sendhtml (struct ast_channel *c, int subclass, const char *data, int datalen) |
| static int | iax2_sendimage (struct ast_channel *c, struct ast_frame *img) |
| static int | iax2_sendtext (struct ast_channel *c, const char *text) |
| static int | iax2_setoption (struct ast_channel *c, int option, void *data, int datalen) |
| static int | iax2_start_transfer (unsigned short callno0, unsigned short callno1, int mediaonly) |
| static int | iax2_transfer (struct ast_channel *c, const char *dest) |
| static int | iax2_transmit (struct iax_frame *fr) |
| static int | iax2_trunk_expired (struct iax2_trunk_peer *tpeer, struct timeval *now) |
| static int | iax2_trunk_queue (struct chan_iax2_pvt *pvt, struct iax_frame *fr) |
| static int | iax2_vnak (int callno) |
| static int | iax2_write (struct ast_channel *c, struct ast_frame *f) |
| static int | iax_check_version (char *dev) |
| static void | iax_debug_output (const char *data) |
| static void | iax_error_output (const char *data) |
| static int | iax_firmware_append (struct iax_ie_data *ied, const unsigned char *dev, unsigned int desc) |
| static void | iax_outputframe (struct iax_frame *f, struct ast_iax2_full_hdr *fhi, int rx, struct sockaddr_in *sin, int datalen) |
| static int | iax_park (struct ast_channel *chan1, struct ast_channel *chan2) |
| static void * | iax_park_thread (void *stuff) |
| static struct iax_frame * | iaxfrdup2 (struct iax_frame *fr) |
| static void | insert_idle_thread (struct iax2_thread *thread) |
| static void | jb_debug_output (const char *fmt,...) |
| static void | jb_error_output (const char *fmt,...) |
| static void | jb_warning_output (const char *fmt,...) |
| static int | load_module (void) |
| Load IAX2 module, load configuraiton ---. | |
| static int | load_objects (void) |
| static void | lock_both (unsigned short callno0, unsigned short callno1) |
| static void | log_jitterstats (unsigned short callno) |
| static int | make_trunk (unsigned short callno, int locked) |
| static int | manager_iax2_show_netstats (struct mansession *s, const struct message *m) |
| static int | manager_iax2_show_peer_list (struct mansession *s, const struct message *m) |
| callback to display iax peers in manager format | |
| static int | manager_iax2_show_peers (struct mansession *s, const struct message *m) |
| callback to display iax peers in manager | |
| static int | manager_iax2_show_registry (struct mansession *s, const struct message *m) |
| static int | match (struct sockaddr_in *sin, unsigned short callno, unsigned short dcallno, const struct chan_iax2_pvt *cur, int check_dcallno) |
| static void | memcpy_decrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_decrypt_key *dcx) |
| static void | memcpy_encrypt (unsigned char *dst, const unsigned char *src, int len, ast_aes_encrypt_key *ecx) |
| static void | merge_encryption (struct chan_iax2_pvt *p, unsigned int enc) |
| static void | mwi_event_cb (const struct ast_event *event, void *userdata) |
| static void * | network_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 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 = "0901e4e500243c855563a2d78b0c03e4" , .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+1] |
| an array of iax2 pvt structures | |
| static ast_mutex_t | iaxsl [ARRAY_LEN(iaxs)] |
| chan_iax2_pvt structure locks | |
| static int | iaxthreadcount = DEFAULT_THREAD_COUNT |
| static int | iaxtrunkdebug = 0 |
| static struct ast_custom_function | iaxvar_function |
| static struct io_context * | io |
| static int | jittertargetextra = 40 |
| static int | lagrq_time = 10 |
| static char | language [MAX_LANGUAGE] = "" |
| static int | last_authmethod = 0 |
| static const time_t | MAX_CALLTOKEN_DELAY = 10 |
| static int | max_reg_expire |
| static int | max_retries = 4 |
| static int | maxauthreq = 3 |
| static int | maxjitterbuffer = 1000 |
| static int | maxjitterinterps = 10 |
| static int | maxnontrunkcall = 1 |
| static int | maxtrunkcall = TRUNK_CALL_START |
| static int | min_reg_expire |
| static char | mohinterpret [MAX_MUSICCLASS] |
| static char | mohsuggest [MAX_MUSICCLASS] |
| static struct ast_netsock_list * | netsock |
| static pthread_t | netthreadid = AST_PTHREADT_NULL |
| static struct ast_netsock_list * | outsock |
| static char * | papp = "IAX2Provision" |
| static struct ao2_container * | peercnts |
| static struct ao2_container * | peers |
| static int | ping_time = 21 |
| static struct ast_codec_pref | prefs |
| struct { | |
| unsigned int cos | |
| unsigned int tos | |
| } | qos |
| static int | randomcalltokendata |
| static char | regcontext [AST_MAX_CONTEXT] = "" |
| static int | resyncthreshold = 1000 |
| static struct ast_sched_thread * | sched |
| static int | srvlookup = 0 |
| static const char | tdesc [] = "Inter Asterisk eXchange Driver (Ver 2)" |
| static int | test_losspct = 0 |
| static struct ast_timer * | timer |
| static uint16_t | total_nonval_callno_used = 0 |
| static 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 as specified in RFC 5456.
Definition in file chan_iax2.c.
| #define ACN_FORMAT1 "%-20.25s %4d %4d %4d %5d %3d %5d %4d %6d %4d %4d %5d %3d %5d %4d %6d %s%s %4s%s\n" |
Referenced by ast_cli_netstats().
| #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" |
Referenced by ast_cli_netstats().
| #define CALLNO_TO_PTR | ( | a | ) | ((void *)(unsigned long)(a)) |
Definition at line 194 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 186 of file chan_iax2.c.
| #define DEBUG_SUPPORT |
Definition at line 202 of file chan_iax2.c.
| #define DEFAULT_CONTEXT "default" |
Definition at line 221 of file chan_iax2.c.
Referenced by check_access(), handle_cli_iax2_show_users(), and reload_config().
| #define DEFAULT_DROP 3 |
Definition at line 200 of file chan_iax2.c.
| #define DEFAULT_FREQ_NOTOK 10 * 1000 |
Definition at line 292 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 291 of file chan_iax2.c.
Referenced by build_peer().
| #define DEFAULT_MAX_THREAD_COUNT 100 |
Definition at line 197 of file chan_iax2.c.
| #define DEFAULT_MAXMS 2000 |
Definition at line 290 of file chan_iax2.c.
Referenced by build_peer(), iax2_poke_peer(), reload_config(), and set_config().
| #define DEFAULT_RETRY_TIME 1000 |
Definition at line 198 of file chan_iax2.c.
Referenced by __find_callno(), and complete_transfer().
| #define DEFAULT_THREAD_COUNT 10 |
Definition at line 196 of file chan_iax2.c.
| #define DEFAULT_TRUNKDATA 640 * 10 |
40ms, uncompressed linear * 10 channels
Definition at line 571 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 207 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 492 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 295 of file chan_iax2.c.
Referenced by iax2_send(), iax2_start_transfer(), and socket_process().
| #define IAX_CAPABILITY_FULLBANDWIDTH 0xFFFF |
Definition at line 270 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 281 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_CAPABILITY_LOWFREE |
Definition at line 286 of file chan_iax2.c.
| #define IAX_CAPABILITY_MEDBANDWIDTH |
Definition at line 272 of file chan_iax2.c.
Referenced by set_config().
| #define IAX_DEBUGDIGEST | ( | msg, | |||
| key | ) |
Definition at line 298 of file chan_iax2.c.
Referenced by iax2_key_rotate(), and socket_process().
| #define MARK_IAX_SUBCLASS_TX 0x8000 |
Definition at line 579 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 568 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 826 of file chan_iax2.c.
Referenced by load_objects().
| #define MAX_RETRY_TIME 10000 |
Definition at line 566 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 573 of file chan_iax2.c.
Referenced by ast_rtp_raw_write(), calc_timestamp(), and calc_txpeerstamp().
| #define MAX_TRUNK_MTU 1240 |
Maximum transmission unit for the UDP packet in the trunk not to be fragmented. This is based on 1516 - ethernet - ip - udp - iax minus one g711 frame = 1240.
Definition at line 216 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 237 of file chan_iax2.c.
Referenced by set_config(), and set_config_destroy().
| #define MAX_USER_BUCKETS MAX_PEER_BUCKETS |
Definition at line 830 of file chan_iax2.c.
Referenced by load_module(), and load_objects().
| #define MEMORY_SIZE 100 |
Definition at line 199 of file chan_iax2.c.
| #define MIN_JITTER_BUFFER 10 |
Definition at line 569 of file chan_iax2.c.
| #define MIN_RETRY_TIME 100 |
Definition at line 565 of file chan_iax2.c.
Referenced by iax2_send().
| #define MIN_REUSE_TIME 60 |
Definition at line 204 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 193 of file chan_iax2.c.
Referenced by __auto_congest(), __get_from_jb(), acf_channel_read(), function_iaxpeer(), iax2_answer(), iax2_bridge(), iax2_call(), iax2_digit_begin(), iax2_digit_end(), iax2_fixup(), iax2_hangup(), iax2_indicate(), iax2_prov_app(), iax2_sendhtml(), iax2_sendimage(), iax2_sendtext(), iax2_setoption(), iax2_transfer(), iax2_write(), and scheduled_destroy().
| #define SCHED_MULTITHREADED |
Definition at line 182 of file chan_iax2.c.
| #define schedule_action | ( | func, | |||
| data | ) | __schedule_action(func, data, __PRETTY_FUNCTION__) |
Definition at line 1353 of file chan_iax2.c.
Referenced by attempt_transmit(), auth_reject(), auto_congest(), auto_hangup(), expire_registry(), get_from_jb(), iax2_do_register_s(), iax2_poke_noanswer(), iax2_poke_peer_s(), send_lagrq(), and send_ping().
| #define TRUNK_CALL_START IAX_MAX_CALLS / 2 |
Definition at line 1040 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 576 of file chan_iax2.c.
| anonymous enum |
Definition at line 886 of file chan_iax2.c.
00886 { 00887 /*! Extension exists */ 00888 CACHE_FLAG_EXISTS = (1 << 0), 00889 /*! Extension is nonexistent */ 00890 CACHE_FLAG_NONEXISTENT = (1 << 1), 00891 /*! Extension can exist */ 00892 CACHE_FLAG_CANEXIST = (1 << 2), 00893 /*! Waiting to hear back response */ 00894 CACHE_FLAG_PENDING = (1 << 3), 00895 /*! Timed out */ 00896 CACHE_FLAG_TIMEOUT = (1 << 4), 00897 /*! Request transmitted */ 00898 CACHE_FLAG_TRANSMITTED = (1 << 5), 00899 /*! Timeout */ 00900 CACHE_FLAG_UNKNOWN = (1 << 6), 00901 /*! Matchmore */ 00902 CACHE_FLAG_MATCHMORE = (1 << 7), 00903 };
| anonymous enum |
Definition at line 1822 of file chan_iax2.c.
01822 { 01823 /* do not allow a new call number, only search ones in use for match */ 01824 NEW_PREVENT = 0, 01825 /* search for match first, then allow a new one to be allocated */ 01826 NEW_ALLOW = 1, 01827 /* do not search for match, force a new call number */ 01828 NEW_FORCE = 2, 01829 /* do not search for match, force a new call number. Signifies call number 01830 * has been calltoken validated */ 01831 NEW_ALLOW_CALLTOKEN_VALIDATED = 3, 01832 };
| enum calltoken_peer_enum |
Call token validation settings.
Definition at line 393 of file chan_iax2.c.
00393 { 00394 /*! \brief Default calltoken required unless the ip is in the ignorelist */ 00395 CALLTOKEN_DEFAULT = 0, 00396 /*! \brief Require call token validation. */ 00397 CALLTOKEN_YES = 1, 00398 /*! \brief Require call token validation after a successful registration 00399 * using call token validation occurs. */ 00400 CALLTOKEN_AUTO = 2, 00401 /*! \brief Do not require call token validation. */ 00402 CALLTOKEN_NO = 3, 00403 };
| enum iax2_flags |
Definition at line 351 of file chan_iax2.c.
00351 { 00352 IAX_HASCALLERID = (1 << 0), /*!< CallerID has been specified */ 00353 IAX_DELME = (1 << 1), /*!< Needs to be deleted */ 00354 IAX_TEMPONLY = (1 << 2), /*!< Temporary (realtime) */ 00355 IAX_TRUNK = (1 << 3), /*!< Treat as a trunk */ 00356 IAX_NOTRANSFER = (1 << 4), /*!< Don't native bridge */ 00357 IAX_USEJITTERBUF = (1 << 5), /*!< Use jitter buffer */ 00358 IAX_DYNAMIC = (1 << 6), /*!< dynamic peer */ 00359 IAX_SENDANI = (1 << 7), /*!< Send ANI along with CallerID */ 00360 /* (1 << 8) is currently unused due to the deprecation of an old option. Go ahead, take it! */ 00361 IAX_ALREADYGONE = (1 << 9), /*!< Already disconnected */ 00362 IAX_PROVISION = (1 << 10), /*!< This is a provisioning request */ 00363 IAX_QUELCH = (1 << 11), /*!< Whether or not we quelch audio */ 00364 IAX_ENCRYPTED = (1 << 12), /*!< Whether we should assume encrypted tx/rx */ 00365 IAX_KEYPOPULATED = (1 << 13), /*!< Whether we have a key populated */ 00366 IAX_CODEC_USER_FIRST = (1 << 14), /*!< are we willing to let the other guy choose the codec? */ 00367 IAX_CODEC_NOPREFS = (1 << 15), /*!< Force old behaviour by turning off prefs */ 00368 IAX_CODEC_NOCAP = (1 << 16), /*!< only consider requested format and ignore capabilities*/ 00369 IAX_RTCACHEFRIENDS = (1 << 17), /*!< let realtime stay till your reload */ 00370 IAX_RTUPDATE = (1 << 18), /*!< Send a realtime update */ 00371 IAX_RTAUTOCLEAR = (1 << 19), /*!< erase me on expire */ 00372 IAX_FORCEJITTERBUF = (1 << 20), /*!< Force jitterbuffer, even when bridged to a channel that can take jitter */ 00373 IAX_RTIGNOREREGEXPIRE = (1 << 21), /*!< When using realtime, ignore registration expiration */ 00374 IAX_TRUNKTIMESTAMPS = (1 << 22), /*!< Send trunk timestamps */ 00375 IAX_TRANSFERMEDIA = (1 << 23), /*!< When doing IAX2 transfers, transfer media only */ 00376 IAX_MAXAUTHREQ = (1 << 24), /*!< Maximum outstanding AUTHREQ restriction is in place */ 00377 IAX_DELAYPBXSTART = (1 << 25), /*!< Don't start a PBX on the channel until the peer sends us a 00378 response, so that we've achieved a three-way handshake with 00379 them before sending voice or anything else*/ 00380 IAX_ALLOWFWDOWNLOAD = (1 << 26), /*!< Allow the FWDOWNL command? */ 00381 IAX_IMMEDIATE = (1 << 27), /*!< Allow immediate off-hook to extension s */ 00382 IAX_FORCE_ENCRYPT = (1 << 28), /*!< Forces call encryption, if encryption not possible hangup */ 00383 IAX_SHRINKCALLERID = (1 << 29), /*!< Turn on and off caller id shrinking */ 00384 };
| enum iax2_state |
Definition at line 340 of file chan_iax2.c.
00340 { 00341 IAX_STATE_STARTED = (1 << 0), 00342 IAX_STATE_AUTHENTICATED = (1 << 1), 00343 IAX_STATE_TBD = (1 << 2), 00344 };
| enum iax2_thread_iostate |
Definition at line 927 of file chan_iax2.c.
00927 { 00928 IAX_IOSTATE_IDLE, 00929 IAX_IOSTATE_READY, 00930 IAX_IOSTATE_PROCESSING, 00931 IAX_IOSTATE_SCHEDREADY, 00932 };
| enum iax2_thread_type |
Definition at line 934 of file chan_iax2.c.
00934 { 00935 IAX_THREAD_TYPE_POOL, 00936 IAX_THREAD_TYPE_DYNAMIC, 00937 };
| 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 524 of file chan_iax2.c.
00524 { 00525 REG_STATE_UNREGISTERED = 0, 00526 REG_STATE_REGSENT, 00527 REG_STATE_AUTHSENT, 00528 REG_STATE_REGISTERED, 00529 REG_STATE_REJECTED, 00530 REG_STATE_TIMEOUT, 00531 REG_STATE_NOAUTH 00532 };
| 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 534 of file chan_iax2.c.
00534 { 00535 TRANSFER_NONE = 0, 00536 TRANSFER_BEGIN, 00537 TRANSFER_READY, 00538 TRANSFER_RELEASED, 00539 TRANSFER_PASSTHROUGH, 00540 TRANSFER_MBEGIN, 00541 TRANSFER_MREADY, 00542 TRANSFER_MRELEASED, 00543 TRANSFER_MPASSTHROUGH, 00544 TRANSFER_MEDIA, 00545 TRANSFER_MEDIAPASS 00546 };
| static void __attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3307 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, ast_channel::name, 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().
03308 { 03309 /* Attempt to transmit the frame to the remote peer... 03310 Called without iaxsl held. */ 03311 struct iax_frame *f = (struct iax_frame *)data; 03312 int freeme = 0; 03313 int callno = f->callno; 03314 /* Make sure this call is still active */ 03315 if (callno) 03316 ast_mutex_lock(&iaxsl[callno]); 03317 if (callno && iaxs[callno]) { 03318 if ((f->retries < 0) /* Already ACK'd */ || 03319 (f->retries >= max_retries) /* Too many attempts */) { 03320 /* Record an error if we've transmitted too many times */ 03321 if (f->retries >= max_retries) { 03322 if (f->transfer) { 03323 /* Transfer timeout */ 03324 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 03325 } else if (f->final) { 03326 iax2_destroy(callno); 03327 } else { 03328 if (iaxs[callno]->owner) 03329 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); 03330 iaxs[callno]->error = ETIMEDOUT; 03331 if (iaxs[callno]->owner) { 03332 struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, .data.uint32 = AST_CAUSE_DESTINATION_OUT_OF_ORDER }; 03333 /* Hangup the fd */ 03334 iax2_queue_frame(callno, &fr); /* XXX */ 03335 /* Remember, owner could disappear */ 03336 if (iaxs[callno] && iaxs[callno]->owner) 03337 iaxs[callno]->owner->hangupcause = AST_CAUSE_DESTINATION_OUT_OF_ORDER; 03338 } else { 03339 if (iaxs[callno]->reg) { 03340 memset(&iaxs[callno]->reg->us, 0, sizeof(iaxs[callno]->reg->us)); 03341 iaxs[callno]->reg->regstate = REG_STATE_TIMEOUT; 03342 iaxs[callno]->reg->refresh = IAX_DEFAULT_REG_EXPIRE; 03343 } 03344 iax2_destroy(callno); 03345 } 03346 } 03347 03348 } 03349 freeme = 1; 03350 } else { 03351 /* Update it if it needs it */ 03352 update_packet(f); 03353 /* Attempt transmission */ 03354 send_packet(f); 03355 f->retries++; 03356 /* Try again later after 10 times as long */ 03357 f->retrytime *= 10; 03358 if (f->retrytime > MAX_RETRY_TIME) 03359 f->retrytime = MAX_RETRY_TIME; 03360 /* Transfer messages max out at one second */ 03361 if (f->transfer && (f->retrytime > 1000)) 03362 f->retrytime = 1000; 03363 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 03364 } 03365 } else { 03366 /* Make sure it gets freed */ 03367 f->retries = -1; 03368 freeme = 1; 03369 } 03370 if (callno) 03371 ast_mutex_unlock(&iaxsl[callno]); 03372 /* Do not try again */ 03373 if (freeme) { 03374 /* Don't attempt delivery, just remove it from the queue */ 03375 AST_LIST_LOCK(&frame_queue); 03376 AST_LIST_REMOVE(&frame_queue, f, list); 03377 AST_LIST_UNLOCK(&frame_queue); 03378 f->retrans = -1; /* this is safe because this is the scheduled function */ 03379 /* Free the IAX frame */ 03380 iax2_frame_free(f); 03381 } 03382 }
| static void __auth_reject | ( | const void * | nothing | ) | [static] |
Definition at line 8606 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().
08607 { 08608 /* Called from IAX thread only, without iaxs lock */ 08609 int callno = (int)(long)(nothing); 08610 struct iax_ie_data ied; 08611 ast_mutex_lock(&iaxsl[callno]); 08612 if (iaxs[callno]) { 08613 memset(&ied, 0, sizeof(ied)); 08614 if (iaxs[callno]->authfail == IAX_COMMAND_REGREJ) { 08615 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Registration Refused"); 08616 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_REJECTED); 08617 } else if (iaxs[callno]->authfail == IAX_COMMAND_REJECT) { 08618 iax_ie_append_str(&ied, IAX_IE_CAUSE, "No authority found"); 08619 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 08620 } 08621 send_command_final(iaxs[callno], AST_FRAME_IAX, iaxs[callno]->authfail, 0, ied.buf, ied.pos, -1); 08622 } 08623 ast_mutex_unlock(&iaxsl[callno]); 08624 }
| static void __auto_congest | ( | const void * | nothing | ) | [static] |
Definition at line 4426 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().
04427 { 04428 int callno = PTR_TO_CALLNO(nothing); 04429 struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_CONGESTION }; 04430 ast_mutex_lock(&iaxsl[callno]); 04431 if (iaxs[callno]) { 04432 iaxs[callno]->initid = -1; 04433 iax2_queue_frame(callno, &f); 04434 ast_log(LOG_NOTICE, "Auto-congesting call due to slow response\n"); 04435 } 04436 ast_mutex_unlock(&iaxsl[callno]); 04437 }
| static void __auto_hangup | ( | const void * | nothing | ) | [static] |
Definition at line 8655 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().
08656 { 08657 /* Called from IAX thread only, without iaxs lock */ 08658 int callno = (int)(long)(nothing); 08659 struct iax_ie_data ied; 08660 ast_mutex_lock(&iaxsl[callno]); 08661 if (iaxs[callno]) { 08662 memset(&ied, 0, sizeof(ied)); 08663 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Timeout"); 08664 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_NO_USER_RESPONSE); 08665 send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); 08666 } 08667 ast_mutex_unlock(&iaxsl[callno]); 08668 }
| static int __do_deliver | ( | void * | data | ) | [static] |
Definition at line 3102 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().
03103 { 03104 /* Just deliver the packet by using queueing. This is called by 03105 the IAX thread with the iaxsl lock held. */ 03106 struct iax_frame *fr = data; 03107 fr->retrans = -1; 03108 ast_clear_flag(&fr->af, AST_FRFLAG_HAS_TIMING_INFO); 03109 if (iaxs[fr->callno] && !ast_test_flag(iaxs[fr->callno], IAX_ALREADYGONE)) 03110 iax2_queue_frame(fr->callno, &fr->af); 03111 /* Free our iax frame */ 03112 iax2_frame_free(fr); 03113 /* And don't run again */ 03114 return 0; 03115 }
| static void __expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8254 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().
08255 { 08256 struct iax2_peer *peer = (struct iax2_peer *) data; 08257 08258 if (!peer) 08259 return; 08260 08261 peer->expire = -1; 08262 08263 ast_debug(1, "Expiring registration for peer '%s'\n", peer->name); 08264 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(peer, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) 08265 realtime_update_peer(peer->name, &peer->addr, 0); 08266 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name); 08267 /* modify entry in peercnts table as _not_ registered */ 08268 peercnt_modify(0, 0, &peer->addr); 08269 /* Reset the address */ 08270 memset(&peer->addr, 0, sizeof(peer->addr)); 08271 /* Reset expiry value */ 08272 peer->expiry = min_reg_expire; 08273 if (!ast_test_flag(peer, IAX_TEMPONLY)) 08274 ast_db_del("IAX/Registry", peer->name); 08275 register_peer_exten(peer, 0); 08276 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 08277 if (iax2_regfunk) 08278 iax2_regfunk(peer->name, 0); 08279 08280 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) 08281 unlink_peer(peer); 08282 08283 peer_unref(peer); 08284 }
| 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 2580 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_FORCE_ENCRYPT, 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().
02581 { 02582 int res = 0; 02583 int x; 02584 /* this call is calltoken validated as long as it is either NEW_FORCE 02585 * or NEW_ALLOW_CALLTOKEN_VALIDATED */ 02586 int validated = (new > NEW_ALLOW) ? 1 : 0; 02587 char host[80]; 02588 02589 if (new <= NEW_ALLOW) { 02590 if (callno) { 02591 struct chan_iax2_pvt *pvt; 02592 struct chan_iax2_pvt tmp_pvt = { 02593 .callno = dcallno, 02594 .peercallno = callno, 02595 .transfercallno = callno, 02596 /* hack!! */ 02597 .frames_received = check_dcallno, 02598 }; 02599 02600 memcpy(&tmp_pvt.addr, sin, sizeof(tmp_pvt.addr)); 02601 /* this works for finding normal call numbers not involving transfering */ 02602 if ((pvt = ao2_find(iax_peercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02603 if (return_locked) { 02604 ast_mutex_lock(&iaxsl[pvt->callno]); 02605 } 02606 res = pvt->callno; 02607 ao2_ref(pvt, -1); 02608 pvt = NULL; 02609 return res; 02610 } 02611 /* this searches for transfer call numbers that might not get caught otherwise */ 02612 memset(&tmp_pvt.addr, 0, sizeof(tmp_pvt.addr)); 02613 memcpy(&tmp_pvt.transfer, sin, sizeof(tmp_pvt.transfer)); 02614 if ((pvt = ao2_find(iax_transfercallno_pvts, &tmp_pvt, OBJ_POINTER))) { 02615 if (return_locked) { 02616 ast_mutex_lock(&iaxsl[pvt->callno]); 02617 } 02618 res = pvt->callno; 02619 ao2_ref(pvt, -1); 02620 pvt = NULL; 02621 return res; 02622 } 02623 } 02624 /* This will occur on the first response to a message that we initiated, 02625 * such as a PING. */ 02626 if (dcallno) { 02627 ast_mutex_lock(&iaxsl[dcallno]); 02628 } 02629 if (callno && dcallno && iaxs[dcallno] && !iaxs[dcallno]->peercallno && match(sin, callno, dcallno, iaxs[dcallno], check_dcallno)) { 02630 iaxs[dcallno]->peercallno = callno; 02631 res = dcallno; 02632 store_by_peercallno(iaxs[dcallno]); 02633 if (!res || !return_locked) { 02634 ast_mutex_unlock(&iaxsl[dcallno]); 02635 } 02636 return res; 02637 } 02638 if (dcallno) { 02639 ast_mutex_unlock(&iaxsl[dcallno]); 02640 } 02641 #ifdef IAX_OLD_FIND 02642 /* If we get here, we SHOULD NOT find a call structure for this 02643 callno; if we do, it means that there is a call structure that 02644 has a peer callno but did NOT get entered into the hash table, 02645 which is bad. 02646 02647 If we find a call structure using this old, slow method, output a log 02648 message so we'll know about it. After a few months of leaving this in 02649 place, if we don't hear about people seeing these messages, we can 02650 remove this code for good. 02651 */ 02652 02653 for (x = 1; !res && x < maxnontrunkcall; x++) { 02654 ast_mutex_lock(&iaxsl[x]); 02655 if (iaxs[x]) { 02656 /* Look for an exact match */ 02657 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02658 res = x; 02659 } 02660 } 02661 if (!res || !return_locked) 02662 ast_mutex_unlock(&iaxsl[x]); 02663 } 02664 for (x = TRUNK_CALL_START; !res && x < maxtrunkcall; x++) { 02665 ast_mutex_lock(&iaxsl[x]); 02666 if (iaxs[x]) { 02667 /* Look for an exact match */ 02668 if (match(sin, callno, dcallno, iaxs[x], check_dcallno)) { 02669 res = x; 02670 } 02671 } 02672 if (!res || !return_locked) 02673 ast_mutex_unlock(&iaxsl[x]); 02674 } 02675 #endif 02676 } 02677 if (!res && (new >= NEW_ALLOW)) { 02678 struct callno_entry *callno_entry; 02679 /* It may seem odd that we look through the peer list for a name for 02680 * this *incoming* call. Well, it is weird. However, users don't 02681 * have an IP address/port number that we can match against. So, 02682 * this is just checking for a peer that has that IP/port and 02683 * assuming that we have a user of the same name. This isn't always 02684 * correct, but it will be changed if needed after authentication. */ 02685 if (!iax2_getpeername(*sin, host, sizeof(host))) 02686 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 02687 02688 if (peercnt_add(sin)) { 02689 /* This address has hit its callnumber limit. When the limit 02690 * is reached, the connection is not added to the peercnts table.*/ 02691 return 0; 02692 } 02693 02694 if (!(callno_entry = get_unused_callno(0, validated))) { 02695 /* since we ran out of space, remove the peercnt 02696 * entry we added earlier */ 02697 peercnt_remove_by_addr(sin); 02698 ast_log(LOG_WARNING, "No more space\n"); 02699 return 0; 02700 } 02701 x = callno_entry->callno; 02702 ast_mutex_lock(&iaxsl[x]); 02703 02704 iaxs[x] = new_iax(sin, host); 02705 update_max_nontrunk(); 02706 if (iaxs[x]) { 02707 if (iaxdebug) 02708 ast_debug(1, "Creating new call structure %d\n", x); 02709 iaxs[x]->callno_entry = callno_entry; 02710 iaxs[x]->sockfd = sockfd; 02711 iaxs[x]->addr.sin_port = sin->sin_port; 02712 iaxs[x]->addr.sin_family = sin->sin_family; 02713 iaxs[x]->addr.sin_addr.s_addr = sin->sin_addr.s_addr; 02714 iaxs[x]->peercallno = callno; 02715 iaxs[x]->callno = x; 02716 iaxs[x]->pingtime = DEFAULT_RETRY_TIME; 02717 iaxs[x]->expiry = min_reg_expire; 02718 iaxs[x]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, (void *)(long)x); 02719 iaxs[x]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, (void *)(long)x); 02720 iaxs[x]->amaflags = amaflags; 02721 ast_copy_flags(iaxs[x], &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT); 02722 ast_string_field_set(iaxs[x], accountcode, accountcode); 02723 ast_string_field_set(iaxs[x], mohinterpret, mohinterpret); 02724 ast_string_field_set(iaxs[x], mohsuggest, mohsuggest); 02725 ast_string_field_set(iaxs[x], parkinglot, default_parkinglot); 02726 02727 if (iaxs[x]->peercallno) { 02728 store_by_peercallno(iaxs[x]); 02729 } 02730 } else { 02731 ast_log(LOG_WARNING, "Out of resources\n"); 02732 ast_mutex_unlock(&iaxsl[x]); 02733 replace_callno(callno_entry); 02734 return 0; 02735 } 02736 if (!return_locked) 02737 ast_mutex_unlock(&iaxsl[x]); 02738 res = x; 02739 } 02740 return res; 02741 }
| static void __get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3879 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().
03880 { 03881 int callno = PTR_TO_CALLNO(p); 03882 struct chan_iax2_pvt *pvt = NULL; 03883 struct iax_frame *fr; 03884 jb_frame frame; 03885 int ret; 03886 long ms; 03887 long next; 03888 struct timeval now = ast_tvnow(); 03889 03890 /* Make sure we have a valid private structure before going on */ 03891 ast_mutex_lock(&iaxsl[callno]); 03892 pvt = iaxs[callno]; 03893 if (!pvt) { 03894 /* No go! */ 03895 ast_mutex_unlock(&iaxsl[callno]); 03896 return; 03897 } 03898 03899 pvt->jbid = -1; 03900 03901 /* round up a millisecond since ast_sched_runq does; */ 03902 /* prevents us from spinning while waiting for our now */ 03903 /* to catch up with runq's now */ 03904 now.tv_usec += 1000; 03905 03906 ms = ast_tvdiff_ms(now, pvt->rxcore); 03907 03908 if(ms >= (next = jb_next(pvt->jb))) { 03909 ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat)); 03910 switch(ret) { 03911 case JB_OK: 03912 fr = frame.data; 03913 __do_deliver(fr); 03914 /* __do_deliver() can cause the call to disappear */ 03915 pvt = iaxs[callno]; 03916 break; 03917 case JB_INTERP: 03918 { 03919 struct ast_frame af = { 0, }; 03920 03921 /* create an interpolation frame */ 03922 af.frametype = AST_FRAME_VOICE; 03923 af.subclass = pvt->voiceformat; 03924 af.samples = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000); 03925 af.src = "IAX2 JB interpolation"; 03926 af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000)); 03927 af.offset = AST_FRIENDLY_OFFSET; 03928 03929 /* queue the frame: For consistency, we would call __do_deliver here, but __do_deliver wants an iax_frame, 03930 * which we'd need to malloc, and then it would free it. That seems like a drag */ 03931 if (!ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) { 03932 iax2_queue_frame(callno, &af); 03933 /* iax2_queue_frame() could cause the call to disappear */ 03934 pvt = iaxs[callno]; 03935 } 03936 } 03937 break; 03938 case JB_DROP: 03939 iax2_frame_free(frame.data); 03940 break; 03941 case JB_NOFRAME: 03942 case JB_EMPTY: 03943 /* do nothing */ 03944 break; 03945 default: 03946 /* shouldn't happen */ 03947 break; 03948 } 03949 } 03950 if (pvt) 03951 update_jbsched(pvt); 03952 ast_mutex_unlock(&iaxsl[callno]); 03953 }
| static void __iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7928 of file chan_iax2.c.
References iax2_registry::expire, and iax2_do_register().
Referenced by iax2_do_register_s().
07929 { 07930 struct iax2_registry *reg = (struct iax2_registry *)data; 07931 reg->expire = -1; 07932 iax2_do_register(reg); 07933 }
| static void __iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11441 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().
11442 { 11443 struct iax2_peer *peer = (struct iax2_peer *)data; 11444 int callno; 11445 11446 if (peer->lastms > -1) { 11447 ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE! Time: %d\n", peer->name, peer->lastms); 11448 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, peer->lastms); 11449 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 11450 } 11451 if ((callno = peer->callno) > 0) { 11452 ast_mutex_lock(&iaxsl[callno]); 11453 iax2_destroy(callno); 11454 ast_mutex_unlock(&iaxsl[callno]); 11455 } 11456 peer->callno = 0; 11457 peer->lastms = -1; 11458 /* Try again quickly */ 11459 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 11460 if (peer->pokeexpire == -1) 11461 peer_unref(peer); 11462 }
| static void __iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 8718 of file chan_iax2.c.
References iax2_poke_peer(), and peer_unref().
Referenced by iax2_poke_peer_s().
08719 { 08720 struct iax2_peer *peer = (struct iax2_peer *)data; 08721 iax2_poke_peer(peer, 0); 08722 peer_unref(peer); 08723 }
| static int __iax2_show_peers | ( | int | manager, | |
| int | fd, | |||
| struct mansession * | s, | |||
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 6324 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_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag, astman_append(), iax2_peer::encmethods, encmethods_to_str(), FORMAT, FORMAT2, IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, name, peer_status(), peer_unref(), RESULT_SHOWUSAGE, RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by handle_cli_iax2_show_peers(), and manager_iax2_show_peers().
06325 { 06326 regex_t regexbuf; 06327 int havepattern = 0; 06328 int total_peers = 0; 06329 int online_peers = 0; 06330 int offline_peers = 0; 06331 int unmonitored_peers = 0; 06332 struct ao2_iterator i; 06333 06334 #define FORMAT2 "%-15.15s %-15.15s %s %-15.15s %-8s %s %-10s%s" 06335 #define FORMAT "%-15.15s %-15.15s %s %-15.15s %-5d%s %s %-10s%s" 06336 06337 struct iax2_peer *peer = NULL; 06338 char name[256]; 06339 struct ast_str *encmethods = ast_str_alloca(256); 06340 int registeredonly=0; 06341 char *term = manager ? "\r\n" : "\n"; 06342 char idtext[256] = ""; 06343 switch (argc) { 06344 case 6: 06345 if (!strcasecmp(argv[3], "registered")) 06346 registeredonly = 1; 06347 else 06348 return RESULT_SHOWUSAGE; 06349 if (!strcasecmp(argv[4], "like")) { 06350 if (regcomp(®exbuf, argv[5], REG_EXTENDED | REG_NOSUB)) 06351 return RESULT_SHOWUSAGE; 06352 havepattern = 1; 06353 } else 06354 return RESULT_SHOWUSAGE; 06355 break; 06356 case 5: 06357 if (!strcasecmp(argv[3], "like")) { 06358 if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) 06359 return RESULT_SHOWUSAGE; 06360 havepattern = 1; 06361 } else 06362 return RESULT_SHOWUSAGE; 06363 break; 06364 case 4: 06365 if (!strcasecmp(argv[3], "registered")) 06366 registeredonly = 1; 06367 else 06368 return RESULT_SHOWUSAGE; 06369 break; 06370 case 3: 06371 break; 06372 default: 06373 return RESULT_SHOWUSAGE; 06374 } 06375 06376 06377 if (!s) 06378 ast_cli(fd, FORMAT2, "Name/Username", "Host", " ", "Mask", "Port", " ", "Status", term); 06379 06380 i = ao2_iterator_init(peers, 0); 06381 for (peer = ao2_iterator_next(&i); peer; 06382 peer_unref(peer), peer = ao2_iterator_next(&i)) { 06383 char nm[20]; 06384 char status[20]; 06385 int retstatus; 06386 06387 if (registeredonly && !peer->addr.sin_addr.s_addr) 06388 continue; 06389 if (havepattern && regexec(®exbuf, peer->name, 0, NULL, 0)) 06390 continue; 06391 06392 if (!ast_strlen_zero(peer->username)) 06393 snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username); 06394 else 06395 ast_copy_string(name, peer->name, sizeof(name)); 06396 06397 encmethods_to_str(peer->encmethods, encmethods); 06398 retstatus = peer_status(peer, status, sizeof(status)); 06399 if (retstatus > 0) 06400 online_peers++; 06401 else if (!retstatus) 06402 offline_peers++; 06403 else 06404 unmonitored_peers++; 06405 06406 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06407 06408 if (s) { 06409 astman_append(s, 06410 "Event: PeerEntry\r\n%s" 06411 "Channeltype: IAX2\r\n" 06412 "ChanObjectType: peer\r\n" 06413 "ObjectName: %s\r\n" 06414 "IPaddress: %s\r\n" 06415 "IPport: %d\r\n" 06416 "Dynamic: %s\r\n" 06417 "Trunk: %s\r\n" 06418 "Encryption: %s\r\n" 06419 "Status: %s\r\n\r\n", 06420 idtext, 06421 name, 06422 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-", 06423 ntohs(peer->addr.sin_port), 06424 ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no", 06425 ast_test_flag(peer, IAX_TRUNK) ? "yes" : "no", 06426 peer->encmethods ? ast_str_buffer(encmethods) : "no", 06427 status); 06428 } else { 06429 ast_cli(fd, FORMAT, name, 06430 peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", 06431 ast_test_flag(peer, IAX_DYNAMIC) ? "(D)" : "(S)", 06432 nm, 06433 ntohs(peer->addr.sin_port), 06434 ast_test_flag(peer, IAX_TRUNK) ? "(T)" : " ", 06435 peer->encmethods ? "(E)" : " ", 06436 status, 06437 term); 06438 } 06439 total_peers++; 06440 } 06441 ao2_iterator_destroy(&i); 06442 06443 if (!s) 06444 ast_cli(fd,"%d iax2 peers [%d online, %d offline, %d unmonitored]%s", total_peers, online_peers, offline_peers, unmonitored_peers, term); 06445 06446 if (havepattern) 06447 regfree(®exbuf); 06448 06449 return RESULT_SUCCESS; 06450 #undef FORMAT 06451 #undef FORMAT2 06452 }
| static void __reg_module | ( | void | ) | [static] |
Definition at line 13915 of file chan_iax2.c.
| static int __schedule_action | ( | void(*)(const void *data) | func, | |
| const void * | data, | |||
| const char * | funcname | |||
| ) | [static] |
Definition at line 1328 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.
01329 { 01330 struct iax2_thread *thread = NULL; 01331 static time_t lasterror; 01332 static time_t t; 01333 01334 thread = find_idle_thread(); 01335 01336 if (thread != NULL) { 01337 thread->schedfunc = func; 01338 thread->scheddata = data; 01339 thread->iostate = IAX_IOSTATE_SCHEDREADY; 01340 #ifdef DEBUG_SCHED_MULTITHREAD 01341 ast_copy_string(thread->curfunc, funcname, sizeof(thread->curfunc)); 01342 #endif 01343 signal_condition(&thread->lock, &thread->cond); 01344 return 0; 01345 } 01346 time(&t); 01347 if (t != lasterror) 01348 ast_debug(1, "Out of idle IAX2 threads for scheduling!\n"); 01349 lasterror = t; 01350 01351 return -1; 01352 }
| 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 7128 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().
07130 { 07131 struct ast_frame f = { 0, }; 07132 int res = 0; 07133 07134 f.frametype = type; 07135 f.subclass = command; 07136 f.datalen = datalen; 07137 f.src = __FUNCTION__; 07138 f.data.ptr = (void *) data; 07139 07140 if ((res = queue_signalling(i, &f)) <= 0) { 07141 return res; 07142 } 07143 07144 return iax2_send(i, &f, ts, seqno, now, transfer, final); 07145 }
| static void __send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1433 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().
01434 { 01435 int callno = (long) data; 01436 01437 ast_mutex_lock(&iaxsl[callno]); 01438 01439 if (iaxs[callno]) { 01440 if (iaxs[callno]->peercallno) { 01441 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); 01442 iaxs[callno]->lagid = iax2_sched_add(sched, lagrq_time * 1000, send_lagrq, data); 01443 } else { 01444 /* I am the schedule, so I'm allowed to do this */ 01445 iaxs[callno]->lagid = -1; 01446 } 01447 } else { 01448 ast_debug(1, "I was supposed to send a LAGRQ with callno %d, but no such call exists.\n", callno); 01449 } 01450 01451 ast_mutex_unlock(&iaxsl[callno]); 01452 }
| static void __send_ping | ( | const void * | data | ) | [static] |
Definition at line 1372 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().
01373 { 01374 int callno = (long) data; 01375 01376 ast_mutex_lock(&iaxsl[callno]); 01377 01378 if (iaxs[callno]) { 01379 if (iaxs[callno]->peercallno) { 01380 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); 01381 iaxs[callno]->pingid = iax2_sched_add(sched, ping_time * 1000, send_ping, data); 01382 } else { 01383 /* I am the schedule, so I'm allowed to do this */ 01384 iaxs[callno]->pingid = -1; 01385 } 01386 } else { 01387 ast_debug(1, "I was supposed to send a PING with callno %d, but no such call exists.\n", callno); 01388 } 01389 01390 ast_mutex_unlock(&iaxsl[callno]); 01391 }
| static int __unload_module | ( | void | ) | [static] |
Definition at line 13611 of file chan_iax2.c.
References ao2_ref, ARRAY_LEN, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_manager_unregister(), ast_mutex_destroy(), ast_netsock_release(), AST_PTHREADT_NULL, ast_sched_thread_destroy(), ast_timer_close(), ast_unload_realtime(), ast_unregister_application(), ast_unregister_switch(), delete_users(), iax2_destroy(), iax_provision_unload(), iaxactivethreadcount, reload_firmware(), thread, and iax2_thread::threadid.
Referenced by load_module(), and unload_module().
13612 { 13613 struct iax2_thread *thread = NULL; 13614 struct ast_context *con; 13615 int x; 13616 13617 /* Make sure threads do not hold shared resources when they are canceled */ 13618 13619 /* Grab the sched lock resource to keep it away from threads about to die */ 13620 /* Cancel the network thread, close the net socket */ 13621 if (netthreadid != AST_PTHREADT_NULL) { 13622 AST_LIST_LOCK(&frame_queue); 13623 pthread_cancel(netthreadid); 13624 AST_LIST_UNLOCK(&frame_queue); 13625 pthread_join(netthreadid, NULL); 13626 } 13627 13628 sched = ast_sched_thread_destroy(sched); 13629 13630 /* Call for all threads to halt */ 13631 AST_LIST_LOCK(&idle_list); 13632 while ((thread = AST_LIST_REMOVE_HEAD(&idle_list, list))) 13633 pthread_cancel(thread->threadid); 13634 AST_LIST_UNLOCK(&idle_list); 13635 13636 AST_LIST_LOCK(&active_list); 13637 while ((thread = AST_LIST_REMOVE_HEAD(&active_list, list))) 13638 pthread_cancel(thread->threadid); 13639 AST_LIST_UNLOCK(&active_list); 13640 13641 AST_LIST_LOCK(&dynamic_list); 13642 while ((thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list))) 13643 pthread_cancel(thread->threadid); 13644 AST_LIST_UNLOCK(&dynamic_list); 13645 13646 /* Wait for threads to exit */ 13647 while(0 < iaxactivethreadcount) 13648 usleep(10000); 13649 13650 ast_netsock_release(netsock); 13651 ast_netsock_release(outsock); 13652 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13653 if (iaxs[x]) { 13654 iax2_destroy(x); 13655 } 13656 } 13657 ast_manager_unregister( "IAXpeers" ); 13658 ast_manager_unregister( "IAXpeerlist" ); 13659 ast_manager_unregister( "IAXnetstats" ); 13660 ast_manager_unregister( "IAXregistry" ); 13661 ast_unregister_application(papp); 13662 ast_cli_unregister_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 13663 ast_unregister_switch(&iax2_switch); 13664 ast_channel_unregister(&iax2_tech); 13665 delete_users(); 13666 iax_provision_unload(); 13667 reload_firmware(1); 13668 13669 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 13670 ast_mutex_destroy(&iaxsl[x]); 13671 } 13672 13673 ao2_ref(peers, -1); 13674 ao2_ref(users, -1); 13675 ao2_ref(iax_peercallno_pvts, -1); 13676 ao2_ref(iax_transfercallno_pvts, -1); 13677 ao2_ref(peercnts, -1); 13678 ao2_ref(callno_limits, -1); 13679 ao2_ref(calltoken_ignores, -1); 13680 ao2_ref(callno_pool, -1); 13681 ao2_ref(callno_pool_trunk, -1); 13682 if (timer) { 13683 ast_timer_close(timer); 13684 } 13685 13686 con = ast_context_find(regcontext); 13687 if (con) 13688 ast_context_destroy(con, "IAX2"); 13689 ast_unload_realtime("iaxpeers"); 13690 return 0; 13691 }
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 13915 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 13396 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.
13397 { 13398 struct chan_iax2_pvt *pvt; 13399 unsigned int callno; 13400 int res = 0; 13401 13402 if (!chan || chan->tech != &iax2_tech) { 13403 ast_log(LOG_ERROR, "This function requires a valid IAX2 channel\n"); 13404 return -1; 13405 } 13406 13407 callno = PTR_TO_CALLNO(chan->tech_pvt); 13408 ast_mutex_lock(&iaxsl[callno]); 13409 if (!(pvt = iaxs[callno])) { 13410 ast_mutex_unlock(&iaxsl[callno]); 13411 return -1; 13412 } 13413 13414 if (!strcasecmp(args, "osptoken")) { 13415 ast_copy_string(buf, pvt->osptoken, buflen); 13416 } else if (!strcasecmp(args, "peerip")) { 13417 ast_copy_string(buf, pvt->addr.sin_addr.s_addr ? ast_inet_ntoa(pvt->addr.sin_addr) : "", buflen); 13418 } else if (!strcasecmp(args, "peername")) { 13419 ast_copy_string(buf, pvt->username, buflen); 13420 } else { 13421 res = -1; 13422 } 13423 13424 ast_mutex_unlock(&iaxsl[callno]); 13425 13426 return res; 13427 }
| static int acf_iaxvar_read | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| char * | buf, | |||
| size_t | len | |||
| ) | [static] |
Definition at line 9386 of file chan_iax2.c.
References ast_channel_datastore_find(), ast_copy_string(), AST_LIST_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_datastore::data, ast_var_t::entries, ast_var_t::name, ast_var_t::value, and var.
09387 { 09388 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09389 AST_LIST_HEAD(, ast_var_t) *varlist; 09390 struct ast_var_t *var; 09391 09392 if (!variablestore) { 09393 *buf = '\0'; 09394 return 0; 09395 } 09396 varlist = variablestore->data; 09397 09398 AST_LIST_LOCK(varlist); 09399 AST_LIST_TRAVERSE(varlist, var, entries) { 09400 if (strcmp(var->name, data) == 0) { 09401 ast_copy_string(buf, var->value, len); 09402 break; 09403 } 09404 } 09405 AST_LIST_UNLOCK(varlist); 09406 return 0; 09407 }
| static int acf_iaxvar_write | ( | struct ast_channel * | chan, | |
| const char * | cmd, | |||
| char * | data, | |||
| const char * | value | |||
| ) | [static] |
Definition at line 9409 of file chan_iax2.c.
References ast_calloc, ast_channel_datastore_add(), ast_channel_datastore_find(), ast_datastore_alloc, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_delete(), ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_var_t::entries, ast_datastore::inheritance, LOG_ERROR, ast_var_t::name, and var.
09410 { 09411 struct ast_datastore *variablestore = ast_channel_datastore_find(chan, &iax2_variable_datastore_info, NULL); 09412 AST_LIST_HEAD(, ast_var_t) *varlist; 09413 struct ast_var_t *var; 09414 09415 if (!variablestore) { 09416 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09417 if (!variablestore) { 09418 ast_log(LOG_ERROR, "Memory allocation error\n"); 09419 return -1; 09420 } 09421 varlist = ast_calloc(1, sizeof(*varlist)); 09422 if (!varlist) { 09423 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09424 return -1; 09425 } 09426 09427 AST_LIST_HEAD_INIT(varlist); 09428 variablestore->data = varlist; 09429 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09430 ast_channel_datastore_add(chan, variablestore); 09431 } else 09432 varlist = variablestore->data; 09433 09434 AST_LIST_LOCK(varlist); 09435 AST_LIST_TRAVERSE_SAFE_BEGIN(varlist, var, entries) { 09436 if (strcmp(var->name, data) == 0) { 09437 AST_LIST_REMOVE_CURRENT(entries); 09438 ast_var_delete(var); 09439 break; 09440 } 09441 } 09442 AST_LIST_TRAVERSE_SAFE_END; 09443 var = ast_var_assign(data, value); 09444 if (var) 09445 AST_LIST_INSERT_TAIL(varlist, var, entries); 09446 else 09447 ast_log(LOG_ERROR, "Unable to assign new variable '%s'\n", data); 09448 AST_LIST_UNLOCK(varlist); 09449 return 0; 09450 }
| static int add_calltoken_ignore | ( | const char * | addr | ) | [static] |
Definition at line 2333 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().
02334 { 02335 struct addr_range tmp; 02336 struct addr_range *addr_range = NULL; 02337 struct ast_ha *ha = NULL; 02338 int error = 0; 02339 02340 if (ast_strlen_zero(addr)) { 02341 ast_log(LOG_WARNING, "invalid calltokenoptional %s\n", addr); 02342 return -1; 02343 } 02344 02345 ha = ast_append_ha("permit", addr, NULL, &error); 02346 02347 /* check for valid config information */ 02348 if (error) { 02349 ast_log(LOG_WARNING, "Error %d creating calltokenoptional entry %s\n", error, addr); 02350 return -1; 02351 } 02352 02353 ast_copy_ha(ha, &tmp.ha); 02354 /* find or create the addr_range */ 02355 if ((addr_range = ao2_find(calltoken_ignores, &tmp, OBJ_POINTER))) { 02356 ao2_lock(addr_range); 02357 addr_range->delme = 0; 02358 ao2_unlock(addr_range); 02359 } else if ((addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02360 /* copy over config data into addr_range object */ 02361 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible */ 02362 ao2_link(calltoken_ignores, addr_range); 02363 } else { 02364 ast_free_ha(ha); 02365 return -1; 02366 } 02367 02368 ast_free_ha(ha); 02369 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02370 02371 return 0; 02372 }
| static void add_empty_calltoken_ie | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | ied | |||
| ) | [static] |
Definition at line 4500 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().
04501 { 04502 /* first make sure their are two empty bytes left in ied->buf */ 04503 if (pvt && ied && (2 < ((int) sizeof(ied->buf) - ied->pos))) { 04504 ied->buf[ied->pos++] = IAX_IE_CALLTOKEN; /* type */ 04505 ied->buf[ied->pos++] = 0; /* data size, ZERO in this case */ 04506 pvt->calltoken_ie_len = 2; 04507 } 04508 }
| static int addr_range_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1995 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 1982 of file chan_iax2.c.
References addr_range::delme.
Referenced by set_config_destroy().
01983 { 01984 struct addr_range *lim = obj; 01985 lim->delme = 1; 01986 return 0; 01987 }
| static int addr_range_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1989 of file chan_iax2.c.
References addr_range::ha, and ast_ha::netaddr.
Referenced by load_objects().
01990 { 01991 const struct addr_range *lim = obj; 01992 return abs((int) lim->ha.netaddr.s_addr); 01993 }
| static int addr_range_match_address_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2015 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().
02016 { 02017 struct addr_range *addr_range = obj; 02018 struct sockaddr_in *sin = arg; 02019 02020 if ((sin->sin_addr.s_addr & addr_range->ha.netmask.s_addr) == addr_range->ha.netaddr.s_addr) { 02021 return CMP_MATCH | CMP_STOP; 02022 } 02023 return 0; 02024 }
| static int apply_context | ( | struct iax2_context * | con, | |
| const char * | context | |||
| ) | [static] |
Definition at line 7186 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 6891 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().
06892 { 06893 int x; 06894 int numchans = 0; 06895 char first_message[10] = { 0, }; 06896 char last_message[10] = { 0, }; 06897 #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" 06898 #define ACN_FORMAT2 "%s %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %s%s %s%s\n" 06899 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06900 ast_mutex_lock(&iaxsl[x]); 06901 if (iaxs[x]) { 06902 int localjitter, localdelay, locallost, locallosspct, localdropped, localooo; 06903 jb_info jbinfo; 06904 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06905 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06906 06907 if(ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06908 jb_getinfo(iaxs[x]->jb, &jbinfo); 06909 localjitter = jbinfo.jitter; 06910 localdelay = jbinfo.current - jbinfo.min; 06911 locallost = jbinfo.frames_lost; 06912 locallosspct = jbinfo.losspct/1000; 06913 localdropped = jbinfo.frames_dropped; 06914 localooo = jbinfo.frames_ooo; 06915 } else { 06916 localjitter = -1; 06917 localdelay = 0; 06918 locallost = -1; 06919 locallosspct = -1; 06920 localdropped = 0; 06921 localooo = -1; 06922 } 06923 if (s) 06924 astman_append(s, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 06925 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06926 iaxs[x]->pingtime, 06927 localjitter, 06928 localdelay, 06929 locallost, 06930 locallosspct, 06931 localdropped, 06932 localooo, 06933 iaxs[x]->frames_received/1000, 06934 iaxs[x]->remote_rr.jitter, 06935 iaxs[x]->remote_rr.delay, 06936 iaxs[x]->remote_rr.losscnt, 06937 iaxs[x]->remote_rr.losspct, 06938 iaxs[x]->remote_rr.dropped, 06939 iaxs[x]->remote_rr.ooo, 06940 iaxs[x]->remote_rr.packets/1000, 06941 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06942 first_message, 06943 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06944 last_message); 06945 else 06946 ast_cli(fd, limit_fmt ? ACN_FORMAT1 : ACN_FORMAT2, 06947 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06948 iaxs[x]->pingtime, 06949 localjitter, 06950 localdelay, 06951 locallost, 06952 locallosspct, 06953 localdropped, 06954 localooo, 06955 iaxs[x]->frames_received/1000, 06956 iaxs[x]->remote_rr.jitter, 06957 iaxs[x]->remote_rr.delay, 06958 iaxs[x]->remote_rr.losscnt, 06959 iaxs[x]->remote_rr.losspct, 06960 iaxs[x]->remote_rr.dropped, 06961 iaxs[x]->remote_rr.ooo, 06962 iaxs[x]->remote_rr.packets/1000, 06963 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06964 first_message, 06965 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06966 last_message); 06967 numchans++; 06968 } 06969 ast_mutex_unlock(&iaxsl[x]); 06970 } 06971 06972 return numchans; 06973 }
| 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 5415 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_var_t::entries, 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_channel::name, 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().
05416 { 05417 struct ast_channel *tmp; 05418 struct chan_iax2_pvt *i; 05419 struct ast_variable *v = NULL; 05420 05421 if (!(i = iaxs[callno])) { 05422 ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno); 05423 return NULL; 05424 } 05425 05426 /* Don't hold call lock */ 05427 ast_mutex_unlock(&iaxsl[callno]); 05428 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); 05429 ast_mutex_lock(&iaxsl[callno]); 05430 if (i != iaxs[callno]) { 05431 if (tmp) { 05432 /* unlock and relock iaxsl[callno] to preserve locking order */ 05433 ast_mutex_unlock(&iaxsl[callno]); 05434 ast_channel_free(tmp); 05435 ast_mutex_lock(&iaxsl[callno]); 05436 } 05437 return NULL; 05438 } 05439 iax2_ami_channelupdate(i); 05440 if (!tmp) 05441 return NULL; 05442 tmp->tech = &iax2_tech; 05443 /* We can support any format by default, until we get restricted */ 05444 tmp->nativeformats = capability; 05445 tmp->readformat = tmp->rawreadformat = ast_best_codec(capability); 05446 tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability); 05447 tmp->tech_pvt = CALLNO_TO_PTR(i->callno); 05448 05449 if (!ast_strlen_zero(i->parkinglot)) 05450 ast_string_field_set(tmp, parkinglot, i->parkinglot); 05451 /* Don't use ast_set_callerid() here because it will 05452 * generate a NewCallerID event before the NewChannel event */ 05453 if (!ast_strlen_zero(i->ani)) 05454 tmp->cid.cid_ani = ast_strdup(i->ani); 05455 else 05456 tmp->cid.cid_ani = ast_strdup(i->cid_num); 05457 tmp->cid.cid_dnid = ast_strdup(i->dnid); 05458 tmp->cid.cid_rdnis = ast_strdup(i->rdnis); 05459 tmp->cid.cid_pres = i->calling_pres; 05460 tmp->cid.cid_ton = i->calling_ton; 05461 tmp->cid.cid_tns = i->calling_tns; 05462 if (!ast_strlen_zero(i->language)) 05463 ast_string_field_set(tmp, language, i->language); 05464 if (!ast_strlen_zero(i->accountcode)) 05465 ast_string_field_set(tmp, accountcode, i->accountcode); 05466 if (i->amaflags) 05467 tmp->amaflags = i->amaflags; 05468 ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); 05469 ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); 05470 if (i->adsi) 05471 tmp->adsicpe = i->peeradsicpe; 05472 else 05473 tmp->adsicpe = AST_ADSI_UNAVAILABLE; 05474 i->owner = tmp; 05475 i->capability = capability; 05476 05477 /* Set inherited variables */ 05478 if (i->vars) { 05479 for (v = i->vars ; v ; v = v->next) 05480 pbx_builtin_setvar_helper(tmp, v->name, v->value); 05481 } 05482 if (i->iaxvars) { 05483 struct ast_datastore *variablestore; 05484 struct ast_variable *var, *prev = NULL; 05485 AST_LIST_HEAD(, ast_var_t) *varlist; 05486 ast_debug(1, "Loading up the channel with IAXVARs\n"); 05487 varlist = ast_calloc(1, sizeof(*varlist)); 05488 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 05489 if (variablestore && varlist) { 05490 variablestore->data = varlist; 05491 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 05492 AST_LIST_HEAD_INIT(varlist); 05493 for (var = i->iaxvars; var; var = var->next) { 05494 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 05495 if (prev) 05496 ast_free(prev); 05497 prev = var; 05498 if (!newvar) { 05499 /* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */ 05500 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 05501 } else { 05502 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 05503 } 05504 } 05505 if (prev) 05506 ast_free(prev); 05507 i->iaxvars = NULL; 05508 ast_channel_datastore_add(i->owner, variablestore); 05509 } else { 05510 if (variablestore) { 05511 ast_datastore_free(variablestore); 05512 } 05513 if (varlist) { 05514 ast_free(varlist); 05515 } 05516 } 05517 } 05518 05519 if (state != AST_STATE_DOWN) { 05520 if (ast_pbx_start(tmp)) { 05521 ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name); 05522 ast_hangup(tmp); 05523 i->owner = NULL; 05524 return NULL; 05525 } 05526 } 05527 05528 ast_module_ref(ast_module_info->self); 05529 return tmp; 05530 }
| static int attempt_transmit | ( | const void * | data | ) | [static] |
Definition at line 3384 of file chan_iax2.c.
References __attempt_transmit(), and schedule_action.
Referenced by __attempt_transmit(), and network_thread().
03385 { 03386 #ifdef SCHED_MULTITHREADED 03387 if (schedule_action(__attempt_transmit, data)) 03388 #endif 03389 __attempt_transmit(data); 03390 return 0; 03391 }
| static int auth_fail | ( | int | callno, | |
| int | failcode | |||
| ) | [static] |
Definition at line 8640 of file chan_iax2.c.
References auth_reject(), chan_iax2_pvt::authfail, chan_iax2_pvt::authid, and iax2_sched_replace().
Referenced by socket_process().
08641 { 08642 /* Schedule sending the authentication failure in one second, to prevent 08643 guessing */ 08644 if (iaxs[callno]) { 08645 iaxs[callno]->authfail = failcode; 08646 if (delayreject) { 08647 iaxs[callno]->authid = iax2_sched_replace(iaxs[callno]->authid, 08648 sched, 1000, auth_reject, (void *)(long)callno); 08649 } else 08650 auth_reject((void *)(long)callno); 08651 } 08652 return 0; 08653 }
| static int auth_reject | ( | const void * | data | ) | [static] |
Definition at line 8626 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().
08627 { 08628 int callno = (int)(long)(data); 08629 ast_mutex_lock(&iaxsl[callno]); 08630 if (iaxs[callno]) 08631 iaxs[callno]->authid = -1; 08632 ast_mutex_unlock(&iaxsl[callno]); 08633 #ifdef SCHED_MULTITHREADED 08634 if (schedule_action(__auth_reject, data)) 08635 #endif 08636 __auth_reject(data); 08637 return 0; 08638 }
| 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 7754 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().
07755 { 07756 int res = -1; 07757 int x; 07758 if (!ast_strlen_zero(keyn)) { 07759 if (!(authmethods & IAX_AUTH_RSA)) { 07760 if (ast_strlen_zero(secret)) 07761 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)); 07762 } else if (ast_strlen_zero(challenge)) { 07763 ast_log(LOG_NOTICE, "No challenge provided for RSA authentication to %s\n", ast_inet_ntoa(sin->sin_addr)); 07764 } else { 07765 char sig[256]; 07766 struct ast_key *key; 07767 key = ast_key_get(keyn, AST_KEY_PRIVATE); 07768 if (!key) { 07769 ast_log(LOG_NOTICE, "Unable to find private key '%s'\n", keyn); 07770 } else { 07771 if (ast_sign(key, (char*)challenge, sig)) { 07772 ast_log(LOG_NOTICE, "Unable to sign challenge with key\n"); 07773 res = -1; 07774 } else { 07775 iax_ie_append_str(ied, IAX_IE_RSA_RESULT, sig); 07776 res = 0; 07777 } 07778 } 07779 } 07780 } 07781 /* Fall back */ 07782 if (res && !ast_strlen_zero(secret)) { 07783 if ((authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(challenge)) { 07784 struct MD5Context md5; 07785 unsigned char digest[16]; 07786 char digres[128]; 07787 MD5Init(&md5); 07788 MD5Update(&md5, (unsigned char *)challenge, strlen(challenge)); 07789 MD5Update(&md5, (unsigned char *)secret, strlen(secret)); 07790 MD5Final(digest, &md5); 07791 /* If they support md5, authenticate with it. */ 07792 for (x=0;x<16;x++) 07793 sprintf(digres + (x << 1), "%2.2x", digest[x]); /* safe */ 07794 if (pvt) { 07795 build_encryption_keys(digest, pvt); 07796 } 07797 iax_ie_append_str(ied, IAX_IE_MD5_RESULT, digres); 07798 res = 0; 07799 } else if (authmethods & IAX_AUTH_PLAINTEXT) { 07800 iax_ie_append_str(ied, IAX_IE_PASSWORD, secret); 07801 res = 0; 07802 } else 07803 ast_log(LOG_NOTICE, "No way to send secret to peer '%s' (their methods: %d)\n", ast_inet_ntoa(sin->sin_addr), authmethods); 07804 } 07805 return res; 07806 }
| 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 7812 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_string_field_set, ast_strlen_zero(), ast_test_flag, 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, ast_var_t::entries, IAX_AUTH_MD5, IAX_COMMAND_AUTHREP, IAX_ENCRYPTED, IAX_FORCE_ENCRYPT, IAX_KEYPOPULATED, ast_datastore::inheritance, LOG_ERROR, LOG_NOTICE, 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().
07813 { 07814 struct iax2_peer *peer = NULL; 07815 /* Start pessimistic */ 07816 int res = -1; 07817 int authmethods = 0; 07818 struct iax_ie_data ied; 07819 uint16_t callno = p->callno; 07820 07821 memset(&ied, 0, sizeof(ied)); 07822 07823 if (ies->username) 07824 ast_string_field_set(p, username, ies->username); 07825 if (ies->challenge) 07826 ast_string_field_set(p, challenge, ies->challenge); 07827 if (ies->authmethods) 07828 authmethods = ies->authmethods; 07829 if (authmethods & IAX_AUTH_MD5) 07830 merge_encryption(p, ies->encmethods); 07831 else 07832 p->encmethods = 0; 07833 07834 /* Check for override RSA authentication first */ 07835 if (!ast_strlen_zero(override) || !ast_strlen_zero(okey)) { 07836 /* Normal password authentication */ 07837 res = authenticate(p->challenge, override, okey, authmethods, &ied, sin, p); 07838 } else { 07839 struct ao2_iterator i = ao2_iterator_init(peers, 0); 07840 while ((peer = ao2_iterator_next(&i))) { 07841 if ((ast_strlen_zero(p->peer) || !strcmp(p->peer, peer->name)) 07842 /* No peer specified at our end, or this is the peer */ 07843 && (ast_strlen_zero(peer->username) || (!strcmp(peer->username, p->username))) 07844 /* No username specified in peer rule, or this is the right username */ 07845 && (!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))) 07846 /* No specified host, or this is our host */ 07847 ) { 07848 res = authenticate(p->challenge, peer->secret, peer->outkey, authmethods, &ied, sin, p); 07849 if (!res) { 07850 peer_unref(peer); 07851 break; 07852 } 07853 } 07854 peer_unref(peer); 07855 } 07856 ao2_iterator_destroy(&i); 07857 if (!peer) { 07858 /* We checked our list and didn't find one. It's unlikely, but possible, 07859 that we're trying to authenticate *to* a realtime peer */ 07860 const char *peer_name = ast_strdupa(p->peer); 07861 ast_mutex_unlock(&iaxsl[callno]); 07862 if ((peer = realtime_peer(peer_name, NULL))) { 07863 ast_mutex_lock(&iaxsl[callno]); 07864 if (!(p = iaxs[callno])) { 07865 peer_unref(peer); 07866 return -1; 07867 } 07868 res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, p); 07869 peer_unref(peer); 07870 } 07871 if (!peer) { 07872 ast_mutex_lock(&iaxsl[callno]); 07873 if (!(p = iaxs[callno])) 07874 return -1; 07875 } 07876 } 07877 } 07878 07879 if (ies->encmethods) { 07880 ast_set_flag(p, IAX_ENCRYPTED | IAX_KEYPOPULATED); 07881 } else if (ast_test_flag(iaxs[callno], IAX_FORCE_ENCRYPT)) { 07882 ast_log(LOG_NOTICE, "Call initiated without encryption while forceencryption=yes option is set"); 07883 return -1; /* if force encryption is yes, and no encryption methods, then return -1 to hangup */ 07884 } 07885 if (!res) { 07886 struct ast_datastore *variablestore; 07887 struct ast_variable *var, *prev = NULL; 07888 AST_LIST_HEAD(, ast_var_t) *varlist; 07889 varlist = ast_calloc(1, sizeof(*varlist)); 07890 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 07891 if (variablestore && varlist && p->owner) { 07892 variablestore->data = varlist; 07893 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 07894 AST_LIST_HEAD_INIT(varlist); 07895 for (var = ies->vars; var; var = var->next) { 07896 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 07897 if (prev) 07898 ast_free(prev); 07899 prev = var; 07900 if (!newvar) { 07901 /* Don't abort list traversal, as this would leave ies->vars in an inconsistent state. */ 07902 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 07903 } else { 07904 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 07905 } 07906 } 07907 if (prev) 07908 ast_free(prev); 07909 ies->vars = NULL; 07910 ast_channel_datastore_add(p->owner, variablestore); 07911 } else { 07912 if (p->owner) 07913 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 07914 if (variablestore) 07915 ast_datastore_free(variablestore); 07916 if (varlist) 07917 ast_free(varlist); 07918 } 07919 } 07920 07921 if (!res) 07922 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); 07923 return res; 07924 }
| static int authenticate_request | ( | int | call_num | ) | [static] |
Definition at line 7462 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().
07463 { 07464 struct iax_ie_data ied; 07465 int res = -1, authreq_restrict = 0; 07466 char challenge[10]; 07467 struct chan_iax2_pvt *p = iaxs[call_num]; 07468 07469 memset(&ied, 0, sizeof(ied)); 07470 07471 /* If an AUTHREQ restriction is in place, make sure we can send an AUTHREQ back */ 07472 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 07473 struct iax2_user *user, tmp_user = { 07474 .name = p->username, 07475 }; 07476 07477 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07478 if (user) { 07479 if (user->curauthreq == user->maxauthreq) 07480 authreq_restrict = 1; 07481 else 07482 user->curauthreq++; 07483 user = user_unref(user); 07484 } 07485 } 07486 07487 /* If the AUTHREQ limit test failed, send back an error */ 07488 if (authreq_restrict) { 07489 iax_ie_append_str(&ied, IAX_IE_CAUSE, "Unauthenticated call limit reached"); 07490 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, AST_CAUSE_CALL_REJECTED); 07491 send_command_final(p, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); 07492 return 0; 07493 } 07494 07495 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, p->authmethods); 07496 if (p->authmethods & (IAX_AUTH_MD5 | IAX_AUTH_RSA)) { 07497 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 07498 ast_string_field_set(p, challenge, challenge); 07499 /* snprintf(p->challenge, sizeof(p->challenge), "%d", (int)ast_random()); */ 07500 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, p->challenge); 07501 } 07502 if (p->encmethods) 07503 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, p->encmethods); 07504 07505 iax_ie_append_str(&ied,IAX_IE_USERNAME, p->username); 07506 07507 res = send_command(p, AST_FRAME_IAX, IAX_COMMAND_AUTHREQ, 0, ied.buf, ied.pos, -1); 07508 07509 if (p->encmethods) 07510 ast_set_flag(p, IAX_ENCRYPTED); 07511 07512 return res; 07513 }
| static int authenticate_verify | ( | struct chan_iax2_pvt * | p, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7515 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_string_field_set, ast_strlen_zero(), ast_test_flag, chan_iax2_pvt::authmethods, chan_iax2_pvt::authrej, chan_iax2_pvt::challenge, iax2_user::curauthreq, chan_iax2_pvt::encmethods, IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, IAX_AUTH_RSA, IAX_FORCE_ENCRYPT, IAX_MAXAUTHREQ, IAX_STATE_AUTHENTICATED, chan_iax2_pvt::inkeys, LOG_NOTICE, LOG_WARNING, 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, user_unref(), and chan_iax2_pvt::username.
Referenced by socket_process().
07516 { 07517 char requeststr[256]; 07518 char md5secret[256] = ""; 07519 char secret[256] = ""; 07520 char rsasecret[256] = ""; 07521 int res = -1; 07522 int x; 07523 struct iax2_user *user, tmp_user = { 07524 .name = p->username, 07525 }; 07526 07527 if (p->authrej) { 07528 return res; 07529 } 07530 user = ao2_find(users, &tmp_user, OBJ_POINTER); 07531 if (user) { 07532 if (ast_test_flag(p, IAX_MAXAUTHREQ)) { 07533 ast_atomic_fetchadd_int(&user->curauthreq, -1); 07534 ast_clear_flag(p, IAX_MAXAUTHREQ); 07535 } 07536 ast_string_field_set(p, host, user->name); 07537 user = user_unref(user); 07538 } 07539 if (ast_test_flag(p, IAX_FORCE_ENCRYPT) && !p->encmethods) { 07540 ast_log(LOG_NOTICE, "Call Terminated, Incomming call is unencrypted while force encrypt is enabled."); 07541 return res; 07542 } 07543 if (!ast_test_flag(&p->state, IAX_STATE_AUTHENTICATED)) 07544 return res; 07545 if (ies->password) 07546 ast_copy_string(secret, ies->password, sizeof(secret)); 07547 if (ies->md5_result) 07548 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07549 if (ies->rsa_result) 07550 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07551 if ((p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(rsasecret) && !ast_strlen_zero(p->inkeys)) { 07552 struct ast_key *key; 07553 char *keyn; 07554 char tmpkey[256]; 07555 char *stringp=NULL; 07556 ast_copy_string(tmpkey, p->inkeys, sizeof(tmpkey)); 07557 stringp=tmpkey; 07558 keyn = strsep(&stringp, ":"); 07559 while(keyn) { 07560 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07561 if (key && !ast_check_signature(key, p->challenge, rsasecret)) { 07562 res = 0; 07563 break; 07564 } else if (!key) 07565 ast_log(LOG_WARNING, "requested inkey '%s' for RSA authentication does not exist\n", keyn); 07566 keyn = strsep(&stringp, ":"); 07567 } 07568 } else if (p->authmethods & IAX_AUTH_MD5) { 07569 struct MD5Context md5; 07570 unsigned char digest[16]; 07571 char *tmppw, *stringp; 07572 07573 tmppw = ast_strdupa(p->secret); 07574 stringp = tmppw; 07575 while((tmppw = strsep(&stringp, ";"))) { 07576 MD5Init(&md5); 07577 MD5Update(&md5, (unsigned char *)p->challenge, strlen(p->challenge)); 07578 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07579 MD5Final(digest, &md5); 07580 /* If they support md5, authenticate with it. */ 07581 for (x=0;x<16;x++) 07582 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07583 if (!strcasecmp(requeststr, md5secret)) { 07584 res = 0; 07585 break; 07586 } 07587 } 07588 } else if (p->authmethods & IAX_AUTH_PLAINTEXT) { 07589 if (!strcmp(secret, p->secret)) 07590 res = 0; 07591 } 07592 return res; 07593 }
| static int auto_congest | ( | const void * | data | ) | [static] |
Definition at line 4439 of file chan_iax2.c.
References __auto_congest(), and schedule_action.
Referenced by iax2_call().
04440 { 04441 #ifdef SCHED_MULTITHREADED 04442 if (schedule_action(__auto_congest, data)) 04443 #endif 04444 __auto_congest(data); 04445 return 0; 04446 }
| static int auto_hangup | ( | const void * | data | ) | [static] |
Definition at line 8670 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().
08671 { 08672 int callno = (int)(long)(data); 08673 ast_mutex_lock(&iaxsl[callno]); 08674 if (iaxs[callno]) { 08675 iaxs[callno]->autoid = -1; 08676 } 08677 ast_mutex_unlock(&iaxsl[callno]); 08678 #ifdef SCHED_MULTITHREADED 08679 if (schedule_action(__auto_hangup, data)) 08680 #endif 08681 __auto_hangup(data); 08682 return 0; 08683 }
| static void build_callno_limits | ( | struct ast_variable * | v | ) | [static] |
Definition at line 2278 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().
02279 { 02280 struct addr_range *addr_range = NULL; 02281 struct addr_range tmp; 02282 struct ast_ha *ha; 02283 int limit; 02284 int error; 02285 int found; 02286 02287 for (; v; v = v->next) { 02288 limit = -1; 02289 error = 0; 02290 found = 0; 02291 ha = ast_append_ha("permit", v->name, NULL, &error); 02292 02293 /* check for valid config information */ 02294 if (error) { 02295 ast_log(LOG_ERROR, "Call number limit for %s could not be added, Invalid address range\n.", v->name); 02296 continue; 02297 } else if ((sscanf(v->value, "%d", &limit) != 1) || (limit < 0)) { 02298 ast_log(LOG_ERROR, "Call number limit for %s could not be added. Invalid limit %s\n.", v->name, v->value); 02299 ast_free_ha(ha); 02300 continue; 02301 } 02302 02303 ast_copy_ha(ha, &tmp.ha); 02304 /* find or create the addr_range */ 02305 if ((addr_range = ao2_find(callno_limits, &tmp, OBJ_POINTER))) { 02306 ao2_lock(addr_range); 02307 found = 1; 02308 } else if (!(addr_range = ao2_alloc(sizeof(*addr_range), NULL))) { 02309 ast_free_ha(ha); 02310 return; /* out of memory */ 02311 } 02312 02313 /* copy over config data into addr_range object */ 02314 ast_copy_ha(ha, &addr_range->ha); /* this is safe because only one ha is possible for each limit */ 02315 ast_free_ha(ha); /* cleanup the tmp ha */ 02316 addr_range->limit = limit; 02317 addr_range->delme = 0; 02318 02319 /* cleanup */ 02320 if (found) { 02321 ao2_unlock(addr_range); 02322 } else { 02323 ao2_link(callno_limits, addr_range); 02324 } 02325 ao2_ref(addr_range, -1); /* decrement ref from ao2_find and ao2_alloc, only container ref remains */ 02326 } 02327 }
| static struct iax2_context* build_context | ( | const char * | context | ) | [static, read] |
Definition at line 11732 of file chan_iax2.c.
References ast_calloc, ast_copy_string(), and iax2_context::context.
Referenced by build_user().
11733 { 11734 struct iax2_context *con; 11735 11736 if ((con = ast_calloc(1, sizeof(*con)))) 11737 ast_copy_string(con->context, context, sizeof(con->context)); 11738 11739 return con; 11740 }
| static void build_ecx_key | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 5873 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().
05874 { 05875 /* it is required to hold the corresponding decrypt key to our encrypt key 05876 * in the pvt struct because queued frames occasionally need to be decrypted and 05877 * re-encrypted when updated for a retransmission */ 05878 build_rand_pad(pvt->semirand, sizeof(pvt->semirand)); 05879 ast_aes_encrypt_key(digest, &pvt->ecx); 05880 ast_aes_decrypt_key(digest, &pvt->mydcx); 05881 }
| static void build_encryption_keys | ( | const unsigned char * | digest, | |
| struct chan_iax2_pvt * | pvt | |||
| ) | [static] |
Definition at line 5867 of file chan_iax2.c.
References ast_aes_decrypt_key, build_ecx_key(), and chan_iax2_pvt::dcx.
Referenced by authenticate(), and decrypt_frame().
05868 { 05869 build_ecx_key(digest, pvt); 05870 ast_aes_decrypt_key(digest, &pvt->dcx); 05871 }
| 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 11880 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_thread_del, ast_set2_flag, ast_set_flag, ast_set_flags_to, 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_FORCE_ENCRYPT, 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, iax2_peer::regexten, S_OR, secret, iax2_peer::smoothing, iax2_peer::sockfd, unlink_peer(), ast_variable::value, and zonetag.
Referenced by realtime_peer(), and set_config().
11881 { 11882 struct iax2_peer *peer = NULL; 11883 struct ast_ha *oldha = NULL; 11884 int maskfound = 0; 11885 int found = 0; 11886 int firstpass = 1; 11887 struct iax2_peer tmp_peer = { 11888 .name = name, 11889 }; 11890 11891 if (!temponly) { 11892 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 11893 if (peer && !ast_test_flag(peer, IAX_DELME)) 11894 firstpass = 0; 11895 } 11896 11897 if (peer) { 11898 found++; 11899 if (firstpass) { 11900 oldha = peer->ha; 11901 peer->ha = NULL; 11902 } 11903 unlink_peer(peer); 11904 } else if ((peer = ao2_alloc(sizeof(*peer), peer_destructor))) { 11905 peer->expire = -1; 11906 peer->pokeexpire = -1; 11907 peer->sockfd = defaultsockfd; 11908 if (ast_string_field_init(peer, 32)) 11909 peer = peer_unref(peer); 11910 } 11911 11912 if (peer) { 11913 if (firstpass) { 11914 ast_copy_flags(peer, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT); 11915 peer->encmethods = iax2_encryption; 11916 peer->adsi = adsi; 11917 ast_string_field_set(peer,secret,""); 11918 if (!found) { 11919 ast_string_field_set(peer, name, name); 11920 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 11921 peer->expiry = min_reg_expire; 11922 } 11923 peer->prefs = prefs; 11924 peer->capability = iax2_capability; 11925 peer->smoothing = 0; 11926 peer->pokefreqok = DEFAULT_FREQ_OK; 11927 peer->pokefreqnotok = DEFAULT_FREQ_NOTOK; 11928 peer->maxcallno = 0; 11929 peercnt_modify(0, 0, &peer->addr); 11930 peer->calltoken_required = CALLTOKEN_DEFAULT; 11931 ast_string_field_set(peer,context,""); 11932 ast_string_field_set(peer,peercontext,""); 11933 ast_clear_flag(peer, IAX_HASCALLERID); 11934 ast_string_field_set(peer, cid_name, ""); 11935 ast_string_field_set(peer, cid_num, ""); 11936 ast_string_field_set(peer, mohinterpret, mohinterpret); 11937 ast_string_field_set(peer, mohsuggest, mohsuggest); 11938 } 11939 11940 if (!v) { 11941 v = alt; 11942 alt = NULL; 11943 } 11944 while(v) { 11945 if (!strcasecmp(v->name, "secret")) { 11946 ast_string_field_set(peer, secret, v->value); 11947 } else if (!strcasecmp(v->name, "mailbox")) { 11948 ast_string_field_set(peer, mailbox, v->value); 11949 } else if (!strcasecmp(v->name, "hasvoicemail")) { 11950 if (ast_true(v->value) && ast_strlen_zero(peer->mailbox)) { 11951 ast_string_field_set(peer, mailbox, name); 11952 } 11953 } else if (!strcasecmp(v->name, "mohinterpret")) { 11954 ast_string_field_set(peer, mohinterpret, v->value); 11955 } else if (!strcasecmp(v->name, "mohsuggest")) { 11956 ast_string_field_set(peer, mohsuggest, v->value); 11957 } else if (!strcasecmp(v->name, "dbsecret")) { 11958 ast_string_field_set(peer, dbsecret, v->value); 11959 } else if (!strcasecmp(v->name, "trunk")) { 11960 ast_set2_flag(peer, ast_true(v->value), IAX_TRUNK); 11961 if (ast_test_flag(peer, IAX_TRUNK) && !timer) { 11962 ast_log(LOG_WARNING, "Unable to support trunking on peer '%s' without a timing interface\n", peer->name); 11963 ast_clear_flag(peer, IAX_TRUNK); 11964 } 11965 } else if (!strcasecmp(v->name, "auth")) { 11966 peer->authmethods = get_auth_methods(v->value); 11967 } else if (!strcasecmp(v->name, "encryption")) { 11968 peer->encmethods |= get_encrypt_methods(v->value); 11969 if (!peer->encmethods) { 11970 ast_clear_flag(peer, IAX_FORCE_ENCRYPT); 11971 } 11972 } else if (!strcasecmp(v->name, "forceencryption")) { 11973 if (ast_false(v->value)) { 11974 ast_clear_flag(peer, IAX_FORCE_ENCRYPT); 11975 } else { 11976 peer->encmethods |= get_encrypt_methods(v->value); 11977 if (peer->encmethods) { 11978 ast_set_flag(peer, IAX_FORCE_ENCRYPT); 11979 } 11980 } 11981 } else if (!strcasecmp(v->name, "transfer")) { 11982 if (!strcasecmp(v->value, "mediaonly")) { 11983 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 11984 } else if (ast_true(v->value)) { 11985 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 11986 } else 11987 ast_set_flags_to(peer, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 11988 } else if (!strcasecmp(v->name, "jitterbuffer")) { 11989 ast_set2_flag(peer, ast_true(v->value), IAX_USEJITTERBUF); 11990 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 11991 ast_set2_flag(peer, ast_true(v->value), IAX_FORCEJITTERBUF); 11992 } else if (!strcasecmp(v->name, "host")) { 11993 if (!strcasecmp(v->value, "dynamic")) { 11994 /* They'll register with us */ 11995 ast_set_flag(peer, IAX_DYNAMIC); 11996 if (!found) { 11997 /* Initialize stuff iff we're not found, otherwise 11998 we keep going with what we had */ 11999 memset(&peer->addr.sin_addr, 0, 4); 12000 if (peer->addr.sin_port) { 12001 /* If we've already got a port, make it the default rather than absolute */ 12002 peer->defaddr.sin_port = peer->addr.sin_port; 12003 peer->addr.sin_port = 0; 12004 } 12005 } 12006 } else { 12007 /* Non-dynamic. Make sure we become that way if we're not */ 12008 ast_sched_thread_del(sched, peer->expire); 12009 ast_clear_flag(peer, IAX_DYNAMIC); 12010 if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, srvlookup ? "_iax._udp" : NULL)) 12011 return peer_unref(peer); 12012 if (!peer->addr.sin_port) 12013 peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO); 12014 } 12015 if (!maskfound) 12016 inet_aton("255.255.255.255", &peer->mask); 12017 } else if (!strcasecmp(v->name, "defaultip")) { 12018 if (ast_get_ip(&peer->defaddr, v->value)) 12019 return peer_unref(peer); 12020 } else if (!strcasecmp(v->name, "sourceaddress")) { 12021 peer_set_srcaddr(peer, v->value); 12022 } else if (!strcasecmp(v->name, "permit") || 12023 !strcasecmp(v->name, "deny")) { 12024 peer->ha = ast_append_ha(v->name, v->value, peer->ha, NULL); 12025 } else if (!strcasecmp(v->name, "mask")) { 12026 maskfound++; 12027 inet_aton(v->value, &peer->mask); 12028 } else if (!strcasecmp(v->name, "context")) { 12029 ast_string_field_set(peer, context, v->value); 12030 } else if (!strcasecmp(v->name, "regexten")) { 12031 ast_string_field_set(peer, regexten, v->value); 12032 } else if (!strcasecmp(v->name, "peercontext")) { 12033 ast_string_field_set(peer, peercontext, v->value); 12034 } else if (!strcasecmp(v->name, "port")) { 12035 if (ast_test_flag(peer, IAX_DYNAMIC)) 12036 peer->defaddr.sin_port = htons(atoi(v->value)); 12037 else 12038 peer->addr.sin_port = htons(atoi(v->value)); 12039 } else if (!strcasecmp(v->name, "username")) { 12040 ast_string_field_set(peer, username, v->value); 12041 } else if (!strcasecmp(v->name, "allow")) { 12042 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1); 12043 } else if (!strcasecmp(v->name, "disallow")) { 12044 ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0); 12045 } else if (!strcasecmp(v->name, "callerid")) { 12046 if (!ast_strlen_zero(v->value)) { 12047 char name2[80]; 12048 char num2[80]; 12049 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12050 ast_string_field_set(peer, cid_name, name2); 12051 ast_string_field_set(peer, cid_num, num2); 12052 } else { 12053 ast_string_field_set(peer, cid_name, ""); 12054 ast_string_field_set(peer, cid_num, ""); 12055 } 12056 ast_set_flag(peer, IAX_HASCALLERID); 12057 } else if (!strcasecmp(v->name, "fullname")) { 12058 ast_string_field_set(peer, cid_name, S_OR(v->value, "")); 12059 ast_set_flag(peer, IAX_HASCALLERID); 12060 } else if (!strcasecmp(v->name, "cid_number")) { 12061 ast_string_field_set(peer, cid_num, S_OR(v->value, "")); 12062 ast_set_flag(peer, IAX_HASCALLERID); 12063 } else if (!strcasecmp(v->name, "sendani")) { 12064 ast_set2_flag(peer, ast_true(v->value), IAX_SENDANI); 12065 } else if (!strcasecmp(v->name, "inkeys")) { 12066 ast_string_field_set(peer, inkeys, v->value); 12067 } else if (!strcasecmp(v->name, "outkey")) { 12068 ast_string_field_set(peer, outkey, v->value); 12069 } else if (!strcasecmp(v->name, "qualify")) { 12070 if (!strcasecmp(v->value, "no")) { 12071 peer->maxms = 0; 12072 } else if (!strcasecmp(v->value, "yes")) { 12073 peer->maxms = DEFAULT_MAXMS; 12074 } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) { 12075 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); 12076 peer->maxms = 0; 12077 } 12078 } else if (!strcasecmp(v->name, "qualifysmoothing")) { 12079 peer->smoothing = ast_true(v->value); 12080 } else if (!strcasecmp(v->name, "qualifyfreqok")) { 12081 if (sscanf(v->value, "%30d", &peer->pokefreqok) != 1) { 12082 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); 12083 } 12084 } else if (!strcasecmp(v->name, "qualifyfreqnotok")) { 12085 if (sscanf(v->value, "%30d", &peer->pokefreqnotok) != 1) { 12086 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); 12087 } else ast_log(LOG_WARNING, "Set peer->pokefreqnotok to %d\n", peer->pokefreqnotok); 12088 } else if (!strcasecmp(v->name, "timezone")) { 12089 ast_string_field_set(peer, zonetag, v->value); 12090 } else if (!strcasecmp(v->name, "adsi")) { 12091 peer->adsi = ast_true(v->value); 12092 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12093 if (sscanf(v->value, "%10hu", &peer->maxcallno) != 1) { 12094 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d.\n", v->value, v->lineno); 12095 } else { 12096 peercnt_modify(1, peer->maxcallno, &peer->addr); 12097 } 12098 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12099 /* default is required unless in optional ip list */ 12100 if (ast_false(v->value)) { 12101 peer->calltoken_required = CALLTOKEN_NO; 12102 } else if (!strcasecmp(v->value, "auto")) { 12103 peer->calltoken_required = CALLTOKEN_AUTO; 12104 } else if (ast_true(v->value)) { 12105 peer->calltoken_required = CALLTOKEN_YES; 12106 } else { 12107 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12108 } 12109 } /* else if (strcasecmp(v->name,"type")) */ 12110 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12111 v = v->next; 12112 if (!v) { 12113 v = alt; 12114 alt = NULL; 12115 } 12116 } 12117 if (!peer->authmethods) 12118 peer->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12119 ast_clear_flag(peer, IAX_DELME); 12120 /* Make sure these are IPv4 addresses */ 12121 peer->addr.sin_family = AF_INET; 12122 } 12123 12124 if (oldha) 12125 ast_free_ha(oldha); 12126 12127 if (!ast_strlen_zero(peer->mailbox)) { 12128 char *mailbox, *context; 12129 context = mailbox = ast_strdupa(peer->mailbox); 12130 strsep(&context, "@"); 12131 if (ast_strlen_zero(context)) 12132 context = "default"; 12133 peer->mwi_event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, NULL, 12134 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 12135 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 12136 AST_EVENT_IE_END); 12137 } 12138 12139 return peer; 12140 }
| static void build_rand_pad | ( | unsigned char * | buf, | |
| ssize_t | len | |||
| ) | [static] |
Definition at line 5857 of file chan_iax2.c.
References ast_random().
Referenced by build_ecx_key(), and update_packet().
05858 { 05859 long tmp; 05860 for (tmp = ast_random(); len > 0; tmp = ast_random()) { 05861 memcpy(buf, (unsigned char *) &tmp, (len > sizeof(tmp)) ? sizeof(tmp) : len); 05862 buf += sizeof(tmp); 05863 len -= sizeof(tmp); 05864 } 05865 }
| 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 12156 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_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_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, 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().
12157 { 12158 struct iax2_user *user = NULL; 12159 struct iax2_context *con, *conl = NULL; 12160 struct ast_ha *oldha = NULL; 12161 struct iax2_context *oldcon = NULL; 12162 int format; 12163 int firstpass=1; 12164 int oldcurauthreq = 0; 12165 char *varname = NULL, *varval = NULL; 12166 struct ast_variable *tmpvar = NULL; 12167 struct iax2_user tmp_user = { 12168 .name = name, 12169 }; 12170 12171 if (!temponly) { 12172 user = ao2_find(users, &tmp_user, OBJ_POINTER); 12173 if (user && !ast_test_flag(user, IAX_DELME)) 12174 firstpass = 0; 12175 } 12176 12177 if (user) { 12178 if (firstpass) { 12179 oldcurauthreq = user->curauthreq; 12180 oldha = user->ha; 12181 oldcon = user->contexts; 12182 user->ha = NULL; 12183 user->contexts = NULL; 12184 } 12185 /* Already in the list, remove it and it will be added back (or FREE'd) */ 12186 ao2_unlink(users, user); 12187 } else { 12188 user = ao2_alloc(sizeof(*user), user_destructor); 12189 } 12190 12191 if (user) { 12192 if (firstpass) { 12193 ast_string_field_free_memory(user); 12194 memset(user, 0, sizeof(struct iax2_user)); 12195 if (ast_string_field_init(user, 32)) { 12196 user = user_unref(user); 12197 goto cleanup; 12198 } 12199 user->maxauthreq = maxauthreq; 12200 user->curauthreq = oldcurauthreq; 12201 user->prefs = prefs; 12202 user->capability = iax2_capability; 12203 user->encmethods = iax2_encryption; 12204 user->adsi = adsi; 12205 user->calltoken_required = CALLTOKEN_DEFAULT; 12206 ast_string_field_set(user, name, name); 12207 ast_string_field_set(user, language, language); 12208 ast_copy_flags(user, &globalflags, IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_CODEC_USER_FIRST | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 12209 ast_clear_flag(user, IAX_HASCALLERID); 12210 ast_string_field_set(user, cid_name, ""); 12211 ast_string_field_set(user, cid_num, ""); 12212 ast_string_field_set(user, accountcode, accountcode); 12213 ast_string_field_set(user, mohinterpret, mohinterpret); 12214 ast_string_field_set(user, mohsuggest, mohsuggest); 12215 } 12216 if (!v) { 12217 v = alt; 12218 alt = NULL; 12219 } 12220 while(v) { 12221 if (!strcasecmp(v->name, "context")) { 12222 con = build_context(v->value); 12223 if (con) { 12224 if (conl) 12225 conl->next = con; 12226 else 12227 user->contexts = con; 12228 conl = con; 12229 } 12230 } else if (!strcasecmp(v->name, "permit") || 12231 !strcasecmp(v->name, "deny")) { 12232 user->ha = ast_append_ha(v->name, v->value, user->ha, NULL); 12233 } else if (!strcasecmp(v->name, "setvar")) { 12234 varname = ast_strdupa(v->value); 12235 if (varname && (varval = strchr(varname,'='))) { 12236 *varval = '\0'; 12237 varval++; 12238 if((tmpvar = ast_variable_new(varname, varval, ""))) { 12239 tmpvar->next = user->vars; 12240 user->vars = tmpvar; 12241 } 12242 } 12243 } else if (!strcasecmp(v->name, "allow")) { 12244 ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1); 12245 } else if (!strcasecmp(v->name, "disallow")) { 12246 ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0); 12247 } else if (!strcasecmp(v->name, "trunk")) { 12248 ast_set2_flag(user, ast_true(v->value), IAX_TRUNK); 12249 if (ast_test_flag(user, IAX_TRUNK) && !timer) { 12250 ast_log(LOG_WARNING, "Unable to support trunking on user '%s' without a timing interface\n", user->name); 12251 ast_clear_flag(user, IAX_TRUNK); 12252 } 12253 } else if (!strcasecmp(v->name, "auth")) { 12254 user->authmethods = get_auth_methods(v->value); 12255 } else if (!strcasecmp(v->name, "encryption")) { 12256 user->encmethods |= get_encrypt_methods(v->value); 12257 if (!user->encmethods) { 12258 ast_clear_flag(user, IAX_FORCE_ENCRYPT); 12259 } 12260 } else if (!strcasecmp(v->name, "forceencryption")) { 12261 if (ast_false(v->value)) { 12262 ast_clear_flag(user, IAX_FORCE_ENCRYPT); 12263 } else { 12264 user->encmethods |= get_encrypt_methods(v->value); 12265 if (user->encmethods) { 12266 ast_set_flag(user, IAX_FORCE_ENCRYPT); 12267 } 12268 } 12269 } else if (!strcasecmp(v->name, "transfer")) { 12270 if (!strcasecmp(v->value, "mediaonly")) { 12271 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12272 } else if (ast_true(v->value)) { 12273 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12274 } else 12275 ast_set_flags_to(user, IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12276 } else if (!strcasecmp(v->name, "codecpriority")) { 12277 if(!strcasecmp(v->value, "caller")) 12278 ast_set_flag(user, IAX_CODEC_USER_FIRST); 12279 else if(!strcasecmp(v->value, "disabled")) 12280 ast_set_flag(user, IAX_CODEC_NOPREFS); 12281 else if(!strcasecmp(v->value, "reqonly")) { 12282 ast_set_flag(user, IAX_CODEC_NOCAP); 12283 ast_set_flag(user, IAX_CODEC_NOPREFS); 12284 } 12285 } else if (!strcasecmp(v->name, "immediate")) { 12286 ast_set2_flag(user, ast_true(v->value), IAX_IMMEDIATE); 12287 } else if (!strcasecmp(v->name, "jitterbuffer")) { 12288 ast_set2_flag(user, ast_true(v->value), IAX_USEJITTERBUF); 12289 } else if (!strcasecmp(v->name, "forcejitterbuffer")) { 12290 ast_set2_flag(user, ast_true(v->value), IAX_FORCEJITTERBUF); 12291 } else if (!strcasecmp(v->name, "dbsecret")) { 12292 ast_string_field_set(user, dbsecret, v->value); 12293 } else if (!strcasecmp(v->name, "secret")) { 12294 if (!ast_strlen_zero(user->secret)) { 12295 char *old = ast_strdupa(user->secret); 12296 12297 ast_string_field_build(user, secret, "%s;%s", old, v->value); 12298 } else 12299 ast_string_field_set(user, secret, v->value); 12300 } else if (!strcasecmp(v->name, "callerid")) { 12301 if (!ast_strlen_zero(v->value) && strcasecmp(v->value, "asreceived")) { 12302 char name2[80]; 12303 char num2[80]; 12304 ast_callerid_split(v->value, name2, sizeof(name2), num2, sizeof(num2)); 12305 ast_string_field_set(user, cid_name, name2); 12306 ast_string_field_set(user, cid_num, num2); 12307 ast_set_flag(user, IAX_HASCALLERID); 12308 } else { 12309 ast_clear_flag(user, IAX_HASCALLERID); 12310 ast_string_field_set(user, cid_name, ""); 12311 ast_string_field_set(user, cid_num, ""); 12312 } 12313 } else if (!strcasecmp(v->name, "fullname")) { 12314 if (!ast_strlen_zero(v->value)) { 12315 ast_string_field_set(user, cid_name, v->value); 12316 ast_set_flag(user, IAX_HASCALLERID); 12317 } else { 12318 ast_string_field_set(user, cid_name, ""); 12319 if (ast_strlen_zero(user->cid_num)) 12320 ast_clear_flag(user, IAX_HASCALLERID); 12321 } 12322 } else if (!strcasecmp(v->name, "cid_number")) { 12323 if (!ast_strlen_zero(v->value)) { 12324 ast_string_field_set(user, cid_num, v->value); 12325 ast_set_flag(user, IAX_HASCALLERID); 12326 } else { 12327 ast_string_field_set(user, cid_num, ""); 12328 if (ast_strlen_zero(user->cid_name)) 12329 ast_clear_flag(user, IAX_HASCALLERID); 12330 } 12331 } else if (!strcasecmp(v->name, "accountcode")) { 12332 ast_string_field_set(user, accountcode, v->value); 12333 } else if (!strcasecmp(v->name, "mohinterpret")) { 12334 ast_string_field_set(user, mohinterpret, v->value); 12335 } else if (!strcasecmp(v->name, "mohsuggest")) { 12336 ast_string_field_set(user, mohsuggest, v->value); 12337 } else if (!strcasecmp(v->name, "parkinglot")) { 12338 ast_string_field_set(user, parkinglot, v->value); 12339 } else if (!strcasecmp(v->name, "language")) { 12340 ast_string_field_set(user, language, v->value); 12341 } else if (!strcasecmp(v->name, "amaflags")) { 12342 format = ast_cdr_amaflags2int(v->value); 12343 if (format < 0) { 12344 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12345 } else { 12346 user->amaflags = format; 12347 } 12348 } else if (!strcasecmp(v->name, "inkeys")) { 12349 ast_string_field_set(user, inkeys, v->value); 12350 } else if (!strcasecmp(v->name, "maxauthreq")) { 12351 user->maxauthreq = atoi(v->value); 12352 if (user->maxauthreq < 0) 12353 user->maxauthreq = 0; 12354 } else if (!strcasecmp(v->name, "adsi")) { 12355 user->adsi = ast_true(v->value); 12356 } else if (!strcasecmp(v->name, "requirecalltoken")) { 12357 /* default is required unless in optional ip list */ 12358 if (ast_false(v->value)) { 12359 user->calltoken_required = CALLTOKEN_NO; 12360 } else if (!strcasecmp(v->value, "auto")) { 12361 user->calltoken_required = CALLTOKEN_AUTO; 12362 } else if (ast_true(v->value)) { 12363 user->calltoken_required = CALLTOKEN_YES; 12364 } else { 12365 ast_log(LOG_WARNING, "requirecalltoken must be set to a valid value. at line %d\n", v->lineno); 12366 } 12367 } /* else if (strcasecmp(v->name,"type")) */ 12368 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12369 v = v->next; 12370 if (!v) { 12371 v = alt; 12372 alt = NULL; 12373 } 12374 } 12375 if (!user->authmethods) { 12376 if (!ast_strlen_zero(user->secret)) { 12377 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12378 if (!ast_strlen_zero(user->inkeys)) 12379 user->authmethods |= IAX_AUTH_RSA; 12380 } else if (!ast_strlen_zero(user->inkeys)) { 12381 user->authmethods = IAX_AUTH_RSA; 12382 } else { 12383 user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; 12384 } 12385 } 12386 ast_clear_flag(user, IAX_DELME); 12387 } 12388 cleanup: 12389 if (oldha) 12390 ast_free_ha(oldha); 12391 if (oldcon) 12392 free_context(oldcon); 12393 return user; 12394 }
| static int cache_get_callno_locked | ( | const char * | data | ) | [static] |
Definition at line 13001 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_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().
13002 { 13003 struct sockaddr_in sin; 13004 int x; 13005 int callno; 13006 struct iax_ie_data ied; 13007 struct create_addr_info cai; 13008 struct parsed_dial_string pds; 13009 char *tmpstr; 13010 13011 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 13012 /* Look for an *exact match* call. Once a call is negotiated, it can only 13013 look up entries for a single context */ 13014 if (!ast_mutex_trylock(&iaxsl[x])) { 13015 if (iaxs[x] && !strcasecmp(data, iaxs[x]->dproot)) 13016 return x; 13017 ast_mutex_unlock(&iaxsl[x]); 13018 } 13019 } 13020 13021 /* No match found, we need to create a new one */ 13022 13023 memset(&cai, 0, sizeof(cai)); 13024 memset(&ied, 0, sizeof(ied)); 13025 memset(&pds, 0, sizeof(pds)); 13026 13027 tmpstr = ast_strdupa(data); 13028 parse_dial_string(tmpstr, &pds); 13029 13030 if (ast_strlen_zero(pds.peer)) { 13031 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", data); 13032 return -1; 13033 } 13034 13035 /* Populate our address from the given */ 13036 if (create_addr(pds.peer, NULL, &sin, &cai)) 13037 return -1; 13038 13039 ast_debug(1, "peer: %s, username: %s, password: %s, context: %s\n", 13040 pds.peer, pds.username, pds.password, pds.context); 13041 13042 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 13043 if (callno < 1) { 13044 ast_log(LOG_WARNING, "Unable to create call\n"); 13045 return -1; 13046 } 13047 13048 ast_string_field_set(iaxs[callno], dproot, data); 13049 iaxs[callno]->capability = IAX_CAPABILITY_FULLBANDWIDTH; 13050 13051 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 13052 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, "TBD"); 13053 /* the string format is slightly different from a standard dial string, 13054 because the context appears in the 'exten' position 13055 */ 13056 if (pds.exten) 13057 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.exten); 13058 if (pds.username) 13059 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 13060 iax_ie_append_int(&ied, IAX_IE_FORMAT, IAX_CAPABILITY_FULLBANDWIDTH); 13061 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, IAX_CAPABILITY_FULLBANDWIDTH); 13062 /* Keep password handy */ 13063 if (pds.password) 13064 ast_string_field_set(iaxs[callno], secret, pds.password); 13065 if (pds.key) 13066 ast_string_field_set(iaxs[callno], outkey, pds.key); 13067 /* Start the call going */ 13068 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 13069 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 13070 13071 return callno; 13072 }
| static unsigned int calc_rxstamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | offset | |||
| ) | [static] |
Definition at line 5709 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().
05710 { 05711 /* Returns where in "receive time" we are. That is, how many ms 05712 since we received (or would have received) the frame with timestamp 0 */ 05713 int ms; 05714 #ifdef IAXTESTS 05715 int jit; 05716 #endif /* IAXTESTS */ 05717 /* Setup rxcore if necessary */ 05718 if (ast_tvzero(p->rxcore)) { 05719 p->rxcore = ast_tvnow(); 05720 if (iaxdebug) 05721 ast_debug(1, "calc_rxstamp: call=%d: rxcore set to %d.%6.6d - %dms\n", 05722 p->callno, (int)(p->rxcore.tv_sec), (int)(p->rxcore.tv_usec), offset); 05723 p->rxcore = ast_tvsub(p->rxcore, ast_samp2tv(offset, 1000)); 05724 #if 1 05725 if (iaxdebug) 05726 ast_debug(1, "calc_rxstamp: call=%d: works out as %d.%6.6d\n", 05727 p->callno, (int)(p->rxcore.tv_sec),(int)( p->rxcore.tv_usec)); 05728 #endif 05729 } 05730 05731 ms = ast_tvdiff_ms(ast_tvnow(), p->rxcore); 05732 #ifdef IAXTESTS 05733 if (test_jit) { 05734 if (!test_jitpct || ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_jitpct)) { 05735 jit = (int)((float)test_jit * ast_random() / (RAND_MAX + 1.0)); 05736 if ((int)(2.0 * ast_random() / (RAND_MAX + 1.0))) 05737 jit = -jit; 05738 ms += jit; 05739 } 05740 } 05741 if (test_late) { 05742 ms += test_late; 05743 test_late = 0; 05744 } 05745 #endif /* IAXTESTS */ 05746 return ms; 05747 }
| static unsigned int calc_timestamp | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | ts, | |||
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 5576 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().
05577 { 05578 int ms; 05579 int voice = 0; 05580 int genuine = 0; 05581 int adjust; 05582 int rate = ast_format_rate(f->subclass) / 1000; 05583 struct timeval *delivery = NULL; 05584 05585 05586 /* What sort of frame do we have?: voice is self-explanatory 05587 "genuine" means an IAX frame - things like LAGRQ/RP, PING/PONG, ACK 05588 non-genuine frames are CONTROL frames [ringing etc], DTMF 05589 The "genuine" distinction is needed because genuine frames must get a clock-based timestamp, 05590 the others need a timestamp slaved to the voice frames so that they go in sequence 05591 */ 05592 if (f) { 05593 if (f->frametype == AST_FRAME_VOICE) { 05594 voice = 1; 05595 delivery = &f->delivery; 05596 } else if (f->frametype == AST_FRAME_IAX) { 05597 genuine = 1; 05598 } else if (f->frametype == AST_FRAME_CNG) { 05599 p->notsilenttx = 0; 05600 } 05601 } 05602 if (ast_tvzero(p->offset)) { 05603 p->offset = ast_tvnow(); 05604 /* Round to nearest 20ms for nice looking traces */ 05605 p->offset.tv_usec -= p->offset.tv_usec % 20000; 05606 } 05607 /* If the timestamp is specified, just send it as is */ 05608 if (ts) 05609 return ts; 05610 /* If we have a time that the frame arrived, always use it to make our timestamp */ 05611 if (delivery && !ast_tvzero(*delivery)) { 05612 ms = ast_tvdiff_ms(*delivery, p->offset); 05613 if (ms < 0) { 05614 ms = 0; 05615 } 05616 if (iaxdebug) 05617 ast_debug(3, "calc_timestamp: call %d/%d: Timestamp slaved to delivery time\n", p->callno, iaxs[p->callno]->peercallno); 05618 } else { 05619 ms = ast_tvdiff_ms(ast_tvnow(), p->offset); 05620 if (ms < 0) 05621 ms = 0; 05622 if (voice) { 05623 /* On a voice frame, use predicted values if appropriate */ 05624 if (p->notsilenttx && abs(ms - p->nextpred) <= MAX_TIMESTAMP_SKEW) { 05625 /* Adjust our txcore, keeping voice and non-voice synchronized */ 05626 /* AN EXPLANATION: 05627 When we send voice, we usually send "calculated" timestamps worked out 05628 on the basis of the number of samples sent. When we send other frames, 05629 we usually send timestamps worked out from the real clock. 05630 The problem is that they can tend to drift out of step because the 05631 source channel's clock and our clock may not be exactly at the same rate. 05632 We fix this by continuously "tweaking" p->offset. p->offset is "time zero" 05633 for this call. Moving it adjusts timestamps for non-voice frames. 05634 We make the adjustment in the style of a moving average. Each time we 05635 adjust p->offset by 10% of the difference between our clock-derived 05636 timestamp and the predicted timestamp. That's why you see "10000" 05637 below even though IAX2 timestamps are in milliseconds. 05638 The use of a moving average avoids offset moving too radically. 05639 Generally, "adjust" roams back and forth around 0, with offset hardly 05640 changing at all. But if a consistent different starts to develop it 05641 will be eliminated over the course of 10 frames (200-300msecs) 05642 */ 05643 adjust = (ms - p->nextpred); 05644 if (adjust < 0) 05645 p->offset = ast_tvsub(p->offset, ast_samp2tv(abs(adjust), 10000)); 05646 else if (adjust > 0) 05647 p->offset = ast_tvadd(p->offset, ast_samp2tv(adjust, 10000)); 05648 05649 if (!p->nextpred) { 05650 p->nextpred = ms; /*f->samples / rate;*/ 05651 if (p->nextpred <= p->lastsent) 05652 p->nextpred = p->lastsent + 3; 05653 } 05654 ms = p->nextpred; 05655 } else { 05656 /* in this case, just use the actual 05657 * time, since we're either way off 05658 * (shouldn't happen), or we're ending a 05659 * silent period -- and seed the next 05660 * predicted time. Also, round ms to the 05661 * next multiple of frame size (so our 05662 * silent periods are multiples of 05663 * frame size too) */ 05664 05665 if (iaxdebug && abs(ms - p->nextpred) > MAX_TIMESTAMP_SKEW ) 05666 ast_debug(1, "predicted timestamp skew (%u) > max (%u), using real ts instead.\n", 05667 abs(ms - p->nextpred), MAX_TIMESTAMP_SKEW); 05668 05669 if (f->samples >= rate) /* check to make sure we dont core dump */ 05670 { 05671 int diff = ms % (f->samples / rate); 05672 if (diff) 05673 ms += f->samples/rate - diff; 05674 } 05675 05676 p->nextpred = ms; 05677 p->notsilenttx = 1; 05678 } 05679 } else if ( f->frametype == AST_FRAME_VIDEO ) { 05680 /* 05681 * IAX2 draft 03 says that timestamps MUST be in order. 05682 * It does not say anything about several frames having the same timestamp 05683 * When transporting video, we can have a frame that spans multiple iax packets 05684 * (so called slices), so it would make sense to use the same timestamp for all of 05685 * them 05686 * We do want to make sure that frames don't go backwards though 05687 */ 05688 if ( (unsigned int)ms < p->lastsent ) 05689 ms = p->lastsent; 05690 } else { 05691 /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) if appropriate unless 05692 it's a genuine frame */ 05693 if (genuine) { 05694 /* genuine (IAX LAGRQ etc) must keep their clock-based stamps */ 05695 if (ms <= p->lastsent) 05696 ms = p->lastsent + 3; 05697 } else if (abs(ms - p->lastsent) <= MAX_TIMESTAMP_SKEW) { 05698 /* non-genuine frames (!?) (DTMF, CONTROL) should be pulled into the predicted stream stamps */ 05699 ms = p->lastsent + 3; 05700 } 05701 } 05702 } 05703 p->lastsent = ms; 05704 if (voice) 05705 p->nextpred = p->nextpred + f->samples / rate; 05706 return ms; 05707 }
| static unsigned int calc_txpeerstamp | ( | struct iax2_trunk_peer * | tpeer, | |
| int | sampms, | |||
| struct timeval * | now | |||
| ) | [static] |
Definition at line 5532 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().
05533 { 05534 unsigned long int mssincetx; /* unsigned to handle overflows */ 05535 long int ms, pred; 05536 05537 tpeer->trunkact = *now; 05538 mssincetx = ast_tvdiff_ms(*now, tpeer->lasttxtime); 05539 if (mssincetx > 5000 || ast_tvzero(tpeer->txtrunktime)) { 05540 /* If it's been at least 5 seconds since the last time we transmitted on this trunk, reset our timers */ 05541 tpeer->txtrunktime = *now; 05542 tpeer->lastsent = 999999; 05543 } 05544 /* Update last transmit time now */ 05545 tpeer->lasttxtime = *now; 05546 05547 /* Calculate ms offset */ 05548 ms = ast_tvdiff_ms(*now, tpeer->txtrunktime); 05549 /* Predict from last value */ 05550 pred = tpeer->lastsent + sampms; 05551 if (abs(ms - pred) < MAX_TIMESTAMP_SKEW) 05552 ms = pred; 05553 05554 /* We never send the same timestamp twice, so fudge a little if we must */ 05555 if (ms == tpeer->lastsent) 05556 ms = tpeer->lastsent + 1; 05557 tpeer->lastsent = ms; 05558 return ms; 05559 }
| static int callno_hash | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 2483 of file chan_iax2.c.
References ast_random().
Referenced by create_callno_pools().
02484 { 02485 return abs(ast_random()); 02486 }
| static int calltoken_required | ( | struct sockaddr_in * | sin, | |
| const char * | name, | |||
| int | subclass | |||
| ) | [static] |
Definition at line 2031 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().
02032 { 02033 struct addr_range *addr_range; 02034 struct iax2_peer *peer = NULL; 02035 struct iax2_user *user = NULL; 02036 /* if no username is given, check for guest accounts */ 02037 const char *find = S_OR(name, "guest"); 02038 int res = 1; /* required by default */ 02039 int optional = 0; 02040 enum calltoken_peer_enum calltoken_required = CALLTOKEN_DEFAULT; 02041 /* There are only two cases in which calltoken validation is not required. 02042 * Case 1. sin falls within the list of address ranges specified in the calltoken optional table and 02043 * the peer definition has not set the requirecalltoken option. 02044 * Case 2. Username is a valid peer/user, and that peer has requirecalltoken set either auto or no. 02045 */ 02046 02047 /* ----- Case 1 ----- */ 02048 if ((addr_range = ao2_callback(calltoken_ignores, 0, addr_range_match_address_cb, sin))) { 02049 ao2_ref(addr_range, -1); 02050 optional = 1; 02051 } 02052 02053 /* ----- Case 2 ----- */ 02054 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(find))) { 02055 calltoken_required = user->calltoken_required; 02056 } else if ((subclass == IAX_COMMAND_NEW) && (user = realtime_user(find, sin))) { 02057 calltoken_required = user->calltoken_required; 02058 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(find, 0))) { 02059 calltoken_required = peer->calltoken_required; 02060 } else if ((subclass != IAX_COMMAND_NEW) && (peer = realtime_peer(find, sin))) { 02061 calltoken_required = peer->calltoken_required; 02062 } 02063 02064 if (peer) { 02065 peer_unref(peer); 02066 } 02067 if (user) { 02068 user_unref(user); 02069 } 02070 02071 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); 02072 if (((calltoken_required == CALLTOKEN_NO) || (calltoken_required == CALLTOKEN_AUTO)) || 02073 (optional && (calltoken_required == CALLTOKEN_DEFAULT))) { 02074 res = 0; 02075 } 02076 02077 return res; 02078 }
| static int check_access | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7197 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_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_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_HASCALLERID, IAX_IMMEDIATE, 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().
07198 { 07199 /* Start pessimistic */ 07200 int res = -1; 07201 int version = 2; 07202 struct iax2_user *user = NULL, *best = NULL; 07203 int bestscore = 0; 07204 int gotcapability = 0; 07205 struct ast_variable *v = NULL, *tmpvar = NULL; 07206 struct ao2_iterator i; 07207 07208 if (!iaxs[callno]) 07209 return res; 07210 if (ies->called_number) 07211 ast_string_field_set(iaxs[callno], exten, ies->called_number); 07212 if (ies->calling_number) { 07213 if (ast_test_flag(&globalflags, IAX_SHRINKCALLERID)) { 07214 ast_shrink_phone_number(ies->calling_number); 07215 } 07216 ast_string_field_set(iaxs[callno], cid_num, ies->calling_number); 07217 } 07218 if (ies->calling_name) 07219 ast_string_field_set(iaxs[callno], cid_name, ies->calling_name); 07220 if (ies->calling_ani) 07221 ast_string_field_set(iaxs[callno], ani, ies->calling_ani); 07222 if (ies->dnid) 07223 ast_string_field_set(iaxs[callno], dnid, ies->dnid); 07224 if (ies->rdnis) 07225 ast_string_field_set(iaxs[callno], rdnis, ies->rdnis); 07226 if (ies->called_context) 07227 ast_string_field_set(iaxs[callno], context, ies->called_context); 07228 if (ies->language) 07229 ast_string_field_set(iaxs[callno], language, ies->language); 07230 if (ies->username) 07231 ast_string_field_set(iaxs[callno], username, ies->username); 07232 if (ies->calling_ton > -1) 07233 iaxs[callno]->calling_ton = ies->calling_ton; 07234 if (ies->calling_tns > -1) 07235 iaxs[callno]->calling_tns = ies->calling_tns; 07236 if (ies->calling_pres > -1) 07237 iaxs[callno]->calling_pres = ies->calling_pres; 07238 if (ies->format) 07239 iaxs[callno]->peerformat = ies->format; 07240 if (ies->adsicpe) 07241 iaxs[callno]->peeradsicpe = ies->adsicpe; 07242 if (ies->capability) { 07243 gotcapability = 1; 07244 iaxs[callno]->peercapability = ies->capability; 07245 } 07246 if (ies->version) 07247 version = ies->version; 07248 07249 /* Use provided preferences until told otherwise for actual preferences */ 07250 if(ies->codec_prefs) { 07251 ast_codec_pref_convert(&iaxs[callno]->rprefs, ies->codec_prefs, 32, 0); 07252 ast_codec_pref_convert(&iaxs[callno]->prefs, ies->codec_prefs, 32, 0); 07253 } 07254 07255 if (!gotcapability) 07256 iaxs[callno]->peercapability = iaxs[callno]->peerformat; 07257 if (version > IAX_PROTO_VERSION) { 07258 ast_log(LOG_WARNING, "Peer '%s' has too new a protocol version (%d) for me\n", 07259 ast_inet_ntoa(sin->sin_addr), version); 07260 return res; 07261 } 07262 /* Search the userlist for a compatible entry, and fill in the rest */ 07263 i = ao2_iterator_init(users, 0); 07264 while ((user = ao2_iterator_next(&i))) { 07265 if ((ast_strlen_zero(iaxs[callno]->username) || /* No username specified */ 07266 !strcmp(iaxs[callno]->username, user->name)) /* Or this username specified */ 07267 && ast_apply_ha(user->ha, sin) /* Access is permitted from this IP */ 07268 && (ast_strlen_zero(iaxs[callno]->context) || /* No context specified */ 07269 apply_context(user->contexts, iaxs[callno]->context))) { /* Context is permitted */ 07270 if (!ast_strlen_zero(iaxs[callno]->username)) { 07271 /* Exact match, stop right now. */ 07272 if (best) 07273 user_unref(best); 07274 best = user; 07275 break; 07276 } else if (ast_strlen_zero(user->secret) && ast_strlen_zero(user->dbsecret) && ast_strlen_zero(user->inkeys)) { 07277 /* No required authentication */ 07278 if (user->ha) { 07279 /* There was host authentication and we passed, bonus! */ 07280 if (bestscore < 4) { 07281 bestscore = 4; 07282 if (best) 07283 user_unref(best); 07284 best = user; 07285 continue; 07286 } 07287 } else { 07288 /* No host access, but no secret, either, not bad */ 07289 if (bestscore < 3) { 07290 bestscore = 3; 07291 if (best) 07292 user_unref(best); 07293 best = user; 07294 continue; 07295 } 07296 } 07297 } else { 07298 if (user->ha) { 07299 /* Authentication, but host access too, eh, it's something.. */ 07300 if (bestscore < 2) { 07301 bestscore = 2; 07302 if (best) 07303 user_unref(best); 07304 best = user; 07305 continue; 07306 } 07307 } else { 07308 /* Authentication and no host access... This is our baseline */ 07309 if (bestscore < 1) { 07310 bestscore = 1; 07311 if (best) 07312 user_unref(best); 07313 best = user; 07314 continue; 07315 } 07316 } 07317 } 07318 } 07319 user_unref(user); 07320 } 07321 ao2_iterator_destroy(&i); 07322 user = best; 07323 if (!user && !ast_strlen_zero(iaxs[callno]->username)) { 07324 user = realtime_user(iaxs[callno]->username, sin); 07325 if (user && !ast_strlen_zero(iaxs[callno]->context) && /* No context specified */ 07326 !apply_context(user->contexts, iaxs[callno]->context)) { /* Context is permitted */ 07327 user = user_unref(user); 07328 } 07329 } 07330 if (user) { 07331 /* We found our match (use the first) */ 07332 /* copy vars */ 07333 for (v = user->vars ; v ; v = v->next) { 07334 if((tmpvar = ast_variable_new(v->name, v->value, v->file))) { 07335 tmpvar->next = iaxs[callno]->vars; 07336 iaxs[callno]->vars = tmpvar; 07337 } 07338 } 07339 /* If a max AUTHREQ restriction is in place, activate it */ 07340 if (user->maxauthreq > 0) 07341 ast_set_flag(iaxs[callno], IAX_MAXAUTHREQ); 07342 iaxs[callno]->prefs = user->prefs; 07343 ast_copy_flags(iaxs[callno], user, IAX_CODEC_USER_FIRST | IAX_IMMEDIATE | IAX_CODEC_NOPREFS | IAX_CODEC_NOCAP | IAX_FORCE_ENCRYPT); 07344 iaxs[callno]->encmethods = user->encmethods; 07345 /* Store the requested username if not specified */ 07346 if (ast_strlen_zero(iaxs[callno]->username)) 07347 ast_string_field_set(iaxs[callno], username, user->name); 07348 /* Store whether this is a trunked call, too, of course, and move if appropriate */ 07349 ast_copy_flags(iaxs[callno], user, IAX_TRUNK); 07350 iaxs[callno]->capability = user->capability; 07351 /* And use the default context */ 07352 if (ast_strlen_zero(iaxs[callno]->context)) { 07353 if (user->contexts) 07354 ast_string_field_set(iaxs[callno], context, user->contexts->context); 07355 else 07356 ast_string_field_set(iaxs[callno], context, DEFAULT_CONTEXT); 07357 } 07358 /* And any input keys */ 07359 ast_string_field_set(iaxs[callno], inkeys, user->inkeys); 07360 /* And the permitted authentication methods */ 07361 iaxs[callno]->authmethods = user->authmethods; 07362 iaxs[callno]->adsi = user->adsi; 07363 /* If the user has callerid, override the remote caller id. */ 07364 if (ast_test_flag(user, IAX_HASCALLERID)) { 07365 iaxs[callno]->calling_tns = 0; 07366 iaxs[callno]->calling_ton = 0; 07367 ast_string_field_set(iaxs[callno], cid_num, user->cid_num); 07368 ast_string_field_set(iaxs[callno], cid_name, user->cid_name); 07369 ast_string_field_set(iaxs[callno], ani, user->cid_num); 07370 iaxs[callno]->calling_pres = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; 07371 } else if (ast_strlen_zero(iaxs[callno]->cid_num) && ast_strlen_zero(iaxs[callno]->cid_name)) { 07372 iaxs[callno]->calling_pres = AST_PRES_NUMBER_NOT_AVAILABLE; 07373 } /* else user is allowed to set their own CID settings */ 07374 if (!ast_strlen_zero(user->accountcode)) 07375 ast_string_field_set(iaxs[callno], accountcode, user->accountcode); 07376 if (!ast_strlen_zero(user->mohinterpret)) 07377 ast_string_field_set(iaxs[callno], mohinterpret, user->mohinterpret); 07378 if (!ast_strlen_zero(user->mohsuggest)) 07379 ast_string_field_set(iaxs[callno], mohsuggest, user->mohsuggest); 07380 if (!ast_strlen_zero(user->parkinglot)) 07381 ast_string_field_set(iaxs[callno], parkinglot, user->parkinglot); 07382 if (user->amaflags) 07383 iaxs[callno]->amaflags = user->amaflags; 07384 if (!ast_strlen_zero(user->language)) 07385 ast_string_field_set(iaxs[callno], language, user->language); 07386 ast_copy_flags(iaxs[callno], user, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 07387 /* Keep this check last */ 07388 if (!ast_strlen_zero(user->dbsecret)) { 07389 char *family, *key=NULL; 07390 char buf[80]; 07391 family = ast_strdupa(user->dbsecret); 07392 key = strchr(family, '/'); 07393 if (key) { 07394 *key = '\0'; 07395 key++; 07396 } 07397 if (!key || ast_db_get(family, key, buf, sizeof(buf))) 07398 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", user->dbsecret); 07399 else 07400 ast_string_field_set(iaxs[callno], secret, buf); 07401 } else 07402 ast_string_field_set(iaxs[callno], secret, user->secret); 07403 res = 0; 07404 user = user_unref(user); 07405 } else { 07406 /* user was not found, but we should still fake an AUTHREQ. 07407 * Set authmethods to the last known authmethod used by the system 07408 * Set a fake secret, it's not looked at, just required to attempt authentication. 07409 * Set authrej so the AUTHREP is rejected without even looking at its contents */ 07410 iaxs[callno]->authmethods = last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 07411 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07412 iaxs[callno]->authrej = 1; 07413 if (!ast_strlen_zero(iaxs[callno]->username)) { 07414 /* only send the AUTHREQ if a username was specified. */ 07415 res = 0; 07416 } 07417 } 07418 ast_set2_flag(iaxs[callno], iax2_getpeertrunk(*sin), IAX_TRUNK); 07419 return res; 07420 }
| static int check_provisioning | ( | struct sockaddr_in * | sin, | |
| int | sockfd, | |||
| char * | si, | |||
| unsigned int | ver | |||
| ) | [static] |
Definition at line 8994 of file chan_iax2.c.
References ast_debug, iax2_provision(), and iax_provision_version().
Referenced by socket_process().
08995 { 08996 unsigned int ourver; 08997 char rsi[80]; 08998 snprintf(rsi, sizeof(rsi), "si-%s", si); 08999 if (iax_provision_version(&ourver, rsi, 1)) 09000 return 0; 09001 ast_debug(1, "Service identifier '%s', we think '%08x', they think '%08x'\n", si, ourver, ver); 09002 if (ourver != ver) 09003 iax2_provision(sin, sockfd, NULL, rsi, 1); 09004 return 0; 09005 }
| static int check_srcaddr | ( | struct sockaddr * | sa, | |
| socklen_t | salen | |||
| ) | [static] |
Check if address can be used as packet source.
Definition at line 11758 of file chan_iax2.c.
References ast_debug, ast_log(), errno, and LOG_ERROR.
Referenced by peer_set_srcaddr().
11759 { 11760 int sd; 11761 int res; 11762 11763 sd = socket(AF_INET, SOCK_DGRAM, 0); 11764 if (sd < 0) { 11765 ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); 11766 return -1; 11767 } 11768 11769 res = bind(sd, sa, salen); 11770 if (res < 0) { 11771 ast_debug(1, "Can't bind: %s\n", strerror(errno)); 11772 close(sd); 11773 return 1; 11774 } 11775 11776 close(sd); 11777 return 0; 11778 }
| static int complete_dpreply | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7979 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().
07980 { 07981 char exten[256] = ""; 07982 int status = CACHE_FLAG_UNKNOWN, expiry = iaxdefaultdpcache, x, matchmore = 0; 07983 struct iax2_dpcache *dp = NULL; 07984 07985 if (ies->called_number) 07986 ast_copy_string(exten, ies->called_number, sizeof(exten)); 07987 07988 if (ies->dpstatus & IAX_DPSTATUS_EXISTS) 07989 status = CACHE_FLAG_EXISTS; 07990 else if (ies->dpstatus & IAX_DPSTATUS_CANEXIST) 07991 status = CACHE_FLAG_CANEXIST; 07992 else if (ies->dpstatus & IAX_DPSTATUS_NONEXISTENT) 07993 status = CACHE_FLAG_NONEXISTENT; 07994 07995 if (ies->refresh) 07996 expiry = ies->refresh; 07997 if (ies->dpstatus & IAX_DPSTATUS_MATCHMORE) 07998 matchmore = CACHE_FLAG_MATCHMORE; 07999 08000 AST_LIST_LOCK(&dpcache); 08001 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, peer_list) { 08002 if (strcmp(dp->exten, exten)) 08003 continue; 08004 AST_LIST_REMOVE_CURRENT(peer_list); 08005 dp->callno = 0; 08006 dp->expiry.tv_sec = dp->orig.tv_sec + expiry; 08007 if (dp->flags & CACHE_FLAG_PENDING) { 08008 dp->flags &= ~CACHE_FLAG_PENDING; 08009 dp->flags |= status; 08010 dp->flags |= matchmore; 08011 } 08012 /* Wake up waiters */ 08013 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 08014 if (dp->waiters[x] > -1) { 08015 if (write(dp->waiters[x], "asdf", 4) < 0) { 08016 } 08017 } 08018 } 08019 } 08020 AST_LIST_TRAVERSE_SAFE_END; 08021 AST_LIST_UNLOCK(&dpcache); 08022 08023 return 0; 08024 }
| static char * complete_iax2_peers | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state, | |||
| int | flags | |||
| ) | [static] |
Definition at line 3647 of file chan_iax2.c.
References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ast_strdup, ast_test_flag, iax2_peer::name, and peer_unref().
Referenced by handle_cli_iax2_prune_realtime(), handle_cli_iax2_set_debug(), and handle_cli_iax2_show_peer().
03648 { 03649 int which = 0; 03650 struct iax2_peer *peer; 03651 char *res = NULL; 03652 int wordlen = strlen(word); 03653 struct ao2_iterator i; 03654 03655 i = ao2_iterator_init(peers, 0); 03656 while ((peer = ao2_iterator_next(&i))) { 03657 if (!strncasecmp(peer->name, word, wordlen) && ++which > state 03658 && (!flags || ast_test_flag(peer, flags))) { 03659 res = ast_strdup(peer->name); 03660 peer_unref(peer); 03661 break; 03662 } 03663 peer_unref(peer); 03664 } 03665 ao2_iterator_destroy(&i); 03666 03667 return res; 03668 }
| static char * complete_iax2_unregister | ( | const char * | line, | |
| const char * | word, | |||
| int | pos, | |||
| int | state | |||
| ) | [static] |
Definition at line 6566 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().
06567 { 06568 int which = 0; 06569 struct iax2_peer *p = NULL; 06570 char *res = NULL; 06571 int wordlen = strlen(word); 06572 06573 /* 0 - iax2; 1 - unregister; 2 - <peername> */ 06574 if (pos == 2) { 06575 struct ao2_iterator i = ao2_iterator_init(peers, 0); 06576 while ((p = ao2_iterator_next(&i))) { 06577 if (!strncasecmp(p->name, word, wordlen) && 06578 ++which > state && p->expire > 0) { 06579 res = ast_strdup(p->name); 06580 peer_unref(p); 06581 break; 06582 } 06583 peer_unref(p); 06584 } 06585 ao2_iterator_destroy(&i); 06586 } 06587 06588 return res; 06589 }
| static int complete_transfer | ( | int | callno, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 8026 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().
08027 { 08028 int peercallno = 0; 08029 struct chan_iax2_pvt *pvt = iaxs[callno]; 08030 struct iax_frame *cur; 08031 jb_frame frame; 08032 08033 if (ies->callno) 08034 peercallno = ies->callno; 08035 08036 if (peercallno < 1) { 08037 ast_log(LOG_WARNING, "Invalid transfer request\n"); 08038 return -1; 08039 } 08040 remove_by_transfercallno(pvt); 08041 /* since a transfer has taken place, the address will change. 08042 * This must be accounted for in the peercnts table. Remove 08043 * the old address and add the new one */ 08044 peercnt_remove_by_addr(&pvt->addr); 08045 peercnt_add(&pvt->transfer); 08046 /* now copy over the new address */ 08047 memcpy(&pvt->addr, &pvt->transfer, sizeof(pvt->addr)); 08048 memset(&pvt->transfer, 0, sizeof(pvt->transfer)); 08049 /* Reset sequence numbers */ 08050 pvt->oseqno = 0; 08051 pvt->rseqno = 0; 08052 pvt->iseqno = 0; 08053 pvt->aseqno = 0; 08054 08055 if (pvt->peercallno) { 08056 remove_by_peercallno(pvt); 08057 } 08058 pvt->peercallno = peercallno; 08059 /*this is where the transfering call swiches hash tables */ 08060 store_by_peercallno(pvt); 08061 pvt->transferring = TRANSFER_NONE; 08062 pvt->svoiceformat = -1; 08063 pvt->voiceformat = 0; 08064 pvt->svideoformat = -1; 08065 pvt->videoformat = 0; 08066 pvt->transfercallno = 0; 08067 memset(&pvt->rxcore, 0, sizeof(pvt->rxcore)); 08068 memset(&pvt->offset, 0, sizeof(pvt->offset)); 08069 /* reset jitterbuffer */ 08070 while(jb_getall(pvt->jb,&frame) == JB_OK) 08071 iax2_frame_free(frame.data); 08072 jb_reset(pvt->jb); 08073 pvt->lag = 0; 08074 pvt->last = 0; 08075 pvt->lastsent = 0; 08076 pvt->nextpred = 0; 08077 pvt->pingtime = DEFAULT_RETRY_TIME; 08078 AST_LIST_LOCK(&frame_queue); 08079 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 08080 /* We must cancel any packets that would have been transmitted 08081 because now we're talking to someone new. It's okay, they 08082 were transmitted to someone that didn't care anyway. */ 08083 if (callno == cur->callno) 08084 cur->retries = -1; 08085 } 08086 AST_LIST_UNLOCK(&frame_queue); 08087 return 0; 08088 }
| static unsigned char compress_subclass | ( | int | subclass | ) | [static] |
Definition at line 1464 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().
01465 { 01466 int x; 01467 int power=-1; 01468 /* If it's 128 or smaller, just return it */ 01469 if (subclass < IAX_FLAG_SC_LOG) 01470 return subclass; 01471 /* Otherwise find its power */ 01472 for (x = 0; x < IAX_MAX_SHIFT; x++) { 01473 if (subclass & (1 << x)) { 01474 if (power > -1) { 01475 ast_log(LOG_WARNING, "Can't compress subclass %d\n", subclass); 01476 return 0; 01477 } else 01478 power = x; 01479 } 01480 } 01481 return power | IAX_FLAG_SC_LOG; 01482 }
| static void construct_rr | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ie_data * | iep | |||
| ) | [static] |
Definition at line 9007 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().
09008 { 09009 jb_info stats; 09010 jb_getinfo(pvt->jb, &stats); 09011 09012 memset(iep, 0, sizeof(*iep)); 09013 09014 iax_ie_append_int(iep,IAX_IE_RR_JITTER, stats.jitter); 09015 if(stats.frames_in == 0) stats.frames_in = 1; 09016 iax_ie_append_int(iep,IAX_IE_RR_LOSS, ((0xff & (stats.losspct/1000)) << 24 | (stats.frames_lost & 0x00ffffff))); 09017 iax_ie_append_int(iep,IAX_IE_RR_PKTS, stats.frames_in); 09018 iax_ie_append_short(iep,IAX_IE_RR_DELAY, stats.current - stats.min); 09019 iax_ie_append_int(iep,IAX_IE_RR_DROPPED, stats.frames_dropped); 09020 iax_ie_append_int(iep,IAX_IE_RR_OOO, stats.frames_ooo); 09021 }
| static int create_addr | ( | const char * | peername, | |
| struct ast_channel * | c, | |||
| struct sockaddr_in * | sin, | |||
| struct create_addr_info * | cai | |||
| ) | [static] |
Definition at line 4337 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_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_FORCE_ENCRYPT, 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().
04338 { 04339 struct iax2_peer *peer; 04340 int res = -1; 04341 struct ast_codec_pref ourprefs; 04342 04343 ast_clear_flag(cai, IAX_SENDANI | IAX_TRUNK); 04344 cai->sockfd = defaultsockfd; 04345 cai->maxtime = 0; 04346 sin->sin_family = AF_INET; 04347 04348 if (!(peer = find_peer(peername, 1))) { 04349 cai->found = 0; 04350 if (ast_get_ip_or_srv(sin, peername, srvlookup ? "_iax._udp" : NULL)) { 04351 ast_log(LOG_WARNING, "No such host: %s\n", peername); 04352 return -1; 04353 } 04354 sin->sin_port = htons(IAX_DEFAULT_PORTNO); 04355 /* use global iax prefs for unknown peer/user */ 04356 /* But move the calling channel's native codec to the top of the preference list */ 04357 memcpy(&ourprefs, &prefs, sizeof(ourprefs)); 04358 if (c) 04359 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04360 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04361 return 0; 04362 } 04363 04364 cai->found = 1; 04365 04366 /* if the peer has no address (current or default), return failure */ 04367 if (!(peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr)) 04368 goto return_unref; 04369 04370 /* if the peer is being monitored and is currently unreachable, return failure */ 04371 if (peer->maxms && ((peer->lastms > peer->maxms) || (peer->lastms < 0))) 04372 goto return_unref; 04373 04374 ast_copy_flags(cai, peer, IAX_SENDANI | IAX_TRUNK | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_FORCE_ENCRYPT); 04375 cai->maxtime = peer->maxms; 04376 cai->capability = peer->capability; 04377 cai->encmethods = peer->encmethods; 04378 cai->sockfd = peer->sockfd; 04379 cai->adsi = peer->adsi; 04380 memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs)); 04381 /* Move the calling channel's native codec to the top of the preference list */ 04382 if (c) { 04383 ast_debug(1, "prepending %x to prefs\n", c->nativeformats); 04384 ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1); 04385 } 04386 ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1); 04387 ast_copy_string(cai->context, peer->context, sizeof(cai->context)); 04388 ast_copy_string(cai->peercontext, peer->peercontext, sizeof(cai->peercontext)); 04389 ast_copy_string(cai->username, peer->username, sizeof(cai->username)); 04390 ast_copy_string(cai->timezone, peer->zonetag, sizeof(cai->timezone)); 04391 ast_copy_string(cai->outkey, peer->outkey, sizeof(cai->outkey)); 04392 ast_copy_string(cai->mohinterpret, peer->mohinterpret, sizeof(cai->mohinterpret)); 04393 ast_copy_string(cai->mohsuggest, peer->mohsuggest, sizeof(cai->mohsuggest)); 04394 if (ast_strlen_zero(peer->dbsecret)) { 04395 ast_copy_string(cai->secret, peer->secret, sizeof(cai->secret)); 04396 } else { 04397 char *family; 04398 char *key = NULL; 04399 04400 family = ast_strdupa(peer->dbsecret); 04401 key = strchr(family, '/'); 04402 if (key) 04403 *key++ = '\0'; 04404 if (!key || ast_db_get(family, key, cai->secret, sizeof(cai->secret))) { 04405 ast_log(LOG_WARNING, "Unable to retrieve database password for family/key '%s'!\n", peer->dbsecret); 04406 goto return_unref; 04407 } 04408 } 04409 04410 if (peer->addr.sin_addr.s_addr) { 04411 sin->sin_addr = peer->addr.sin_addr; 04412 sin->sin_port = peer->addr.sin_port; 04413 } else { 04414 sin->sin_addr = peer->defaddr.sin_addr; 04415 sin->sin_port = peer->defaddr.sin_port; 04416 } 04417 04418 res = 0; 04419 04420 return_unref: 04421 peer_unref(peer); 04422 04423 return res; 04424 }
| static int create_callno_pools | ( | void | ) | [static] |
Definition at line 2488 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().
02489 { 02490 uint16_t i; 02491 02492 if (!(callno_pool = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02493 return -1; 02494 } 02495 02496 if (!(callno_pool_trunk = ao2_container_alloc(CALLNO_POOL_BUCKETS, callno_hash, NULL))) { 02497 return -1; 02498 } 02499 02500 /* start at 2, 0 and 1 are reserved */ 02501 for (i = 2; i <= IAX_MAX_CALLS; i++) { 02502 struct callno_entry *callno_entry; 02503 02504 if (!(callno_entry = ao2_alloc(sizeof(*callno_entry), NULL))) { 02505 return -1; 02506 } 02507 02508 callno_entry->callno = i; 02509 02510 if (i < TRUNK_CALL_START) { 02511 ao2_link(callno_pool, callno_entry); 02512 } else { 02513 ao2_link(callno_pool_trunk, callno_entry); 02514 } 02515 02516 ao2_ref(callno_entry, -1); 02517 } 02518 02519 return 0; 02520 }
| 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 5931 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().
05932 { 05933 int padding; 05934 unsigned char *workspace; 05935 05936 workspace = alloca(*datalen); 05937 memset(f, 0, sizeof(*f)); 05938 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05939 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05940 if (*datalen < 16 + sizeof(struct ast_iax2_full_hdr)) 05941 return -1; 05942 /* Decrypt */ 05943 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr), dcx); 05944 05945 padding = 16 + (workspace[15] & 0x0f); 05946 if (iaxdebug) 05947 ast_debug(1, "Decoding full frame with length %d (padding = %d) (15=%02x)\n", *datalen, padding, workspace[15]); 05948 if (*datalen < padding + sizeof(struct ast_iax2_full_hdr)) 05949 return -1; 05950 05951 *datalen -= padding; 05952 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05953 f->frametype = fh->type; 05954 if (f->frametype == AST_FRAME_VIDEO) { 05955 f->subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 05956 } else { 05957 f->subclass = uncompress_subclass(fh->csub); 05958 } 05959 } else { 05960 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 05961 if (iaxdebug) 05962 ast_debug(1, "Decoding mini with length %d\n", *datalen); 05963 if (*datalen < 16 + sizeof(struct ast_iax2_mini_hdr)) 05964 return -1; 05965 /* Decrypt */ 05966 memcpy_decrypt(workspace, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), dcx); 05967 padding = 16 + (workspace[15] & 0x0f); 05968 if (*datalen < padding + sizeof(struct ast_iax2_mini_hdr)) 05969 return -1; 05970 *datalen -= padding; 05971 memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 05972 } 05973 return 0; 05974 }
| static int decrypt_frame | ( | int | callno, | |
| struct ast_iax2_full_hdr * | fh, | |||
| struct ast_frame * | f, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 6017 of file chan_iax2.c.
References ast_set_flag, ast_test_flag, build_encryption_keys(), decode_frame(), IAX_KEYPOPULATED, MD5Final(), MD5Init(), MD5Update(), and secret.
Referenced by socket_process().
06018 { 06019 int res=-1; 06020 if (!ast_test_flag(iaxs[callno], IAX_KEYPOPULATED)) { 06021 /* Search for possible keys, given secrets */ 06022 struct MD5Context md5; 06023 unsigned char digest[16]; 06024 char *tmppw, *stringp; 06025 06026 tmppw = ast_strdupa(iaxs[callno]->secret); 06027 stringp = tmppw; 06028 while ((tmppw = strsep(&stringp, ";"))) { 06029 MD5Init(&md5); 06030 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 06031 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 06032 MD5Final(digest, &md5); 06033 build_encryption_keys(digest, iaxs[callno]); 06034 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06035 if (!res) { 06036 ast_set_flag(iaxs[callno], IAX_KEYPOPULATED); 06037 break; 06038 } 06039 } 06040 } else 06041 res = decode_frame(&iaxs[callno]->dcx, fh, f, datalen); 06042 return res; 06043 }
| 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 9154 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().
09155 { 09156 struct iax2_pkt_buf *pkt_buf, *cur_pkt_buf; 09157 struct ast_iax2_full_hdr *fh, *cur_fh; 09158 09159 if (!(pkt_buf = ast_calloc(1, sizeof(*pkt_buf) + from_here->buf_len))) 09160 return; 09161 09162 pkt_buf->len = from_here->buf_len; 09163 memcpy(pkt_buf->buf, from_here->buf, pkt_buf->len); 09164 09165 fh = (struct ast_iax2_full_hdr *) pkt_buf->buf; 09166 ast_mutex_lock(&to_here->lock); 09167 AST_LIST_TRAVERSE_SAFE_BEGIN(&to_here->full_frames, cur_pkt_buf, entry) { 09168 cur_fh = (struct ast_iax2_full_hdr *) cur_pkt_buf->buf; 09169 if (fh->oseqno < cur_fh->oseqno) { 09170 AST_LIST_INSERT_BEFORE_CURRENT(pkt_buf, entry); 09171 break; 09172 } 09173 } 09174 AST_LIST_TRAVERSE_SAFE_END 09175 09176 if (!cur_pkt_buf) 09177 AST_LIST_INSERT_TAIL(&to_here->full_frames, pkt_buf, entry); 09178 09179 ast_mutex_unlock(&to_here->lock); 09180 }
| static void delete_users | ( | void | ) | [static] |
Definition at line 12414 of file chan_iax2.c.
References ao2_callback, ast_dnsmgr_release(), ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), ast_sched_thread_del, iax2_registry::callno, iax2_registry::dnsmgr, iax2_registry::expire, iax2_destroy(), peer_delme_cb(), chan_iax2_pvt::reg, and user_delme_cb().
Referenced by __unload_module(), and set_config_destroy().
12415 { 12416 struct iax2_registry *reg; 12417 12418 ao2_callback(users, 0, user_delme_cb, NULL); 12419 12420 AST_LIST_LOCK(®istrations); 12421 while ((reg = AST_LIST_REMOVE_HEAD(®istrations, entry))) { 12422 if (sched) { 12423 ast_sched_thread_del(sched, reg->expire); 12424 } 12425 if (reg->callno) { 12426 int callno = reg->callno; 12427 ast_mutex_lock(&iaxsl[callno]); 12428 if (iaxs[callno]) { 12429 iaxs[callno]->reg = NULL; 12430 iax2_destroy(callno); 12431 } 12432 ast_mutex_unlock(&iaxsl[callno]); 12433 } 12434 if (reg->dnsmgr) 12435 ast_dnsmgr_release(reg->dnsmgr); 12436 ast_free(reg); 12437 } 12438 AST_LIST_UNLOCK(®istrations); 12439 12440 ao2_callback(peers, 0, peer_delme_cb, NULL); 12441 }
| static void destroy_firmware | ( | struct iax_firmware * | cur | ) | [static] |
Definition at line 2843 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 8855 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().
08856 { 08857 unsigned short dpstatus = 0; 08858 struct iax_ie_data ied1; 08859 int mm; 08860 08861 memset(&ied1, 0, sizeof(ied1)); 08862 mm = ast_matchmore_extension(NULL, context, callednum, 1, callerid); 08863 /* Must be started */ 08864 if (!strcmp(callednum, ast_parking_ext()) || ast_exists_extension(NULL, context, callednum, 1, callerid)) { 08865 dpstatus = IAX_DPSTATUS_EXISTS; 08866 } else if (ast_canmatch_extension(NULL, context, callednum, 1, callerid)) { 08867 dpstatus = IAX_DPSTATUS_CANEXIST; 08868 } else { 08869 dpstatus = IAX_DPSTATUS_NONEXISTENT; 08870 } 08871 if (ast_ignore_pattern(context, callednum)) 08872 dpstatus |= IAX_DPSTATUS_IGNOREPAT; 08873 if (mm) 08874 dpstatus |= IAX_DPSTATUS_MATCHMORE; 08875 if (!skiplock) 08876 ast_mutex_lock(&iaxsl[callno]); 08877 if (iaxs[callno]) { 08878 iax_ie_append_str(&ied1, IAX_IE_CALLED_NUMBER, callednum); 08879 iax_ie_append_short(&ied1, IAX_IE_DPSTATUS, dpstatus); 08880 iax_ie_append_short(&ied1, IAX_IE_REFRESH, iaxdefaultdpcache); 08881 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREP, 0, ied1.buf, ied1.pos, -1); 08882 } 08883 if (!skiplock) 08884 ast_mutex_unlock(&iaxsl[callno]); 08885 }
| static void* dp_lookup_thread | ( | void * | data | ) | [static] |
Definition at line 8887 of file chan_iax2.c.
References ast_free, dpreq_data::callednum, dpreq_data::callerid, dpreq_data::callno, dpreq_data::context, and dp_lookup().
Referenced by spawn_dp_lookup().
| static void encmethods_to_str | ( | int | e, | |
| struct ast_str * | buf | |||
| ) | [static] |
Definition at line 1403 of file chan_iax2.c.
References ast_str_append(), ast_str_set(), ast_str_strlen(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by __iax2_show_peers(), handle_cli_iax2_show_peer(), and manager_iax2_show_peer_list().
01404 { 01405 ast_str_set(&buf, 0, "("); 01406 if (e & IAX_ENCRYPT_AES128) { 01407 ast_str_append(&buf, 0, "aes128"); 01408 } 01409 if (e & IAX_ENCRYPT_KEYROTATE) { 01410 ast_str_append(&buf, 0, ",keyrotate"); 01411 } 01412 if (ast_str_strlen(buf) > 1) { 01413 ast_str_append(&buf, 0, ")"); 01414 } else { 01415 ast_str_set(&buf, 0, "No"); 01416 } 01417 }
| static int encrypt_frame | ( | ast_aes_encrypt_key * | ecx, | |
| struct ast_iax2_full_hdr * | fh, | |||
| unsigned char * | poo, | |||
| int * | datalen | |||
| ) | [static] |
Definition at line 5976 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().
05977 { 05978 int padding; 05979 unsigned char *workspace; 05980 workspace = alloca(*datalen + 32); 05981 if (!workspace) 05982 return -1; 05983 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 05984 struct ast_iax2_full_enc_hdr *efh = (struct ast_iax2_full_enc_hdr *)fh; 05985 if (iaxdebug) 05986 ast_debug(1, "Encoding full frame %d/%d with length %d\n", fh->type, fh->csub, *datalen); 05987 padding = 16 - ((*datalen - sizeof(struct ast_iax2_full_enc_hdr)) % 16); 05988 padding = 16 + (padding & 0xf); 05989 memcpy(workspace, poo, padding); 05990 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_full_enc_hdr)); 05991 workspace[15] &= 0xf0; 05992 workspace[15] |= (padding & 0xf); 05993 if (iaxdebug) 05994 ast_debug(1, "Encoding full frame %d/%d with length %d + %d padding (15=%02x)\n", fh->type, fh->csub, *datalen, padding, workspace[15]); 05995 *datalen += padding; 05996 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_full_enc_hdr), ecx); 05997 if (*datalen >= 32 + sizeof(struct ast_iax2_full_enc_hdr)) 05998 memcpy(poo, workspace + *datalen - 32, 32); 05999 } else { 06000 struct ast_iax2_mini_enc_hdr *efh = (struct ast_iax2_mini_enc_hdr *)fh; 06001 if (iaxdebug) 06002 ast_debug(1, "Encoding mini frame with length %d\n", *datalen); 06003 padding = 16 - ((*datalen - sizeof(struct ast_iax2_mini_enc_hdr)) % 16); 06004 padding = 16 + (padding & 0xf); 06005 memcpy(workspace, poo, padding); 06006 memcpy(workspace + padding, efh->encdata, *datalen - sizeof(struct ast_iax2_mini_enc_hdr)); 06007 workspace[15] &= 0xf0; 06008 workspace[15] |= (padding & 0x0f); 06009 *datalen += padding; 06010 memcpy_encrypt(efh->encdata, workspace, *datalen - sizeof(struct ast_iax2_mini_enc_hdr), ecx); 06011 if (*datalen >= 32 + sizeof(struct ast_iax2_mini_enc_hdr)) 06012 memcpy(poo, workspace + *datalen - 32, 32); 06013 } 06014 return 0; 06015 }
| static int expire_registry | ( | const void * | data | ) | [static] |
Definition at line 8286 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().
08287 { 08288 #ifdef SCHED_MULTITHREADED 08289 if (schedule_action(__expire_registry, data)) 08290 #endif 08291 __expire_registry(data); 08292 return 0; 08293 }
| 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 13074 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().
13075 { 13076 struct iax2_dpcache *dp = NULL; 13077 struct timeval now = ast_tvnow(); 13078 int x, com[2], timeout, old = 0, outfd, doabort, callno; 13079 struct ast_channel *c = NULL; 13080 struct ast_frame *f = NULL; 13081 13082 AST_LIST_TRAVERSE_SAFE_BEGIN(&dpcache, dp, cache_list) { 13083 if (ast_tvcmp(now, dp->expiry) > 0) { 13084 AST_LIST_REMOVE_CURRENT(cache_list); 13085 if ((dp->flags & CACHE_FLAG_PENDING) || dp->callno) 13086 ast_log(LOG_WARNING, "DP still has peer field or pending or callno (flags = %d, peer = blah, callno = %d)\n", dp->flags, dp->callno); 13087 else 13088 ast_free(dp); 13089 continue; 13090 } 13091 if (!strcmp(dp->peercontext, data) && !strcmp(dp->exten, exten)) 13092 break; 13093 } 13094 AST_LIST_TRAVERSE_SAFE_END; 13095 13096 if (!dp) { 13097 /* No matching entry. Create a new one. */ 13098 /* First, can we make a callno? */ 13099 if ((callno = cache_get_callno_locked(data)) < 0) { 13100 ast_log(LOG_WARNING, "Unable to generate call for '%s'\n", data); 13101 return NULL; 13102 } 13103 if (!(dp = ast_calloc(1, sizeof(*dp)))) { 13104 ast_mutex_unlock(&iaxsl[callno]); 13105 return NULL; 13106 } 13107 ast_copy_string(dp->peercontext, data, sizeof(dp->peercontext)); 13108 ast_copy_string(dp->exten, exten, sizeof(dp->exten)); 13109 dp->expiry = ast_tvnow(); 13110 dp->orig = dp->expiry; 13111 /* Expires in 30 mins by default */ 13112 dp->expiry.tv_sec += iaxdefaultdpcache; 13113 dp->flags = CACHE_FLAG_PENDING; 13114 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) 13115 dp->waiters[x] = -1; 13116 /* Insert into the lists */ 13117 AST_LIST_INSERT_TAIL(&dpcache, dp, cache_list); 13118 AST_LIST_INSERT_TAIL(&iaxs[callno]->dpentries, dp, peer_list); 13119 /* Send the request if we're already up */ 13120 if (ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 13121 iax2_dprequest(dp, callno); 13122 ast_mutex_unlock(&iaxsl[callno]); 13123 } 13124 13125 /* By here we must have a dp */ 13126 if (dp->flags & CACHE_FLAG_PENDING) { 13127 /* Okay, here it starts to get nasty. We need a pipe now to wait 13128 for a reply to come back so long as it's pending */ 13129 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13130 /* Find an empty slot */ 13131 if (dp->waiters[x] < 0) 13132 break; 13133 } 13134 if (x >= ARRAY_LEN(dp->waiters)) { 13135 ast_log(LOG_WARNING, "No more waiter positions available\n"); 13136 return NULL; 13137 } 13138 if (pipe(com)) { 13139 ast_log(LOG_WARNING, "Unable to create pipe for comm\n"); 13140 return NULL; 13141 } 13142 dp->waiters[x] = com[1]; 13143 /* Okay, now we wait */ 13144 timeout = iaxdefaulttimeout * 1000; 13145 /* Temporarily unlock */ 13146 AST_LIST_UNLOCK(&dpcache); 13147 /* Defer any dtmf */ 13148 if (chan) 13149 old = ast_channel_defer_dtmf(chan); 13150 doabort = 0; 13151 while(timeout) { 13152 c = ast_waitfor_nandfds(&chan, chan ? 1 : 0, &com[0], 1, NULL, &outfd, &timeout); 13153 if (outfd > -1) 13154 break; 13155 if (!c) 13156 continue; 13157 if (!(f = ast_read(c))) { 13158 doabort = 1; 13159 break; 13160 } 13161 ast_frfree(f); 13162 } 13163 if (!timeout) { 13164 ast_log(LOG_WARNING, "Timeout waiting for %s exten %s\n", data, exten); 13165 } 13166 AST_LIST_LOCK(&dpcache); 13167 dp->waiters[x] = -1; 13168 close(com[1]); 13169 close(com[0]); 13170 if (doabort) { 13171 /* Don't interpret anything, just abort. Not sure what th epoint 13172 of undeferring dtmf on a hung up channel is but hey whatever */ 13173 if (!old && chan) 13174 ast_channel_undefer_dtmf(chan); 13175 return NULL; 13176 } 13177 if (!(dp->flags & CACHE_FLAG_TIMEOUT)) { 13178 /* Now to do non-independent analysis the results of our wait */ 13179 if (dp->flags & CACHE_FLAG_PENDING) { 13180 /* Still pending... It's a timeout. Wake everybody up. Consider it no longer 13181 pending. Don't let it take as long to timeout. */ 13182 dp->flags &= ~CACHE_FLAG_PENDING; 13183 dp->flags |= CACHE_FLAG_TIMEOUT; 13184 /* Expire after only 60 seconds now. This is designed to help reduce backlog in heavily loaded 13185 systems without leaving it unavailable once the server comes back online */ 13186 dp->expiry.tv_sec = dp->orig.tv_sec + 60; 13187 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 13188 if (dp->waiters[x] > -1) { 13189 if (write(dp->waiters[x], "asdf", 4) < 0) { 13190 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 13191 } 13192 } 13193 } 13194 } 13195 } 13196 /* Our caller will obtain the rest */ 13197 if (!old && chan) 13198 ast_channel_undefer_dtmf(chan); 13199 } 13200 return dp; 13201 }
| 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 2743 of file chan_iax2.c.
References __find_callno().
Referenced by iax2_poke_peer(), and socket_process().
02743 { 02744 02745 return __find_callno(callno, dcallno, sin, new, sockfd, 0, full_frame); 02746 }
| 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 2748 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().
02748 { 02749 02750 return __find_callno(callno, dcallno, sin, new, sockfd, 1, full_frame); 02751 }
| static struct iax2_thread* find_idle_thread | ( | void | ) | [static, read] |
Definition at line 1264 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().
01265 { 01266 struct iax2_thread *thread = NULL; 01267 01268 /* Pop the head of the idle list off */ 01269 AST_LIST_LOCK(&idle_list); 01270 thread = AST_LIST_REMOVE_HEAD(&idle_list, list); 01271 AST_LIST_UNLOCK(&idle_list); 01272 01273 /* If we popped a thread off the idle list, just return it */ 01274 if (thread) { 01275 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01276 return thread; 01277 } 01278 01279 /* Pop the head of the dynamic list off */ 01280 AST_LIST_LOCK(&dynamic_list); 01281 thread = AST_LIST_REMOVE_HEAD(&dynamic_list, list); 01282 AST_LIST_UNLOCK(&dynamic_list); 01283 01284 /* If we popped a thread off the dynamic list, just return it */ 01285 if (thread) { 01286 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01287 return thread; 01288 } 01289 01290 /* If we can't create a new dynamic thread for any reason, return no thread at all */ 01291 if (iaxdynamicthreadcount >= iaxmaxthreadcount || !(thread = ast_calloc(1, sizeof(*thread)))) 01292 return NULL; 01293 01294 /* Set default values */ 01295 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, 1); 01296 thread->threadnum = ast_atomic_fetchadd_int(&iaxdynamicthreadnum, 1); 01297 thread->type = IAX_THREAD_TYPE_DYNAMIC; 01298 01299 /* Initialize lock and condition */ 01300 ast_mutex_init(&thread->lock); 01301 ast_cond_init(&thread->cond, NULL); 01302 ast_mutex_init(&thread->init_lock); 01303 ast_cond_init(&thread->init_cond, NULL); 01304 ast_mutex_lock(&thread->init_lock); 01305 01306 /* Create thread and send it on it's way */ 01307 if (ast_pthread_create_detached_background(&thread->threadid, NULL, iax2_process_thread, thread)) { 01308 ast_cond_destroy(&thread->cond); 01309 ast_mutex_destroy(&thread->lock); 01310 ast_free(thread); 01311 return NULL; 01312 } 01313 01314 /* this thread is not processing a full frame (since it is idle), 01315 so ensure that the field for the full frame call number is empty */ 01316 memset(&thread->ffinfo, 0, sizeof(thread->ffinfo)); 01317 01318 /* Wait for the thread to be ready before returning it to the caller */ 01319 ast_cond_wait(&thread->init_cond, &thread->init_lock); 01320 01321 /* Done with init_lock */ 01322 ast_mutex_unlock(&thread->init_lock); 01323 01324 return thread; 01325 }
| static struct iax2_peer* find_peer | ( | const char * | name, | |
| int | realtime | |||
| ) | [static, read] |
Definition at line 1542 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().
01543 { 01544 struct iax2_peer *peer = NULL; 01545 struct iax2_peer tmp_peer = { 01546 .name = name, 01547 }; 01548 01549 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 01550 01551 /* Now go for realtime if applicable */ 01552 if(!peer && realtime) 01553 peer = realtime_peer(name, NULL); 01554 01555 return peer; 01556 }
| static struct iax2_trunk_peer* find_tpeer | ( | struct sockaddr_in * | sin, | |
| int | fd | |||
| ) | [static, read] |
Definition at line 5749 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().
05750 { 05751 struct iax2_trunk_peer *tpeer = NULL; 05752 05753 /* Finds and locks trunk peer */ 05754 AST_LIST_LOCK(&tpeers); 05755 05756 AST_LIST_TRAVERSE(&tpeers, tpeer, list) { 05757 if (!inaddrcmp(&tpeer->addr, sin)) { 05758 ast_mutex_lock(&tpeer->lock); 05759 break; 05760 } 05761 } 05762 05763 if (!tpeer) { 05764 if ((tpeer = ast_calloc(1, sizeof(*tpeer)))) { 05765 ast_mutex_init(&tpeer->lock); 05766 tpeer->lastsent = 9999; 05767 memcpy(&tpeer->addr, sin, sizeof(tpeer->addr)); 05768 tpeer->trunkact = ast_tvnow(); 05769 ast_mutex_lock(&tpeer->lock); 05770 tpeer->sockfd = fd; 05771 #ifdef SO_NO_CHECK 05772 setsockopt(tpeer->sockfd, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 05773 #endif 05774 ast_debug(1, "Created trunk peer for '%s:%d'\n", ast_inet_ntoa(tpeer->addr.sin_addr), ntohs(tpeer->addr.sin_port)); 05775 AST_LIST_INSERT_TAIL(&tpeers, tpeer, list); 05776 } 05777 } 05778 05779 AST_LIST_UNLOCK(&tpeers); 05780 05781 return tpeer; 05782 }
| static struct iax2_user* find_user | ( | const char * | name | ) | [static, read] |
Definition at line 1570 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().
01571 { 01572 struct iax2_user tmp_user = { 01573 .name = name, 01574 }; 01575 01576 return ao2_find(users, &tmp_user, OBJ_POINTER); 01577 }
| static unsigned int fix_peerts | ( | struct timeval * | rxtrunktime, | |
| int | callno, | |||
| unsigned int | ts | |||
| ) | [static] |
Definition at line 5561 of file chan_iax2.c.
References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and chan_iax2_pvt::rxcore.
Referenced by socket_process_meta().
05562 { 05563 long ms; /* NOT unsigned */ 05564 if (ast_tvzero(iaxs[callno]->rxcore)) { 05565 /* Initialize rxcore time if appropriate */ 05566 iaxs[callno]->rxcore = ast_tvnow(); 05567 /* Round to nearest 20ms so traces look pretty */ 05568 iaxs[callno]->rxcore.tv_usec -= iaxs[callno]->rxcore.tv_usec % 20000; 05569 } 05570 /* Calculate difference between trunk and channel */ 05571 ms = ast_tvdiff_ms(*rxtrunktime, iaxs[callno]->rxcore); 05572 /* Return as the sum of trunk time and the difference between trunk and real time */ 05573 return ms + ts; 05574 }
| static void free_context | ( | struct iax2_context * | con | ) | [static] |
Definition at line 11551 of file chan_iax2.c.
References ast_free, and iax2_context::next.
Referenced by build_user(), and user_destructor().
11552 { 11553 struct iax2_context *conl; 11554 while(con) { 11555 conl = con; 11556 con = con->next; 11557 ast_free(conl); 11558 } 11559 }
| static void free_signaling_queue_entry | ( | struct signaling_queue_entry * | s | ) | [static] |
Definition at line 1670 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 13324 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_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.
13325 { 13326 struct iax2_peer *peer; 13327 char *peername, *colname; 13328 13329 peername = ast_strdupa(data); 13330 13331 /* if our channel, return the IP address of the endpoint of current channel */ 13332 if (!strcmp(peername,"CURRENTCHANNEL")) { 13333 unsigned short callno; 13334 if (chan->tech != &iax2_tech) 13335 return -1; 13336 callno = PTR_TO_CALLNO(chan->tech_pvt); 13337 ast_copy_string(buf, iaxs[callno]->addr.sin_addr.s_addr ? ast_inet_ntoa(iaxs[callno]->addr.sin_addr) : "", len); 13338 return 0; 13339 } 13340 13341 if ((colname = strchr(peername, ','))) 13342 *colname++ = '\0'; 13343 else 13344 colname = "ip"; 13345 13346 if (!(peer = find_peer(peername, 1))) 13347 return -1; 13348 13349 if (!strcasecmp(colname, "ip")) { 13350 ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len); 13351 } else if (!strcasecmp(colname, "status")) { 13352 peer_status(peer, buf, len); 13353 } else if (!strcasecmp(colname, "mailbox")) { 13354 ast_copy_string(buf, peer->mailbox, len); 13355 } else if (!strcasecmp(colname, "context")) { 13356 ast_copy_string(buf, peer->context, len); 13357 } else if (!strcasecmp(colname, "expire")) { 13358 snprintf(buf, len, "%d", peer->expire); 13359 } else if (!strcasecmp(colname, "dynamic")) { 13360 ast_copy_string(buf, (ast_test_flag(peer, IAX_DYNAMIC) ? "yes" : "no"), len); 13361 } else if (!strcasecmp(colname, "callerid_name")) { 13362 ast_copy_string(buf, peer->cid_name, len); 13363 } else if (!strcasecmp(colname, "callerid_num")) { 13364 ast_copy_string(buf, peer->cid_num, len); 13365 } else if (!strcasecmp(colname, "codecs")) { 13366 ast_getformatname_multiple(buf, len -1, peer->capability); 13367 } else if (!strncasecmp(colname, "codec[", 6)) { 13368 char *codecnum, *ptr; 13369 int codec = 0; 13370 13371 codecnum = strchr(colname, '['); 13372 *codecnum = '\0'; 13373 codecnum++; 13374 if ((ptr = strchr(codecnum, ']'))) { 13375 *ptr = '\0'; 13376 } 13377 if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) { 13378 ast_copy_string(buf, ast_getformatname(codec), len); 13379 } else { 13380 buf[0] = '\0'; 13381 } 13382 } else { 13383 buf[0] = '\0'; 13384 } 13385 13386 peer_unref(peer); 13387 13388 return 0; 13389 }
| static int get_auth_methods | ( | const char * | value | ) | [static] |
Definition at line 11742 of file chan_iax2.c.
References IAX_AUTH_MD5, IAX_AUTH_PLAINTEXT, and IAX_AUTH_RSA.
Referenced by build_peer(), and build_user().
11743 { 11744 int methods = 0; 11745 if (strstr(value, "rsa")) 11746 methods |= IAX_AUTH_RSA; 11747 if (strstr(value, "md5")) 11748 methods |= IAX_AUTH_MD5; 11749 if (strstr(value, "plaintext")) 11750 methods |= IAX_AUTH_PLAINTEXT; 11751 return methods; 11752 }
| static int get_encrypt_methods | ( | const char * | s | ) | [static] |
Definition at line 1419 of file chan_iax2.c.
References ast_true(), IAX_ENCRYPT_AES128, and IAX_ENCRYPT_KEYROTATE.
Referenced by build_peer(), build_user(), and set_config().
01420 { 01421 int e; 01422 if (!strcasecmp(s, "aes128")) 01423 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01424 else if (ast_true(s)) 01425 e = IAX_ENCRYPT_AES128 | IAX_ENCRYPT_KEYROTATE; 01426 else 01427 e = 0; 01428 return e; 01429 }
| static int get_from_jb | ( | const void * | p | ) | [static] |
Definition at line 3955 of file chan_iax2.c.
References __get_from_jb(), and schedule_action.
Referenced by update_jbsched().
03956 { 03957 #ifdef SCHED_MULTITHREADED 03958 if (schedule_action(__get_from_jb, data)) 03959 #endif 03960 __get_from_jb(data); 03961 return 0; 03962 }
| static struct callno_entry * get_unused_callno | ( | int | trunk, | |
| int | validated | |||
| ) | [static, read] |
Definition at line 2421 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().
02422 { 02423 struct callno_entry *callno_entry = NULL; 02424 if ((!ao2_container_count(callno_pool) && !trunk) || (!ao2_container_count(callno_pool_trunk) && trunk)) { 02425 ast_log(LOG_WARNING, "Out of CallNumbers\n"); 02426 /* Minor optimization for the extreme case. */ 02427 return NULL; 02428 } 02429 02430 /* the callno_pool container is locked here primarily to ensure thread 02431 * safety of the total_nonval_callno_used check and increment */ 02432 ao2_lock(callno_pool); 02433 02434 /* only a certain number of nonvalidated call numbers should be allocated. 02435 * If there ever is an attack, this separates the calltoken validating 02436 * users from the non calltoken validating users. */ 02437 if (!validated && (total_nonval_callno_used >= global_maxcallno_nonval)) { 02438 ast_log(LOG_WARNING, "NON-CallToken callnumber limit is reached. Current:%d Max:%d\n", total_nonval_callno_used, global_maxcallno_nonval); 02439 ao2_unlock(callno_pool); 02440 return NULL; 02441 } 02442 02443 /* unlink the object from the container, taking over ownership 02444 * of the reference the container had to the object */ 02445 callno_entry = ao2_find((trunk ? callno_pool_trunk : callno_pool), NULL, OBJ_POINTER | OBJ_UNLINK | OBJ_CONTINUE); 02446 02447 if (callno_entry) { 02448 callno_entry->validated = validated; 02449 if (!validated) { 02450 total_nonval_callno_used++; 02451 } 02452 } 02453 02454 ao2_unlock(callno_pool); 02455 return callno_entry; 02456 }
| 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 4634 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().
04636 { 04637 #define CALLTOKEN_HASH_FORMAT "%s%d%u%d" /* address + port + ts + randomcalldata */ 04638 #define CALLTOKEN_IE_FORMAT "%u?%s" /* time + ? + (40 char hash) */ 04639 struct ast_str *buf = ast_str_alloca(256); 04640 time_t t = time(NULL); 04641 char hash[41]; /* 40 char sha1 hash */ 04642 int subclass = uncompress_subclass(fh->csub); 04643 04644 /* ----- Case 1 ----- */ 04645 if (ies->calltoken && !ies->calltokendata) { /* empty calltoken is provided, client supports calltokens */ 04646 struct iax_ie_data ied = { 04647 .buf = { 0 }, 04648 .pos = 0, 04649 }; 04650 04651 /* create the hash with their address data and our timestamp */ 04652 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) t, randomcalltokendata); 04653 ast_sha1_hash(hash, ast_str_buffer(buf)); 04654 04655 ast_str_set(&buf, 0, CALLTOKEN_IE_FORMAT, (unsigned int) t, hash); 04656 iax_ie_append_str(&ied, IAX_IE_CALLTOKEN, ast_str_buffer(buf)); 04657 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_CALLTOKEN, ntohl(fh->ts), fh->iseqno + 1, fd, &ied); 04658 04659 return 1; 04660 04661 /* ----- Case 2 ----- */ 04662 } else if (ies->calltoken && ies->calltokendata) { /* calltoken received, check to see if it is valid */ 04663 char *rec_hash = NULL; /* the received hash, make sure it matches with ours. */ 04664 char *rec_ts = NULL; /* received timestamp */ 04665 unsigned int rec_time; /* received time_t */ 04666 04667 /* split the timestamp from the hash data */ 04668 rec_hash = strchr((char *) ies->calltokendata, '?'); 04669 if (rec_hash) { 04670 *rec_hash++ = '\0'; 04671 rec_ts = (char *) ies->calltokendata; 04672 } 04673 04674 /* check that we have valid data before we do any comparisons */ 04675 if (!rec_hash || !rec_ts) { 04676 goto reject; 04677 } else if (sscanf(rec_ts, "%u", &rec_time) != 1) { 04678 goto reject; 04679 } 04680 04681 /* create a hash with their address and the _TOKEN'S_ timestamp */ 04682 ast_str_set(&buf, 0, CALLTOKEN_HASH_FORMAT, ast_inet_ntoa(sin->sin_addr), sin->sin_port, (unsigned int) rec_time, randomcalltokendata); 04683 ast_sha1_hash(hash, ast_str_buffer(buf)); 04684 04685 /* compare hashes and then check timestamp delay */ 04686 if (strcmp(hash, rec_hash)) { 04687 ast_log(LOG_WARNING, "Address %s failed CallToken hash inspection\n", ast_inet_ntoa(sin->sin_addr)); 04688 goto reject; /* received hash does not match ours, reject */ 04689 } else if ((t < rec_time) || ((t - rec_time) >= MAX_CALLTOKEN_DELAY)) { 04690 ast_log(LOG_WARNING, "Too much delay in IAX2 calltoken timestamp from address %s\n", ast_inet_ntoa(sin->sin_addr)); 04691 goto reject; /* too much delay, reject */ 04692 } 04693 04694 /* at this point the call token is valid, returning 0 04695 * will allow socket_process to continue as usual */ 04696 requirecalltoken_mark_auto(ies->username, subclass); 04697 return 0; 04698 04699 /* ----- Case 3 ----- */ 04700 } else { /* calltokens are not supported for this client, how do we respond? */ 04701 if (calltoken_required(sin, ies->username, subclass)) { 04702 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")); 04703 goto reject; 04704 } 04705 return 0; /* calltoken is not required for this addr, so permit it. */ 04706 } 04707 04708 reject: 04709 /* received frame has failed calltoken inspection, send apathetic reject messages */ 04710 if (subclass == IAX_COMMAND_REGREQ || subclass == IAX_COMMAND_REGREL) { 04711 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04712 } else { 04713 send_apathetic_reply(1, ntohs(fh->scallno), sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 04714 } 04715 04716 return 1; 04717 }
| static char* handle_cli_iax2_provision | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 11402 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.
11403 { 11404 int force = 0; 11405 int res; 11406 11407 switch (cmd) { 11408 case CLI_INIT: 11409 e->command = "iax2 provision"; 11410 e->usage = 11411 "Usage: iax2 provision <host> <template> [forced]\n" 11412 " Provisions the given peer or IP address using a template\n" 11413 " matching either 'template' or '*' if the template is not\n" 11414 " found. If 'forced' is specified, even empty provisioning\n" 11415 " fields will be provisioned as empty fields.\n"; 11416 return NULL; 11417 case CLI_GENERATE: 11418 if (a->pos == 3) 11419 return iax_prov_complete_template(a->line, a->word, a->pos, a->n); 11420 return NULL; 11421 } 11422 11423 if (a->argc < 4) 11424 return CLI_SHOWUSAGE; 11425 if (a->argc > 4) { 11426 if (!strcasecmp(a->argv[4], "forced")) 11427 force = 1; 11428 else 11429 return CLI_SHOWUSAGE; 11430 } 11431 res = iax2_provision(NULL, -1, a->argv[2], a->argv[3], force); 11432 if (res < 0) 11433 ast_cli(a->fd, "Unable to find peer/address '%s'\n", a->argv[2]); 11434 else if (res < 1) 11435 ast_cli(a->fd, "No template (including wildcard) matching '%s'\n", a->argv[3]); 11436 else 11437 ast_cli(a->fd, "Provisioning '%s' with template '%s'%s\n", a->argv[2], a->argv[3], force ? ", forced" : ""); 11438 return CLI_SUCCESS; 11439 }
| static char* handle_cli_iax2_prune_realtime | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3393 of file chan_iax2.c.
References ao2_unlink, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_cli_complete(), 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.
03394 { 03395 struct iax2_peer *peer = NULL; 03396 struct iax2_user *user = NULL; 03397 static char *choices[] = { "all", NULL }; 03398 char *cmplt; 03399 03400 switch (cmd) { 03401 case CLI_INIT: 03402 e->command = "iax2 prune realtime"; 03403 e->usage = 03404 "Usage: iax2 prune realtime [<peername>|all]\n" 03405 " Prunes object(s) from the cache\n"; 03406 return NULL; 03407 case CLI_GENERATE: 03408 if (a->pos == 3) { 03409 cmplt = ast_cli_complete(a->word, choices, a->n); 03410 if (!cmplt) 03411 cmplt = complete_iax2_peers(a->line, a->word, a->pos, a->n - sizeof(choices), IAX_RTCACHEFRIENDS); 03412 return cmplt; 03413 } 03414 return NULL; 03415 } 03416 if (a->argc != 4) 03417 return CLI_SHOWUSAGE; 03418 if (!strcmp(a->argv[3], "all")) { 03419 prune_users(); 03420 prune_peers(); 03421 ast_cli(a->fd, "Cache flushed successfully.\n"); 03422 return CLI_SUCCESS; 03423 } 03424 peer = find_peer(a->argv[3], 0); 03425 user = find_user(a->argv[3]); 03426 if (peer || user) { 03427 if (peer) { 03428 if (ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 03429 ast_set_flag(peer, IAX_RTAUTOCLEAR); 03430 expire_registry(peer_ref(peer)); 03431 ast_cli(a->fd, "Peer %s was removed from the cache.\n", a->argv[3]); 03432 } else { 03433 ast_cli(a->fd, "Peer %s is not eligible for this operation.\n", a->argv[3]); 03434 } 03435 peer_unref(peer); 03436 } 03437 if (user) { 03438 if (ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 03439 ast_set_flag(user, IAX_RTAUTOCLEAR); 03440 ast_cli(a->fd, "User %s was removed from the cache.\n", a->argv[3]); 03441 } else { 03442 ast_cli(a->fd, "User %s is not eligible for this operation.\n", a->argv[3]); 03443 } 03444 ao2_unlink(users,user); 03445 user_unref(user); 03446 } 03447 } else { 03448 ast_cli(a->fd, "%s was not found in the cache.\n", a->argv[3]); 03449 } 03450 03451 return CLI_SUCCESS; 03452 }
| static char* handle_cli_iax2_reload | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 12978 of file chan_iax2.c.
References CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, reload_config(), and ast_cli_entry::usage.
12979 { 12980 switch (cmd) { 12981 case CLI_INIT: 12982 e->command = "iax2 reload"; 12983 e->usage = 12984 "Usage: iax2 reload\n" 12985 " Reloads IAX configuration from iax.conf\n"; 12986 return NULL; 12987 case CLI_GENERATE: 12988 return NULL; 12989 } 12990 12991 reload_config(); 12992 12993 return CLI_SUCCESS; 12994 }
| static char* handle_cli_iax2_set_debug | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6998 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.
06999 { 07000 switch (cmd) { 07001 case CLI_INIT: 07002 e->command = "iax2 set debug {on|off|peer}"; 07003 e->usage = 07004 "Usage: iax2 set debug {on|off|peer peername}\n" 07005 " Enables/Disables dumping of IAX packets for debugging purposes.\n"; 07006 return NULL; 07007 case CLI_GENERATE: 07008 if (a->pos == 4 && !strcasecmp(a->argv[3], "peer")) 07009 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 07010 return NULL; 07011 } 07012 07013 if (a->argc < e->args || a->argc > e->args + 1) 07014 return CLI_SHOWUSAGE; 07015 07016 if (!strcasecmp(a->argv[3], "peer")) { 07017 struct iax2_peer *peer; 07018 07019 if (a->argc != e->args + 1) 07020 return CLI_SHOWUSAGE; 07021 07022 peer = find_peer(a->argv[4], 1); 07023 07024 if (!peer) { 07025 ast_cli(a->fd, "IAX2 peer '%s' does not exist\n", a->argv[e->args-1]); 07026 return CLI_FAILURE; 07027 } 07028 07029 debugaddr.sin_addr = peer->addr.sin_addr; 07030 debugaddr.sin_port = peer->addr.sin_port; 07031 07032 ast_cli(a->fd, "IAX2 Debugging Enabled for IP: %s:%d\n", 07033 ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port)); 07034 07035 ao2_ref(peer, -1); 07036 } else if (!strncasecmp(a->argv[3], "on", 2)) { 07037 iaxdebug = 1; 07038 ast_cli(a->fd, "IAX2 Debugging Enabled\n"); 07039 } else { 07040 iaxdebug = 0; 07041 memset(&debugaddr, 0, sizeof(debugaddr)); 07042 ast_cli(a->fd, "IAX2 Debugging Disabled\n"); 07043 } 07044 return CLI_SUCCESS; 07045 }
| static char* handle_cli_iax2_set_debug_jb | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7073 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.
07074 { 07075 switch (cmd) { 07076 case CLI_INIT: 07077 e->command = "iax2 set debug jb {on|off}"; 07078 e->usage = 07079 "Usage: iax2 set debug jb {on|off}\n" 07080 " Enables/Disables jitterbuffer debugging information\n"; 07081 return NULL; 07082 case CLI_GENERATE: 07083 return NULL; 07084 } 07085 07086 if (a->argc != e->args) 07087 return CLI_SHOWUSAGE; 07088 07089 if (!strncasecmp(a->argv[e->args -1], "on", 2)) { 07090 jb_setoutput(jb_error_output, jb_warning_output, jb_debug_output); 07091 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Enabled\n"); 07092 } else { 07093 jb_setoutput(jb_error_output, jb_warning_output, NULL); 07094 ast_cli(a->fd, "IAX2 Jitterbuffer Debugging Disabled\n"); 07095 } 07096 return CLI_SUCCESS; 07097 }
| static char* handle_cli_iax2_set_debug_trunk | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 7047 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.
07048 { 07049 switch (cmd) { 07050 case CLI_INIT: 07051 e->command = "iax2 set debug trunk {on|off}"; 07052 e->usage = 07053 "Usage: iax2 set debug trunk {on|off}\n" 07054 " Enables/Disables debugging of IAX trunking\n"; 07055 return NULL; 07056 case CLI_GENERATE: 07057 return NULL; 07058 } 07059 07060 if (a->argc != e->args) 07061 return CLI_SHOWUSAGE; 07062 07063 if (!strncasecmp(a->argv[e->args - 1], "on", 2)) { 07064 iaxtrunkdebug = 1; 07065 ast_cli(a->fd, "IAX2 Trunk Debugging Enabled\n"); 07066 } else { 07067 iaxtrunkdebug = 0; 07068 ast_cli(a->fd, "IAX2 Trunk Debugging Disabled\n"); 07069 } 07070 return CLI_SUCCESS; 07071 }
| 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 3714 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.
03715 { 03716 int mtuv; 03717 03718 switch (cmd) { 03719 case CLI_INIT: 03720 e->command = "iax2 set mtu"; 03721 e->usage = 03722 "Usage: iax2 set mtu <value>\n" 03723 " Set the system-wide IAX IP mtu to <value> bytes net or\n" 03724 " zero to disable. Disabling means that the operating system\n" 03725 " must handle fragmentation of UDP packets when the IAX2 trunk\n" 03726 " packet exceeds the UDP payload size. This is substantially\n" 03727 " below the IP mtu. Try 1240 on ethernets. Must be 172 or\n" 03728 " greater for G.711 samples.\n"; 03729 return NULL; 03730 case CLI_GENERATE: 03731 return NULL; 03732 } 03733 03734 if (a->argc != 4) 03735 return CLI_SHOWUSAGE; 03736 if (strncasecmp(a->argv[3], "default", strlen(a->argv[3])) == 0) 03737 mtuv = MAX_TRUNK_MTU; 03738 else 03739 mtuv = atoi(a->argv[3]); 03740 03741 if (mtuv == 0) { 03742 ast_cli(a->fd, "Trunk MTU control disabled (mtu was %d)\n", global_max_trunk_mtu); 03743 global_max_trunk_mtu = 0; 03744 return CLI_SUCCESS; 03745 } 03746 if (mtuv < 172 || mtuv > 4000) { 03747 ast_cli(a->fd, "Trunk MTU must be between 172 and 4000\n"); 03748 return CLI_SHOWUSAGE; 03749 } 03750 ast_cli(a->fd, "Trunk MTU changed from %d to %d\n", global_max_trunk_mtu, mtuv); 03751 global_max_trunk_mtu = mtuv; 03752 return CLI_SUCCESS; 03753 }
| static char* handle_cli_iax2_show_cache | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3755 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.
03756 { 03757 struct iax2_dpcache *dp = NULL; 03758 char tmp[1024], *pc = NULL; 03759 int s, x, y; 03760 struct timeval now = ast_tvnow(); 03761 03762 switch (cmd) { 03763 case CLI_INIT: 03764 e->command = "iax2 show cache"; 03765 e->usage = 03766 "Usage: iax2 show cache\n" 03767 " Display currently cached IAX Dialplan results.\n"; 03768 return NULL; 03769 case CLI_GENERATE: 03770 return NULL; 03771 } 03772 03773 AST_LIST_LOCK(&dpcache); 03774 03775 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8.8s %s\n", "Peer/Context", "Exten", "Exp.", "Wait.", "Flags"); 03776 03777 AST_LIST_TRAVERSE(&dpcache, dp, cache_list) { 03778 s = dp->expiry.tv_sec - now.tv_sec; 03779 tmp[0] = '\0'; 03780 if (dp->flags & CACHE_FLAG_EXISTS) 03781 strncat(tmp, "EXISTS|", sizeof(tmp) - strlen(tmp) - 1); 03782 if (dp->flags & CACHE_FLAG_NONEXISTENT) 03783 strncat(tmp, "NONEXISTENT|", sizeof(tmp) - strlen(tmp) - 1); 03784 if (dp->flags & CACHE_FLAG_CANEXIST) 03785 strncat(tmp, "CANEXIST|", sizeof(tmp) - strlen(tmp) - 1); 03786 if (dp->flags & CACHE_FLAG_PENDING) 03787 strncat(tmp, "PENDING|", sizeof(tmp) - strlen(tmp) - 1); 03788 if (dp->flags & CACHE_FLAG_TIMEOUT) 03789 strncat(tmp, "TIMEOUT|", sizeof(tmp) - strlen(tmp) - 1); 03790 if (dp->flags & CACHE_FLAG_TRANSMITTED) 03791 strncat(tmp, "TRANSMITTED|", sizeof(tmp) - strlen(tmp) - 1); 03792 if (dp->flags & CACHE_FLAG_MATCHMORE) 03793 strncat(tmp, "MATCHMORE|", sizeof(tmp) - strlen(tmp) - 1); 03794 if (dp->flags & CACHE_FLAG_UNKNOWN) 03795 strncat(tmp, "UNKNOWN|", sizeof(tmp) - strlen(tmp) - 1); 03796 /* Trim trailing pipe */ 03797 if (!ast_strlen_zero(tmp)) { 03798 tmp[strlen(tmp) - 1] = '\0'; 03799 } else { 03800 ast_copy_string(tmp, "(none)", sizeof(tmp)); 03801 } 03802 y = 0; 03803 pc = strchr(dp->peercontext, '@'); 03804 if (!pc) { 03805 pc = dp->peercontext; 03806 } else { 03807 pc++; 03808 } 03809 for (x = 0; x < ARRAY_LEN(dp->waiters); x++) { 03810 if (dp->waiters[x] > -1) 03811 y++; 03812 } 03813 if (s > 0) { 03814 ast_cli(a->fd, "%-20.20s %-12.12s %-9d %-8d %s\n", pc, dp->exten, s, y, tmp); 03815 } else { 03816 ast_cli(a->fd, "%-20.20s %-12.12s %-9.9s %-8d %s\n", pc, dp->exten, "(expired)", y, tmp); 03817 } 03818 } 03819 03820 AST_LIST_UNLOCK(&dpcache); 03821 03822 return CLI_SUCCESS; 03823 }
| static char* handle_cli_iax2_show_callno_limits | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 2374 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.
02375 { 02376 struct ao2_iterator i; 02377 struct peercnt *peercnt; 02378 struct sockaddr_in sin; 02379 int found = 0; 02380 02381 switch (cmd) { 02382 case CLI_INIT: 02383 e->command = "iax2 show callnumber usage"; 02384 e->usage = 02385 "Usage: iax2 show callnumber usage <ip address (optional)>\n" 02386 " Shows current ip addresses which are consuming iax2 call numbers\n"; 02387 return NULL; 02388 case CLI_GENERATE: 02389 return NULL; 02390 case CLI_HANDLER: 02391 if (a->argc < 4 || a->argc > 5) 02392 return CLI_SHOWUSAGE; 02393 02394 ast_cli(a->fd, "%-15s %-12s %-12s\n", "Address", "Callno Usage", "Callno Limit"); 02395 i = ao2_iterator_init(peercnts, 0); 02396 while ((peercnt = ao2_iterator_next(&i))) { 02397 sin.sin_addr.s_addr = peercnt->addr; 02398 if (a->argc == 5 && (!strcasecmp(a->argv[4], ast_inet_ntoa(sin.sin_addr)))) { 02399 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02400 found = 1; 02401 break; 02402 } else { 02403 ast_cli(a->fd, "%-15s %-12d %-12d\n", ast_inet_ntoa(sin.sin_addr), peercnt->cur, peercnt->limit); 02404 } 02405 ao2_ref(peercnt, -1); 02406 } 02407 ao2_iterator_destroy(&i); 02408 02409 if (a->argc == 4) { 02410 ast_cli(a->fd, "\nNon-CallToken Validation Limit: %d\nNon-CallToken Validated: %d\n", global_maxcallno_nonval, total_nonval_callno_used); 02411 } else if (a->argc == 5 && !found) { 02412 ast_cli(a->fd, "No callnumber table entries for %s found\n", a->argv[4] ); 02413 } 02414 02415 return CLI_SUCCESS; 02416 default: 02417 return NULL; 02418 } 02419 }
| static char* handle_cli_iax2_show_channels | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6825 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, ast_channel::name, chan_iax2_pvt::owner, chan_iax2_pvt::remote_rr, S_OR, and ast_cli_entry::usage.
06826 { 06827 #define FORMAT2 "%-20.20s %-15.15s %-10.10s %-11.11s %-11.11s %-7.7s %-6.6s %-6.6s %s %s %9s\n" 06828 #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" 06829 #define FORMATB "%-20.20s %-15.15s %-10.10s %5.5d/%5.5d %5.5d/%5.5d [Native Bridged to ID=%5.5d]\n" 06830 int x; 06831 int numchans = 0; 06832 char first_message[10] = { 0, }; 06833 char last_message[10] = { 0, }; 06834 06835 switch (cmd) { 06836 case CLI_INIT: 06837 e->command = "iax2 show channels"; 06838 e->usage = 06839 "Usage: iax2 show channels\n" 06840 " Lists all currently active IAX channels.\n"; 06841 return NULL; 06842 case CLI_GENERATE: 06843 return NULL; 06844 } 06845 06846 if (a->argc != 3) 06847 return CLI_SHOWUSAGE; 06848 ast_cli(a->fd, FORMAT2, "Channel", "Peer", "Username", "ID (Lo/Rem)", "Seq (Tx/Rx)", "Lag", "Jitter", "JitBuf", "Format", "FirstMsg", "LastMsg"); 06849 for (x = 0; x < ARRAY_LEN(iaxs); x++) { 06850 ast_mutex_lock(&iaxsl[x]); 06851 if (iaxs[x]) { 06852 int lag, jitter, localdelay; 06853 jb_info jbinfo; 06854 if (ast_test_flag(iaxs[x], IAX_USEJITTERBUF)) { 06855 jb_getinfo(iaxs[x]->jb, &jbinfo); 06856 jitter = jbinfo.jitter; 06857 localdelay = jbinfo.current - jbinfo.min; 06858 } else { 06859 jitter = -1; 06860 localdelay = 0; 06861 } 06862 06863 iax_frame_subclass2str(iaxs[x]->first_iax_message & ~MARK_IAX_SUBCLASS_TX, first_message, sizeof(first_message)); 06864 iax_frame_subclass2str(iaxs[x]->last_iax_message & ~MARK_IAX_SUBCLASS_TX, last_message, sizeof(last_message)); 06865 lag = iaxs[x]->remote_rr.delay; 06866 ast_cli(a->fd, FORMAT, 06867 iaxs[x]->owner ? iaxs[x]->owner->name : "(None)", 06868 ast_inet_ntoa(iaxs[x]->addr.sin_addr), 06869 S_OR(iaxs[x]->username, "(None)"), 06870 iaxs[x]->callno, iaxs[x]->peercallno, 06871 iaxs[x]->oseqno, iaxs[x]->iseqno, 06872 lag, 06873 jitter, 06874 localdelay, 06875 ast_getformatname(iaxs[x]->voiceformat), 06876 (iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06877 first_message, 06878 (iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:", 06879 last_message); 06880 numchans++; 06881 } 06882 ast_mutex_unlock(&iaxsl[x]); 06883 } 06884 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 06885 return CLI_SUCCESS; 06886 #undef FORMAT 06887 #undef FORMAT2 06888 #undef FORMATB 06889 }
| static char* handle_cli_iax2_show_firmware | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6623 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.
06624 { 06625 struct iax_firmware *cur = NULL; 06626 06627 switch (cmd) { 06628 case CLI_INIT: 06629 e->command = "iax2 show firmware"; 06630 e->usage = 06631 "Usage: iax2 show firmware\n" 06632 " Lists all known IAX firmware images.\n"; 06633 return NULL; 06634 case CLI_GENERATE: 06635 return NULL; 06636 } 06637 06638 if (a->argc != 3 && a->argc != 4) 06639 return CLI_SHOWUSAGE; 06640 06641 ast_cli(a->fd, "%-15.15s %-15.15s %-15.15s\n", "Device", "Version", "Size"); 06642 AST_LIST_LOCK(&firmwares); 06643 AST_LIST_TRAVERSE(&firmwares, cur, list) { 06644 if ((a->argc == 3) || (!strcasecmp(a->argv[3], (char *) cur->fwh->devname))) { 06645 ast_cli(a->fd, "%-15.15s %-15d %-15d\n", cur->fwh->devname, 06646 ntohs(cur->fwh->version), (int)ntohl(cur->fwh->datalen)); 06647 } 06648 } 06649 AST_LIST_UNLOCK(&firmwares); 06650 06651 return CLI_SUCCESS; 06652 }
| static char* handle_cli_iax2_show_netstats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6975 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.
06976 { 06977 int numchans = 0; 06978 06979 switch (cmd) { 06980 case CLI_INIT: 06981 e->command = "iax2 show netstats"; 06982 e->usage = 06983 "Usage: iax2 show netstats\n" 06984 " Lists network status for all currently active IAX channels.\n"; 06985 return NULL; 06986 case CLI_GENERATE: 06987 return NULL; 06988 } 06989 if (a->argc != 3) 06990 return CLI_SHOWUSAGE; 06991 ast_cli(a->fd, " -------- LOCAL --------------------- -------- REMOTE --------------------\n"); 06992 ast_cli(a->fd, "Channel RTT Jit Del Lost %% Drop OOO Kpkts Jit Del Lost %% Drop OOO Kpkts FirstMsg LastMsg\n"); 06993 numchans = ast_cli_netstats(NULL, a->fd, 1); 06994 ast_cli(a->fd, "%d active IAX channel%s\n", numchans, (numchans != 1) ? "s" : ""); 06995 return CLI_SUCCESS; 06996 }
| 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 3568 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_str_alloca, ast_str_buffer(), 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::encmethods, encmethods_to_str(), iax2_peer::expire, ast_cli_args::fd, find_peer(), iax2_peer::ha, IAX_DYNAMIC, IAX_TRUNK, ast_cli_args::line, iax2_peer::mailbox, iax2_peer::maxcallno, ast_cli_args::n, iax2_peer::name, iax2_peer::parkinglot, peer_status(), peer_unref(), iax2_peer::pokefreqnotok, iax2_peer::pokefreqok, ast_cli_args::pos, iax2_peer::prefs, iax2_peer::secret, iax2_peer::smoothing, status, ast_cli_entry::usage, iax2_peer::username, and ast_cli_args::word.
03569 { 03570 char status[30]; 03571 char cbuf[256]; 03572 struct iax2_peer *peer; 03573 char codec_buf[512]; 03574 struct ast_str *encmethods = ast_str_alloca(256); 03575 int x = 0, codec = 0, load_realtime = 0; 03576 03577 switch (cmd) { 03578 case CLI_INIT: 03579 e->command = "iax2 show peer"; 03580 e->usage = 03581 "Usage: iax2 show peer <name>\n" 03582 " Display details on specific IAX peer\n"; 03583 return NULL; 03584 case CLI_GENERATE: 03585 if (a->pos == 3) 03586 return complete_iax2_peers(a->line, a->word, a->pos, a->n, 0); 03587 return NULL; 03588 } 03589 03590 if (a->argc < 4) 03591 return CLI_SHOWUSAGE; 03592 03593 load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? 1 : 0; 03594 03595 peer = find_peer(a->argv[3], load_realtime); 03596 if (peer) { 03597 encmethods_to_str(peer->encmethods, encmethods); 03598 ast_cli(a->fd, "\n\n"); 03599 ast_cli(a->fd, " * Name : %s\n", peer->name); 03600 ast_cli(a->fd, " Secret : %s\n", ast_strlen_zero(peer->secret) ? "<Not set>" : "<Set>"); 03601 ast_cli(a->fd, " Context : %s\n", peer->context); 03602 ast_cli(a->fd, " Parking lot : %s\n", peer->parkinglot); 03603 ast_cli(a->fd, " Mailbox : %s\n", peer->mailbox); 03604 ast_cli(a->fd, " Dynamic : %s\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No"); 03605 ast_cli(a->fd, " Callnum limit: %d\n", peer->maxcallno); 03606 ast_cli(a->fd, " Calltoken req: %s\n", (peer->calltoken_required == CALLTOKEN_YES) ? "Yes" : ((peer->calltoken_required == CALLTOKEN_AUTO) ? "Auto" : "No")); 03607 ast_cli(a->fd, " Trunk : %s\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No"); 03608 ast_cli(a->fd, " Encryption : %s\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 03609 ast_cli(a->fd, " Callerid : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>")); 03610 ast_cli(a->fd, " Expire : %d\n", peer->expire); 03611 ast_cli(a->fd, " ACL : %s\n", (peer->ha ? "Yes" : "No")); 03612 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)); 03613 ast_cli(a->fd, " Defaddr->IP : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port)); 03614 ast_cli(a->fd, " Username : %s\n", peer->username); 03615 ast_cli(a->fd, " Codecs : "); 03616 ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability); 03617 ast_cli(a->fd, "%s\n", codec_buf); 03618 03619 ast_cli(a->fd, " Codec Order : ("); 03620 for(x = 0; x < 32 ; x++) { 03621 codec = ast_codec_pref_index(&peer->prefs,x); 03622 if(!codec) 03623 break; 03624 ast_cli(a->fd, "%s", ast_getformatname(codec)); 03625 if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1)) 03626 ast_cli(a->fd, "|"); 03627 } 03628 03629 if (!x) 03630 ast_cli(a->fd, "none"); 03631 ast_cli(a->fd, ")\n"); 03632 03633 ast_cli(a->fd, " Status : "); 03634 peer_status(peer, status, sizeof(status)); 03635 ast_cli(a->fd, "%s\n",status); 03636 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"); 03637 ast_cli(a->fd, "\n"); 03638 peer_unref(peer); 03639 } else { 03640 ast_cli(a->fd, "Peer %s not found.\n", a->argv[3]); 03641 ast_cli(a->fd, "\n"); 03642 } 03643 03644 return CLI_SUCCESS; 03645 }
| static char* handle_cli_iax2_show_peers | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6591 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.
06592 { 06593 switch (cmd) { 06594 case CLI_INIT: 06595 e->command = "iax2 show peers"; 06596 e->usage = 06597 "Usage: iax2 show peers [registered] [like <pattern>]\n" 06598 " Lists all known IAX2 peers.\n" 06599 " Optional 'registered' argument lists only peers with known addresses.\n" 06600 " Optional regular expression pattern is used to filter the peer list.\n"; 06601 return NULL; 06602 case CLI_GENERATE: 06603 return NULL; 06604 } 06605 06606 switch (__iax2_show_peers(0, a->fd, NULL, a->argc, a->argv)) { 06607 case RESULT_SHOWUSAGE: 06608 return CLI_SHOWUSAGE; 06609 case RESULT_FAILURE: 06610 return CLI_FAILURE; 06611 default: 06612 return CLI_SUCCESS; 06613 } 06614 }
| static char* handle_cli_iax2_show_registry | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6735 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.
06736 { 06737 #define FORMAT2 "%-20.20s %-6.6s %-10.10s %-20.20s %8.8s %s\n" 06738 #define FORMAT "%-20.20s %-6.6s %-10.10s %-20.20s %8d %s\n" 06739 struct iax2_registry *reg = NULL; 06740 char host[80]; 06741 char perceived[80]; 06742 int counter = 0; 06743 06744 switch (cmd) { 06745 case CLI_INIT: 06746 e->command = "iax2 show registry"; 06747 e->usage = 06748 "Usage: iax2 show registry\n" 06749 " Lists all registration requests and status.\n"; 06750 return NULL; 06751 case CLI_GENERATE: 06752 return NULL; 06753 } 06754 if (a->argc != 3) 06755 return CLI_SHOWUSAGE; 06756 ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Perceived", "Refresh", "State"); 06757 AST_LIST_LOCK(®istrations); 06758 AST_LIST_TRAVERSE(®istrations, reg, entry) { 06759 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 06760 if (reg->us.sin_addr.s_addr) 06761 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06762 else 06763 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 06764 ast_cli(a->fd, FORMAT, host, 06765 (reg->dnsmgr) ? "Y" : "N", 06766 reg->username, perceived, reg->refresh, regstate2str(reg->regstate)); 06767 counter++; 06768 } 06769 AST_LIST_UNLOCK(®istrations); 06770 ast_cli(a->fd, "%d IAX2 registrations.\n", counter); 06771 return CLI_SUCCESS; 06772 #undef FORMAT 06773 #undef FORMAT2 06774 }
| static char* handle_cli_iax2_show_stats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3670 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.
03671 { 03672 struct iax_frame *cur; 03673 int cnt = 0, dead = 0, final = 0; 03674 03675 switch (cmd) { 03676 case CLI_INIT: 03677 e->command = "iax2 show stats"; 03678 e->usage = 03679 "Usage: iax2 show stats\n" 03680 " Display statistics on IAX channel driver.\n"; 03681 return NULL; 03682 case CLI_GENERATE: 03683 return NULL; 03684 } 03685 03686 if (a->argc != 3) 03687 return CLI_SHOWUSAGE; 03688 03689 AST_LIST_LOCK(&frame_queue); 03690 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 03691 if (cur->retries < 0) 03692 dead++; 03693 if (cur->final) 03694 final++; 03695 cnt++; 03696 } 03697 AST_LIST_UNLOCK(&frame_queue); 03698 03699 ast_cli(a->fd, " IAX Statistics\n"); 03700 ast_cli(a->fd, "---------------------\n"); 03701 ast_cli(a->fd, "Outstanding frames: %d (%d ingress, %d egress)\n", iax_get_frames(), iax_get_iframes(), iax_get_oframes()); 03702 ast_cli(a->fd, "%d timed and %d untimed transmits; MTU %d/%d/%d\n", trunk_timed, trunk_untimed, 03703 trunk_maxmtu, trunk_nmaxmtu, global_max_trunk_mtu); 03704 ast_cli(a->fd, "Packets in transmit queue: %d dead, %d final, %d total\n\n", dead, final, cnt); 03705 03706 trunk_timed = trunk_untimed = 0; 03707 if (trunk_maxmtu > trunk_nmaxmtu) 03708 trunk_nmaxmtu = trunk_maxmtu; 03709 03710 return CLI_SUCCESS; 03711 }
| static char* handle_cli_iax2_show_threads | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6454 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.
06455 { 06456 struct iax2_thread *thread = NULL; 06457 time_t t; 06458 int threadcount = 0, dynamiccount = 0; 06459 char type; 06460 06461 switch (cmd) { 06462 case CLI_INIT: 06463 e->command = "iax2 show threads"; 06464 e->usage = 06465 "Usage: iax2 show threads\n" 06466 " Lists status of IAX helper threads\n"; 06467 return NULL; 06468 case CLI_GENERATE: 06469 return NULL; 06470 } 06471 if (a->argc != 3) 06472 return CLI_SHOWUSAGE; 06473 06474 ast_cli(a->fd, "IAX2 Thread Information\n"); 06475 time(&t); 06476 ast_cli(a->fd, "Idle Threads:\n"); 06477 AST_LIST_LOCK(&idle_list); 06478 AST_LIST_TRAVERSE(&idle_list, thread, list) { 06479 #ifdef DEBUG_SCHED_MULTITHREAD 06480 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06481 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06482 #else 06483 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06484 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06485 #endif 06486 threadcount++; 06487 } 06488 AST_LIST_UNLOCK(&idle_list); 06489 ast_cli(a->fd, "Active Threads:\n"); 06490 AST_LIST_LOCK(&active_list); 06491 AST_LIST_TRAVERSE(&active_list, thread, list) { 06492 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) 06493 type = 'D'; 06494 else 06495 type = 'P'; 06496 #ifdef DEBUG_SCHED_MULTITHREAD 06497 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d, func='%s'\n", 06498 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06499 #else 06500 ast_cli(a->fd, "Thread %c%d: state=%d, update=%d, actions=%d\n", 06501 type, thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06502 #endif 06503 threadcount++; 06504 } 06505 AST_LIST_UNLOCK(&active_list); 06506 ast_cli(a->fd, "Dynamic Threads:\n"); 06507 AST_LIST_LOCK(&dynamic_list); 06508 AST_LIST_TRAVERSE(&dynamic_list, thread, list) { 06509 #ifdef DEBUG_SCHED_MULTITHREAD 06510 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d, func='%s'\n", 06511 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions, thread->curfunc); 06512 #else 06513 ast_cli(a->fd, "Thread %d: state=%d, update=%d, actions=%d\n", 06514 thread->threadnum, thread->iostate, (int)(t - thread->checktime), thread->actions); 06515 #endif 06516 dynamiccount++; 06517 } 06518 AST_LIST_UNLOCK(&dynamic_list); 06519 ast_cli(a->fd, "%d of %d threads accounted for with %d dynamic threads\n", threadcount, iaxthreadcount, dynamiccount); 06520 return CLI_SUCCESS; 06521 }
| static char* handle_cli_iax2_show_users | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6250 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().
06251 { 06252 regex_t regexbuf; 06253 int havepattern = 0; 06254 06255 #define FORMAT "%-15.15s %-20.20s %-15.15s %-15.15s %-5.5s %-5.10s\n" 06256 #define FORMAT2 "%-15.15s %-20.20s %-15.15d %-15.15s %-5.5s %-5.10s\n" 06257 06258 struct iax2_user *user = NULL; 06259 char auth[90]; 06260 char *pstr = ""; 06261 struct ao2_iterator i; 06262 06263 switch (cmd) { 06264 case CLI_INIT: 06265 e->command = "iax2 show users [like]"; 06266 e->usage = 06267 "Usage: iax2 show users [like <pattern>]\n" 06268 " Lists all known IAX2 users.\n" 06269 " Optional regular expression pattern is used to filter the user list.\n"; 06270 return NULL; 06271 case CLI_GENERATE: 06272 return NULL; 06273 } 06274 06275 switch (a->argc) { 06276 case 5: 06277 if (!strcasecmp(a->argv[3], "like")) { 06278 if (regcomp(®exbuf, a->argv[4], REG_EXTENDED | REG_NOSUB)) 06279 return CLI_SHOWUSAGE; 06280 havepattern = 1; 06281 } else 06282 return CLI_SHOWUSAGE; 06283 case 3: 06284 break; 06285 default: 06286 return CLI_SHOWUSAGE; 06287 } 06288 06289 ast_cli(a->fd, FORMAT, "Username", "Secret", "Authen", "Def.Context", "A/C","Codec Pref"); 06290 i = ao2_iterator_init(users, 0); 06291 for (user = ao2_iterator_next(&i); user; 06292 user_unref(user), user = ao2_iterator_next(&i)) { 06293 if (havepattern && regexec(®exbuf, user->name, 0, NULL, 0)) 06294 continue; 06295 06296 if (!ast_strlen_zero(user->secret)) { 06297 ast_copy_string(auth,user->secret, sizeof(auth)); 06298 } else if (!ast_strlen_zero(user->inkeys)) { 06299 snprintf(auth, sizeof(auth), "Key: %-15.15s ", user->inkeys); 06300 } else 06301 ast_copy_string(auth, "-no secret-", sizeof(auth)); 06302 06303 if(ast_test_flag(user,IAX_CODEC_NOCAP)) 06304 pstr = "REQ Only"; 06305 else if(ast_test_flag(user,IAX_CODEC_NOPREFS)) 06306 pstr = "Disabled"; 06307 else 06308 pstr = ast_test_flag(user,IAX_CODEC_USER_FIRST) ? "Caller" : "Host"; 06309 06310 ast_cli(a->fd, FORMAT2, user->name, auth, user->authmethods, 06311 user->contexts ? user->contexts->context : DEFAULT_CONTEXT, 06312 user->ha ? "Yes" : "No", pstr); 06313 } 06314 ao2_iterator_destroy(&i); 06315 06316 if (havepattern) 06317 regfree(®exbuf); 06318 06319 return CLI_SUCCESS; 06320 #undef FORMAT 06321 #undef FORMAT2 06322 }
| static char* handle_cli_iax2_test_losspct | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 3454 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.
03455 { 03456 switch (cmd) { 03457 case CLI_INIT: 03458 e->command = "iax2 test losspct"; 03459 e->usage = 03460 "Usage: iax2 test losspct <percentage>\n" 03461 " For testing, throws away <percentage> percent of incoming packets\n"; 03462 return NULL; 03463 case CLI_GENERATE: 03464 return NULL; 03465 } 03466 if (a->argc != 4) 03467 return CLI_SHOWUSAGE; 03468 03469 test_losspct = atoi(a->argv[3]); 03470 03471 return CLI_SUCCESS; 03472 }
| static char* handle_cli_iax2_unregister | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 6523 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.
06524 { 06525 struct iax2_peer *p; 06526 06527 switch (cmd) { 06528 case CLI_INIT: 06529 e->command = "iax2 unregister"; 06530 e->usage = 06531 "Usage: iax2 unregister <peername>\n" 06532 " Unregister (force expiration) an IAX2 peer from the registry.\n"; 06533 return NULL; 06534 case CLI_GENERATE: 06535 return complete_iax2_unregister(a->line, a->word, a->pos, a->n); 06536 } 06537 06538 if (a->argc != 3) 06539 return CLI_SHOWUSAGE; 06540 06541 p = find_peer(a->argv[2], 1); 06542 if (p) { 06543 if (p->expire > 0) { 06544 struct iax2_peer tmp_peer = { 06545 .name = a->argv[2], 06546 }; 06547 struct iax2_peer *peer; 06548 06549 peer = ao2_find(peers, &tmp_peer, OBJ_POINTER); 06550 if (peer) { 06551 expire_registry(peer_ref(peer)); /* will release its own reference when done */ 06552 peer_unref(peer); /* ref from ao2_find() */ 06553 ast_cli(a->fd, "Peer %s unregistered\n", a->argv[2]); 06554 } else { 06555 ast_cli(a->fd, "Peer %s not found\n", a->argv[2]); 06556 } 06557 } else { 06558 ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]); 06559 } 06560 } else { 06561 ast_cli(a->fd, "Peer unknown: %s. Not unregistered\n", a->argv[2]); 06562 } 06563 return CLI_SUCCESS; 06564 }
| static void handle_deferred_full_frames | ( | struct iax2_thread * | thread | ) | [static] |
Handle any deferred full frames for this thread.
Definition at line 9124 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().
09125 { 09126 struct iax2_pkt_buf *pkt_buf; 09127 09128 ast_mutex_lock(&thread->lock); 09129 09130 while ((pkt_buf = AST_LIST_REMOVE_HEAD(&thread->full_frames, entry))) { 09131 ast_mutex_unlock(&thread->lock); 09132 09133 thread->buf = pkt_buf->buf; 09134 thread->buf_len = pkt_buf->len; 09135 thread->buf_size = pkt_buf->len + 1; 09136 09137 socket_process(thread); 09138 09139 thread->buf = NULL; 09140 ast_free(pkt_buf); 09141 09142 ast_mutex_lock(&thread->lock); 09143 } 09144 09145 ast_mutex_unlock(&thread->lock); 09146 }
| static int handle_error | ( | void | ) | [static] |
Definition at line 3117 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().
03118 { 03119 /* XXX Ideally we should figure out why an error occurred and then abort those 03120 rather than continuing to try. Unfortunately, the published interface does 03121 not seem to work XXX */ 03122 #if 0 03123 struct sockaddr_in *sin; 03124 int res; 03125 struct msghdr m; 03126 struct sock_extended_err e; 03127 m.msg_name = NULL; 03128 m.msg_namelen = 0; 03129 m.msg_iov = NULL; 03130 m.msg_control = &e; 03131 m.msg_controllen = sizeof(e); 03132 m.msg_flags = 0; 03133 res = recvmsg(netsocket, &m, MSG_ERRQUEUE); 03134 if (res < 0) 03135 ast_log(LOG_WARNING, "Error detected, but unable to read error: %s\n", strerror(errno)); 03136 else { 03137 if (m.msg_controllen) { 03138 sin = (struct sockaddr_in *)SO_EE_OFFENDER(&e); 03139 if (sin) 03140 ast_log(LOG_WARNING, "Receive error from %s\n", ast_inet_ntoa(sin->sin_addr)); 03141 else 03142 ast_log(LOG_WARNING, "No address detected??\n"); 03143 } else { 03144 ast_log(LOG_WARNING, "Local error: %s\n", strerror(e.ee_errno)); 03145 } 03146 } 03147 #endif 03148 return 0; 03149 }
| static int iax2_ack_registry | ( | struct iax_ies * | ies, | |
| struct sockaddr_in * | sin, | |||
| int | callno | |||
| ) | [static] |
Acknowledgment received for OUR registration.
Definition at line 8091 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().
08092 { 08093 struct iax2_registry *reg; 08094 /* Start pessimistic */ 08095 char peer[256] = ""; 08096 char msgstatus[60]; 08097 int refresh = 60; 08098 char ourip[256] = "<Unspecified>"; 08099 struct sockaddr_in oldus; 08100 struct sockaddr_in us; 08101 int oldmsgs; 08102 08103 memset(&us, 0, sizeof(us)); 08104 if (ies->apparent_addr) 08105 memmove(&us, ies->apparent_addr, sizeof(us)); 08106 if (ies->username) 08107 ast_copy_string(peer, ies->username, sizeof(peer)); 08108 if (ies->refresh) 08109 refresh = ies->refresh; 08110 if (ies->calling_number) { 08111 /* We don't do anything with it really, but maybe we should */ 08112 } 08113 reg = iaxs[callno]->reg; 08114 if (!reg) { 08115 ast_log(LOG_WARNING, "Registry acknowledge on unknown registry '%s'\n", peer); 08116 return -1; 08117 } 08118 memcpy(&oldus, ®->us, sizeof(oldus)); 08119 oldmsgs = reg->messages; 08120 if (inaddrcmp(®->addr, sin)) { 08121 ast_log(LOG_WARNING, "Received unsolicited registry ack from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08122 return -1; 08123 } 08124 memcpy(®->us, &us, sizeof(reg->us)); 08125 if (ies->msgcount >= 0) 08126 reg->messages = ies->msgcount & 0xffff; /* only low 16 bits are used in the transmission of the IE */ 08127 /* always refresh the registration at the interval requested by the server 08128 we are registering to 08129 */ 08130 reg->refresh = refresh; 08131 reg->expire = iax2_sched_replace(reg->expire, sched, 08132 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 08133 if (inaddrcmp(&oldus, ®->us) || (reg->messages != oldmsgs)) { 08134 if (reg->messages > 255) 08135 snprintf(msgstatus, sizeof(msgstatus), " with %d new and %d old messages waiting", reg->messages & 0xff, reg->messages >> 8); 08136 else if (reg->messages > 1) 08137 snprintf(msgstatus, sizeof(msgstatus), " with %d new messages waiting\n", reg->messages); 08138 else if (reg->messages > 0) 08139 ast_copy_string(msgstatus, " with 1 new message waiting\n", sizeof(msgstatus)); 08140 else 08141 ast_copy_string(msgstatus, " with no messages waiting\n", sizeof(msgstatus)); 08142 snprintf(ourip, sizeof(ourip), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 08143 ast_verb(3, "Registered IAX2 to '%s', who sees us as %s%s\n", ast_inet_ntoa(sin->sin_addr), ourip, msgstatus); 08144 manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: IAX2\r\nDomain: %s\r\nStatus: Registered\r\n", ast_inet_ntoa(sin->sin_addr)); 08145 } 08146 reg->regstate = REG_STATE_REGISTERED; 08147 return 0; 08148 }
| static int attribute_pure iax2_allow_new | ( | int | frametype, | |
| int | subclass, | |||
| int | inbound | |||
| ) | [inline, static] |
Definition at line 2557 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().
02558 { 02559 if (frametype != AST_FRAME_IAX) { 02560 return 0; 02561 } 02562 switch (subclass) { 02563 case IAX_COMMAND_NEW: 02564 case IAX_COMMAND_REGREQ: 02565 case IAX_COMMAND_FWDOWNL: 02566 case IAX_COMMAND_REGREL: 02567 return 1; 02568 case IAX_COMMAND_POKE: 02569 if (!inbound) { 02570 return 1; 02571 } 02572 break; 02573 } 02574 return 0; 02575 }
| 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 1192 of file chan_iax2.c.
References chan_iax2_pvt::callno, EVENT_FLAG_SYSTEM, manager_event, ast_channel::name, chan_iax2_pvt::owner, chan_iax2_pvt::peer, and chan_iax2_pvt::peercallno.
Referenced by ast_iax2_new(), and iax2_answer().
01193 { 01194 manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", 01195 "Channel: %s\r\nChanneltype: IAX2\r\nIAX2-callno-local: %d\r\nIAX2-callno-remote: %d\r\nIAX2-peer: %s\r\n", 01196 pvt->owner ? pvt->owner->name : "", 01197 pvt->callno, pvt->peercallno, pvt->peer ? pvt->peer : ""); 01198 }
| static int iax2_answer | ( | struct ast_channel * | c | ) | [static] |
Definition at line 5325 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.
05326 { 05327 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05328 ast_debug(1, "Answering IAX2 call\n"); 05329 ast_mutex_lock(&iaxsl[callno]); 05330 if (iaxs[callno]) 05331 iax2_ami_channelupdate(iaxs[callno]); 05332 ast_mutex_unlock(&iaxsl[callno]); 05333 return send_command_locked(callno, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); 05334 }
| static int iax2_append_register | ( | const char * | hostname, | |
| const char * | username, | |||
| const char * | secret, | |||
| const char * | porta | |||
| ) | [static] |
Definition at line 8150 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().
08152 { 08153 struct iax2_registry *reg; 08154 08155 if (!(reg = ast_calloc(1, sizeof(*reg)))) 08156 return -1; 08157 08158 if (ast_dnsmgr_lookup(hostname, ®->addr, ®->dnsmgr, srvlookup ? "_iax._udp" : NULL) < 0) { 08159 ast_free(reg); 08160 return -1; 08161 } 08162 08163 ast_copy_string(reg->username, username, sizeof(reg->username)); 08164 08165 if (secret) 08166 ast_copy_string(reg->secret, secret, sizeof(reg->secret)); 08167 08168 reg->expire = -1; 08169 reg->refresh = IAX_DEFAULT_REG_EXPIRE; 08170 reg->addr.sin_family = AF_INET; 08171 reg->addr.sin_port = porta ? htons(atoi(porta)) : htons(IAX_DEFAULT_PORTNO); 08172 08173 AST_LIST_LOCK(®istrations); 08174 AST_LIST_INSERT_HEAD(®istrations, reg, entry); 08175 AST_LIST_UNLOCK(®istrations); 08176 08177 return 0; 08178 }
| 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 5170 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, buf1, 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().
05171 { 05172 struct ast_channel *cs[3]; 05173 struct ast_channel *who, *other; 05174 int to = -1; 05175 int res = -1; 05176 int transferstarted=0; 05177 struct ast_frame *f; 05178 unsigned short callno0 = PTR_TO_CALLNO(c0->tech_pvt); 05179 unsigned short callno1 = PTR_TO_CALLNO(c1->tech_pvt); 05180 struct timeval waittimer = {0, 0}; 05181 05182 /* We currently do not support native bridging if a timeoutms value has been provided */ 05183 if (timeoutms > 0) { 05184 return AST_BRIDGE_FAILED; 05185 } 05186 05187 timeoutms = -1; 05188 05189 lock_both(callno0, callno1); 05190 if (!iaxs[callno0] || !iaxs[callno1]) { 05191 unlock_both(callno0, callno1); 05192 return AST_BRIDGE_FAILED; 05193 } 05194 /* Put them in native bridge mode */ 05195 if (!(flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))) { 05196 iaxs[callno0]->bridgecallno = callno1; 05197 iaxs[callno1]->bridgecallno = callno0; 05198 } 05199 unlock_both(callno0, callno1); 05200 05201 /* If not, try to bridge until we can execute a transfer, if we can */ 05202 cs[0] = c0; 05203 cs[1] = c1; 05204 for (/* ever */;;) { 05205 /* Check in case we got masqueraded into */ 05206 if ((c0->tech != &iax2_tech) || (c1->tech != &iax2_tech)) { 05207 ast_verb(3, "Can't masquerade, we're different...\n"); 05208 /* Remove from native mode */ 05209 if (c0->tech == &iax2_tech) { 05210 ast_mutex_lock(&iaxsl[callno0]); 05211 iaxs[callno0]->bridgecallno = 0; 05212 ast_mutex_unlock(&iaxsl[callno0]); 05213 } 05214 if (c1->tech == &iax2_tech) { 05215 ast_mutex_lock(&iaxsl[callno1]); 05216 iaxs[callno1]->bridgecallno = 0; 05217 ast_mutex_unlock(&iaxsl[callno1]); 05218 } 05219 return AST_BRIDGE_FAILED_NOWARN; 05220 } 05221 if (c0->nativeformats != c1->nativeformats) { 05222 char buf0[255]; 05223 char buf1[255]; 05224 ast_getformatname_multiple(buf0, sizeof(buf0) -1, c0->nativeformats); 05225 ast_getformatname_multiple(buf1, sizeof(buf1) -1, c1->nativeformats); 05226 ast_verb(3, "Operating with different codecs %d[%s] %d[%s] , can't native bridge...\n", c0->nativeformats, buf0, c1->nativeformats, buf1); 05227 /* Remove from native mode */ 05228 lock_both(callno0, callno1); 05229 if (iaxs[callno0]) 05230 iaxs[callno0]->bridgecallno = 0; 05231 if (iaxs[callno1]) 05232 iaxs[callno1]->bridgecallno = 0; 05233 unlock_both(callno0, callno1); 05234 return AST_BRIDGE_FAILED_NOWARN; 05235 } 05236 /* check if transfered and if we really want native bridging */ 05237 if (!transferstarted && !ast_test_flag(iaxs[callno0], IAX_NOTRANSFER) && !ast_test_flag(iaxs[callno1], IAX_NOTRANSFER)) { 05238 /* Try the transfer */ 05239 if (iax2_start_transfer(callno0, callno1, (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) || 05240 ast_test_flag(iaxs[callno0], IAX_TRANSFERMEDIA) | ast_test_flag(iaxs[callno1], IAX_TRANSFERMEDIA))) 05241 ast_log(LOG_WARNING, "Unable to start the transfer\n"); 05242 transferstarted = 1; 05243 } 05244 if ((iaxs[callno0]->transferring == TRANSFER_RELEASED) && (iaxs[callno1]->transferring == TRANSFER_RELEASED)) { 05245 /* Call has been transferred. We're no longer involved */ 05246 struct timeval now = ast_tvnow(); 05247 if (ast_tvzero(waittimer)) { 05248 waittimer = now; 05249 } else if (now.tv_sec - waittimer.tv_sec > IAX_LINGER_TIMEOUT) { 05250 c0->_softhangup |= AST_SOFTHANGUP_DEV; 05251 c1->_softhangup |= AST_SOFTHANGUP_DEV; 05252 *fo = NULL; 05253 *rc = c0; 05254 res = AST_BRIDGE_COMPLETE; 05255 break; 05256 } 05257 } 05258 to = 1000; 05259 who = ast_waitfor_n(cs, 2, &to); 05260 if (timeoutms > -1) { 05261 timeoutms -= (1000 - to); 05262 if (timeoutms < 0) 05263 timeoutms = 0; 05264 } 05265 if (!who) { 05266 if (!timeoutms) { 05267 res = AST_BRIDGE_RETRY; 05268 break; 05269 } 05270 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 05271 res = AST_BRIDGE_FAILED; 05272 break; 05273 } 05274 continue; 05275 } 05276 f = ast_read(who); 05277 if (!f) { 05278 *fo = NULL; 05279 *rc = who; 05280 res = AST_BRIDGE_COMPLETE; 05281 break; 05282 } 05283 if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS) && (f->subclass != AST_CONTROL_SRCUPDATE)) { 05284 *fo = f; 05285 *rc = who; 05286 res = AST_BRIDGE_COMPLETE; 05287 break; 05288 } 05289 other = (who == c0) ? c1 : c0; /* the 'other' channel */ 05290 if ((f->frametype == AST_FRAME_VOICE) || 05291 (f->frametype == AST_FRAME_TEXT) || 05292 (f->frametype == AST_FRAME_VIDEO) || 05293 (f->frametype == AST_FRAME_IMAGE) || 05294 (f->frametype == AST_FRAME_DTMF) || 05295 (f->frametype == AST_FRAME_CONTROL)) { 05296 /* monitored dtmf take out of the bridge. 05297 * check if we monitor the specific source. 05298 */ 05299 int monitored_source = (who == c0) ? AST_BRIDGE_DTMF_CHANNEL_0 : AST_BRIDGE_DTMF_CHANNEL_1; 05300 if (f->frametype == AST_FRAME_DTMF && (flags & monitored_source)) { 05301 *rc = who; 05302 *fo = f; 05303 res = AST_BRIDGE_COMPLETE; 05304 /* Remove from native mode */ 05305 break; 05306 } 05307 /* everything else goes to the other side */ 05308 ast_write(other, f); 05309 } 05310 ast_frfree(f); 05311 /* Swap who gets priority */ 05312 cs[2] = cs[0]; 05313 cs[0] = cs[1]; 05314 cs[1] = cs[2]; 05315 } 05316 lock_both(callno0, callno1); 05317 if(iaxs[callno0]) 05318 iaxs[callno0]->bridgecallno = 0; 05319 if(iaxs[callno1]) 05320 iaxs[callno1]->bridgecallno = 0; 05321 unlock_both(callno0, callno1); 05322 return res; 05323 }
| static int iax2_call | ( | struct ast_channel * | c, | |
| char * | dest, | |||
| int | timeout | |||
| ) | [static] |
Definition at line 4777 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_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_FORCE_ENCRYPT, IAX_IE_ADSICPE, iax_ie_append(), iax_ie_append_byte(), iax_ie_append_int(), iax_ie_append_raw(), iax_ie_append_short(), iax_ie_append_str(), IAX_IE_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, ast_channel::language, LOG_WARNING, chan_iax2_pvt::maxtime, create_addr_info::mohinterpret, create_addr_info::mohsuggest, ast_channel::name, ast_channel::nativeformats, parsed_dial_string::options, create_addr_info::outkey, parse_dial_string(), parsed_dial_string::password, pbx_builtin_getvar_helper(), parsed_dial_string::peer, create_addr_info::peercontext, chan_iax2_pvt::pingtime, 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.
04778 { 04779 struct sockaddr_in sin; 04780 char *l=NULL, *n=NULL, *tmpstr; 04781 struct iax_ie_data ied; 04782 char *defaultrdest = "s"; 04783 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04784 struct parsed_dial_string pds; 04785 struct create_addr_info cai; 04786 struct ast_var_t *var; 04787 struct ast_datastore *variablestore = ast_channel_datastore_find(c, &iax2_variable_datastore_info, NULL); 04788 const char* osp_token_ptr; 04789 unsigned int osp_token_length; 04790 unsigned char osp_block_index; 04791 unsigned int osp_block_length; 04792 unsigned char osp_buffer[256]; 04793 04794 if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) { 04795 ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name); 04796 return -1; 04797 } 04798 04799 memset(&cai, 0, sizeof(cai)); 04800 cai.encmethods = iax2_encryption; 04801 04802 memset(&pds, 0, sizeof(pds)); 04803 tmpstr = ast_strdupa(dest); 04804 parse_dial_string(tmpstr, &pds); 04805 04806 if (ast_strlen_zero(pds.peer)) { 04807 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", dest); 04808 return -1; 04809 } 04810 if (!pds.exten) { 04811 pds.exten = defaultrdest; 04812 } 04813 if (create_addr(pds.peer, c, &sin, &cai)) { 04814 ast_log(LOG_WARNING, "No address associated with '%s'\n", pds.peer); 04815 return -1; 04816 } 04817 if (ast_strlen_zero(cai.secret) && ast_test_flag(iaxs[callno], IAX_FORCE_ENCRYPT)) { 04818 ast_log(LOG_WARNING, "Call terminated. No secret given and force encrypt enabled\n"); 04819 return -1; 04820 } 04821 if (!pds.username && !ast_strlen_zero(cai.username)) 04822 pds.username = cai.username; 04823 if (!pds.password && !ast_strlen_zero(cai.secret)) 04824 pds.password = cai.secret; 04825 if (!pds.key && !ast_strlen_zero(cai.outkey)) 04826 pds.key = cai.outkey; 04827 if (!pds.context && !ast_strlen_zero(cai.peercontext)) 04828 pds.context = cai.peercontext; 04829 04830 /* Keep track of the context for outgoing calls too */ 04831 ast_copy_string(c->context, cai.context, sizeof(c->context)); 04832 04833 if (pds.port) 04834 sin.sin_port = htons(atoi(pds.port)); 04835 04836 l = c->cid.cid_num; 04837 n = c->cid.cid_name; 04838 04839 /* Now build request */ 04840 memset(&ied, 0, sizeof(ied)); 04841 04842 /* On new call, first IE MUST be IAX version of caller */ 04843 iax_ie_append_short(&ied, IAX_IE_VERSION, IAX_PROTO_VERSION); 04844 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, pds.exten); 04845 if (pds.options && strchr(pds.options, 'a')) { 04846 /* Request auto answer */ 04847 iax_ie_append(&ied, IAX_IE_AUTOANSWER); 04848 } 04849 04850 iax_ie_append_str(&ied, IAX_IE_CODEC_PREFS, cai.prefs); 04851 04852 if (l) { 04853 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, l); 04854 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04855 } else { 04856 if (n) 04857 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, c->cid.cid_pres); 04858 else 04859 iax_ie_append_byte(&ied, IAX_IE_CALLINGPRES, AST_PRES_NUMBER_NOT_AVAILABLE); 04860 } 04861 04862 iax_ie_append_byte(&ied, IAX_IE_CALLINGTON, c->cid.cid_ton); 04863 iax_ie_append_short(&ied, IAX_IE_CALLINGTNS, c->cid.cid_tns); 04864 04865 if (n) 04866 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, n); 04867 if (ast_test_flag(iaxs[callno], IAX_SENDANI) && c->cid.cid_ani) 04868 iax_ie_append_str(&ied, IAX_IE_CALLING_ANI, c->cid.cid_ani); 04869 04870 if (!ast_strlen_zero(c->language)) 04871 iax_ie_append_str(&ied, IAX_IE_LANGUAGE, c->language); 04872 if (!ast_strlen_zero(c->cid.cid_dnid)) 04873 iax_ie_append_str(&ied, IAX_IE_DNID, c->cid.cid_dnid); 04874 if (!ast_strlen_zero(c->cid.cid_rdnis)) 04875 iax_ie_append_str(&ied, IAX_IE_RDNIS, c->cid.cid_rdnis); 04876 04877 if (pds.context) 04878 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, pds.context); 04879 04880 if (pds.username) 04881 iax_ie_append_str(&ied, IAX_IE_USERNAME, pds.username); 04882 04883 if (cai.encmethods) 04884 iax_ie_append_short(&ied, IAX_IE_ENCRYPTION, cai.encmethods); 04885 04886 ast_mutex_lock(&iaxsl[callno]); 04887 04888 if (!ast_strlen_zero(c->context)) 04889 ast_string_field_set(iaxs[callno], context, c->context); 04890 04891 if (pds.username) 04892 ast_string_field_set(iaxs[callno], username, pds.username); 04893 04894 iaxs[callno]->encmethods = cai.encmethods; 04895 04896 iaxs[callno]->adsi = cai.adsi; 04897 04898 ast_string_field_set(iaxs[callno], mohinterpret, cai.mohinterpret); 04899 ast_string_field_set(iaxs[callno], mohsuggest, cai.mohsuggest); 04900 04901 if (pds.key) 04902 ast_string_field_set(iaxs[callno], outkey, pds.key); 04903 if (pds.password) 04904 ast_string_field_set(iaxs[callno], secret, pds.password); 04905 04906 iax_ie_append_int(&ied, IAX_IE_FORMAT, c->nativeformats); 04907 iax_ie_append_int(&ied, IAX_IE_CAPABILITY, iaxs[callno]->capability); 04908 iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe); 04909 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(cai.timezone)); 04910 04911 if (iaxs[callno]->maxtime) { 04912 /* Initialize pingtime and auto-congest time */ 04913 iaxs[callno]->pingtime = iaxs[callno]->maxtime / 2; 04914 iaxs[callno]->initid = iax2_sched_add(sched, iaxs[callno]->maxtime * 2, auto_congest, CALLNO_TO_PTR(callno)); 04915 } else if (autokill) { 04916 iaxs[callno]->pingtime = autokill / 2; 04917 iaxs[callno]->initid = iax2_sched_add(sched, autokill * 2, auto_congest, CALLNO_TO_PTR(callno)); 04918 } 04919 04920 /* Check if there is an OSP token */ 04921 osp_token_ptr = pbx_builtin_getvar_helper(c, "IAX2OSPTOKEN"); 04922 if (!ast_strlen_zero(osp_token_ptr)) { 04923 if ((osp_token_length = strlen(osp_token_ptr)) <= IAX_MAX_OSPTOKEN_SIZE) { 04924 osp_block_index = 0; 04925 while (osp_token_length > 0) { 04926 osp_block_length = IAX_MAX_OSPBLOCK_SIZE < osp_token_length ? IAX_MAX_OSPBLOCK_SIZE : osp_token_length; 04927 osp_buffer[0] = osp_block_index; 04928 memcpy(osp_buffer + 1, osp_token_ptr, osp_block_length); 04929 iax_ie_append_raw(&ied, IAX_IE_OSPTOKEN, osp_buffer, osp_block_length + 1); 04930 osp_block_index++; 04931 osp_token_ptr += osp_block_length; 04932 osp_token_length -= osp_block_length; 04933 } 04934 } else 04935 ast_log(LOG_WARNING, "OSP token is too long\n"); 04936 } else if (iaxdebug) 04937 ast_debug(1, "OSP token is undefined\n"); 04938 04939 /* send the command using the appropriate socket for this peer */ 04940 iaxs[callno]->sockfd = cai.sockfd; 04941 04942 /* Add remote vars */ 04943 if (variablestore) { 04944 AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data; 04945 ast_debug(1, "Found an IAX variable store on this channel\n"); 04946 AST_LIST_LOCK(variablelist); 04947 AST_LIST_TRAVERSE(variablelist, var, entries) { 04948 char tmp[256]; 04949 int i; 04950 ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var)); 04951 /* Automatically divide the value up into sized chunks */ 04952 for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) { 04953 snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i); 04954 iax_ie_append_str(&ied, IAX_IE_VARIABLE, tmp); 04955 } 04956 } 04957 AST_LIST_UNLOCK(variablelist); 04958 } 04959 04960 /* Transmit the string in a "NEW" request */ 04961 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 04962 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); 04963 04964 ast_mutex_unlock(&iaxsl[callno]); 04965 ast_setstate(c, AST_STATE_RINGING); 04966 04967 return 0; 04968 }
| 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 13227 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.
13228 { 13229 int res = 0; 13230 struct iax2_dpcache *dp = NULL; 13231 #if 0 13232 ast_log(LOG_NOTICE, "iax2_canmatch: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13233 #endif 13234 if ((priority != 1) && (priority != 2)) 13235 return 0; 13236 13237 AST_LIST_LOCK(&dpcache); 13238 if ((dp = find_cache(chan, data, context, exten, priority))) { 13239 if (dp->flags & CACHE_FLAG_CANEXIST) 13240 res = 1; 13241 } else { 13242 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13243 } 13244 AST_LIST_UNLOCK(&dpcache); 13245 13246 return res; 13247 }
| static unsigned int iax2_datetime | ( | const char * | tz | ) | [static] |
Definition at line 4448 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().
04449 { 04450 struct timeval t = ast_tvnow(); 04451 struct ast_tm tm; 04452 unsigned int tmp; 04453 ast_localtime(&t, &tm, ast_strlen_zero(tz) ? NULL : tz); 04454 tmp = (tm.tm_sec >> 1) & 0x1f; /* 5 bits of seconds */ 04455 tmp |= (tm.tm_min & 0x3f) << 5; /* 6 bits of minutes */ 04456 tmp |= (tm.tm_hour & 0x1f) << 11; /* 5 bits of hours */ 04457 tmp |= (tm.tm_mday & 0x1f) << 16; /* 5 bits of day of month */ 04458 tmp |= ((tm.tm_mon + 1) & 0xf) << 21; /* 4 bits of month */ 04459 tmp |= ((tm.tm_year - 100) & 0x7f) << 25; /* 7 bits of year */ 04460 return tmp; 04461 }
| static void iax2_destroy | ( | int | callno | ) | [static] |
Definition at line 3223 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().
03224 { 03225 struct chan_iax2_pvt *pvt = NULL; 03226 struct ast_channel *owner = NULL; 03227 03228 retry: 03229 if ((pvt = iaxs[callno])) { 03230 iax2_destroy_helper(pvt); 03231 } 03232 03233 owner = pvt ? pvt->owner : NULL; 03234 03235 if (owner) { 03236 if (ast_channel_trylock(owner)) { 03237 ast_debug(3, "Avoiding IAX destroy deadlock\n"); 03238 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 03239 goto retry; 03240 } 03241 } 03242 03243 if (!owner) { 03244 iaxs[callno] = NULL; 03245 } 03246 03247 if (pvt) { 03248 if (!owner) { 03249 pvt->owner = NULL; 03250 } else { 03251 /* If there's an owner, prod it to give up */ 03252 /* It is ok to use ast_queue_hangup() here instead of iax2_queue_hangup() 03253 * because we already hold the owner channel lock. */ 03254 ast_queue_hangup(owner); 03255 } 03256 03257 if (pvt->peercallno) { 03258 remove_by_peercallno(pvt); 03259 } 03260 03261 if (pvt->transfercallno) { 03262 remove_by_transfercallno(pvt); 03263 } 03264 03265 if (!owner) { 03266 ao2_ref(pvt, -1); 03267 pvt = NULL; 03268 } 03269 } 03270 03271 if (owner) { 03272 ast_channel_unlock(owner); 03273 } 03274 03275 if (callno & 0x4000) { 03276 update_max_trunk(); 03277 } 03278 }
| static void iax2_destroy_helper | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1623 of file chan_iax2.c.
References ao2_find, ast_atomic_fetchadd_int(), ast_clear_flag, AST_SCHED_DEL_SPINLOCK, ast_sched_thread_del, ast_sched_thread_get_context(), 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().
01624 { 01625 /* Decrement AUTHREQ count if needed */ 01626 if (ast_test_flag(pvt, IAX_MAXAUTHREQ)) { 01627 struct iax2_user *user; 01628 struct iax2_user tmp_user = { 01629 .name = pvt->username, 01630 }; 01631 01632 user = ao2_find(users, &tmp_user, OBJ_POINTER); 01633 if (user) { 01634 ast_atomic_fetchadd_int(&user->curauthreq, -1); 01635 user_unref(user); 01636 } 01637 01638 ast_clear_flag(pvt, IAX_MAXAUTHREQ); 01639 } 01640 /* No more pings or lagrq's */ 01641 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->pingid, &iaxsl[pvt->callno]); 01642 AST_SCHED_DEL_SPINLOCK(ast_sched_thread_get_context(sched), pvt->lagid, &iaxsl[pvt->callno]); 01643 ast_sched_thread_del(sched, pvt->autoid); 01644 ast_sched_thread_del(sched, pvt->authid); 01645 ast_sched_thread_del(sched, pvt->initid); 01646 ast_sched_thread_del(sched, pvt->jbid); 01647 ast_sched_thread_del(sched, pvt->keyrotateid); 01648 }
| static int iax2_devicestate | ( | void * | data | ) | [static] |
Part of the device state notification system ---.
Definition at line 13430 of file chan_iax2.c.
References iax2_peer::addr, ast_debug, AST_DEVICE_INVALID, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_log(), 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().
13431 { 13432 struct parsed_dial_string pds; 13433 char *tmp = ast_strdupa(data); 13434 struct iax2_peer *p; 13435 int res = AST_DEVICE_INVALID; 13436 13437 memset(&pds, 0, sizeof(pds)); 13438 parse_dial_string(tmp, &pds); 13439 13440 if (ast_strlen_zero(pds.peer)) { 13441 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 13442 return res; 13443 } 13444 13445 ast_debug(3, "Checking device state for device %s\n", pds.peer); 13446 13447 /* SLD: FIXME: second call to find_peer during registration */ 13448 if (!(p = find_peer(pds.peer, 1))) 13449 return res; 13450 13451 res = AST_DEVICE_UNAVAILABLE; 13452 ast_debug(3, "iax2_devicestate: Found peer. What's device state of %s? addr=%d, defaddr=%d maxms=%d, lastms=%d\n", 13453 pds.peer, p->addr.sin_addr.s_addr, p->defaddr.sin_addr.s_addr, p->maxms, p->lastms); 13454 13455 if ((p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) && 13456 (!p->maxms || ((p->lastms > -1) && (p->historicms <= p->maxms)))) { 13457 /* Peer is registered, or have default IP address 13458 and a valid registration */ 13459 if (p->historicms == 0 || p->historicms <= p->maxms) 13460 /* let the core figure out whether it is in use or not */ 13461 res = AST_DEVICE_UNKNOWN; 13462 } 13463 13464 peer_unref(p); 13465 13466 return res; 13467 }
| static int iax2_digit_begin | ( | struct ast_channel * | c, | |
| char | digit | |||
| ) | [static] |
Definition at line 4072 of file chan_iax2.c.
References AST_FRAME_DTMF_BEGIN, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04073 { 04074 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_BEGIN, digit, 0, NULL, 0, -1); 04075 }
| static int iax2_digit_end | ( | struct ast_channel * | c, | |
| char | digit, | |||
| unsigned int | duration | |||
| ) | [static] |
Definition at line 4077 of file chan_iax2.c.
References AST_FRAME_DTMF_END, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04078 { 04079 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_DTMF_END, digit, 0, NULL, 0, -1); 04080 }
| static int iax2_do_register | ( | struct iax2_registry * | reg | ) | [static] |
Definition at line 11265 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().
11266 { 11267 struct iax_ie_data ied; 11268 if (iaxdebug) 11269 ast_debug(1, "Sending registration request for '%s'\n", reg->username); 11270 11271 if (reg->dnsmgr && 11272 ((reg->regstate == REG_STATE_TIMEOUT) || !reg->addr.sin_addr.s_addr)) { 11273 /* Maybe the IP has changed, force DNS refresh */ 11274 ast_dnsmgr_refresh(reg->dnsmgr); 11275 } 11276 11277 /* 11278 * if IP has Changed, free allocated call to create a new one with new IP 11279 * call has the pointer to IP and must be updated to the new one 11280 */ 11281 if (reg->dnsmgr && ast_dnsmgr_changed(reg->dnsmgr) && (reg->callno > 0)) { 11282 int callno = reg->callno; 11283 ast_mutex_lock(&iaxsl[callno]); 11284 iax2_destroy(callno); 11285 ast_mutex_unlock(&iaxsl[callno]); 11286 reg->callno = 0; 11287 } 11288 if (!reg->addr.sin_addr.s_addr) { 11289 if (iaxdebug) 11290 ast_debug(1, "Unable to send registration request for '%s' without IP address\n", reg->username); 11291 /* Setup the next registration attempt */ 11292 reg->expire = iax2_sched_replace(reg->expire, sched, 11293 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11294 return -1; 11295 } 11296 11297 if (!reg->callno) { 11298 ast_debug(3, "Allocate call number\n"); 11299 reg->callno = find_callno_locked(0, 0, ®->addr, NEW_FORCE, defaultsockfd, 0); 11300 if (reg->callno < 1) { 11301 ast_log(LOG_WARNING, "Unable to create call for registration\n"); 11302 return -1; 11303 } else 11304 ast_debug(3, "Registration created on call %d\n", reg->callno); 11305 iaxs[reg->callno]->reg = reg; 11306 ast_mutex_unlock(&iaxsl[reg->callno]); 11307 } 11308 /* Setup the next registration a little early */ 11309 reg->expire = iax2_sched_replace(reg->expire, sched, 11310 (5 * reg->refresh / 6) * 1000, iax2_do_register_s, reg); 11311 /* Send the request */ 11312 memset(&ied, 0, sizeof(ied)); 11313 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 11314 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 11315 add_empty_calltoken_ie(iaxs[reg->callno], &ied); /* this _MUST_ be the last ie added */ 11316 send_command(iaxs[reg->callno],AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 11317 reg->regstate = REG_STATE_REGSENT; 11318 return 0; 11319 }
| static int iax2_do_register_s | ( | const void * | data | ) | [static] |
Definition at line 7935 of file chan_iax2.c.
References __iax2_do_register_s(), and schedule_action.
Referenced by iax2_ack_registry(), and iax2_do_register().
07936 { 07937 #ifdef SCHED_MULTITHREADED 07938 if (schedule_action(__iax2_do_register_s, data)) 07939 #endif 07940 __iax2_do_register_s(data); 07941 return 0; 07942 }
| static void iax2_dprequest | ( | struct iax2_dpcache * | dp, | |
| int | callno | |||
| ) | [static] |
Definition at line 8685 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().
08686 { 08687 struct iax_ie_data ied; 08688 /* Auto-hangup with 30 seconds of inactivity */ 08689 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 08690 sched, 30000, auto_hangup, (void *)(long)callno); 08691 memset(&ied, 0, sizeof(ied)); 08692 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, dp->exten); 08693 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); 08694 dp->flags |= CACHE_FLAG_TRANSMITTED; 08695 }
| static void * iax2_dup_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1207 of file chan_iax2.c.
References ast_calloc, AST_LIST_HEAD, AST_LIST_HEAD_INIT, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_var_assign(), ast_var_name(), ast_var_value(), ast_var_t::entries, and LOG_ERROR.
01208 { 01209 AST_LIST_HEAD(, ast_var_t) *oldlist = old, *newlist; 01210 struct ast_var_t *oldvar, *newvar; 01211 01212 newlist = ast_calloc(sizeof(*newlist), 1); 01213 if (!newlist) { 01214 ast_log(LOG_ERROR, "Unable to duplicate iax2 variables\n"); 01215 return NULL; 01216 } 01217 01218 AST_LIST_HEAD_INIT(newlist); 01219 AST_LIST_LOCK(oldlist); 01220 AST_LIST_TRAVERSE(oldlist, oldvar, entries) { 01221 newvar = ast_var_assign(ast_var_name(oldvar), ast_var_value(oldvar)); 01222 if (newvar) 01223 AST_LIST_INSERT_TAIL(newlist, newvar, entries); 01224 else 01225 ast_log(LOG_ERROR, "Unable to duplicate iax2 variable '%s'\n", ast_var_name(oldvar)); 01226 } 01227 AST_LIST_UNLOCK(oldlist); 01228 return newlist; 01229 }
| 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 13273 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().
13274 { 13275 char odata[256]; 13276 char req[256]; 13277 char *ncontext; 13278 struct iax2_dpcache *dp = NULL; 13279 struct ast_app *dial = NULL; 13280 #if 0 13281 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); 13282 #endif 13283 if (priority == 2) { 13284 /* Indicate status, can be overridden in dialplan */ 13285 const char *dialstatus = pbx_builtin_getvar_helper(chan, "DIALSTATUS"); 13286 if (dialstatus) { 13287 dial = pbx_findapp(dialstatus); 13288 if (dial) 13289 pbx_exec(chan, dial, ""); 13290 } 13291 return -1; 13292 } else if (priority != 1) 13293 return -1; 13294 13295 AST_LIST_LOCK(&dpcache); 13296 if ((dp = find_cache(chan, data, context, exten, priority))) { 13297 if (dp->flags & CACHE_FLAG_EXISTS) { 13298 ast_copy_string(odata, data, sizeof(odata)); 13299 ncontext = strchr(odata, '/'); 13300 if (ncontext) { 13301 *ncontext = '\0'; 13302 ncontext++; 13303 snprintf(req, sizeof(req), "IAX2/%s/%s@%s", odata, exten, ncontext); 13304 } else { 13305 snprintf(req, sizeof(req), "IAX2/%s/%s", odata, exten); 13306 } 13307 ast_verb(3, "Executing Dial('%s')\n", req); 13308 } else { 13309 AST_LIST_UNLOCK(&dpcache); 13310 ast_log(LOG_WARNING, "Can't execute nonexistent extension '%s[@%s]' in data '%s'\n", exten, context, data); 13311 return -1; 13312 } 13313 } 13314 AST_LIST_UNLOCK(&dpcache); 13315 13316 if ((dial = pbx_findapp("Dial"))) 13317 return pbx_exec(chan, dial, req); 13318 else 13319 ast_log(LOG_WARNING, "No dial application registered\n"); 13320 13321 return -1; 13322 }
| 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 13204 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.
13205 { 13206 int res = 0; 13207 struct iax2_dpcache *dp = NULL; 13208 #if 0 13209 ast_log(LOG_NOTICE, "iax2_exists: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13210 #endif 13211 if ((priority != 1) && (priority != 2)) 13212 return 0; 13213 13214 AST_LIST_LOCK(&dpcache); 13215 if ((dp = find_cache(chan, data, context, exten, priority))) { 13216 if (dp->flags & CACHE_FLAG_EXISTS) 13217 res = 1; 13218 } else { 13219 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13220 } 13221 AST_LIST_UNLOCK(&dpcache); 13222 13223 return res; 13224 }
| static int iax2_fixup | ( | struct ast_channel * | oldchannel, | |
| struct ast_channel * | newchan | |||
| ) | [static] |
Definition at line 4099 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.
04100 { 04101 unsigned short callno = PTR_TO_CALLNO(newchan->tech_pvt); 04102 ast_mutex_lock(&iaxsl[callno]); 04103 if (iaxs[callno]) 04104 iaxs[callno]->owner = newchan; 04105 else 04106 ast_log(LOG_WARNING, "Uh, this isn't a good sign...\n"); 04107 ast_mutex_unlock(&iaxsl[callno]); 04108 return 0; 04109 }
| static void iax2_frame_free | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 1650 of file chan_iax2.c.
References ast_sched_thread_del, iax_frame_free(), and iax_frame::retrans.
Referenced by __attempt_transmit(), __do_deliver(), __get_from_jb(), complete_transfer(), pvt_destructor(), resend_with_token(), and schedule_delivery().
01651 { 01652 ast_sched_thread_del(sched, fr->retrans); 01653 iax_frame_free(fr); 01654 }
| static void iax2_free_variable_datastore | ( | void * | old | ) | [static] |
Definition at line 1231 of file chan_iax2.c.
References ast_free, AST_LIST_HEAD, AST_LIST_HEAD_DESTROY, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and ast_var_t::entries.
01232 { 01233 AST_LIST_HEAD(, ast_var_t) *oldlist = old; 01234 struct ast_var_t *oldvar; 01235 01236 AST_LIST_LOCK(oldlist); 01237 while ((oldvar = AST_LIST_REMOVE_HEAD(oldlist, entries))) { 01238 ast_free(oldvar); 01239 } 01240 AST_LIST_UNLOCK(oldlist); 01241 AST_LIST_HEAD_DESTROY(oldlist); 01242 ast_free(oldlist); 01243 }
| static int iax2_getpeername | ( | struct sockaddr_in | sin, | |
| char * | host, | |||
| int | len | |||
| ) | [static] |
Definition at line 1590 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().
01591 { 01592 struct iax2_peer *peer = NULL; 01593 int res = 0; 01594 struct ao2_iterator i; 01595 01596 i = ao2_iterator_init(peers, 0); 01597 while ((peer = ao2_iterator_next(&i))) { 01598 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 01599 (peer->addr.sin_port == sin.sin_port)) { 01600 ast_copy_string(host, peer->name, len); 01601 peer_unref(peer); 01602 res = 1; 01603 break; 01604 } 01605 peer_unref(peer); 01606 } 01607 ao2_iterator_destroy(&i); 01608 01609 if (!peer) { 01610 peer = realtime_peer(NULL, &sin); 01611 if (peer) { 01612 ast_copy_string(host, peer->name, len); 01613 peer_unref(peer); 01614 res = 1; 01615 } 01616 } 01617 01618 return res; 01619 }
| static int iax2_getpeertrunk | ( | struct sockaddr_in | sin | ) | [static] |
Definition at line 5393 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().
05394 { 05395 struct iax2_peer *peer; 05396 int res = 0; 05397 struct ao2_iterator i; 05398 05399 i = ao2_iterator_init(peers, 0); 05400 while ((peer = ao2_iterator_next(&i))) { 05401 if ((peer->addr.sin_addr.s_addr == sin.sin_addr.s_addr) && 05402 (peer->addr.sin_port == sin.sin_port)) { 05403 res = ast_test_flag(peer, IAX_TRUNK); 05404 peer_unref(peer); 05405 break; 05406 } 05407 peer_unref(peer); 05408 } 05409 ao2_iterator_destroy(&i); 05410 05411 return res; 05412 }
| static int iax2_hangup | ( | struct ast_channel * | c | ) | [static] |
Definition at line 4970 of file chan_iax2.c.
References ast_debug, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_thread_add(), ast_test_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, ast_channel::name, iax_ie_data::pos, PTR_TO_CALLNO, scheduled_destroy(), send_command_final(), and ast_channel::tech_pvt.
04971 { 04972 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 04973 struct iax_ie_data ied; 04974 int alreadygone; 04975 memset(&ied, 0, sizeof(ied)); 04976 ast_mutex_lock(&iaxsl[callno]); 04977 if (callno && iaxs[callno]) { 04978 ast_debug(1, "We're hanging up %s now...\n", c->name); 04979 alreadygone = ast_test_flag(iaxs[callno], IAX_ALREADYGONE); 04980 /* Send the hangup unless we have had a transmission error or are already gone */ 04981 iax_ie_append_byte(&ied, IAX_IE_CAUSECODE, (unsigned char)c->hangupcause); 04982 if (!iaxs[callno]->error && !alreadygone) { 04983 if (send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1)) { 04984 ast_log(LOG_WARNING, "No final packet could be sent for callno %d\n", callno); 04985 } 04986 if (!iaxs[callno]) { 04987 ast_mutex_unlock(&iaxsl[callno]); 04988 return 0; 04989 } 04990 } 04991 /* Explicitly predestroy it */ 04992 iax2_predestroy(callno); 04993 /* If we were already gone to begin with, destroy us now */ 04994 if (iaxs[callno] && alreadygone) { 04995 ast_debug(1, "Really destroying %s now...\n", c->name); 04996 iax2_destroy(callno); 04997 } else if (iaxs[callno]) { 04998 if (ast_sched_thread_add(sched, 10000, scheduled_destroy, CALLNO_TO_PTR(callno)) < 0) { 04999 ast_log(LOG_ERROR, "Unable to schedule iax2 callno %d destruction?!! Destroying immediately.\n", callno); 05000 iax2_destroy(callno); 05001 } 05002 } 05003 } else if (c->tech_pvt) { 05004 /* If this call no longer exists, but the channel still 05005 * references it we need to set the channel's tech_pvt to null 05006 * to avoid ast_channel_free() trying to free it. 05007 */ 05008 c->tech_pvt = NULL; 05009 } 05010 ast_mutex_unlock(&iaxsl[callno]); 05011 ast_verb(3, "Hungup '%s'\n", c->name); 05012 return 0; 05013 }
| static int iax2_indicate | ( | struct ast_channel * | c, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) | [static] |
Definition at line 5336 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().
05337 { 05338 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05339 struct chan_iax2_pvt *pvt; 05340 int res = 0; 05341 05342 if (iaxdebug) 05343 ast_debug(1, "Indicating condition %d\n", condition); 05344 05345 ast_mutex_lock(&iaxsl[callno]); 05346 pvt = iaxs[callno]; 05347 05348 if (wait_for_peercallno(pvt)) { 05349 res = -1; 05350 goto done; 05351 } 05352 05353 switch (condition) { 05354 case AST_CONTROL_HOLD: 05355 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05356 ast_moh_start(c, data, pvt->mohinterpret); 05357 goto done; 05358 } 05359 break; 05360 case AST_CONTROL_UNHOLD: 05361 if (strcasecmp(pvt->mohinterpret, "passthrough")) { 05362 ast_moh_stop(c); 05363 goto done; 05364 } 05365 } 05366 05367 res = send_command(pvt, AST_FRAME_CONTROL, condition, 0, data, datalen, -1); 05368 05369 done: 05370 ast_mutex_unlock(&iaxsl[callno]); 05371 05372 return res; 05373 }
| static int iax2_key_rotate | ( | const void * | vpvt | ) | [static] |
Definition at line 5088 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), ast_sched_thread_add(), iax_ie_data::buf, build_ecx_key(), chan_iax2_pvt::callno, IAX_COMMAND_RTKEY, IAX_DEBUGDIGEST, iax_ie_append_raw(), IAX_IE_CHALLENGE, chan_iax2_pvt::keyrotateid, MD5Final(), MD5Init(), MD5Update(), iax_ie_data::pos, and send_command().
Referenced by iax2_send().
05089 { 05090 int res = 0; 05091 struct chan_iax2_pvt *pvt = (void *) vpvt; 05092 struct MD5Context md5; 05093 char key[17] = ""; 05094 struct iax_ie_data ied = { 05095 .pos = 0, 05096 }; 05097 05098 ast_mutex_lock(&iaxsl[pvt->callno]); 05099 pvt->keyrotateid = 05100 ast_sched_thread_add(sched, 120000 + (ast_random() % 180001), iax2_key_rotate, vpvt); 05101 05102 snprintf(key, sizeof(key), "%lX", ast_random()); 05103 05104 MD5Init(&md5); 05105 MD5Update(&md5, (unsigned char *) key, strlen(key)); 05106 MD5Final((unsigned char *) key, &md5); 05107 05108 IAX_DEBUGDIGEST("Sending", key); 05109 05110 iax_ie_append_raw(&ied, IAX_IE_CHALLENGE, key, 16); 05111 05112 res = send_command(pvt, AST_FRAME_IAX, IAX_COMMAND_RTKEY, 0, ied.buf, ied.pos, -1); 05113 05114 build_ecx_key((unsigned char *) key, pvt); 05115 05116 ast_mutex_unlock(&iaxsl[pvt->callno]); 05117 05118 return res; 05119 }
| 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 13250 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.
13251 { 13252 int res = 0; 13253 struct iax2_dpcache *dp = NULL; 13254 #if 0 13255 ast_log(LOG_NOTICE, "iax2_matchmore: con: %s, exten: %s, pri: %d, cid: %s, data: %s\n", context, exten, priority, callerid ? callerid : "<unknown>", data); 13256 #endif 13257 if ((priority != 1) && (priority != 2)) 13258 return 0; 13259 13260 AST_LIST_LOCK(&dpcache); 13261 if ((dp = find_cache(chan, data, context, exten, priority))) { 13262 if (dp->flags & CACHE_FLAG_MATCHMORE) 13263 res = 1; 13264 } else { 13265 ast_log(LOG_WARNING, "Unable to make DP cache\n"); 13266 } 13267 AST_LIST_UNLOCK(&dpcache); 13268 13269 return res; 13270 }
| static int iax2_poke_noanswer | ( | const void * | data | ) | [static] |
Definition at line 11464 of file chan_iax2.c.
References __iax2_poke_noanswer(), peer_unref(), iax2_peer::pokeexpire, and schedule_action.
Referenced by iax2_poke_peer().
11465 { 11466 struct iax2_peer *peer = (struct iax2_peer *)data; 11467 peer->pokeexpire = -1; 11468 #ifdef SCHED_MULTITHREADED 11469 if (schedule_action(__iax2_poke_noanswer, data)) 11470 #endif 11471 __iax2_poke_noanswer(data); 11472 peer_unref(peer); 11473 return 0; 11474 }
| static int iax2_poke_peer | ( | struct iax2_peer * | peer, | |
| int | heldcall | |||
| ) | [static] |
Definition at line 11485 of file chan_iax2.c.
References add_empty_calltoken_ie(), iax2_peer::addr, AST_FRAME_IAX, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_thread_del, 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().
11486 { 11487 int callno; 11488 if (!peer->maxms || (!peer->addr.sin_addr.s_addr && !peer->dnsmgr)) { 11489 /* IF we have no IP without dnsmgr, or this isn't to be monitored, return 11490 immediately after clearing things out */ 11491 peer->lastms = 0; 11492 peer->historicms = 0; 11493 peer->pokeexpire = -1; 11494 peer->callno = 0; 11495 return 0; 11496 } 11497 11498 /* The peer could change the callno inside iax2_destroy, since we do deadlock avoidance */ 11499 if ((callno = peer->callno) > 0) { 11500 ast_log(LOG_NOTICE, "Still have a callno...\n"); 11501 ast_mutex_lock(&iaxsl[callno]); 11502 iax2_destroy(callno); 11503 ast_mutex_unlock(&iaxsl[callno]); 11504 } 11505 if (heldcall) 11506 ast_mutex_unlock(&iaxsl[heldcall]); 11507 callno = peer->callno = find_callno(0, 0, &peer->addr, NEW_FORCE, peer->sockfd, 0); 11508 if (heldcall) 11509 ast_mutex_lock(&iaxsl[heldcall]); 11510 if (peer->callno < 1) { 11511 ast_log(LOG_WARNING, "Unable to allocate call for poking peer '%s'\n", peer->name); 11512 return -1; 11513 } 11514 11515 /* Speed up retransmission times for this qualify call */ 11516 iaxs[peer->callno]->pingtime = peer->maxms / 4 + 1; 11517 iaxs[peer->callno]->peerpoke = peer; 11518 11519 if (peer->pokeexpire > -1) { 11520 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 11521 peer->pokeexpire = -1; 11522 peer_unref(peer); 11523 } 11524 } 11525 11526 /* Queue up a new task to handle no reply */ 11527 /* If the host is already unreachable then use the unreachable interval instead */ 11528 if (peer->lastms < 0) 11529 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_noanswer, peer_ref(peer)); 11530 else 11531 peer->pokeexpire = iax2_sched_add(sched, DEFAULT_MAXMS * 2, iax2_poke_noanswer, peer_ref(peer)); 11532 11533 if (peer->pokeexpire == -1) 11534 peer_unref(peer); 11535 11536 /* And send the poke */ 11537 ast_mutex_lock(&iaxsl[callno]); 11538 if (iaxs[callno]) { 11539 struct iax_ie_data ied = { 11540 .buf = { 0 }, 11541 .pos = 0, 11542 }; 11543 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 11544 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_POKE, 0, ied.buf, ied.pos, -1); 11545 } 11546 ast_mutex_unlock(&iaxsl[callno]); 11547 11548 return 0; 11549 }
| static int iax2_poke_peer_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 11476 of file chan_iax2.c.
References iax2_poke_peer().
Referenced by load_module().
11477 { 11478 struct iax2_peer *peer = obj; 11479 11480 iax2_poke_peer(peer, 0); 11481 11482 return 0; 11483 }
| static int iax2_poke_peer_s | ( | const void * | data | ) | [static] |
Definition at line 8725 of file chan_iax2.c.
References __iax2_poke_peer_s(), iax2_peer::pokeexpire, and schedule_action.
Referenced by __iax2_poke_noanswer(), and socket_process().
08726 { 08727 struct iax2_peer *peer = (struct iax2_peer *)data; 08728 peer->pokeexpire = -1; 08729 #ifdef SCHED_MULTITHREADED 08730 if (schedule_action(__iax2_poke_peer_s, data)) 08731 #endif 08732 __iax2_poke_peer_s(data); 08733 return 0; 08734 }
| static int iax2_predestroy | ( | int | callno | ) | [static] |
Definition at line 3200 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().
03201 { 03202 struct ast_channel *c = NULL; 03203 struct chan_iax2_pvt *pvt = iaxs[callno]; 03204 03205 if (!pvt) 03206 return -1; 03207 03208 if (!ast_test_flag(pvt, IAX_ALREADYGONE)) { 03209 iax2_destroy_helper(pvt); 03210 ast_set_flag(pvt, IAX_ALREADYGONE); 03211 } 03212 03213 if ((c = pvt->owner)) { 03214 c->tech_pvt = NULL; 03215 iax2_queue_hangup(callno); 03216 pvt->owner = NULL; 03217 ast_module_unref(ast_module_info->self); 03218 } 03219 03220 return 0; 03221 }
| static void * iax2_process_thread | ( | void * | data | ) | [static] |
Definition at line 11136 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().
11137 { 11138 struct iax2_thread *thread = data; 11139 struct timeval wait; 11140 struct timespec ts; 11141 int put_into_idle = 0; 11142 int first_time = 1; 11143 11144 ast_atomic_fetchadd_int(&iaxactivethreadcount,1); 11145 pthread_cleanup_push(iax2_process_thread_cleanup, data); 11146 for(;;) { 11147 /* Wait for something to signal us to be awake */ 11148 ast_mutex_lock(&thread->lock); 11149 11150 /* Flag that we're ready to accept signals */ 11151 if (first_time) { 11152 signal_condition(&thread->init_lock, &thread->init_cond); 11153 first_time = 0; 11154 } 11155 11156 /* Put into idle list if applicable */ 11157 if (put_into_idle) 11158 insert_idle_thread(thread); 11159 11160 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 11161 struct iax2_thread *t = NULL; 11162 /* Wait to be signalled or time out */ 11163 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11164 ts.tv_sec = wait.tv_sec; 11165 ts.tv_nsec = wait.tv_usec * 1000; 11166 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) { 11167 /* This thread was never put back into the available dynamic 11168 * thread list, so just go away. */ 11169 if (!put_into_idle) { 11170 ast_mutex_unlock(&thread->lock); 11171 break; 11172 } 11173 AST_LIST_LOCK(&dynamic_list); 11174 /* Account for the case where this thread is acquired *right* after a timeout */ 11175 if ((t = AST_LIST_REMOVE(&dynamic_list, thread, list))) 11176 ast_atomic_fetchadd_int(&iaxdynamicthreadcount, -1); 11177 AST_LIST_UNLOCK(&dynamic_list); 11178 if (t) { 11179 /* This dynamic thread timed out waiting for a task and was 11180 * not acquired immediately after the timeout, 11181 * so it's time to go away. */ 11182 ast_mutex_unlock(&thread->lock); 11183 break; 11184 } 11185 /* Someone grabbed our thread *right* after we timed out. 11186 * Wait for them to set us up with something to do and signal 11187 * us to continue. */ 11188 wait = ast_tvadd(ast_tvnow(), ast_samp2tv(30000, 1000)); 11189 ts.tv_sec = wait.tv_sec; 11190 ts.tv_nsec = wait.tv_usec * 1000; 11191 if (ast_cond_timedwait(&thread->cond, &thread->lock, &ts) == ETIMEDOUT) 11192 { 11193 ast_mutex_unlock(&thread->lock); 11194 break; 11195 } 11196 } 11197 } else { 11198 ast_cond_wait(&thread->cond, &thread->lock); 11199 } 11200 11201 /* Go back into our respective list */ 11202 put_into_idle = 1; 11203 11204 ast_mutex_unlock(&thread->lock); 11205 11206 if (thread->iostate == IAX_IOSTATE_IDLE) 11207 continue; 11208 11209 /* Add ourselves to the active list now */ 11210 AST_LIST_LOCK(&active_list); 11211 AST_LIST_INSERT_HEAD(&active_list, thread, list); 11212 AST_LIST_UNLOCK(&active_list); 11213 11214 /* See what we need to do */ 11215 switch(thread->iostate) { 11216 case IAX_IOSTATE_READY: 11217 thread->actions++; 11218 thread->iostate = IAX_IOSTATE_PROCESSING; 11219 socket_process(thread); 11220 handle_deferred_full_frames(thread); 11221 break; 11222 case IAX_IOSTATE_SCHEDREADY: 11223 thread->actions++; 11224 thread->iostate = IAX_IOSTATE_PROCESSING; 11225 #ifdef SCHED_MULTITHREADED 11226 thread->schedfunc(thread->scheddata); 11227 #endif 11228 default: 11229 break; 11230 } 11231 time(&thread->checktime); 11232 thread->iostate = IAX_IOSTATE_IDLE; 11233 #ifdef DEBUG_SCHED_MULTITHREAD 11234 thread->curfunc[0]='\0'; 11235 #endif 11236 11237 /* Now... remove ourselves from the active list, and return to the idle list */ 11238 AST_LIST_LOCK(&active_list); 11239 AST_LIST_REMOVE(&active_list, thread, list); 11240 AST_LIST_UNLOCK(&active_list); 11241 11242 /* Make sure another frame didn't sneak in there after we thought we were done. */ 11243 handle_deferred_full_frames(thread); 11244 } 11245 11246 /*!\note For some reason, idle threads are exiting without being removed 11247 * from an idle list, which is causing memory corruption. Forcibly remove 11248 * it from the list, if it's there. 11249 */ 11250 AST_LIST_LOCK(&idle_list); 11251 AST_LIST_REMOVE(&idle_list, thread, list); 11252 AST_LIST_UNLOCK(&idle_list); 11253 11254 AST_LIST_LOCK(&dynamic_list); 11255 AST_LIST_REMOVE(&dynamic_list, thread, list); 11256 AST_LIST_UNLOCK(&dynamic_list); 11257 11258 /* I am exiting here on my own volition, I need to clean up my own data structures 11259 * Assume that I am no longer in any of the lists (idle, active, or dynamic) 11260 */ 11261 pthread_cleanup_pop(1); 11262 return NULL; 11263 }
| static void iax2_process_thread_cleanup | ( | void * | data | ) | [static] |
Definition at line 11125 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().
11126 { 11127 struct iax2_thread *thread = data; 11128 ast_mutex_destroy(&thread->lock); 11129 ast_cond_destroy(&thread->cond); 11130 ast_mutex_destroy(&thread->init_lock); 11131 ast_cond_destroy(&thread->init_cond); 11132 ast_free(thread); 11133 ast_atomic_dec_and_test(&iaxactivethreadcount); 11134 }
| static int iax2_provision | ( | struct sockaddr_in * | end, | |
| int | sockfd, | |||
| char * | dest, | |||
| const char * | template, | |||
| int | force | |||
| ) | [static] |
Definition at line 11321 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().
11322 { 11323 /* Returns 1 if provisioned, -1 if not able to find destination, or 0 if no provisioning 11324 is found for template */ 11325 struct iax_ie_data provdata; 11326 struct iax_ie_data ied; 11327 unsigned int sig; 11328 struct sockaddr_in sin; 11329 int callno; 11330 struct create_addr_info cai; 11331 11332 memset(&cai, 0, sizeof(cai)); 11333 11334 ast_debug(1, "Provisioning '%s' from template '%s'\n", dest, template); 11335 11336 if (iax_provision_build(&provdata, &sig, template, force)) { 11337 ast_debug(1, "No provisioning found for template '%s'\n", template); 11338 return 0; 11339 } 11340 11341 if (end) { 11342 memcpy(&sin, end, sizeof(sin)); 11343 cai.sockfd = sockfd; 11344 } else if (create_addr(dest, NULL, &sin, &cai)) 11345 return -1; 11346 11347 /* Build the rest of the message */ 11348 memset(&ied, 0, sizeof(ied)); 11349 iax_ie_append_raw(&ied, IAX_IE_PROVISIONING, provdata.buf, provdata.pos); 11350 11351 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11352 if (!callno) 11353 return -1; 11354 11355 if (iaxs[callno]) { 11356 /* Schedule autodestruct in case they don't ever give us anything back */ 11357 iaxs[callno]->autoid = iax2_sched_replace(iaxs[callno]->autoid, 11358 sched, 15000, auto_hangup, (void *)(long)callno); 11359 ast_set_flag(iaxs[callno], IAX_PROVISION); 11360 /* Got a call number now, so go ahead and send the provisioning information */ 11361 send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_PROVISION, 0, ied.buf, ied.pos, -1); 11362 } 11363 ast_mutex_unlock(&iaxsl[callno]); 11364 11365 return 1; 11366 }
| 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 2825 of file chan_iax2.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_control_data(), and DEADLOCK_AVOIDANCE.
Referenced by socket_process().
02827 { 02828 for (;;) { 02829 if (iaxs[callno] && iaxs[callno]->owner) { 02830 if (ast_channel_trylock(iaxs[callno]->owner)) { 02831 /* Avoid deadlock by pausing and trying again */ 02832 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02833 } else { 02834 ast_queue_control_data(iaxs[callno]->owner, control, data, datalen); 02835 ast_channel_unlock(iaxs[callno]->owner); 02836 break; 02837 } 02838 } else 02839 break; 02840 } 02841 return 0; 02842 }
| 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 2763 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().
02764 { 02765 for (;;) { 02766 if (iaxs[callno] && iaxs[callno]->owner) { 02767 if (ast_channel_trylock(iaxs[callno]->owner)) { 02768 /* Avoid deadlock by pausing and trying again */ 02769 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02770 } else { 02771 ast_queue_frame(iaxs[callno]->owner, f); 02772 ast_channel_unlock(iaxs[callno]->owner); 02773 break; 02774 } 02775 } else 02776 break; 02777 } 02778 return 0; 02779 }
| 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 2794 of file chan_iax2.c.
References ast_channel_trylock, ast_channel_unlock, ast_queue_hangup(), and DEADLOCK_AVOIDANCE.
Referenced by iax2_predestroy().
02795 { 02796 for (;;) { 02797 if (iaxs[callno] && iaxs[callno]->owner) { 02798 if (ast_channel_trylock(iaxs[callno]->owner)) { 02799 /* Avoid deadlock by pausing and trying again */ 02800 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 02801 } else { 02802 ast_queue_hangup(iaxs[callno]->owner); 02803 ast_channel_unlock(iaxs[callno]->owner); 02804 break; 02805 } 02806 } else 02807 break; 02808 } 02809 return 0; 02810 }
| static struct ast_frame * iax2_read | ( | struct ast_channel * | c | ) | [static, read] |
Definition at line 5082 of file chan_iax2.c.
References ast_log(), ast_null_frame, and LOG_NOTICE.
05083 { 05084 ast_log(LOG_NOTICE, "I should never be called!\n"); 05085 return &ast_null_frame; 05086 }
| static int iax2_register | ( | const char * | value, | |
| int | lineno | |||
| ) | [static] |
Definition at line 8180 of file chan_iax2.c.
References ast_copy_string(), ast_log(), copy(), hostname, iax2_append_register(), LOG_WARNING, and secret.
Referenced by set_config().
08181 { 08182 char copy[256]; 08183 char *username, *hostname, *secret; 08184 char *porta; 08185 char *stringp=NULL; 08186 08187 if (!value) 08188 return -1; 08189 08190 ast_copy_string(copy, value, sizeof(copy)); 08191 stringp = copy; 08192 username = strsep(&stringp, "@"); 08193 hostname = strsep(&stringp, "@"); 08194 08195 if (!hostname) { 08196 ast_log(LOG_WARNING, "Format for registration is user[:secret]@host[:port] at line %d\n", lineno); 08197 return -1; 08198 } 08199 08200 stringp = username; 08201 username = strsep(&stringp, ":"); 08202 secret = strsep(&stringp, ":"); 08203 stringp = hostname; 08204 hostname = strsep(&stringp, ":"); 08205 porta = strsep(&stringp, ":"); 08206 08207 if (porta && !atoi(porta)) { 08208 ast_log(LOG_WARNING, "%s is not a valid port number at line %d\n", porta, lineno); 08209 return -1; 08210 } 08211 08212 return iax2_append_register(hostname, username, secret, porta); 08213 }
| static struct ast_channel * iax2_request | ( | const char * | type, | |
| int | format, | |||
| void * | data, | |||
| int * | cause | |||
| ) | [static, read] |
Definition at line 11561 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_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::name, 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.
11562 { 11563 int callno; 11564 int res; 11565 int fmt, native; 11566 struct sockaddr_in sin; 11567 struct ast_channel *c; 11568 struct parsed_dial_string pds; 11569 struct create_addr_info cai; 11570 char *tmpstr; 11571 11572 memset(&pds, 0, sizeof(pds)); 11573 tmpstr = ast_strdupa(data); 11574 parse_dial_string(tmpstr, &pds); 11575 11576 if (ast_strlen_zero(pds.peer)) { 11577 ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data); 11578 return NULL; 11579 } 11580 11581 memset(&cai, 0, sizeof(cai)); 11582 cai.capability = iax2_capability; 11583 11584 ast_copy_flags(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 11585 11586 /* Populate our address from the given */ 11587 if (create_addr(pds.peer, NULL, &sin, &cai)) { 11588 *cause = AST_CAUSE_UNREGISTERED; 11589 return NULL; 11590 } 11591 11592 if (pds.port) 11593 sin.sin_port = htons(atoi(pds.port)); 11594 11595 callno = find_callno_locked(0, 0, &sin, NEW_FORCE, cai.sockfd, 0); 11596 if (callno < 1) { 11597 ast_log(LOG_WARNING, "Unable to create call\n"); 11598 *cause = AST_CAUSE_CONGESTION; 11599 return NULL; 11600 } 11601 11602 /* If this is a trunk, update it now */ 11603 ast_copy_flags(iaxs[callno], &cai, IAX_TRUNK | IAX_SENDANI | IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF); 11604 if (ast_test_flag(&cai, IAX_TRUNK)) { 11605 int new_callno; 11606 if ((new_callno = make_trunk(callno, 1)) != -1) 11607 callno = new_callno; 11608 } 11609 iaxs[callno]->maxtime = cai.maxtime; 11610 if (cai.found) 11611 ast_string_field_set(iaxs[callno], host, pds.peer); 11612 11613 c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability); 11614 11615 ast_mutex_unlock(&iaxsl[callno]); 11616 11617 if (c) { 11618 /* Choose a format we can live with */ 11619 if (c->nativeformats & format) 11620 c->nativeformats &= format; 11621 else { 11622 native = c->nativeformats; 11623 fmt = format; 11624 res = ast_translator_best_choice(&fmt, &native); 11625 if (res < 0) { 11626 ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n", 11627 ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name); 11628 ast_hangup(c); 11629 return NULL; 11630 } 11631 c->nativeformats = native; 11632 } 11633 c->readformat = ast_best_codec(c->nativeformats); 11634 c->writeformat = c->readformat; 11635 } 11636 11637 return c; 11638 }
| static int iax2_sched_add | ( | struct ast_sched_thread * | st, | |
| int | when, | |||
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 1364 of file chan_iax2.c.
References ast_sched_thread_add().
Referenced by __attempt_transmit(), __find_callno(), __iax2_poke_noanswer(), __send_lagrq(), __send_ping(), iax2_call(), iax2_poke_peer(), make_trunk(), network_thread(), realtime_peer(), reg_source_db(), sched_delay_remove(), socket_process(), and update_registry().
01366 { 01367 return ast_sched_thread_add(st, when, callback, data); 01368 }
| static int iax2_sched_replace | ( | int | id, | |
| struct ast_sched_thread * | st, | |||
| int | when, | |||
| ast_sched_cb | callback, | |||
| const void * | data | |||
| ) | [static] |
Definition at line 1356 of file chan_iax2.c.
References ast_sched_thread_add(), and ast_sched_thread_del.
Referenced by auth_fail(), iax2_ack_registry(), iax2_do_register(), iax2_dprequest(), iax2_provision(), and update_jbsched().
01358 { 01359 ast_sched_thread_del(st, id); 01360 01361 return ast_sched_thread_add(st, when, callback, data); 01362 }
| 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 6045 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().
06046 { 06047 /* Queue a packet for delivery on a given private structure. Use "ts" for 06048 timestamp, or calculate if ts is 0. Send immediately without retransmission 06049 or delayed, with retransmission */ 06050 struct ast_iax2_full_hdr *fh; 06051 struct ast_iax2_mini_hdr *mh; 06052 struct ast_iax2_video_hdr *vh; 06053 struct { 06054 struct iax_frame fr2; 06055 unsigned char buffer[4096]; 06056 } frb; 06057 struct iax_frame *fr; 06058 int res; 06059 int sendmini=0; 06060 unsigned int lastsent; 06061 unsigned int fts; 06062 06063 frb.fr2.afdatalen = sizeof(frb.buffer); 06064 06065 if (!pvt) { 06066 ast_log(LOG_WARNING, "No private structure for packet?\n"); 06067 return -1; 06068 } 06069 06070 lastsent = pvt->lastsent; 06071 06072 /* Calculate actual timestamp */ 06073 fts = calc_timestamp(pvt, ts, f); 06074 06075 /* Bail here if this is an "interp" frame; we don't want or need to send these placeholders out 06076 * (the endpoint should detect the lost packet itself). But, we want to do this here, so that we 06077 * increment the "predicted timestamps" for voice, if we're predicting */ 06078 if(f->frametype == AST_FRAME_VOICE && f->datalen == 0) 06079 return 0; 06080 #if 0 06081 ast_log(LOG_NOTICE, 06082 "f->frametype %c= AST_FRAME_VOICE, %sencrypted, %srotation scheduled...\n", 06083 *("=!" + (f->frametype == AST_FRAME_VOICE)), 06084 IAX_CALLENCRYPTED(pvt) ? "" : "not ", 06085 pvt->keyrotateid != -1 ? "" : "no " 06086 ); 06087 #endif 06088 if (pvt->keyrotateid == -1 && f->frametype == AST_FRAME_VOICE && IAX_CALLENCRYPTED(pvt)) { 06089 iax2_key_rotate(pvt); 06090 } 06091 06092 if ((ast_test_flag(pvt, IAX_TRUNK) || 06093 (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) || 06094 ((fts & 0xFFFF0000L) == ((lastsent + 0x10000) & 0xFFFF0000L)))) 06095 /* High two bytes are the same on timestamp, or sending on a trunk */ && 06096 (f->frametype == AST_FRAME_VOICE) 06097 /* is a voice frame */ && 06098 (f->subclass == pvt->svoiceformat) 06099 /* is the same type */ ) { 06100 /* Force immediate rather than delayed transmission */ 06101 now = 1; 06102 /* Mark that mini-style frame is appropriate */ 06103 sendmini = 1; 06104 } 06105 if ( f->frametype == AST_FRAME_VIDEO ) { 06106 /* 06107 * If the lower 15 bits of the timestamp roll over, or if 06108 * the video format changed then send a full frame. 06109 * Otherwise send a mini video frame 06110 */ 06111 if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && 06112 ((f->subclass & ~0x1) == pvt->svideoformat) 06113 ) { 06114 now = 1; 06115 sendmini = 1; 06116 } else { 06117 now = 0; 06118 sendmini = 0; 06119 } 06120 pvt->lastvsent = fts; 06121 } 06122 if (f->frametype == AST_FRAME_IAX) { 06123 /* 0x8000 marks this message as TX:, this bit will be stripped later */ 06124 pvt->last_iax_message = f->subclass | MARK_IAX_SUBCLASS_TX; 06125 if (!pvt->first_iax_message) { 06126 pvt->first_iax_message = pvt->last_iax_message; 06127 } 06128 } 06129 /* Allocate an iax_frame */ 06130 if (now) { 06131 fr = &frb.fr2; 06132 } else 06133 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)); 06134 if (!fr) { 06135 ast_log(LOG_WARNING, "Out of memory\n"); 06136 return -1; 06137 } 06138 /* Copy our prospective frame into our immediate or retransmitted wrapper */ 06139 iax_frame_wrap(fr, f); 06140 06141 fr->ts = fts; 06142 fr->callno = pvt->callno; 06143 fr->transfer = transfer; 06144 fr->final = final; 06145 fr->encmethods = 0; 06146 if (!sendmini) { 06147 /* We need a full frame */ 06148 if (seqno > -1) 06149 fr->oseqno = seqno; 06150 else 06151 fr->oseqno = pvt->oseqno++; 06152 fr->iseqno = pvt->iseqno; 06153 fh = (struct ast_iax2_full_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_full_hdr)); 06154 fh->scallno = htons(fr->callno | IAX_FLAG_FULL); 06155 fh->ts = htonl(fr->ts); 06156 fh->oseqno = fr->oseqno; 06157 if (transfer) { 06158 fh->iseqno = 0; 06159 } else 06160 fh->iseqno = fr->iseqno; 06161 /* Keep track of the last thing we've acknowledged */ 06162 if (!transfer) 06163 pvt->aseqno = fr->iseqno; 06164 fh->type = fr->af.frametype & 0xFF; 06165 if (fr->af.frametype == AST_FRAME_VIDEO) 06166 fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); 06167 else 06168 fh->csub = compress_subclass(fr->af.subclass); 06169 if (transfer) { 06170 fr->dcallno = pvt->transfercallno; 06171 } else 06172 fr->dcallno = pvt->peercallno; 06173 fh->dcallno = htons(fr->dcallno); 06174 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); 06175 fr->data = fh; 06176 fr->retries = 0; 06177 /* Retry after 2x the ping time has passed */ 06178 fr->retrytime = pvt->pingtime * 2; 06179 if (fr->retrytime < MIN_RETRY_TIME) 06180 fr->retrytime = MIN_RETRY_TIME; 06181 if (fr->retrytime > MAX_RETRY_TIME) 06182 fr->retrytime = MAX_RETRY_TIME; 06183 /* Acks' don't get retried */ 06184 if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) 06185 fr->retries = -1; 06186 else if (f->frametype == AST_FRAME_VOICE) 06187 pvt->svoiceformat = f->subclass; 06188 else if (f->frametype == AST_FRAME_VIDEO) 06189 pvt->svideoformat = f->subclass & ~0x1; 06190 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 06191 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 06192 if (fr->transfer) 06193 iax_outputframe(fr, NULL, 2, &pvt->transfer, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06194 else 06195 iax_outputframe(fr, NULL, 2, &pvt->addr, fr->datalen - sizeof(struct ast_iax2_full_hdr)); 06196 encrypt_frame(&pvt->ecx, fh, pvt->semirand, &fr->datalen); 06197 fr->encmethods = pvt->encmethods; 06198 fr->ecx = pvt->ecx; 06199 fr->mydcx = pvt->mydcx; 06200 memcpy(fr->semirand, pvt->semirand, sizeof(fr->semirand)); 06201 } else 06202 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06203 } 06204 06205 if (now) { 06206 res = send_packet(fr); 06207 } else 06208 res = iax2_transmit(fr); 06209 } else { 06210 if (ast_test_flag(pvt, IAX_TRUNK)) { 06211 iax2_trunk_queue(pvt, fr); 06212 res = 0; 06213 } else if (fr->af.frametype == AST_FRAME_VIDEO) { 06214 /* Video frame have no sequence number */ 06215 fr->oseqno = -1; 06216 fr->iseqno = -1; 06217 vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr)); 06218 vh->zeros = 0; 06219 vh->callno = htons(0x8000 | fr->callno); 06220 vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); 06221 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); 06222 fr->data = vh; 06223 fr->retries = -1; 06224 res = send_packet(fr); 06225 } else { 06226 /* Mini-frames have no sequence number */ 06227 fr->oseqno = -1; 06228 fr->iseqno = -1; 06229 /* Mini frame will do */ 06230 mh = (struct ast_iax2_mini_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_mini_hdr)); 06231 mh->callno = htons(fr->callno); 06232 mh->ts = htons(fr->ts & 0xFFFF); 06233 fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); 06234 fr->data = mh; 06235 fr->retries = -1; 06236 if (pvt->transferring == TRANSFER_MEDIAPASS) 06237 fr->transfer = 1; 06238 if (ast_test_flag(pvt, IAX_ENCRYPTED)) { 06239 if (ast_test_flag(pvt, IAX_KEYPOPULATED)) { 06240 encrypt_frame(&pvt->ecx, (struct ast_iax2_full_hdr *)mh, pvt->semirand, &fr->datalen); 06241 } else 06242 ast_log(LOG_WARNING, "Supposed to send packet encrypted, but no key?\n"); 06243 } 06244 res = send_packet(fr); 06245 } 06246 } 06247 return res; 06248 }
| static int iax2_sendhtml | ( | struct ast_channel * | c, | |
| int | subclass, | |||
| const char * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 4094 of file chan_iax2.c.
References AST_FRAME_HTML, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04095 { 04096 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_HTML, subclass, 0, (unsigned char *)data, datalen, -1); 04097 }
| static int iax2_sendimage | ( | struct ast_channel * | c, | |
| struct ast_frame * | img | |||
| ) | [static] |
Definition at line 4089 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.
04090 { 04091 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_IMAGE, img->subclass, 0, img->data.ptr, img->datalen, -1); 04092 }
| static int iax2_sendtext | ( | struct ast_channel * | c, | |
| const char * | text | |||
| ) | [static] |
Definition at line 4082 of file chan_iax2.c.
References AST_FRAME_TEXT, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
04083 { 04084 04085 return send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_TEXT, 04086 0, 0, (unsigned char *)text, strlen(text) + 1, -1); 04087 }
| static int iax2_setoption | ( | struct ast_channel * | c, | |
| int | option, | |||
| void * | data, | |||
| int | datalen | |||
| ) | [static] |
Definition at line 5037 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_OPRMODE, 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().
05038 { 05039 struct ast_option_header *h; 05040 int res; 05041 05042 switch (option) { 05043 case AST_OPTION_TXGAIN: 05044 case AST_OPTION_RXGAIN: 05045 /* these two cannot be sent, because they require a result */ 05046 errno = ENOSYS; 05047 return -1; 05048 case AST_OPTION_OPRMODE: 05049 errno = EINVAL; 05050 return -1; 05051 default: 05052 { 05053 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05054 struct chan_iax2_pvt *pvt; 05055 05056 ast_mutex_lock(&iaxsl[callno]); 05057 pvt = iaxs[callno]; 05058 05059 if (wait_for_peercallno(pvt)) { 05060 ast_mutex_unlock(&iaxsl[callno]); 05061 return -1; 05062 } 05063 05064 ast_mutex_unlock(&iaxsl[callno]); 05065 05066 if (!(h = ast_malloc(datalen + sizeof(*h)))) { 05067 return -1; 05068 } 05069 05070 h->flag = AST_OPTION_FLAG_REQUEST; 05071 h->option = htons(option); 05072 memcpy(h->data, data, datalen); 05073 res = send_command_locked(PTR_TO_CALLNO(c->tech_pvt), AST_FRAME_CONTROL, 05074 AST_CONTROL_OPTION, 0, (unsigned char *) h, 05075 datalen + sizeof(*h), -1); 05076 ast_free(h); 05077 return res; 05078 } 05079 } 05080 }
| static int iax2_start_transfer | ( | unsigned short | callno0, | |
| unsigned short | callno1, | |||
| int | mediaonly | |||
| ) | [static] |
Definition at line 5121 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().
05122 { 05123 int res; 05124 struct iax_ie_data ied0; 05125 struct iax_ie_data ied1; 05126 unsigned int transferid = (unsigned int)ast_random(); 05127 05128 if (IAX_CALLENCRYPTED(iaxs[callno0]) || IAX_CALLENCRYPTED(iaxs[callno1])) { 05129 ast_debug(1, "transfers are not supported for encrypted calls at this time"); 05130 ast_set_flag(iaxs[callno0], IAX_NOTRANSFER); 05131 ast_set_flag(iaxs[callno1], IAX_NOTRANSFER); 05132 return 0; 05133 } 05134 05135 memset(&ied0, 0, sizeof(ied0)); 05136 iax_ie_append_addr(&ied0, IAX_IE_APPARENT_ADDR, &iaxs[callno1]->addr); 05137 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[callno1]->peercallno); 05138 iax_ie_append_int(&ied0, IAX_IE_TRANSFERID, transferid); 05139 05140 memset(&ied1, 0, sizeof(ied1)); 05141 iax_ie_append_addr(&ied1, IAX_IE_APPARENT_ADDR, &iaxs[callno0]->addr); 05142 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[callno0]->peercallno); 05143 iax_ie_append_int(&ied1, IAX_IE_TRANSFERID, transferid); 05144 05145 res = send_command(iaxs[callno0], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); 05146 if (res) 05147 return -1; 05148 res = send_command(iaxs[callno1], AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); 05149 if (res) 05150 return -1; 05151 iaxs[callno0]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05152 iaxs[callno1]->transferring = mediaonly ? TRANSFER_MBEGIN : TRANSFER_BEGIN; 05153 return 0; 05154 }
| static int iax2_transfer | ( | struct ast_channel * | c, | |
| const char * | dest | |||
| ) | [static] |
Definition at line 5375 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, ast_channel::name, iax_ie_data::pos, PTR_TO_CALLNO, send_command_locked(), and ast_channel::tech_pvt.
05376 { 05377 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 05378 struct iax_ie_data ied = { "", }; 05379 char tmp[256], *context; 05380 ast_copy_string(tmp, dest, sizeof(tmp)); 05381 context = strchr(tmp, '@'); 05382 if (context) { 05383 *context = '\0'; 05384 context++; 05385 } 05386 iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, tmp); 05387 if (context) 05388 iax_ie_append_str(&ied, IAX_IE_CALLED_CONTEXT, context); 05389 ast_debug(1, "Transferring '%s' to '%s'\n", c->name, dest); 05390 return send_command_locked(callno, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); 05391 }
| static int iax2_transmit | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 4054 of file chan_iax2.c.
References AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_sched_thread_poke(), and iax_frame::sentyet.
Referenced by iax2_send().
04055 { 04056 /* Lock the queue and place this packet at the end */ 04057 /* By setting this to 0, the network thread will send it for us, and 04058 queue retransmission if necessary */ 04059 fr->sentyet = 0; 04060 AST_LIST_LOCK(&frame_queue); 04061 AST_LIST_INSERT_TAIL(&frame_queue, fr, list); 04062 AST_LIST_UNLOCK(&frame_queue); 04063 /* Wake up the network and scheduler thread */ 04064 if (netthreadid != AST_PTHREADT_NULL) 04065 pthread_kill(netthreadid, SIGURG); 04066 ast_sched_thread_poke(sched); 04067 return 0; 04068 }
| static int iax2_trunk_expired | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [inline, static] |
Definition at line 8779 of file chan_iax2.c.
References iax2_trunk_peer::trunkact.
Referenced by timing_read().
08780 { 08781 /* Drop when trunk is about 5 seconds idle */ 08782 if (now->tv_sec > tpeer->trunkact.tv_sec + 5) 08783 return 1; 08784 return 0; 08785 }
| static int iax2_trunk_queue | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_frame * | fr | |||
| ) | [static] |
Definition at line 5784 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().
05785 { 05786 struct ast_frame *f; 05787 struct iax2_trunk_peer *tpeer; 05788 void *tmp, *ptr; 05789 struct timeval now; 05790 int res; 05791 struct ast_iax2_meta_trunk_entry *met; 05792 struct ast_iax2_meta_trunk_mini *mtm; 05793 05794 f = &fr->af; 05795 tpeer = find_tpeer(&pvt->addr, pvt->sockfd); 05796 if (tpeer) { 05797 if (tpeer->trunkdatalen + f->datalen + 4 >= tpeer->trunkdataalloc) { 05798 /* Need to reallocate space */ 05799 if (tpeer->trunkdataalloc < trunkmaxsize) { 05800 if (!(tmp = ast_realloc(tpeer->trunkdata, tpeer->trunkdataalloc + DEFAULT_TRUNKDATA + IAX2_TRUNK_PREFACE))) { 05801 ast_mutex_unlock(&tpeer->lock); 05802 return -1; 05803 } 05804 05805 tpeer->trunkdataalloc += DEFAULT_TRUNKDATA; 05806 tpeer->trunkdata = tmp; 05807 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); 05808 } else { 05809 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)); 05810 ast_mutex_unlock(&tpeer->lock); 05811 return -1; 05812 } 05813 } 05814 05815 /* Append to meta frame */ 05816 ptr = tpeer->trunkdata + IAX2_TRUNK_PREFACE + tpeer->trunkdatalen; 05817 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) { 05818 mtm = (struct ast_iax2_meta_trunk_mini *)ptr; 05819 mtm->len = htons(f->datalen); 05820 mtm->mini.callno = htons(pvt->callno); 05821 mtm->mini.ts = htons(0xffff & fr->ts); 05822 ptr += sizeof(struct ast_iax2_meta_trunk_mini); 05823 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_mini); 05824 } else { 05825 met = (struct ast_iax2_meta_trunk_entry *)ptr; 05826 /* Store call number and length in meta header */ 05827 met->callno = htons(pvt->callno); 05828 met->len = htons(f->datalen); 05829 /* Advance pointers/decrease length past trunk entry header */ 05830 ptr += sizeof(struct ast_iax2_meta_trunk_entry); 05831 tpeer->trunkdatalen += sizeof(struct ast_iax2_meta_trunk_entry); 05832 } 05833 /* Copy actual trunk data */ 05834 memcpy(ptr, f->data.ptr, f->datalen); 05835 tpeer->trunkdatalen += f->datalen; 05836 05837 tpeer->calls++; 05838 05839 /* track the largest mtu we actually have sent */ 05840 if (tpeer->trunkdatalen + f->datalen + 4 > trunk_maxmtu) 05841 trunk_maxmtu = tpeer->trunkdatalen + f->datalen + 4 ; 05842 05843 /* if we have enough for a full MTU, ship it now without waiting */ 05844 if (global_max_trunk_mtu > 0 && tpeer->trunkdatalen + f->datalen + 4 >= global_max_trunk_mtu) { 05845 now = ast_tvnow(); 05846 res = send_trunk(tpeer, &now); 05847 trunk_untimed ++; 05848 } 05849 05850 ast_mutex_unlock(&tpeer->lock); 05851 } 05852 return 0; 05853 }
| static int iax2_vnak | ( | int | callno | ) | [static] |
Definition at line 8697 of file chan_iax2.c.
References AST_FRAME_IAX, IAX_COMMAND_VNAK, and send_command_immediate().
Referenced by socket_process(), and socket_process_meta().
08698 { 08699 return send_command_immediate(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_VNAK, 0, NULL, 0, iaxs[callno]->iseqno); 08700 }
| static int iax2_write | ( | struct ast_channel * | c, | |
| struct ast_frame * | f | |||
| ) | [static] |
Definition at line 7099 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.
07100 { 07101 unsigned short callno = PTR_TO_CALLNO(c->tech_pvt); 07102 int res = -1; 07103 ast_mutex_lock(&iaxsl[callno]); 07104 if (iaxs[callno]) { 07105 /* If there's an outstanding error, return failure now */ 07106 if (!iaxs[callno]->error) { 07107 if (ast_test_flag(iaxs[callno], IAX_ALREADYGONE)) 07108 res = 0; 07109 /* Don't waste bandwidth sending null frames */ 07110 else if (f->frametype == AST_FRAME_NULL) 07111 res = 0; 07112 else if ((f->frametype == AST_FRAME_VOICE) && ast_test_flag(iaxs[callno], IAX_QUELCH)) 07113 res = 0; 07114 else if (!ast_test_flag(&iaxs[callno]->state, IAX_STATE_STARTED)) 07115 res = 0; 07116 else 07117 /* Simple, just queue for transmission */ 07118 res = iax2_send(iaxs[callno], f, 0, -1, 0, 0, 0); 07119 } else { 07120 ast_debug(1, "Write error: %s\n", strerror(errno)); 07121 } 07122 } 07123 /* If it's already gone, just return */ 07124 ast_mutex_unlock(&iaxsl[callno]); 07125 return res; 07126 }
| static int iax_check_version | ( | char * | dev | ) | [static] |
Definition at line 2992 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().
02993 { 02994 int res = 0; 02995 struct iax_firmware *cur = NULL; 02996 02997 if (ast_strlen_zero(dev)) 02998 return 0; 02999 03000 AST_LIST_LOCK(&firmwares); 03001 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03002 if (!strcmp(dev, (char *)cur->fwh->devname)) { 03003 res = ntohs(cur->fwh->version); 03004 break; 03005 } 03006 } 03007 AST_LIST_UNLOCK(&firmwares); 03008 03009 return res; 03010 }
| static void iax_debug_output | ( | const char * | data | ) | [static] |
Definition at line 1062 of file chan_iax2.c.
References ast_verbose.
Referenced by load_module().
01063 { 01064 if (iaxdebug) 01065 ast_verbose("%s", data); 01066 }
| static void iax_error_output | ( | const char * | data | ) | [static] |
Definition at line 1068 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by load_module().
01069 { 01070 ast_log(LOG_WARNING, "%s", data); 01071 }
| static int iax_firmware_append | ( | struct iax_ie_data * | ied, | |
| const unsigned char * | dev, | |||
| unsigned int | desc | |||
| ) | [static] |
Definition at line 3012 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().
03013 { 03014 int res = -1; 03015 unsigned int bs = desc & 0xff; 03016 unsigned int start = (desc >> 8) & 0xffffff; 03017 unsigned int bytes; 03018 struct iax_firmware *cur; 03019 03020 if (ast_strlen_zero((char *)dev) || !bs) 03021 return -1; 03022 03023 start *= bs; 03024 03025 AST_LIST_LOCK(&firmwares); 03026 AST_LIST_TRAVERSE(&firmwares, cur, list) { 03027 if (strcmp((char *)dev, (char *)cur->fwh->devname)) 03028 continue; 03029 iax_ie_append_int(ied, IAX_IE_FWBLOCKDESC, desc); 03030 if (start < ntohl(cur->fwh->datalen)) { 03031 bytes = ntohl(cur->fwh->datalen) - start; 03032 if (bytes > bs) 03033 bytes = bs; 03034 iax_ie_append_raw(ied, IAX_IE_FWBLOCKDATA, cur->fwh->data + start, bytes); 03035 } else { 03036 bytes = 0; 03037 iax_ie_append(ied, IAX_IE_FWBLOCKDATA); 03038 } 03039 if (bytes == bs) 03040 res = 0; 03041 else 03042 res = 1; 03043 break; 03044 } 03045 AST_LIST_UNLOCK(&firmwares); 03046 03047 return res; 03048 }
| 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 1045 of file chan_iax2.c.
References debugaddr, and iax_showframe().
Referenced by iax2_send(), raw_hangup(), and socket_process().
01046 { 01047 if (iaxdebug || 01048 (sin && debugaddr.sin_addr.s_addr && 01049 (!ntohs(debugaddr.sin_port) || 01050 debugaddr.sin_port == sin->sin_port) && 01051 debugaddr.sin_addr.s_addr == sin->sin_addr.s_addr)) { 01052 if (iaxdebug) { 01053 iax_showframe(f, fhi, rx, sin, datalen); 01054 } else { 01055 iaxdebug = 1; 01056 iax_showframe(f, fhi, rx, sin, datalen); 01057 iaxdebug = 0; 01058 } 01059 } 01060 }
| static int iax_park | ( | struct ast_channel * | chan1, | |
| struct ast_channel * | chan2 | |||
| ) | [static] |
Definition at line 8941 of file chan_iax2.c.
References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, ast_channel_alloc, ast_channel_masquerade(), ast_copy_string(), ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, iax_dual::chan1, iax_dual::chan2, ast_channel::context, ast_channel::exten, iax_park_thread(), LOG_WARNING, ast_channel::name, ast_channel::priority, ast_channel::readformat, and ast_channel::writeformat.
Referenced by socket_process().
08942 { 08943 struct iax_dual *d; 08944 struct ast_channel *chan1m, *chan2m; 08945 pthread_t th; 08946 chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); 08947 chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); 08948 if (chan2m && chan1m) { 08949 /* Make formats okay */ 08950 chan1m->readformat = chan1->readformat; 08951 chan1m->writeformat = chan1->writeformat; 08952 ast_channel_masquerade(chan1m, chan1); 08953 /* Setup the extensions and such */ 08954 ast_copy_string(chan1m->context, chan1->context, sizeof(chan1m->context)); 08955 ast_copy_string(chan1m->exten, chan1->exten, sizeof(chan1m->exten)); 08956 chan1m->priority = chan1->priority; 08957 08958 /* We make a clone of the peer channel too, so we can play 08959 back the announcement */ 08960 /* Make formats okay */ 08961 chan2m->readformat = chan2->readformat; 08962 chan2m->writeformat = chan2->writeformat; 08963 ast_channel_masquerade(chan2m, chan2); 08964 /* Setup the extensions and such */ 08965 ast_copy_string(chan2m->context, chan2->context, sizeof(chan2m->context)); 08966 ast_copy_string(chan2m->exten, chan2->exten, sizeof(chan2m->exten)); 08967 chan2m->priority = chan2->priority; 08968 if (ast_do_masquerade(chan2m)) { 08969 ast_log(LOG_WARNING, "Masquerade failed :(\n"); 08970 ast_hangup(chan2m); 08971 return -1; 08972 } 08973 } else { 08974 if (chan1m) 08975 ast_hangup(chan1m); 08976 if (chan2m) 08977 ast_hangup(chan2m); 08978 return -1; 08979 } 08980 if ((d = ast_calloc(1, sizeof(*d)))) { 08981 d->chan1 = chan1m; 08982 d->chan2 = chan2m; 08983 if (!ast_pthread_create_detached_background(&th, NULL, iax_park_thread, d)) { 08984 return 0; 08985 } 08986 ast_free(d); 08987 } 08988 return -1; 08989 }
| static void* iax_park_thread | ( | void * | stuff | ) | [static] |
Definition at line 8921 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().
08922 { 08923 struct ast_channel *chan1, *chan2; 08924 struct iax_dual *d; 08925 struct ast_frame *f; 08926 int ext; 08927 int res; 08928 d = stuff; 08929 chan1 = d->chan1; 08930 chan2 = d->chan2; 08931 ast_free(d); 08932 f = ast_read(chan1); 08933 if (f) 08934 ast_frfree(f); 08935 res = ast_park_call(chan1, chan2, 0, &ext); 08936 ast_hangup(chan2); 08937 ast_log(LOG_NOTICE, "Parked on extension '%d'\n", ext); 08938 return NULL; 08939 }
Definition at line 1805 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().
01806 { 01807 struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); 01808 if (new) { 01809 size_t afdatalen = new->afdatalen; 01810 memcpy(new, fr, sizeof(*new)); 01811 iax_frame_wrap(new, &fr->af); 01812 new->afdatalen = afdatalen; 01813 new->data = NULL; 01814 new->datalen = 0; 01815 new->direction = DIRECTION_INGRESS; 01816 new->retrans = -1; 01817 } 01818 return new; 01819 }
| static void insert_idle_thread | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 1249 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().
01250 { 01251 if (thread->type == IAX_THREAD_TYPE_DYNAMIC) { 01252 AST_LIST_LOCK(&dynamic_list); 01253 AST_LIST_INSERT_TAIL(&dynamic_list, thread, list); 01254 AST_LIST_UNLOCK(&dynamic_list); 01255 } else { 01256 AST_LIST_LOCK(&idle_list); 01257 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 01258 AST_LIST_UNLOCK(&idle_list); 01259 } 01260 01261 return; 01262 }
| static void jb_debug_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1097 of file chan_iax2.c.
References ast_verbose.
Referenced by handle_cli_iax2_set_debug_jb().
01098 { 01099 va_list args; 01100 char buf[1024]; 01101 01102 va_start(args, fmt); 01103 vsnprintf(buf, sizeof(buf), fmt, args); 01104 va_end(args); 01105 01106 ast_verbose("%s", buf); 01107 }
| static void jb_error_output | ( | const char * | fmt, | |
| ... | ||||
| ) | [static] |
Definition at line 1073 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 1085 of file chan_iax2.c.
References ast_log(), and LOG_WARNING.
Referenced by handle_cli_iax2_set_debug_jb(), and load_module().
01086 { 01087 va_list args; 01088 char buf[1024]; 01089 01090 va_start(args, fmt); 01091 vsnprintf(buf, sizeof(buf), fmt, args); 01092 va_end(args); 01093 01094 ast_log(LOG_WARNING, "%s", buf); 01095 }
| static int load_module | ( | void | ) | [static] |
Load IAX2 module, load configuraiton ---.
Definition at line 13805 of file chan_iax2.c.
References __unload_module(), ao2_callback, ARRAY_LEN, ast_channel_register(), ast_cli_register_multiple(), 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_xml, ast_register_switch(), ast_sched_thread_create(), ast_sched_thread_destroy(), 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(), manager_iax2_show_registry(), peer_set_sock_cb(), reload_firmware(), RQ_CHAR, RQ_UINTEGER2, SENTINEL, set_config(), and start_network_thread().
13806 { 13807 13808 static const char config[] = "iax.conf"; 13809 int x = 0; 13810 struct iax2_registry *reg = NULL; 13811 13812 if (load_objects()) { 13813 return AST_MODULE_LOAD_FAILURE; 13814 } 13815 13816 randomcalltokendata = ast_random(); 13817 ast_custom_function_register(&iaxpeer_function); 13818 ast_custom_function_register(&iaxvar_function); 13819 13820 iax_set_output(iax_debug_output); 13821 iax_set_error(iax_error_output); 13822 jb_setoutput(jb_error_output, jb_warning_output, NULL); 13823 13824 memset(iaxs, 0, sizeof(iaxs)); 13825 13826 for (x = 0; x < ARRAY_LEN(iaxsl); x++) { 13827 ast_mutex_init(&iaxsl[x]); 13828 } 13829 13830 if (!(sched = ast_sched_thread_create())) { 13831 ast_log(LOG_ERROR, "Failed to create scheduler thread\n"); 13832 return AST_MODULE_LOAD_FAILURE; 13833 } 13834 13835 if (!(io = io_context_create())) { 13836 ast_log(LOG_ERROR, "Failed to create I/O context\n"); 13837 sched = ast_sched_thread_destroy(sched); 13838 return AST_MODULE_LOAD_FAILURE; 13839 } 13840 13841 if (!(netsock = ast_netsock_list_alloc())) { 13842 ast_log(LOG_ERROR, "Failed to create netsock list\n"); 13843 io_context_destroy(io); 13844 sched = ast_sched_thread_destroy(sched); 13845 return AST_MODULE_LOAD_FAILURE; 13846 } 13847 ast_netsock_init(netsock); 13848 13849 outsock = ast_netsock_list_alloc(); 13850 if (!outsock) { 13851 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 13852 io_context_destroy(io); 13853 sched = ast_sched_thread_destroy(sched); 13854 return AST_MODULE_LOAD_FAILURE; 13855 } 13856 ast_netsock_init(outsock); 13857 13858 ast_cli_register_multiple(cli_iax2, ARRAY_LEN(cli_iax2)); 13859 13860 ast_register_application_xml(papp, iax2_prov_app); 13861 13862 ast_manager_register( "IAXpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peers, "List IAX Peers" ); 13863 ast_manager_register( "IAXpeerlist", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_peer_list, "List IAX Peers" ); 13864 ast_manager_register( "IAXnetstats", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_netstats, "Show IAX Netstats" ); 13865 ast_manager_register( "IAXregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_iax2_show_registry, "Show IAX registrations"); 13866 13867 if ((timer = ast_timer_open())) { 13868 ast_timer_set_rate(timer, trunkfreq); 13869 } 13870 13871 if (set_config(config, 0) == -1) { 13872 if (timer) { 13873 ast_timer_close(timer); 13874 } 13875 return AST_MODULE_LOAD_DECLINE; 13876 } 13877 13878 if (ast_channel_register(&iax2_tech)) { 13879 ast_log(LOG_ERROR, "Unable to register channel class %s\n", "IAX2"); 13880 __unload_module(); 13881 return AST_MODULE_LOAD_FAILURE; 13882 } 13883 13884 if (ast_register_switch(&iax2_switch)) 13885 ast_log(LOG_ERROR, "Unable to register IAX switch\n"); 13886 13887 if (start_network_thread()) { 13888 ast_log(LOG_ERROR, "Unable to start network thread\n"); 13889 __unload_module(); 13890 return AST_MODULE_LOAD_FAILURE; 13891 } else 13892 ast_verb(2, "IAX Ready and Listening\n"); 13893 13894 AST_LIST_LOCK(®istrations); 13895 AST_LIST_TRAVERSE(®istrations, reg, entry) 13896 iax2_do_register(reg); 13897 AST_LIST_UNLOCK(®istrations); 13898 13899 ao2_callback(peers, 0, peer_set_sock_cb, NULL); 13900 ao2_callback(peers, 0, iax2_poke_peer_cb, NULL); 13901 13902 13903 reload_firmware(0); 13904 iax_provision_reload(0); 13905 13906 ast_realtime_require_field("iaxpeers", "name", RQ_CHAR, 10, "ipaddr", RQ_CHAR, 15, "port", RQ_UINTEGER2, 5, "regseconds", RQ_UINTEGER2, 6, SENTINEL); 13907 13908 return AST_MODULE_LOAD_SUCCESS; 13909 }
| static int load_objects | ( | void | ) | [static] |
Definition at line 13746 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().
13747 { 13748 peers = users = iax_peercallno_pvts = iax_transfercallno_pvts = NULL; 13749 peercnts = callno_limits = calltoken_ignores = callno_pool = callno_pool_trunk = NULL; 13750 13751 if (!(peers = ao2_container_alloc(MAX_PEER_BUCKETS, peer_hash_cb, peer_cmp_cb))) { 13752 goto container_fail; 13753 } else if (!(users = ao2_container_alloc(MAX_USER_BUCKETS, user_hash_cb, user_cmp_cb))) { 13754 goto container_fail; 13755 } else if (!(iax_peercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, pvt_hash_cb, pvt_cmp_cb))) { 13756 goto container_fail; 13757 } else if (!(iax_transfercallno_pvts = ao2_container_alloc(IAX_MAX_CALLS, transfercallno_pvt_hash_cb, transfercallno_pvt_cmp_cb))) { 13758 goto container_fail; 13759 } else if (!(peercnts = ao2_container_alloc(MAX_PEER_BUCKETS, peercnt_hash_cb, peercnt_cmp_cb))) { 13760 goto container_fail; 13761 } else if (!(callno_limits = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 13762 goto container_fail; 13763 } else if (!(calltoken_ignores = ao2_container_alloc(MAX_PEER_BUCKETS, addr_range_hash_cb, addr_range_cmp_cb))) { 13764 goto container_fail; 13765 } else if (create_callno_pools()) { 13766 goto container_fail; 13767 } 13768 13769 return 0; 13770 13771 container_fail: 13772 if (peers) { 13773 ao2_ref(peers, -1); 13774 } 13775 if (users) { 13776 ao2_ref(users, -1); 13777 } 13778 if (iax_peercallno_pvts) { 13779 ao2_ref(iax_peercallno_pvts, -1); 13780 } 13781 if (iax_transfercallno_pvts) { 13782 ao2_ref(iax_transfercallno_pvts, -1); 13783 } 13784 if (peercnts) { 13785 ao2_ref(peercnts, -1); 13786 } 13787 if (callno_limits) { 13788 ao2_ref(callno_limits, -1); 13789 } 13790 if (calltoken_ignores) { 13791 ao2_ref(calltoken_ignores, -1); 13792 } 13793 if (callno_pool) { 13794 ao2_ref(callno_pool, -1); 13795 } 13796 if (callno_pool_trunk) { 13797 ao2_ref(callno_pool_trunk, -1); 13798 } 13799 return AST_MODULE_LOAD_FAILURE; 13800 }
| static void lock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5156 of file chan_iax2.c.
References ast_mutex_lock(), ast_mutex_trylock(), and DEADLOCK_AVOIDANCE.
Referenced by iax2_bridge().
05157 { 05158 ast_mutex_lock(&iaxsl[callno0]); 05159 while (ast_mutex_trylock(&iaxsl[callno1])) { 05160 DEADLOCK_AVOIDANCE(&iaxsl[callno0]); 05161 } 05162 }
| static void log_jitterstats | ( | unsigned short | callno | ) | [static] |
Definition at line 9064 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().
09065 { 09066 int localjitter = -1, localdelay = 0, locallost = -1, locallosspct = -1, localdropped = 0, localooo = -1, localpackets = -1; 09067 jb_info jbinfo; 09068 09069 ast_mutex_lock(&iaxsl[callno]); 09070 if (iaxs[callno] && iaxs[callno]->owner && iaxs[callno]->owner->name) { 09071 if(ast_test_flag(iaxs[callno], IAX_USEJITTERBUF)) { 09072 jb_getinfo(iaxs[callno]->jb, &jbinfo); 09073 localjitter = jbinfo.jitter; 09074 localdelay = jbinfo.current - jbinfo.min; 09075 locallost = jbinfo.frames_lost; 09076 locallosspct = jbinfo.losspct/1000; 09077 localdropped = jbinfo.frames_dropped; 09078 localooo = jbinfo.frames_ooo; 09079 localpackets = jbinfo.frames_in; 09080 } 09081 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", 09082 iaxs[callno]->owner->name, 09083 iaxs[callno]->pingtime, 09084 localjitter, 09085 localdelay, 09086 locallost, 09087 locallosspct, 09088 localdropped, 09089 localooo, 09090 localpackets, 09091 iaxs[callno]->remote_rr.jitter, 09092 iaxs[callno]->remote_rr.delay, 09093 iaxs[callno]->remote_rr.losscnt, 09094 iaxs[callno]->remote_rr.losspct/1000, 09095 iaxs[callno]->remote_rr.dropped, 09096 iaxs[callno]->remote_rr.ooo, 09097 iaxs[callno]->remote_rr.packets); 09098 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", 09099 iaxs[callno]->owner->name, 09100 iaxs[callno]->pingtime, 09101 localjitter, 09102 localdelay, 09103 locallost, 09104 locallosspct, 09105 localdropped, 09106 localooo, 09107 localpackets, 09108 iaxs[callno]->remote_rr.jitter, 09109 iaxs[callno]->remote_rr.delay, 09110 iaxs[callno]->remote_rr.losscnt, 09111 iaxs[callno]->remote_rr.losspct/1000, 09112 iaxs[callno]->remote_rr.dropped, 09113 iaxs[callno]->remote_rr.ooo, 09114 iaxs[callno]->remote_rr.packets); 09115 } 09116 ast_mutex_unlock(&iaxsl[callno]); 09117 }
| static int make_trunk | ( | unsigned short | callno, | |
| int | locked | |||
| ) | [static] |
Definition at line 1885 of file chan_iax2.c.
References ast_debug, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_thread_del, chan_iax2_pvt::callno, callno_entry::callno, chan_iax2_pvt::callno_entry, get_unused_callno(), iax2_sched_add(), 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().
01886 { 01887 int x; 01888 int res= 0; 01889 struct callno_entry *callno_entry; 01890 if (iaxs[callno]->oseqno) { 01891 ast_log(LOG_WARNING, "Can't make trunk once a call has started!\n"); 01892 return -1; 01893 } 01894 if (callno & TRUNK_CALL_START) { 01895 ast_log(LOG_WARNING, "Call %d is already a trunk\n", callno); 01896 return -1; 01897 } 01898 01899 if (!(callno_entry = get_unused_callno(1, iaxs[callno]->callno_entry->validated))) { 01900 ast_log(LOG_WARNING, "Unable to trunk call: Insufficient space\n"); 01901 return -1; 01902 } 01903 01904 x = callno_entry->callno; 01905 ast_mutex_lock(&iaxsl[x]); 01906 01907 /*! 01908 * \note We delete these before switching the slot, because if 01909 * they fire in the meantime, they will generate a warning. 01910 */ 01911 ast_sched_thread_del(sched, iaxs[callno]->pingid); 01912 ast_sched_thread_del(sched, iaxs[callno]->lagid); 01913 iaxs[x] = iaxs[callno]; 01914 iaxs[x]->callno = x; 01915 01916 /* since we copied over the pvt from a different callno, make sure the old entry is replaced 01917 * before assigning the new one */ 01918 if (iaxs[x]->callno_entry) { 01919 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, iaxs[x]->callno_entry); 01920 } 01921 iaxs[x]->callno_entry = callno_entry; 01922 01923 iaxs[callno] = NULL; 01924 /* Update the two timers that should have been started */ 01925 iaxs[x]->pingid = iax2_sched_add(sched, 01926 ping_time * 1000, send_ping, (void *)(long)x); 01927 iaxs[x]->lagid = iax2_sched_add(sched, 01928 lagrq_time * 1000, send_lagrq, (void *)(long)x); 01929 01930 if (locked) 01931 ast_mutex_unlock(&iaxsl[callno]); 01932 res = x; 01933 if (!locked) 01934 ast_mutex_unlock(&iaxsl[x]); 01935 01936 ast_debug(1, "Made call %d into trunk call %d\n", callno, x); 01937 /* We move this call from a non-trunked to a trunked call */ 01938 update_max_trunk(); 01939 update_max_nontrunk(); 01940 return res; 01941 }
| static int manager_iax2_show_netstats | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 6616 of file chan_iax2.c.
References ast_cli_netstats(), astman_append(), and RESULT_SUCCESS.
Referenced by load_module().
06617 { 06618 ast_cli_netstats(s, -1, 0); 06619 astman_append(s, "\r\n"); 06620 return RESULT_SUCCESS; 06621 }
| 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 6668 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_str_alloca, ast_str_buffer(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), iax2_peer::encmethods, encmethods_to_str(), IAX_DYNAMIC, IAX_TRUNK, iax2_peer::mask, iax2_peer::name, peer_status(), peer_unref(), RESULT_SUCCESS, status, and iax2_peer::username.
Referenced by load_module().
06669 { 06670 struct iax2_peer *peer = NULL; 06671 int peer_count = 0; 06672 char nm[20]; 06673 char status[20]; 06674 const char *id = astman_get_header(m,"ActionID"); 06675 char idtext[256] = ""; 06676 struct ast_str *encmethods = ast_str_alloca(256); 06677 struct ao2_iterator i; 06678 06679 if (!ast_strlen_zero(id)) 06680 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06681 06682 astman_append(s, "Response: Success\r\n%sMessage: IAX Peer status list will follow\r\n\r\n", idtext); 06683 06684 06685 i = ao2_iterator_init(peers, 0); 06686 for (peer = ao2_iterator_next(&i); peer; peer_unref(peer), peer = ao2_iterator_next(&i)) { 06687 encmethods_to_str(peer->encmethods, encmethods); 06688 astman_append(s, "Event: PeerEntry\r\n%sChanneltype: IAX\r\n", idtext); 06689 if (!ast_strlen_zero(peer->username)) { 06690 astman_append(s, "ObjectName: %s\r\nObjectUsername: %s\r\n", peer->name, peer->username); 06691 } else { 06692 astman_append(s, "ObjectName: %s\r\n", peer->name); 06693 } 06694 astman_append(s, "ChanObjectType: peer\r\n"); 06695 astman_append(s, "IPaddress: %s\r\n", peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-"); 06696 ast_copy_string(nm, ast_inet_ntoa(peer->mask), sizeof(nm)); 06697 astman_append(s, "Mask: %s\r\n", nm); 06698 astman_append(s, "Port: %d\r\n", ntohs(peer->addr.sin_port)); 06699 astman_append(s, "Dynamic: %s\r\n", ast_test_flag(peer, IAX_DYNAMIC) ? "Yes" : "No"); 06700 astman_append(s, "Trunk: %s\r\n", ast_test_flag(peer, IAX_TRUNK) ? "Yes" : "No"); 06701 astman_append(s, "Encryption: %s\r\n", peer->encmethods ? ast_str_buffer(encmethods) : "No"); 06702 peer_status(peer, status, sizeof(status)); 06703 astman_append(s, "Status: %s\r\n\r\n", status); 06704 peer_count++; 06705 } 06706 ao2_iterator_destroy(&i); 06707 06708 astman_append(s, "Event: PeerlistComplete\r\n%sListItems: %d\r\n\r\n", idtext, peer_count); 06709 return RESULT_SUCCESS; 06710 }
| static int manager_iax2_show_peers | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
callback to display iax peers in manager
Definition at line 6655 of file chan_iax2.c.
References __iax2_show_peers(), ast_strlen_zero(), astman_get_header(), and astman_send_ack().
Referenced by load_module().
06656 { 06657 char *a[] = { "iax2", "show", "users" }; 06658 const char *id = astman_get_header(m,"ActionID"); 06659 char idtext[256] = ""; 06660 06661 if (!ast_strlen_zero(id)) 06662 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06663 astman_send_ack(s, m, "Peer status list will follow"); 06664 return __iax2_show_peers(1, -1, s, 3, a ); 06665 }
| static int manager_iax2_show_registry | ( | struct mansession * | s, | |
| const struct message * | m | |||
| ) | [static] |
Definition at line 6776 of file chan_iax2.c.
References iax2_registry::addr, ast_copy_string(), ast_inet_ntoa(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), iax2_registry::dnsmgr, iax2_registry::refresh, iax2_registry::regstate, regstate2str(), total, iax2_registry::us, and iax2_registry::username.
Referenced by load_module().
06777 { 06778 const char *id = astman_get_header(m, "ActionID"); 06779 struct iax2_registry *reg = NULL; 06780 char idtext[256] = ""; 06781 char host[80] = ""; 06782 char perceived[80] = ""; 06783 int total = 0; 06784 06785 if (!ast_strlen_zero(id)) 06786 snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id); 06787 06788 astman_send_listack(s, m, "Registrations will follow", "start"); 06789 06790 AST_LIST_LOCK(®istrations); 06791 AST_LIST_TRAVERSE(®istrations, reg, entry) { 06792 snprintf(host, sizeof(host), "%s:%d", ast_inet_ntoa(reg->addr.sin_addr), ntohs(reg->addr.sin_port)); 06793 06794 if (reg->us.sin_addr.s_addr) { 06795 snprintf(perceived, sizeof(perceived), "%s:%d", ast_inet_ntoa(reg->us.sin_addr), ntohs(reg->us.sin_port)); 06796 } else { 06797 ast_copy_string(perceived, "<Unregistered>", sizeof(perceived)); 06798 } 06799 06800 astman_append(s, 06801 "Event: RegistryEntry\r\n" 06802 "Host: %s\r\n" 06803 "DNSmanager: %s\r\n" 06804 "Username: %s\r\n" 06805 "Perceived: %s\r\n" 06806 "Refresh: %d\r\n" 06807 "State: %s\r\n" 06808 "\r\n", host, (reg->dnsmgr) ? "Y" : "N", reg->username, perceived, 06809 reg->refresh, regstate2str(reg->regstate)); 06810 06811 total++; 06812 } 06813 AST_LIST_UNLOCK(®istrations); 06814 06815 astman_append(s, 06816 "Event: RegistrationsComplete\r\n" 06817 "EventList: Complete\r\n" 06818 "ListItems: %d\r\n" 06819 "%s" 06820 "\r\n", total, idtext); 06821 06822 return 0; 06823 }
| 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 1834 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_by_name(), find_command(), handle_updates(), lua_find_extension(), pbx_find_extension(), pvt_cmp_cb(), realtime_switch_common(), and transfercallno_pvt_cmp_cb().
01835 { 01836 if ((cur->addr.sin_addr.s_addr == sin->sin_addr.s_addr) && 01837 (cur->addr.sin_port == sin->sin_port)) { 01838 /* This is the main host */ 01839 if ( (cur->peercallno == 0 || cur->peercallno == callno) && 01840 (check_dcallno ? dcallno == cur->callno : 1) ) { 01841 /* That's us. Be sure we keep track of the peer call number */ 01842 return 1; 01843 } 01844 } 01845 if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && 01846 (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { 01847 /* We're transferring */ 01848 if ((dcallno == cur->callno) || (cur->transferring == TRANSFER_MEDIAPASS && cur->transfercallno == callno)) 01849 return 1; 01850 } 01851 return 0; 01852 }
| static void memcpy_decrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_decrypt_key * | dcx | |||
| ) | [static] |
Definition at line 5883 of file chan_iax2.c.
References ast_aes_decrypt, ast_log(), and LOG_WARNING.
Referenced by decode_frame().
05884 { 05885 #if 0 05886 /* Debug with "fake encryption" */ 05887 int x; 05888 if (len % 16) 05889 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05890 for (x=0;x<len;x++) 05891 dst[x] = src[x] ^ 0xff; 05892 #else 05893 unsigned char lastblock[16] = { 0 }; 05894 int x; 05895 while(len > 0) { 05896 ast_aes_decrypt(src, dst, dcx); 05897 for (x=0;x<16;x++) 05898 dst[x] ^= lastblock[x]; 05899 memcpy(lastblock, src, sizeof(lastblock)); 05900 dst += 16; 05901 src += 16; 05902 len -= 16; 05903 } 05904 #endif 05905 }
| static void memcpy_encrypt | ( | unsigned char * | dst, | |
| const unsigned char * | src, | |||
| int | len, | |||
| ast_aes_encrypt_key * | ecx | |||
| ) | [static] |
Definition at line 5907 of file chan_iax2.c.
References ast_aes_encrypt, ast_log(), and LOG_WARNING.
Referenced by encrypt_frame().
05908 { 05909 #if 0 05910 /* Debug with "fake encryption" */ 05911 int x; 05912 if (len % 16) 05913 ast_log(LOG_WARNING, "len should be multiple of 16, not %d!\n", len); 05914 for (x=0;x<len;x++) 05915 dst[x] = src[x] ^ 0xff; 05916 #else 05917 unsigned char curblock[16] = { 0 }; 05918 int x; 05919 while(len > 0) { 05920 for (x=0;x<16;x++) 05921 curblock[x] ^= src[x]; 05922 ast_aes_encrypt(curblock, dst, ecx); 05923 memcpy(curblock, dst, sizeof(curblock)); 05924 dst += 16; 05925 src += 16; 05926 len -= 16; 05927 } 05928 #endif 05929 }
| static void merge_encryption | ( | struct chan_iax2_pvt * | p, | |
| unsigned int | enc | |||
| ) | [static] |
Definition at line 7441 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().
07442 { 07443 /* Select exactly one common encryption if there are any */ 07444 p->encmethods &= enc; 07445 if (p->encmethods) { 07446 if (!(p->encmethods & IAX_ENCRYPT_KEYROTATE)){ /* if key rotation is not supported, turn off keyrotation. */ 07447 p->keyrotateid = -2; 07448 } 07449 if (p->encmethods & IAX_ENCRYPT_AES128) 07450 p->encmethods = IAX_ENCRYPT_AES128; 07451 else 07452 p->encmethods = 0; 07453 } 07454 }
| static void mwi_event_cb | ( | const struct ast_event * | event, | |
| void * | userdata | |||
| ) | [static] |
Definition at line 1183 of file chan_iax2.c.
Referenced by build_peer().
| static void* network_thread | ( | void * | ignore | ) | [static] |
Definition at line 11640 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().
11641 { 11642 /* Our job is simple: Send queued messages, retrying if necessary. Read frames 11643 from the network, and queue them for delivery to the channels */ 11644 int res, count, wakeup; 11645 struct iax_frame *f; 11646 11647 if (timer) 11648 ast_io_add(io, ast_timer_fd(timer), timing_read, AST_IO_IN | AST_IO_PRI, NULL); 11649 11650 for(;;) { 11651 pthread_testcancel(); 11652 11653 /* Go through the queue, sending messages which have not yet been 11654 sent, and scheduling retransmissions if appropriate */ 11655 AST_LIST_LOCK(&frame_queue); 11656 count = 0; 11657 wakeup = -1; 11658 AST_LIST_TRAVERSE_SAFE_BEGIN(&frame_queue, f, list) { 11659 if (f->sentyet) 11660 continue; 11661 11662 /* Try to lock the pvt, if we can't... don't fret - defer it till later */ 11663 if (ast_mutex_trylock(&iaxsl[f->callno])) { 11664 wakeup = 1; 11665 continue; 11666 } 11667 11668 f->sentyet = 1; 11669 11670 if (iaxs[f->callno]) { 11671 send_packet(f); 11672 count++; 11673 } 11674 11675 ast_mutex_unlock(&iaxsl[f->callno]); 11676 11677 if (f->retries < 0) { 11678 /* This is not supposed to be retransmitted */ 11679 AST_LIST_REMOVE_CURRENT(list); 11680 /* Free the iax frame */ 11681 iax_frame_free(f); 11682 } else { 11683 /* We need reliable delivery. Schedule a retransmission */ 11684 f->retries++; 11685 f->retrans = iax2_sched_add(sched, f->retrytime, attempt_transmit, f); 11686 } 11687 } 11688 AST_LIST_TRAVERSE_SAFE_END; 11689 AST_LIST_UNLOCK(&frame_queue); 11690 11691 pthread_testcancel(); 11692 if (count >= 20) 11693 ast_debug(1, "chan_iax2: Sent %d queued outbound frames all at once\n", count); 11694 11695 /* Now do the IO, and run scheduled tasks */ 11696 res = ast_io_wait(io, wakeup); 11697 if (res >= 0) { 11698 if (res >= 20) 11699 ast_debug(1, "chan_iax2: ast_io_wait ran %d I/Os all at once\n", res); 11700 } 11701 } 11702 return NULL; 11703 }
| static struct chan_iax2_pvt* new_iax | ( | struct sockaddr_in * | sin, | |
| const char * | host | |||
| ) | [static, read] |
Definition at line 1763 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().
01764 { 01765 struct chan_iax2_pvt *tmp; 01766 jb_conf jbconf; 01767 01768 if (!(tmp = ao2_alloc(sizeof(*tmp), pvt_destructor))) { 01769 return NULL; 01770 } 01771 01772 if (ast_string_field_init(tmp, 32)) { 01773 ao2_ref(tmp, -1); 01774 tmp = NULL; 01775 return NULL; 01776 } 01777 01778 tmp->prefs = prefs; 01779 tmp->pingid = -1; 01780 tmp->lagid = -1; 01781 tmp->autoid = -1; 01782 tmp->authid = -1; 01783 tmp->initid = -1; 01784 tmp->keyrotateid = -1; 01785 01786 ast_string_field_set(tmp,exten, "s"); 01787 ast_string_field_set(tmp,host, host); 01788 01789 tmp->jb = jb_new(); 01790 tmp->jbid = -1; 01791 jbconf.max_jitterbuf = maxjitterbuffer; 01792 jbconf.resync_threshold = resyncthreshold; 01793 jbconf.max_contig_interp = maxjitterinterps; 01794 jbconf.target_extra = jittertargetextra; 01795 jb_setconf(tmp->jb,&jbconf); 01796 01797 AST_LIST_HEAD_INIT_NOLOCK(&tmp->dpentries); 01798 01799 tmp->hold_signaling = 1; 01800 AST_LIST_HEAD_INIT_NOLOCK(&tmp->signaling_queue); 01801 01802 return tmp; 01803 }
| 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 4737 of file chan_iax2.c.
References ast_strip_quoted(), ast_strlen_zero(), parsed_dial_string::context, parsed_dial_string::exten, parsed_dial_string::key, parsed_dial_string::options, parsed_dial_string::password, parsed_dial_string::peer, parsed_dial_string::port, and parsed_dial_string::username.
Referenced by cache_get_callno_locked(), iax2_call(), iax2_devicestate(), and iax2_request().
04738 { 04739 if (ast_strlen_zero(data)) 04740 return; 04741 04742 pds->peer = strsep(&data, "/"); 04743 pds->exten = strsep(&data, "/"); 04744 pds->options = data; 04745 04746 if (pds->exten) { 04747 data = pds->exten; 04748 pds->exten = strsep(&data, "@"); 04749 pds->context = data; 04750 } 04751 04752 if (strchr(pds->peer, '@')) { 04753 data = pds->peer; 04754 pds->username = strsep(&data, "@"); 04755 pds->peer = data; 04756 } 04757 04758 if (pds->username) { 04759 data = pds->username; 04760 pds->username = strsep(&data, ":"); 04761 pds->password = data; 04762 } 04763 04764 data = pds->peer; 04765 pds->peer = strsep(&data, ":"); 04766 pds->port = data; 04767 04768 /* check for a key name wrapped in [] in the secret position, if found, 04769 move it to the key field instead 04770 */ 04771 if (pds->password && (pds->password[0] == '[')) { 04772 pds->key = ast_strip_quoted(pds->password, "[", "]"); 04773 pds->password = NULL; 04774 } 04775 }
| static int peer_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1511 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 12396 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
12397 { 12398 struct iax2_peer *peer = obj; 12399 12400 ast_set_flag(peer, IAX_DELME); 12401 12402 return 0; 12403 }
| static void peer_destructor | ( | void * | obj | ) | [static] |
Definition at line 11855 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().
11856 { 11857 struct iax2_peer *peer = obj; 11858 int callno = peer->callno; 11859 11860 ast_free_ha(peer->ha); 11861 11862 if (callno > 0) { 11863 ast_mutex_lock(&iaxsl[callno]); 11864 iax2_destroy(callno); 11865 ast_mutex_unlock(&iaxsl[callno]); 11866 } 11867 11868 register_peer_exten(peer, 0); 11869 11870 if (peer->dnsmgr) 11871 ast_dnsmgr_release(peer->dnsmgr); 11872 11873 if (peer->mwi_event_sub) 11874 ast_event_unsubscribe(peer->mwi_event_sub); 11875 11876 ast_string_field_free_memory(peer); 11877 }
| static int peer_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1501 of file chan_iax2.c.
References ast_str_hash(), and iax2_peer::name.
Referenced by load_objects().
01502 { 01503 const struct iax2_peer *peer = obj; 01504 01505 return ast_str_hash(peer->name); 01506 }
Definition at line 1558 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().
01559 { 01560 ao2_ref(peer, +1); 01561 return peer; 01562 }
| static int peer_set_sock_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 13700 of file chan_iax2.c.
References iax2_peer::sockfd.
Referenced by load_module().
13701 { 13702 struct iax2_peer *peer = obj; 13703 13704 if (peer->sockfd < 0) 13705 peer->sockfd = defaultsockfd; 13706 13707 return 0; 13708 }
| 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 11783 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(), check_srcaddr(), IAX_DEFAULT_PORTNO, LOG_WARNING, iax2_peer::name, qos, socket_read(), iax2_peer::sockfd, and iax2_trunk_peer::sockfd.
Referenced by build_peer().
11784 { 11785 struct sockaddr_in sin; 11786 int nonlocal = 1; 11787 int port = IAX_DEFAULT_PORTNO; 11788 int sockfd = defaultsockfd; 11789 char *tmp; 11790 char *addr; 11791 char *portstr; 11792 11793 if (!(tmp = ast_strdupa(srcaddr))) 11794 return -1; 11795 11796 addr = strsep(&tmp, ":"); 11797 portstr = tmp; 11798 11799 if (portstr) { 11800 port = atoi(portstr); 11801 if (port < 1) 11802 port = IAX_DEFAULT_PORTNO; 11803 } 11804 11805 if (!ast_get_ip(&sin, addr)) { 11806 struct ast_netsock *sock; 11807 int res; 11808 11809 sin.sin_port = 0; 11810 sin.sin_family = AF_INET; 11811 res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); 11812 if (res == 0) { 11813 /* ip address valid. */ 11814 sin.sin_port = htons(port); 11815 if (!(sock = ast_netsock_find(netsock, &sin))) 11816 sock = ast_netsock_find(outsock, &sin); 11817 if (sock) { 11818 sockfd = ast_netsock_sockfd(sock); 11819 nonlocal = 0; 11820 } else { 11821 unsigned int orig_saddr = sin.sin_addr.s_addr; 11822 /* INADDR_ANY matches anyway! */ 11823 sin.sin_addr.s_addr = INADDR_ANY; 11824 if (ast_netsock_find(netsock, &sin)) { 11825 sin.sin_addr.s_addr = orig_saddr; 11826 sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); 11827 if (sock) { 11828 sockfd = ast_netsock_sockfd(sock); 11829 ast_netsock_unref(sock); 11830 nonlocal = 0; 11831 } else { 11832 nonlocal = 2; 11833 } 11834 } 11835 } 11836 } 11837 } 11838 11839 peer->sockfd = sockfd; 11840 11841 if (nonlocal == 1) { 11842 ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", 11843 srcaddr, peer->name); 11844 return -1; 11845 } else if (nonlocal == 2) { 11846 ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", 11847 srcaddr, peer->name); 11848 return -1; 11849 } else { 11850 ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); 11851 return 0; 11852 } 11853 }
| static int peer_status | ( | struct iax2_peer * | peer, | |
| char * | status, | |||
| int | statuslen | |||
| ) | [static] |
peer_status: Report Peer status in character string
Definition at line 3545 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().
03546 { 03547 int res = 0; 03548 if (peer->maxms) { 03549 if (peer->lastms < 0) { 03550 ast_copy_string(status, "UNREACHABLE", statuslen); 03551 } else if (peer->lastms > peer->maxms) { 03552 snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms); 03553 res = 1; 03554 } else if (peer->lastms) { 03555 snprintf(status, statuslen, "OK (%d ms)", peer->lastms); 03556 res = 1; 03557 } else { 03558 ast_copy_string(status, "UNKNOWN", statuslen); 03559 } 03560 } else { 03561 ast_copy_string(status, "Unmonitored", statuslen); 03562 res = -1; 03563 } 03564 return res; 03565 }
Definition at line 1564 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().
01565 { 01566 ao2_ref(peer, -1); 01567 return NULL; 01568 }
| static int peercnt_add | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2169 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().
02170 { 02171 struct peercnt *peercnt; 02172 unsigned long addr = sin->sin_addr.s_addr; 02173 int res = 0; 02174 struct peercnt tmp = { 02175 .addr = addr, 02176 }; 02177 02178 /* Reasoning for peercnts container lock: Two identical ip addresses 02179 * could be added by different threads at the "same time". Without the container 02180 * lock, both threads could alloc space for the same object and attempt 02181 * to link to table. With the lock, one would create the object and link 02182 * to table while the other would find the already created peercnt object 02183 * rather than creating a new one. */ 02184 ao2_lock(peercnts); 02185 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02186 ao2_lock(peercnt); 02187 } else if ((peercnt = ao2_alloc(sizeof(*peercnt), NULL))) { 02188 ao2_lock(peercnt); 02189 /* create and set defaults */ 02190 peercnt->addr = addr; 02191 set_peercnt_limit(peercnt); 02192 /* guarantees it does not go away after unlocking table 02193 * ao2_find automatically adds this */ 02194 ao2_link(peercnts, peercnt); 02195 } else { 02196 ao2_unlock(peercnts); 02197 return -1; 02198 } 02199 02200 /* check to see if the address has hit its callno limit. If not increment cur. */ 02201 if (peercnt->limit > peercnt->cur) { 02202 peercnt->cur++; 02203 ast_debug(1, "ip callno count incremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin->sin_addr)); 02204 } else { /* max num call numbers for this peer has been reached! */ 02205 ast_log(LOG_ERROR, "maxcallnumber limit of %d for %s has been reached!\n", peercnt->limit, ast_inet_ntoa(sin->sin_addr)); 02206 res = -1; 02207 } 02208 02209 /* clean up locks and ref count */ 02210 ao2_unlock(peercnt); 02211 ao2_unlock(peercnts); 02212 ao2_ref(peercnt, -1); /* decrement ref from find/alloc, only the container ref remains. */ 02213 02214 return res; 02215 }
| static int peercnt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2009 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 2003 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 2141 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().
02142 { 02143 /* this function turns off and on custom callno limits set by peer registration */ 02144 struct peercnt *peercnt; 02145 struct peercnt tmp = { 02146 .addr = sin->sin_addr.s_addr, 02147 }; 02148 02149 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02150 peercnt->reg = reg; 02151 if (limit) { 02152 peercnt->limit = limit; 02153 } else { 02154 set_peercnt_limit(peercnt); 02155 } 02156 ast_debug(1, "peercnt entry %s modified limit:%d registered:%d", ast_inet_ntoa(sin->sin_addr), peercnt->limit, peercnt->reg); 02157 ao2_ref(peercnt, -1); /* decrement ref from find */ 02158 } 02159 }
| static void peercnt_remove | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2221 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().
02222 { 02223 struct sockaddr_in sin = { 02224 .sin_addr.s_addr = peercnt->addr, 02225 }; 02226 02227 if (peercnt) { 02228 /* Container locked here since peercnt may be unlinked from list. If left unlocked, 02229 * peercnt_add could try and grab this entry from the table and modify it at the 02230 * "same time" this thread attemps to unlink it.*/ 02231 ao2_lock(peercnts); 02232 peercnt->cur--; 02233 ast_debug(1, "ip callno count decremented to %d for %s\n", peercnt->cur, ast_inet_ntoa(sin.sin_addr)); 02234 /* if this was the last connection from the peer remove it from table */ 02235 if (peercnt->cur == 0) { 02236 ao2_unlink(peercnts, peercnt);/* decrements ref from table, last ref is left to scheduler */ 02237 } 02238 ao2_unlock(peercnts); 02239 } 02240 }
| static int peercnt_remove_by_addr | ( | struct sockaddr_in * | sin | ) | [static] |
Definition at line 2260 of file chan_iax2.c.
References peercnt::addr, ao2_find, ao2_ref, OBJ_POINTER, and peercnt_remove().
Referenced by __find_callno(), and complete_transfer().
02261 { 02262 struct peercnt *peercnt; 02263 struct peercnt tmp = { 02264 .addr = sin->sin_addr.s_addr, 02265 }; 02266 02267 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02268 peercnt_remove(peercnt); 02269 ao2_ref(peercnt, -1); /* decrement ref from find */ 02270 } 02271 return 0; 02272 }
| static int peercnt_remove_cb | ( | const void * | obj | ) | [static] |
Definition at line 2246 of file chan_iax2.c.
References ao2_ref, and peercnt_remove().
Referenced by sched_delay_remove().
02247 { 02248 struct peercnt *peercnt = (struct peercnt *) obj; 02249 02250 peercnt_remove(peercnt); 02251 ao2_ref(peercnt, -1); /* decrement ref from scheduler */ 02252 02253 return 0; 02254 }
| static void poke_all_peers | ( | void | ) | [static] |
Definition at line 12935 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().
12936 { 12937 struct ao2_iterator i; 12938 struct iax2_peer *peer; 12939 12940 i = ao2_iterator_init(peers, 0); 12941 while ((peer = ao2_iterator_next(&i))) { 12942 iax2_poke_peer(peer, 0); 12943 peer_unref(peer); 12944 } 12945 ao2_iterator_destroy(&i); 12946 }
| static int prune_addr_range_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2130 of file chan_iax2.c.
References CMP_MATCH, and addr_range::delme.
Referenced by reload_config().
02131 { 02132 struct addr_range *addr_range = obj; 02133 02134 return addr_range->delme ? CMP_MATCH : 0; 02135 }
| static void prune_peers | ( | void | ) | [static] |
Definition at line 12459 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().
12460 { 12461 struct iax2_peer *peer; 12462 struct ao2_iterator i; 12463 12464 i = ao2_iterator_init(peers, 0); 12465 while ((peer = ao2_iterator_next(&i))) { 12466 if (ast_test_flag(peer, IAX_DELME) || ast_test_flag(peer, IAX_RTCACHEFRIENDS)) { 12467 unlink_peer(peer); 12468 } 12469 peer_unref(peer); 12470 } 12471 ao2_iterator_destroy(&i); 12472 }
| static void prune_users | ( | void | ) | [static] |
Definition at line 12443 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().
12444 { 12445 struct iax2_user *user; 12446 struct ao2_iterator i; 12447 12448 i = ao2_iterator_init(users, 0); 12449 while ((user = ao2_iterator_next(&i))) { 12450 if (ast_test_flag(user, IAX_DELME) || ast_test_flag(user, IAX_RTCACHEFRIENDS)) { 12451 ao2_unlink(users, user); 12452 } 12453 user_unref(user); 12454 } 12455 ao2_iterator_destroy(&i); 12456 }
| static int pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 13717 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
13718 { 13719 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 13720 13721 /* The frames_received field is used to hold whether we're matching 13722 * against a full frame or not ... */ 13723 13724 return match(&pvt2->addr, pvt2->peercallno, pvt2->callno, pvt, 13725 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 13726 }
| static void pvt_destructor | ( | void * | obj | ) | [static] |
Definition at line 1715 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().
01716 { 01717 struct chan_iax2_pvt *pvt = obj; 01718 struct iax_frame *cur = NULL; 01719 struct signaling_queue_entry *s = NULL; 01720 01721 ast_mutex_lock(&iaxsl[pvt->callno]); 01722 iax2_destroy_helper(pvt); 01723 sched_delay_remove(&pvt->addr, pvt->callno_entry); 01724 pvt->callno_entry = NULL; 01725 ast_mutex_unlock(&iaxsl[pvt->callno]); 01726 01727 /* Already gone */ 01728 ast_set_flag(pvt, IAX_ALREADYGONE); 01729 01730 AST_LIST_LOCK(&frame_queue); 01731 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 01732 /* Cancel any pending transmissions */ 01733 if (cur->callno == pvt->callno) { 01734 cur->retries = -1; 01735 } 01736 } 01737 AST_LIST_UNLOCK(&frame_queue); 01738 01739 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01740 free_signaling_queue_entry(s); 01741 } 01742 01743 if (pvt->reg) { 01744 pvt->reg->callno = 0; 01745 } 01746 01747 if (!pvt->owner) { 01748 jb_frame frame; 01749 if (pvt->vars) { 01750 ast_variables_destroy(pvt->vars); 01751 pvt->vars = NULL; 01752 } 01753 01754 while (jb_getall(pvt->jb, &frame) == JB_OK) { 01755 iax2_frame_free(frame.data); 01756 } 01757 01758 jb_destroy(pvt->jb); 01759 ast_string_field_free_memory(pvt); 01760 } 01761 }
| static int pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 13710 of file chan_iax2.c.
References chan_iax2_pvt::peercallno.
Referenced by load_objects().
13711 { 13712 const struct chan_iax2_pvt *pvt = obj; 13713 13714 return pvt->peercallno; 13715 }
| 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 1691 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().
01692 { 01693 struct signaling_queue_entry *new; 01694 01695 if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) { 01696 return 1; /* do not queue this frame */ 01697 } else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) { 01698 return -1; /* out of memory */ 01699 } 01700 01701 memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */ 01702 01703 if (new->f.datalen) { /* if there is data in this frame copy it over as well */ 01704 if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) { 01705 free_signaling_queue_entry(new); 01706 return -1; 01707 } 01708 memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr)); 01709 } 01710 AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next); 01711 01712 return 0; 01713 }
| static int raw_hangup | ( | struct sockaddr_in * | sin, | |
| unsigned short | src, | |||
| unsigned short | dst, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 7422 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().
07423 { 07424 struct ast_iax2_full_hdr fh; 07425 fh.scallno = htons(src | IAX_FLAG_FULL); 07426 fh.dcallno = htons(dst); 07427 fh.ts = 0; 07428 fh.oseqno = 0; 07429 fh.iseqno = 0; 07430 fh.type = AST_FRAME_IAX; 07431 fh.csub = compress_subclass(IAX_COMMAND_INVAL); 07432 iax_outputframe(NULL, &fh, 0, sin, 0); 07433 #if 0 07434 if (option_debug) 07435 #endif 07436 ast_debug(1, "Raw Hangup %s:%d, src=%d, dst=%d\n", 07437 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), src, dst); 07438 return sendto(sockfd, &fh, sizeof(fh), 0, (struct sockaddr *)sin, sizeof(*sin)); 07439 }
| static struct iax2_peer * realtime_peer | ( | const char * | peername, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4115 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_thread_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().
04116 { 04117 struct ast_variable *var = NULL; 04118 struct ast_variable *tmp; 04119 struct iax2_peer *peer=NULL; 04120 time_t regseconds = 0, nowtime; 04121 int dynamic=0; 04122 04123 if (peername) { 04124 var = ast_load_realtime("iaxpeers", "name", peername, "host", "dynamic", SENTINEL); 04125 if (!var && sin) 04126 var = ast_load_realtime("iaxpeers", "name", peername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04127 } else if (sin) { 04128 char porta[25]; 04129 sprintf(porta, "%d", ntohs(sin->sin_port)); 04130 var = ast_load_realtime("iaxpeers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04131 if (var) { 04132 /* We'll need the peer name in order to build the structure! */ 04133 for (tmp = var; tmp; tmp = tmp->next) { 04134 if (!strcasecmp(tmp->name, "name")) 04135 peername = tmp->value; 04136 } 04137 } 04138 } 04139 if (!var && peername) { /* Last ditch effort */ 04140 var = ast_load_realtime("iaxpeers", "name", peername, SENTINEL); 04141 /*!\note 04142 * If this one loaded something, then we need to ensure that the host 04143 * field matched. The only reason why we can't have this as a criteria 04144 * is because we only have the IP address and the host field might be 04145 * set as a name (and the reverse PTR might not match). 04146 */ 04147 if (var && sin) { 04148 for (tmp = var; tmp; tmp = tmp->next) { 04149 if (!strcasecmp(tmp->name, "host")) { 04150 struct ast_hostent ahp; 04151 struct hostent *hp; 04152 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04153 /* No match */ 04154 ast_variables_destroy(var); 04155 var = NULL; 04156 } 04157 break; 04158 } 04159 } 04160 } 04161 } 04162 if (!var) 04163 return NULL; 04164 04165 peer = build_peer(peername, var, NULL, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); 04166 04167 if (!peer) { 04168 ast_variables_destroy(var); 04169 return NULL; 04170 } 04171 04172 for (tmp = var; tmp; tmp = tmp->next) { 04173 /* Make sure it's not a user only... */ 04174 if (!strcasecmp(tmp->name, "type")) { 04175 if (strcasecmp(tmp->value, "friend") && 04176 strcasecmp(tmp->value, "peer")) { 04177 /* Whoops, we weren't supposed to exist! */ 04178 peer = peer_unref(peer); 04179 break; 04180 } 04181 } else if (!strcasecmp(tmp->name, "regseconds")) { 04182 ast_get_time_t(tmp->value, ®seconds, 0, NULL); 04183 } else if (!strcasecmp(tmp->name, "ipaddr")) { 04184 inet_aton(tmp->value, &(peer->addr.sin_addr)); 04185 } else if (!strcasecmp(tmp->name, "port")) { 04186 peer->addr.sin_port = htons(atoi(tmp->value)); 04187 } else if (!strcasecmp(tmp->name, "host")) { 04188 if (!strcasecmp(tmp->value, "dynamic")) 04189 dynamic = 1; 04190 } 04191 } 04192 04193 ast_variables_destroy(var); 04194 04195 if (!peer) 04196 return NULL; 04197 04198 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 04199 ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); 04200 if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { 04201 if (peer->expire > -1) { 04202 if (!ast_sched_thread_del(sched, peer->expire)) { 04203 peer->expire = -1; 04204 peer_unref(peer); 04205 } 04206 } 04207 peer->expire = iax2_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer_ref(peer)); 04208 if (peer->expire == -1) 04209 peer_unref(peer); 04210 } 04211 ao2_link(peers, peer); 04212 if (ast_test_flag(peer, IAX_DYNAMIC)) 04213 reg_source_db(peer); 04214 } else { 04215 ast_set_flag(peer, IAX_TEMPONLY); 04216 } 04217 04218 if (!ast_test_flag(&globalflags, IAX_RTIGNOREREGEXPIRE) && dynamic) { 04219 time(&nowtime); 04220 if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { 04221 memset(&peer->addr, 0, sizeof(peer->addr)); 04222 realtime_update_peer(peer->name, &peer->addr, 0); 04223 ast_debug(1, "realtime_peer: Bah, '%s' is expired (%d/%d/%d)!\n", 04224 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04225 } 04226 else { 04227 ast_debug(1, "realtime_peer: Registration for '%s' still active (%d/%d/%d)!\n", 04228 peername, (int)(nowtime - regseconds), (int)regseconds, (int)nowtime); 04229 } 04230 } 04231 04232 return peer; 04233 }
| static void realtime_update_peer | ( | const char * | peername, | |
| struct sockaddr_in * | sin, | |||
| time_t | regtime | |||
| ) | [static] |
Definition at line 4306 of file chan_iax2.c.
References ast_inet_ntoa(), ast_update_realtime(), and SENTINEL.
Referenced by __expire_registry(), realtime_peer(), and update_registry().
04307 { 04308 char port[10]; 04309 char regseconds[20]; 04310 04311 snprintf(regseconds, sizeof(regseconds), "%d", (int)regtime); 04312 snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port)); 04313 ast_update_realtime("iaxpeers", "name", peername, 04314 "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", port, 04315 "regseconds", regseconds, SENTINEL); 04316 }
| static struct iax2_user * realtime_user | ( | const char * | username, | |
| struct sockaddr_in * | sin | |||
| ) | [static, read] |
Definition at line 4235 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().
04236 { 04237 struct ast_variable *var; 04238 struct ast_variable *tmp; 04239 struct iax2_user *user=NULL; 04240 04241 var = ast_load_realtime("iaxusers", "name", username, "host", "dynamic", SENTINEL); 04242 if (!var) 04243 var = ast_load_realtime("iaxusers", "name", username, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL); 04244 if (!var && sin) { 04245 char porta[6]; 04246 snprintf(porta, sizeof(porta), "%d", ntohs(sin->sin_port)); 04247 var = ast_load_realtime("iaxusers", "name", username, "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04248 if (!var) 04249 var = ast_load_realtime("iaxusers", "ipaddr", ast_inet_ntoa(sin->sin_addr), "port", porta, SENTINEL); 04250 } 04251 if (!var) { /* Last ditch effort */ 04252 var = ast_load_realtime("iaxusers", "name", username, SENTINEL); 04253 /*!\note 04254 * If this one loaded something, then we need to ensure that the host 04255 * field matched. The only reason why we can't have this as a criteria 04256 * is because we only have the IP address and the host field might be 04257 * set as a name (and the reverse PTR might not match). 04258 */ 04259 if (var) { 04260 for (tmp = var; tmp; tmp = tmp->next) { 04261 if (!strcasecmp(tmp->name, "host")) { 04262 struct ast_hostent ahp; 04263 struct hostent *hp; 04264 if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) { 04265 /* No match */ 04266 ast_variables_destroy(var); 04267 var = NULL; 04268 } 04269 break; 04270 } 04271 } 04272 } 04273 } 04274 if (!var) 04275 return NULL; 04276 04277 tmp = var; 04278 while(tmp) { 04279 /* Make sure it's not a peer only... */ 04280 if (!strcasecmp(tmp->name, "type")) { 04281 if (strcasecmp(tmp->value, "friend") && 04282 strcasecmp(tmp->value, "user")) { 04283 return NULL; 04284 } 04285 } 04286 tmp = tmp->next; 04287 } 04288 04289 user = build_user(username, var, NULL, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); 04290 04291 ast_variables_destroy(var); 04292 04293 if (!user) 04294 return NULL; 04295 04296 if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { 04297 ast_set_flag(user, IAX_RTCACHEFRIENDS); 04298 ao2_link(users, user); 04299 } else { 04300 ast_set_flag(user, IAX_TEMPONLY); 04301 } 04302 04303 return user; 04304 }
| static void reg_source_db | ( | struct iax2_peer * | p | ) | [static] |
Definition at line 8297 of file chan_iax2.c.
References iax2_peer::addr, ast_db_get(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_inet_ntoa(), ast_sched_thread_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().
08298 { 08299 char data[80]; 08300 struct in_addr in; 08301 char *c, *d; 08302 if (!ast_test_flag(p, IAX_TEMPONLY) && (!ast_db_get("IAX/Registry", p->name, data, sizeof(data)))) { 08303 c = strchr(data, ':'); 08304 if (c) { 08305 *c = '\0'; 08306 c++; 08307 if (inet_aton(data, &in)) { 08308 d = strchr(c, ':'); 08309 if (d) { 08310 *d = '\0'; 08311 d++; 08312 ast_verb(3, "Seeding '%s' at %s:%d for %d\n", p->name, 08313 ast_inet_ntoa(in), atoi(c), atoi(d)); 08314 iax2_poke_peer(p, 0); 08315 p->expiry = atoi(d); 08316 memset(&p->addr, 0, sizeof(p->addr)); 08317 p->addr.sin_family = AF_INET; 08318 p->addr.sin_addr = in; 08319 p->addr.sin_port = htons(atoi(c)); 08320 if (p->expire > -1) { 08321 if (!ast_sched_thread_del(sched, p->expire)) { 08322 p->expire = -1; 08323 peer_unref(p); 08324 } 08325 } 08326 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08327 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08328 if (p->expire == -1) 08329 peer_unref(p); 08330 if (iax2_regfunk) 08331 iax2_regfunk(p->name, 1); 08332 register_peer_exten(p, 1); 08333 } 08334 08335 } 08336 } 08337 } 08338 }
| static void register_peer_exten | ( | struct iax2_peer * | peer, | |
| int | onoff | |||
| ) | [static] |
Definition at line 8216 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, and S_OR.
Referenced by __expire_registry(), peer_destructor(), reg_source_db(), and update_registry().
08217 { 08218 char multi[256]; 08219 char *stringp, *ext; 08220 if (!ast_strlen_zero(regcontext)) { 08221 ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi)); 08222 stringp = multi; 08223 while((ext = strsep(&stringp, "&"))) { 08224 if (onoff) { 08225 if (!ast_exists_extension(NULL, regcontext, ext, 1, NULL)) 08226 ast_add_extension(regcontext, 1, ext, 1, NULL, NULL, 08227 "Noop", ast_strdup(peer->name), ast_free_ptr, "IAX2"); 08228 } else 08229 ast_context_remove_extension(regcontext, ext, 1, NULL); 08230 } 08231 } 08232 }
| static int register_verify | ( | int | callno, | |
| struct sockaddr_in * | sin, | |||
| struct iax_ies * | ies | |||
| ) | [static] |
Verify inbound registration.
Definition at line 7596 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_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, and iax_ies::username.
Referenced by socket_process().
07597 { 07598 char requeststr[256] = ""; 07599 char peer[256] = ""; 07600 char md5secret[256] = ""; 07601 char rsasecret[256] = ""; 07602 char secret[256] = ""; 07603 struct iax2_peer *p = NULL; 07604 struct ast_key *key; 07605 char *keyn; 07606 int x; 07607 int expire = 0; 07608 int res = -1; 07609 07610 ast_clear_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07611 /* iaxs[callno]->peer[0] = '\0'; not necc. any more-- stringfield is pre-inited to null string */ 07612 if (ies->username) 07613 ast_copy_string(peer, ies->username, sizeof(peer)); 07614 if (ies->password) 07615 ast_copy_string(secret, ies->password, sizeof(secret)); 07616 if (ies->md5_result) 07617 ast_copy_string(md5secret, ies->md5_result, sizeof(md5secret)); 07618 if (ies->rsa_result) 07619 ast_copy_string(rsasecret, ies->rsa_result, sizeof(rsasecret)); 07620 if (ies->refresh) 07621 expire = ies->refresh; 07622 07623 if (ast_strlen_zero(peer)) { 07624 ast_log(LOG_NOTICE, "Empty registration from %s\n", ast_inet_ntoa(sin->sin_addr)); 07625 return -1; 07626 } 07627 07628 /* SLD: first call to lookup peer during registration */ 07629 ast_mutex_unlock(&iaxsl[callno]); 07630 p = find_peer(peer, 1); 07631 ast_mutex_lock(&iaxsl[callno]); 07632 if (!p || !iaxs[callno]) { 07633 if (iaxs[callno]) { 07634 int plaintext = ((last_authmethod & IAX_AUTH_PLAINTEXT) | (iaxs[callno]->authmethods & IAX_AUTH_PLAINTEXT)); 07635 /* Anything, as long as it's non-blank */ 07636 ast_string_field_set(iaxs[callno], secret, "badsecret"); 07637 /* An AUTHREQ must be sent in response to a REGREQ of an invalid peer unless 07638 * 1. A challenge already exists indicating a AUTHREQ was already sent out. 07639 * 2. A plaintext secret is present in ie as result of a previous AUTHREQ requesting it. 07640 * 3. A plaintext secret is present in the ie and the last_authmethod used by a peer happened 07641 * to be plaintext, indicating it is an authmethod used by other peers on the system. 07642 * 07643 * If none of these cases exist, res will be returned as 0 without authentication indicating 07644 * an AUTHREQ needs to be sent out. */ 07645 07646 if (ast_strlen_zero(iaxs[callno]->challenge) && 07647 !(!ast_strlen_zero(secret) && plaintext)) { 07648 /* by setting res to 0, an REGAUTH will be sent */ 07649 res = 0; 07650 } 07651 } 07652 if (authdebug && !p) 07653 ast_log(LOG_NOTICE, "No registration for peer '%s' (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07654 goto return_unref; 07655 } 07656 07657 if (!ast_test_flag(p, IAX_DYNAMIC)) { 07658 if (authdebug) 07659 ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, ast_inet_ntoa(sin->sin_addr)); 07660 goto return_unref; 07661 } 07662 07663 if (!ast_apply_ha(p->ha, sin)) { 07664 if (authdebug) 07665 ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 07666 goto return_unref; 07667 } 07668 ast_string_field_set(iaxs[callno], secret, p->secret); 07669 ast_string_field_set(iaxs[callno], inkeys, p->inkeys); 07670 /* Check secret against what we have on file */ 07671 if (!ast_strlen_zero(rsasecret) && (p->authmethods & IAX_AUTH_RSA) && !ast_strlen_zero(iaxs[callno]->challenge)) { 07672 if (!ast_strlen_zero(p->inkeys)) { 07673 char tmpkeys[256]; 07674 char *stringp=NULL; 07675 ast_copy_string(tmpkeys, p->inkeys, sizeof(tmpkeys)); 07676 stringp=tmpkeys; 07677 keyn = strsep(&stringp, ":"); 07678 while(keyn) { 07679 key = ast_key_get(keyn, AST_KEY_PUBLIC); 07680 if (key && !ast_check_signature(key, iaxs[callno]->challenge, rsasecret)) { 07681 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07682 break; 07683 } else if (!key) 07684 ast_log(LOG_WARNING, "requested inkey '%s' does not exist\n", keyn); 07685 keyn = strsep(&stringp, ":"); 07686 } 07687 if (!keyn) { 07688 if (authdebug) 07689 ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); 07690 goto return_unref; 07691 } 07692 } else { 07693 if (authdebug) 07694 ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); 07695 goto return_unref; 07696 } 07697 } else if (!ast_strlen_zero(md5secret) && (p->authmethods & IAX_AUTH_MD5) && !ast_strlen_zero(iaxs[callno]->challenge)) { 07698 struct MD5Context md5; 07699 unsigned char digest[16]; 07700 char *tmppw, *stringp; 07701 07702 tmppw = ast_strdupa(p->secret); 07703 stringp = tmppw; 07704 while((tmppw = strsep(&stringp, ";"))) { 07705 MD5Init(&md5); 07706 MD5Update(&md5, (unsigned char *)iaxs[callno]->challenge, strlen(iaxs[callno]->challenge)); 07707 MD5Update(&md5, (unsigned char *)tmppw, strlen(tmppw)); 07708 MD5Final(digest, &md5); 07709 for (x=0;x<16;x++) 07710 sprintf(requeststr + (x << 1), "%2.2x", digest[x]); /* safe */ 07711 if (!strcasecmp(requeststr, md5secret)) 07712 break; 07713 } 07714 if (tmppw) { 07715 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07716 } else { 07717 if (authdebug) 07718 ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", ast_inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); 07719 goto return_unref; 07720 } 07721 } else if (!ast_strlen_zero(secret) && (p->authmethods & IAX_AUTH_PLAINTEXT)) { 07722 /* They've provided a plain text password and we support that */ 07723 if (strcmp(secret, p->secret)) { 07724 if (authdebug) 07725 ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", ast_inet_ntoa(sin->sin_addr), p->name); 07726 goto return_unref; 07727 } else 07728 ast_set_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED); 07729 } else if (!ast_strlen_zero(iaxs[callno]->challenge) && ast_strlen_zero(md5secret) && ast_strlen_zero(rsasecret)) { 07730 /* if challenge has been sent, but no challenge response if given, reject. */ 07731 goto return_unref; 07732 } 07733 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 07734 07735 /* either Authentication has taken place, or a REGAUTH must be sent before verifying registration */ 07736 res = 0; 07737 07738 return_unref: 07739 if (iaxs[callno]) { 07740 ast_string_field_set(iaxs[callno], peer, peer); 07741 07742 /* Choose lowest expiry number */ 07743 if (expire && (expire < iaxs[callno]->expiry)) { 07744 iaxs[callno]->expiry = expire; 07745 } 07746 } 07747 07748 if (p) { 07749 peer_unref(p); 07750 } 07751 return res; 07752 }
| static int registry_authrequest | ( | int | callno | ) | [static] |
Definition at line 8505 of file chan_iax2.c.
References AST_FRAME_IAX, ast_mutex_lock(), ast_mutex_unlock(), ast_random(), 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().
08506 { 08507 struct iax_ie_data ied; 08508 struct iax2_peer *p; 08509 char challenge[10]; 08510 const char *peer_name; 08511 int sentauthmethod; 08512 08513 peer_name = ast_strdupa(iaxs[callno]->peer); 08514 08515 /* SLD: third call to find_peer in registration */ 08516 ast_mutex_unlock(&iaxsl[callno]); 08517 if ((p = find_peer(peer_name, 1))) { 08518 last_authmethod = p->authmethods; 08519 } 08520 08521 ast_mutex_lock(&iaxsl[callno]); 08522 if (!iaxs[callno]) 08523 goto return_unref; 08524 08525 memset(&ied, 0, sizeof(ied)); 08526 /* The selection of which delayed reject is sent may leak information, 08527 * if it sets a static response. For example, if a host is known to only 08528 * use MD5 authentication, then an RSA response would indicate that the 08529 * peer does not exist, and vice-versa. 08530 * Therefore, we use whatever the last peer used (which may vary over the 08531 * course of a server, which should leak minimal information). */ 08532 sentauthmethod = p ? p->authmethods : last_authmethod ? last_authmethod : (IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT); 08533 if (!p) { 08534 iaxs[callno]->authmethods = sentauthmethod; 08535 } 08536 iax_ie_append_short(&ied, IAX_IE_AUTHMETHODS, sentauthmethod); 08537 if (sentauthmethod & (IAX_AUTH_RSA | IAX_AUTH_MD5)) { 08538 /* Build the challenge */ 08539 snprintf(challenge, sizeof(challenge), "%d", (int)ast_random()); 08540 ast_string_field_set(iaxs[callno], challenge, challenge); 08541 iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); 08542 } 08543 iax_ie_append_str(&ied, IAX_IE_USERNAME, peer_name); 08544 08545 return_unref: 08546 if (p) { 08547 peer_unref(p); 08548 } 08549 08550 return iaxs[callno] ? send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1) : -1; 08551 }
| static int registry_rerequest | ( | struct iax_ies * | ies, | |
| int | callno, | |||
| struct sockaddr_in * | sin | |||
| ) | [static] |
Definition at line 8553 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().
08554 { 08555 struct iax2_registry *reg; 08556 /* Start pessimistic */ 08557 struct iax_ie_data ied; 08558 char peer[256] = ""; 08559 char challenge[256] = ""; 08560 int res; 08561 int authmethods = 0; 08562 if (ies->authmethods) 08563 authmethods = ies->authmethods; 08564 if (ies->username) 08565 ast_copy_string(peer, ies->username, sizeof(peer)); 08566 if (ies->challenge) 08567 ast_copy_string(challenge, ies->challenge, sizeof(challenge)); 08568 memset(&ied, 0, sizeof(ied)); 08569 reg = iaxs[callno]->reg; 08570 if (reg) { 08571 if (inaddrcmp(®->addr, sin)) { 08572 ast_log(LOG_WARNING, "Received unsolicited registry authenticate request from '%s'\n", ast_inet_ntoa(sin->sin_addr)); 08573 return -1; 08574 } 08575 if (ast_strlen_zero(reg->secret)) { 08576 ast_log(LOG_NOTICE, "No secret associated with peer '%s'\n", reg->username); 08577 reg->regstate = REG_STATE_NOAUTH; 08578 return -1; 08579 } 08580 iax_ie_append_str(&ied, IAX_IE_USERNAME, reg->username); 08581 iax_ie_append_short(&ied, IAX_IE_REFRESH, reg->refresh); 08582 if (reg->secret[0] == '[') { 08583 char tmpkey[256]; 08584 ast_copy_string(tmpkey, reg->secret + 1, sizeof(tmpkey)); 08585 tmpkey[strlen(tmpkey) - 1] = '\0'; 08586 res = authenticate(challenge, NULL, tmpkey, authmethods, &ied, sin, NULL); 08587 } else 08588 res = authenticate(challenge, reg->secret, NULL, authmethods, &ied, sin, NULL); 08589 if (!res) { 08590 reg->regstate = REG_STATE_AUTHSENT; 08591 add_empty_calltoken_ie(iaxs[callno], &ied); /* this _MUST_ be the last ie added */ 08592 return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); 08593 } else 08594 return -1; 08595 ast_log(LOG_WARNING, "Registry acknowledge on unknown registery '%s'\n", peer); 08596 } else 08597 ast_log(LOG_NOTICE, "Can't reregister without a reg\n"); 08598 return -1; 08599 }
| static char* regstate2str | ( | int | regstate | ) | [static] |
Definition at line 6713 of file chan_iax2.c.
References REG_STATE_AUTHSENT, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REGSENT, REG_STATE_REJECTED, REG_STATE_TIMEOUT, and REG_STATE_UNREGISTERED.
Referenced by handle_cli_iax2_show_registry(), and manager_iax2_show_registry().
06714 { 06715 switch(regstate) { 06716 case REG_STATE_UNREGISTERED: 06717 return "Unregistered"; 06718 case REG_STATE_REGSENT: 06719 return "Request Sent"; 06720 case REG_STATE_AUTHSENT: 06721 return "Auth. Sent"; 06722 case REG_STATE_REGISTERED: 06723 return "Registered"; 06724 case REG_STATE_REJECTED: 06725 return "Rejected"; 06726 case REG_STATE_TIMEOUT: 06727 return "Timeout"; 06728 case REG_STATE_NOAUTH: 06729 return "No Authentication"; 06730 default: 06731 return "Unknown"; 06732 } 06733 }
| static int reload | ( | void | ) | [static] |
Definition at line 12996 of file chan_iax2.c.
References reload_config().
12997 { 12998 return reload_config(); 12999 }
| static int reload_config | ( | void | ) | [static] |
Definition at line 12947 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().
12948 { 12949 static const char config[] = "iax.conf"; 12950 struct iax2_registry *reg; 12951 12952 if (set_config(config, 1) > 0) { 12953 prune_peers(); 12954 prune_users(); 12955 ao2_callback(callno_limits, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 12956 ao2_callback(calltoken_ignores, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, prune_addr_range_cb, NULL); 12957 ao2_callback(peercnts, OBJ_NODATA, set_peercnt_limit_all_cb, NULL); 12958 trunk_timed = trunk_untimed = 0; 12959 trunk_nmaxmtu = trunk_maxmtu = 0; 12960 memset(&debugaddr, '\0', sizeof(debugaddr)); 12961 12962 AST_LIST_LOCK(®istrations); 12963 AST_LIST_TRAVERSE(®istrations, reg, entry) 12964 iax2_do_register(reg); 12965 AST_LIST_UNLOCK(®istrations); 12966 12967 /* Qualify hosts, too */ 12968 poke_all_peers(); 12969 } 12970 12971 reload_firmware(0); 12972 iax_provision_reload(1); 12973 ast_unload_realtime("iaxpeers"); 12974 12975 return 0; 12976 }
| static void reload_firmware | ( | int | unload | ) | [static] |
Definition at line 3051 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().
03052 { 03053 struct iax_firmware *cur = NULL; 03054 DIR *fwd; 03055 struct dirent *de; 03056 char dir[256], fn[256]; 03057 03058 AST_LIST_LOCK(&firmwares); 03059 03060 /* Mark all as dead */ 03061 AST_LIST_TRAVERSE(&firmwares, cur, list) 03062 cur->dead = 1; 03063 03064 /* Now that we have marked them dead... load new ones */ 03065 if (!unload) { 03066 snprintf(dir, sizeof(dir), "%s/firmware/iax", ast_config_AST_DATA_DIR); 03067 fwd = opendir(dir); 03068 if (fwd) { 03069 while((de = readdir(fwd))) { 03070 if (de->d_name[0] != '.') { 03071 snprintf(fn, sizeof(fn), "%s/%s", dir, de->d_name); 03072 if (!try_firmware(fn)) { 03073 ast_verb(2, "Loaded firmware '%s'\n", de->d_name); 03074 } 03075 } 03076 } 03077 closedir(fwd); 03078 } else 03079 ast_log(LOG_WARNING, "Error opening firmware directory '%s': %s\n", dir, strerror(errno)); 03080 } 03081 03082 /* Clean up leftovers */ 03083 AST_LIST_TRAVERSE_SAFE_BEGIN(&firmwares, cur, list) { 03084 if (!cur->dead) 03085 continue; 03086 AST_LIST_REMOVE_CURRENT(list); 03087 destroy_firmware(cur); 03088 } 03089 AST_LIST_TRAVERSE_SAFE_END; 03090 03091 AST_LIST_UNLOCK(&firmwares); 03092 }
| static void remove_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1972 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().
01973 { 01974 if (!pvt->peercallno) { 01975 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01976 return; 01977 } 01978 01979 ao2_unlink(iax_peercallno_pvts, pvt); 01980 }
| static void remove_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1953 of file chan_iax2.c.
References ao2_unlink, ast_log(), LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by complete_transfer(), and iax2_destroy().
01954 { 01955 if (!pvt->transfercallno) { 01956 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01957 return; 01958 } 01959 01960 ao2_unlink(iax_transfercallno_pvts, pvt); 01961 }
| static int replace_callno | ( | const void * | obj | ) | [static] |
Definition at line 2458 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().
02459 { 02460 struct callno_entry *callno_entry = (struct callno_entry *) obj; 02461 02462 /* the callno_pool container is locked here primarily to ensure thread 02463 * safety of the total_nonval_callno_used check and decrement */ 02464 ao2_lock(callno_pool); 02465 02466 if (!callno_entry->validated && (total_nonval_callno_used != 0)) { 02467 total_nonval_callno_used--; 02468 } else if (!callno_entry->validated && (total_nonval_callno_used == 0)) { 02469 ast_log(LOG_ERROR, "Attempted to decrement total non calltoken validated callnumbers below zero... Callno is:%d \n", callno_entry->callno); 02470 } 02471 02472 if (callno_entry->callno < TRUNK_CALL_START) { 02473 ao2_link(callno_pool, callno_entry); 02474 } else { 02475 ao2_link(callno_pool_trunk, callno_entry); 02476 } 02477 ao2_ref(callno_entry, -1); /* only container ref remains */ 02478 02479 ao2_unlock(callno_pool); 02480 return 0; 02481 }
| static void requirecalltoken_mark_auto | ( | const char * | name, | |
| int | subclass | |||
| ) | [static] |
Definition at line 4594 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().
04595 { 04596 struct iax2_user *user = NULL; 04597 struct iax2_peer *peer = NULL; 04598 04599 if (ast_strlen_zero(name)) { 04600 return; /* no username given */ 04601 } 04602 04603 if ((subclass == IAX_COMMAND_NEW) && (user = find_user(name)) && (user->calltoken_required == CALLTOKEN_AUTO)) { 04604 user->calltoken_required = CALLTOKEN_YES; 04605 } else if ((subclass != IAX_COMMAND_NEW) && (peer = find_peer(name, 1)) && (peer->calltoken_required == CALLTOKEN_AUTO)) { 04606 peer->calltoken_required = CALLTOKEN_YES; 04607 } 04608 04609 if (peer) { 04610 peer_unref(peer); 04611 } 04612 if (user) { 04613 user_unref(user); 04614 } 04615 }
| static void resend_with_token | ( | int | callno, | |
| struct iax_frame * | f, | |||
| const char * | newtoken | |||
| ) | [static] |
Definition at line 4510 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().
04511 { 04512 struct chan_iax2_pvt *pvt = iaxs[callno]; 04513 int frametype = f->af.frametype; 04514 int subclass = f->af.subclass; 04515 struct { 04516 struct ast_iax2_full_hdr fh; 04517 struct iax_ie_data ied; 04518 } data = { 04519 .ied.buf = { 0 }, 04520 .ied.pos = 0, 04521 }; 04522 /* total len - header len gives us the frame's IE len */ 04523 int ie_data_pos = f->datalen - sizeof(struct ast_iax2_full_hdr); 04524 04525 if (!pvt) { 04526 return; /* this should not be possible if called from socket_process() */ 04527 } 04528 04529 /* 04530 * Check to make sure last frame sent is valid for call token resend 04531 * 1. Frame should _NOT_ be encrypted since it starts the IAX dialog 04532 * 2. Frame should _NOT_ already have a destination callno 04533 * 3. Frame must be a valid iax_frame subclass capable of starting dialog 04534 * 4. Pvt must have a calltoken_ie_len which represents the number of 04535 * bytes at the end of the frame used for the previous calltoken ie. 04536 * 5. Pvt's calltoken_ie_len must be _LESS_ than the total IE length 04537 * 6. Total length of f->data must be _LESS_ than size of our data struct 04538 * because f->data must be able to fit within data. 04539 */ 04540 if (f->encmethods || f->dcallno || !iax2_allow_new(frametype, subclass, 0) 04541 || !pvt->calltoken_ie_len || (pvt->calltoken_ie_len > ie_data_pos) || 04542 (f->datalen > sizeof(data))) { 04543 04544 return; /* ignore resend, token was not valid for the dialog */ 04545 } 04546 04547 /* token is valid 04548 * 1. Copy frame data over 04549 * 2. Redo calltoken IE, it will always be the last ie in the frame. 04550 * NOTE: Having the ie always be last is not protocol specified, 04551 * it is only an implementation choice. Since we only expect the ie to 04552 * be last for frames we have sent, this can no way be affected by 04553 * another end point. 04554 * 3. Remove frame from queue 04555 * 4. Free old frame 04556 * 5. Clear previous seqnos 04557 * 6. Resend with CALLTOKEN ie. 04558 */ 04559 04560 /* ---1.--- */ 04561 memcpy(&data, f->data, f->datalen); 04562 data.ied.pos = ie_data_pos; 04563 04564 /* ---2.--- */ 04565 /* move to the beginning of the calltoken ie so we can write over it */ 04566 data.ied.pos -= pvt->calltoken_ie_len; 04567 iax_ie_append_str(&data.ied, IAX_IE_CALLTOKEN, newtoken); 04568 04569 /* make sure to update token length incase it ever has to be stripped off again */ 04570 pvt->calltoken_ie_len = data.ied.pos - ie_data_pos; /* new pos minus old pos tells how big token ie is */ 04571 04572 /* ---3.--- */ 04573 AST_LIST_LOCK(&frame_queue); 04574 AST_LIST_REMOVE(&frame_queue, f, list); 04575 AST_LIST_UNLOCK(&frame_queue); 04576 04577 /* ---4.--- */ 04578 iax2_frame_free(f); 04579 04580 /* ---5.--- */ 04581 pvt->oseqno = 0; 04582 pvt->rseqno = 0; 04583 pvt->iseqno = 0; 04584 pvt->aseqno = 0; 04585 if (pvt->peercallno) { 04586 remove_by_peercallno(pvt); 04587 pvt->peercallno = 0; 04588 } 04589 04590 /* ---6.--- */ 04591 send_command(pvt, AST_FRAME_IAX, subclass, 0, data.ied.buf, data.ied.pos, -1); 04592 }
Definition at line 9034 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().
09035 { 09036 int i; 09037 unsigned int length, offset = 0; 09038 char full_osptoken[IAX_MAX_OSPBUFF_SIZE]; 09039 09040 for (i = 0; i < IAX_MAX_OSPBLOCK_NUM; i++) { 09041 length = ies->ospblocklength[i]; 09042 if (length != 0) { 09043 if (length > IAX_MAX_OSPBLOCK_SIZE) { 09044 /* OSP token block length wrong, clear buffer */ 09045 offset = 0; 09046 break; 09047 } else { 09048 memcpy(full_osptoken + offset, ies->osptokenblock[i], length); 09049 offset += length; 09050 } 09051 } else { 09052 break; 09053 } 09054 } 09055 *(full_osptoken + offset) = '\0'; 09056 if (strlen(full_osptoken) != offset) { 09057 /* OSP token length wrong, clear buffer */ 09058 *full_osptoken = '\0'; 09059 } 09060 09061 ast_string_field_set(iaxs[fr->callno], osptoken, full_osptoken); 09062 }
Definition at line 9023 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().
09024 { 09025 iaxs[fr->callno]->remote_rr.jitter = ies->rr_jitter; 09026 iaxs[fr->callno]->remote_rr.losspct = ies->rr_loss >> 24; 09027 iaxs[fr->callno]->remote_rr.losscnt = ies->rr_loss & 0xffffff; 09028 iaxs[fr->callno]->remote_rr.packets = ies->rr_pkts; 09029 iaxs[fr->callno]->remote_rr.delay = ies->rr_delay; 09030 iaxs[fr->callno]->remote_rr.dropped = ies->rr_dropped; 09031 iaxs[fr->callno]->remote_rr.ooo = ies->rr_ooo; 09032 }
| static void sched_delay_remove | ( | struct sockaddr_in * | sin, | |
| struct callno_entry * | callno_entry | |||
| ) | [static] |
Definition at line 2530 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().
02531 { 02532 int i; 02533 struct peercnt *peercnt; 02534 struct peercnt tmp = { 02535 .addr = sin->sin_addr.s_addr, 02536 }; 02537 02538 if ((peercnt = ao2_find(peercnts, &tmp, OBJ_POINTER))) { 02539 /* refcount is incremented with ao2_find. keep that ref for the scheduler */ 02540 ast_debug(1, "schedule decrement of callno used for %s in %d seconds\n", ast_inet_ntoa(sin->sin_addr), MIN_REUSE_TIME); 02541 i = iax2_sched_add(sched, MIN_REUSE_TIME * 1000, peercnt_remove_cb, peercnt); 02542 if (i == -1) { 02543 ao2_ref(peercnt, -1); 02544 } 02545 } 02546 02547 iax2_sched_add(sched, MIN_REUSE_TIME * 1000, replace_callno, callno_entry); 02548 }
| static int schedule_delivery | ( | struct iax_frame * | fr, | |
| int | updatehistory, | |||
| int | fromtrunk, | |||
| unsigned int * | tsout | |||
| ) | [static] |
Definition at line 3970 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_thread_del, ast_test_flag, ast_tv(), ast_tvadd(), ast_tvzero(), ast_channel::bridge, 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().
03971 { 03972 int type, len; 03973 int ret; 03974 int needfree = 0; 03975 struct ast_channel *owner = NULL; 03976 struct ast_channel *bridge = NULL; 03977 03978 /* Attempt to recover wrapped timestamps */ 03979 unwrap_timestamp(fr); 03980 03981 /* delivery time is sender's sent timestamp converted back into absolute time according to our clock */ 03982 if ( !fromtrunk && !ast_tvzero(iaxs[fr->callno]->rxcore)) 03983 fr->af.delivery = ast_tvadd(iaxs[fr->callno]->rxcore, ast_samp2tv(fr->ts, 1000)); 03984 else { 03985 #if 0 03986 ast_debug(1, "schedule_delivery: set delivery to 0 as we don't have an rxcore yet, or frame is from trunk.\n"); 03987 #endif 03988 fr->af.delivery = ast_tv(0,0); 03989 } 03990 03991 type = JB_TYPE_CONTROL; 03992 len = 0; 03993 03994 if(fr->af.frametype == AST_FRAME_VOICE) { 03995 type = JB_TYPE_VOICE; 03996 len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass) / 1000); 03997 } else if(fr->af.frametype == AST_FRAME_CNG) { 03998 type = JB_TYPE_SILENCE; 03999 } 04000 04001 if ( (!ast_test_flag(iaxs[fr->callno], IAX_USEJITTERBUF)) ) { 04002 if (tsout) 04003 *tsout = fr->ts; 04004 __do_deliver(fr); 04005 return -1; 04006 } 04007 04008 if ((owner = iaxs[fr->callno]->owner)) 04009 bridge = ast_bridged_channel(owner); 04010 04011 /* if the user hasn't requested we force the use of the jitterbuffer, and we're bridged to 04012 * a channel that can accept jitter, then flush and suspend the jb, and send this frame straight through */ 04013 if ( (!ast_test_flag(iaxs[fr->callno], IAX_FORCEJITTERBUF)) && owner && bridge && (bridge->tech->properties & AST_CHAN_TP_WANTSJITTER) ) { 04014 jb_frame frame; 04015 04016 /* deliver any frames in the jb */ 04017 while (jb_getall(iaxs[fr->callno]->jb, &frame) == JB_OK) { 04018 __do_deliver(frame.data); 04019 /* __do_deliver() can make the call disappear */ 04020 if (!iaxs[fr->callno]) 04021 return -1; 04022 } 04023 04024 jb_reset(iaxs[fr->callno]->jb); 04025 04026 ast_sched_thread_del(sched, iaxs[fr->callno]->jbid); 04027 04028 /* deliver this frame now */ 04029 if (tsout) 04030 *tsout = fr->ts; 04031 __do_deliver(fr); 04032 return -1; 04033 } 04034 04035 /* insert into jitterbuffer */ 04036 /* TODO: Perhaps we could act immediately if it's not droppable and late */ 04037 ret = jb_put(iaxs[fr->callno]->jb, fr, type, len, fr->ts, 04038 calc_rxstamp(iaxs[fr->callno],fr->ts)); 04039 if (ret == JB_DROP) { 04040 needfree++; 04041 } else if (ret == JB_SCHED) { 04042 update_jbsched(iaxs[fr->callno]); 04043 } 04044 if (tsout) 04045 *tsout = fr->ts; 04046 if (needfree) { 04047 /* Free our iax frame */ 04048 iax2_frame_free(fr); 04049 return -1; 04050 } 04051 return 0; 04052 }
| static int scheduled_destroy | ( | const void * | vid | ) | [static] |
Definition at line 1656 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().
01657 { 01658 unsigned short callno = PTR_TO_CALLNO(vid); 01659 ast_mutex_lock(&iaxsl[callno]); 01660 if (iaxs[callno]) { 01661 if (option_debug) { 01662 ast_log(LOG_DEBUG, "Really destroying %d now...\n", callno); 01663 } 01664 iax2_destroy(callno); 01665 } 01666 ast_mutex_unlock(&iaxsl[callno]); 01667 return 0; 01668 }
| 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 4474 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().
04477 { 04478 struct { 04479 struct ast_iax2_full_hdr f; 04480 struct iax_ie_data ied; 04481 } data; 04482 size_t size = sizeof(struct ast_iax2_full_hdr); 04483 04484 if (ied) { 04485 size += ied->pos; 04486 memcpy(&data.ied, ied->buf, ied->pos); 04487 } 04488 04489 data.f.scallno = htons(0x8000 | callno); 04490 data.f.dcallno = htons(dcallno); 04491 data.f.ts = htonl(ts); 04492 data.f.iseqno = seqno; 04493 data.f.oseqno = 0; 04494 data.f.type = AST_FRAME_IAX; 04495 data.f.csub = compress_subclass(command); 04496 04497 return sendto(sockfd, &data, size, 0, (struct sockaddr *)sin, sizeof(*sin)); 04498 }
| 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 7147 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().
07148 { 07149 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0); 07150 }
| 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 7166 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().
07167 { 07168 int call_num = i->callno; 07169 /* It is assumed that the callno has already been locked */ 07170 iax2_predestroy(i->callno); 07171 if (!iaxs[call_num]) 07172 return -1; 07173 return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1); 07174 }
| 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 7176 of file chan_iax2.c.
References __send_command().
Referenced by iax2_vnak(), and socket_process().
07177 { 07178 return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0); 07179 }
| 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 7152 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().
07153 { 07154 int res; 07155 ast_mutex_lock(&iaxsl[callno]); 07156 res = send_command(iaxs[callno], type, command, ts, data, datalen, seqno); 07157 ast_mutex_unlock(&iaxsl[callno]); 07158 return res; 07159 }
| 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 7181 of file chan_iax2.c.
References __send_command().
Referenced by socket_process(), and try_transfer().
07182 { 07183 return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0); 07184 }
| static int send_lagrq | ( | const void * | data | ) | [static] |
Definition at line 1454 of file chan_iax2.c.
References __send_lagrq(), and schedule_action.
Referenced by __find_callno(), __send_lagrq(), and make_trunk().
01455 { 01456 #ifdef SCHED_MULTITHREADED 01457 if (schedule_action(__send_lagrq, data)) 01458 #endif 01459 __send_lagrq(data); 01460 01461 return 0; 01462 }
| static int send_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3164 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().
03165 { 03166 int res; 03167 int callno = f->callno; 03168 03169 /* Don't send if there was an error, but return error instead */ 03170 if (!callno || !iaxs[callno] || iaxs[callno]->error) 03171 return -1; 03172 03173 /* Called with iaxsl held */ 03174 if (iaxdebug) 03175 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)); 03176 03177 if (f->transfer) { 03178 if (iaxdebug) 03179 iax_showframe(f, NULL, 0, &iaxs[callno]->transfer, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03180 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->transfer, sizeof(iaxs[callno]->transfer)); 03181 } else { 03182 if (iaxdebug) 03183 iax_showframe(f, NULL, 0, &iaxs[callno]->addr, f->datalen - sizeof(struct ast_iax2_full_hdr)); 03184 res = sendto(iaxs[callno]->sockfd, f->data, f->datalen, 0,(struct sockaddr *)&iaxs[callno]->addr, sizeof(iaxs[callno]->addr)); 03185 } 03186 if (res < 0) { 03187 if (iaxdebug) 03188 ast_debug(1, "Received error: %s\n", strerror(errno)); 03189 handle_error(); 03190 } else 03191 res = 0; 03192 03193 return res; 03194 }
| static int send_ping | ( | const void * | data | ) | [static] |
Definition at line 1393 of file chan_iax2.c.
References __send_ping(), and schedule_action.
Referenced by __find_callno(), __send_ping(), and make_trunk().
01394 { 01395 #ifdef SCHED_MULTITHREADED 01396 if (schedule_action(__send_ping, data)) 01397 #endif 01398 __send_ping(data); 01399 01400 return 0; 01401 }
| 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 1678 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().
01679 { 01680 struct signaling_queue_entry *s = NULL; 01681 01682 while ((s = AST_LIST_REMOVE_HEAD(&pvt->signaling_queue, next))) { 01683 iax2_send(pvt, &s->f, 0, -1, 0, 0, 0); 01684 free_signaling_queue_entry(s); 01685 } 01686 pvt->hold_signaling = 0; 01687 }
| static int send_trunk | ( | struct iax2_trunk_peer * | tpeer, | |
| struct timeval * | now | |||
| ) | [static] |
Definition at line 8736 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().
08737 { 08738 int res = 0; 08739 struct iax_frame *fr; 08740 struct ast_iax2_meta_hdr *meta; 08741 struct ast_iax2_meta_trunk_hdr *mth; 08742 int calls = 0; 08743 08744 /* Point to frame */ 08745 fr = (struct iax_frame *)tpeer->trunkdata; 08746 /* Point to meta data */ 08747 meta = (struct ast_iax2_meta_hdr *)fr->afdata; 08748 mth = (struct ast_iax2_meta_trunk_hdr *)meta->data; 08749 if (tpeer->trunkdatalen) { 08750 /* We're actually sending a frame, so fill the meta trunk header and meta header */ 08751 meta->zeros = 0; 08752 meta->metacmd = IAX_META_TRUNK; 08753 if (ast_test_flag(&globalflags, IAX_TRUNKTIMESTAMPS)) 08754 meta->cmddata = IAX_META_TRUNK_MINI; 08755 else 08756 meta->cmddata = IAX_META_TRUNK_SUPERMINI; 08757 mth->ts = htonl(calc_txpeerstamp(tpeer, trunkfreq, now)); 08758 /* And the rest of the ast_iax2 header */ 08759 fr->direction = DIRECTION_OUTGRESS; 08760 fr->retrans = -1; 08761 fr->transfer = 0; 08762 /* Any appropriate call will do */ 08763 fr->data = fr->afdata; 08764 fr->datalen = tpeer->trunkdatalen + sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr); 08765 res = transmit_trunk(fr, &tpeer->addr, tpeer->sockfd); 08766 calls = tpeer->calls; 08767 #if 0 08768 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)); 08769 #endif 08770 /* Reset transmit trunk side data */ 08771 tpeer->trunkdatalen = 0; 08772 tpeer->calls = 0; 08773 } 08774 if (res < 0) 08775 return res; 08776 return calls; 08777 }
| static int set_config | ( | const char * | config_file, | |
| int | reload | |||
| ) | [static] |
Load configuration.
Definition at line 12493 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_FILEINVALID, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_MAXMS, errno, format, gen, get_encrypt_methods(), iax2_register(), IAX_ALLOWFWDOWNLOAD, IAX_CAPABILITY_FULLBANDWIDTH, IAX_CAPABILITY_LOWBANDWIDTH, IAX_CAPABILITY_MEDBANDWIDTH, IAX_CODEC_NOCAP, IAX_CODEC_NOPREFS, IAX_CODEC_USER_FIRST, IAX_DEFAULT_PORTNO, IAX_DEFAULT_REG_EXPIRE, IAX_DYNAMIC, IAX_FORCE_ENCRYPT, IAX_FORCEJITTERBUF, IAX_NOTRANSFER, IAX_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().
12494 { 12495 struct ast_config *cfg, *ucfg; 12496 int capability=iax2_capability; 12497 struct ast_variable *v; 12498 char *cat; 12499 const char *utype; 12500 const char *tosval; 12501 int format; 12502 int portno = IAX_DEFAULT_PORTNO; 12503 int x; 12504 int mtuv; 12505 struct iax2_user *user; 12506 struct iax2_peer *peer; 12507 struct ast_netsock *ns; 12508 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; 12509 #if 0 12510 static unsigned short int last_port=0; 12511 #endif 12512 12513 cfg = ast_config_load(config_file, config_flags); 12514 12515 if (!cfg) { 12516 ast_log(LOG_ERROR, "Unable to load config %s\n", config_file); 12517 return -1; 12518 } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) { 12519 ucfg = ast_config_load("users.conf", config_flags); 12520 if (ucfg == CONFIG_STATUS_FILEUNCHANGED) 12521 return 0; 12522 /* Otherwise we need to reread both files */ 12523 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12524 if ((cfg = ast_config_load(config_file, config_flags)) == CONFIG_STATUS_FILEINVALID) { 12525 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 12526 ast_config_destroy(ucfg); 12527 return 0; 12528 } 12529 } else if (cfg == CONFIG_STATUS_FILEINVALID) { 12530 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config_file); 12531 return 0; 12532 } else { /* iax.conf changed, gotta reread users.conf, too */ 12533 ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED); 12534 if ((ucfg = ast_config_load("users.conf", config_flags)) == CONFIG_STATUS_FILEINVALID) { 12535 ast_log(LOG_ERROR, "Config file users.conf is in an invalid format. Aborting.\n"); 12536 ast_config_destroy(cfg); 12537 return 0; 12538 } 12539 } 12540 12541 if (reload) { 12542 set_config_destroy(); 12543 } 12544 12545 /* Reset global codec prefs */ 12546 memset(&prefs, 0 , sizeof(struct ast_codec_pref)); 12547 12548 /* Reset Global Flags */ 12549 memset(&globalflags, 0, sizeof(globalflags)); 12550 ast_set_flag(&globalflags, IAX_RTUPDATE); 12551 ast_set_flag(&globalflags, IAX_SHRINKCALLERID); 12552 12553 #ifdef SO_NO_CHECK 12554 nochecksums = 0; 12555 #endif 12556 /* Reset default parking lot */ 12557 default_parkinglot[0] = '\0'; 12558 12559 min_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12560 max_reg_expire = IAX_DEFAULT_REG_EXPIRE; 12561 global_max_trunk_mtu = MAX_TRUNK_MTU; 12562 global_maxcallno = DEFAULT_MAXCALLNO_LIMIT; 12563 global_maxcallno_nonval = DEFAULT_MAXCALLNO_LIMIT_NONVAL; 12564 12565 maxauthreq = 3; 12566 12567 srvlookup = 0; 12568 12569 v = ast_variable_browse(cfg, "general"); 12570 12571 /* Seed initial tos value */ 12572 tosval = ast_variable_retrieve(cfg, "general", "tos"); 12573 if (tosval) { 12574 if (ast_str2tos(tosval, &qos.tos)) 12575 ast_log(LOG_WARNING, "Invalid tos value, refer to QoS documentation\n"); 12576 } 12577 /* Seed initial cos value */ 12578 tosval = ast_variable_retrieve(cfg, "general", "cos"); 12579 if (tosval) { 12580 if (ast_str2cos(tosval, &qos.cos)) 12581 ast_log(LOG_WARNING, "Invalid cos value, refer to QoS documentation\n"); 12582 } 12583 while(v) { 12584 if (!strcasecmp(v->name, "bindport")){ 12585 if (reload) 12586 ast_log(LOG_NOTICE, "Ignoring bindport on reload\n"); 12587 else 12588 portno = atoi(v->value); 12589 } else if (!strcasecmp(v->name, "pingtime")) 12590 ping_time = atoi(v->value); 12591 else if (!strcasecmp(v->name, "iaxthreadcount")) { 12592 if (reload) { 12593 if (atoi(v->value) != iaxthreadcount) 12594 ast_log(LOG_NOTICE, "Ignoring any changes to iaxthreadcount during reload\n"); 12595 } else { 12596 iaxthreadcount = atoi(v->value); 12597 if (iaxthreadcount < 1) { 12598 ast_log(LOG_NOTICE, "iaxthreadcount must be at least 1.\n"); 12599 iaxthreadcount = 1; 12600 } else if (iaxthreadcount > 256) { 12601 ast_log(LOG_NOTICE, "limiting iaxthreadcount to 256\n"); 12602 iaxthreadcount = 256; 12603 } 12604 } 12605 } else if (!strcasecmp(v->name, "iaxmaxthreadcount")) { 12606 if (reload) { 12607 AST_LIST_LOCK(&dynamic_list); 12608 iaxmaxthreadcount = atoi(v->value); 12609 AST_LIST_UNLOCK(&dynamic_list); 12610 } else { 12611 iaxmaxthreadcount = atoi(v->value); 12612 if (iaxmaxthreadcount < 0) { 12613 ast_log(LOG_NOTICE, "iaxmaxthreadcount must be at least 0.\n"); 12614 iaxmaxthreadcount = 0; 12615 } else if (iaxmaxthreadcount > 256) { 12616 ast_log(LOG_NOTICE, "Limiting iaxmaxthreadcount to 256\n"); 12617 iaxmaxthreadcount = 256; 12618 } 12619 } 12620 } else if (!strcasecmp(v->name, "nochecksums")) { 12621 #ifdef SO_NO_CHECK 12622 if (ast_true(v->value)) 12623 nochecksums = 1; 12624 else 12625 nochecksums = 0; 12626 #else 12627 if (ast_true(v->value)) 12628 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 12629 #endif 12630 } 12631 else if (!strcasecmp(v->name, "maxjitterbuffer")) 12632 maxjitterbuffer = atoi(v->value); 12633 else if (!strcasecmp(v->name, "resyncthreshold")) 12634 resyncthreshold = atoi(v->value); 12635 else if (!strcasecmp(v->name, "maxjitterinterps")) 12636 maxjitterinterps = atoi(v->value); 12637 else if (!strcasecmp(v->name, "jittertargetextra")) 12638 jittertargetextra = atoi(v->value); 12639 else if (!strcasecmp(v->name, "lagrqtime")) 12640 lagrq_time = atoi(v->value); 12641 else if (!strcasecmp(v->name, "maxregexpire")) 12642 max_reg_expire = atoi(v->value); 12643 else if (!strcasecmp(v->name, "minregexpire")) 12644 min_reg_expire = atoi(v->value); 12645 else if (!strcasecmp(v->name, "bindaddr")) { 12646 if (reload) { 12647 ast_log(LOG_NOTICE, "Ignoring bindaddr on reload\n"); 12648 } else { 12649 if (!(ns = ast_netsock_bind(netsock, io, v->value, portno, qos.tos, qos.cos, socket_read, NULL))) { 12650 ast_log(LOG_WARNING, "Unable apply binding to '%s' at line %d\n", v->value, v->lineno); 12651 } else { 12652 if (strchr(v->value, ':')) 12653 ast_verb(2, "Binding IAX2 to '%s'\n", v->value); 12654 else 12655 ast_verb(2, "Binding IAX2 to '%s:%d'\n", v->value, portno); 12656 if (defaultsockfd < 0) 12657 defaultsockfd = ast_netsock_sockfd(ns); 12658 ast_netsock_unref(ns); 12659 } 12660 } 12661 } else if (!strcasecmp(v->name, "authdebug")) { 12662 authdebug = ast_true(v->value); 12663 } else if (!strcasecmp(v->name, "encryption")) { 12664 iax2_encryption |= get_encrypt_methods(v->value); 12665 if (!iax2_encryption) { 12666 ast_clear_flag((&globalflags), IAX_FORCE_ENCRYPT); 12667 } 12668 } else if (!strcasecmp(v->name, "forceencryption")) { 12669 if (ast_false(v->value)) { 12670 ast_clear_flag((&globalflags), IAX_FORCE_ENCRYPT); 12671 } else { 12672 iax2_encryption |= get_encrypt_methods(v->value); 12673 if (iax2_encryption) { 12674 ast_set_flag((&globalflags), IAX_FORCE_ENCRYPT); 12675 } 12676 } 12677 } else if (!strcasecmp(v->name, "transfer")) { 12678 if (!strcasecmp(v->value, "mediaonly")) { 12679 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_TRANSFERMEDIA); 12680 } else if (ast_true(v->value)) { 12681 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, 0); 12682 } else 12683 ast_set_flags_to((&globalflags), IAX_NOTRANSFER|IAX_TRANSFERMEDIA, IAX_NOTRANSFER); 12684 } else if (!strcasecmp(v->name, "codecpriority")) { 12685 if(!strcasecmp(v->value, "caller")) 12686 ast_set_flag((&globalflags), IAX_CODEC_USER_FIRST); 12687 else if(!strcasecmp(v->value, "disabled")) 12688 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 12689 else if(!strcasecmp(v->value, "reqonly")) { 12690 ast_set_flag((&globalflags), IAX_CODEC_NOCAP); 12691 ast_set_flag((&globalflags), IAX_CODEC_NOPREFS); 12692 } 12693 } else if (!strcasecmp(v->name, "jitterbuffer")) 12694 ast_set2_flag((&globalflags), ast_true(v->value), IAX_USEJITTERBUF); 12695 else if (!strcasecmp(v->name, "forcejitterbuffer")) 12696 ast_set2_flag((&globalflags), ast_true(v->value), IAX_FORCEJITTERBUF); 12697 else if (!strcasecmp(v->name, "delayreject")) 12698 delayreject = ast_true(v->value); 12699 else if (!strcasecmp(v->name, "allowfwdownload")) 12700 ast_set2_flag((&globalflags), ast_true(v->value), IAX_ALLOWFWDOWNLOAD); 12701 else if (!strcasecmp(v->name, "rtcachefriends")) 12702 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTCACHEFRIENDS); 12703 else if (!strcasecmp(v->name, "rtignoreregexpire")) 12704 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTIGNOREREGEXPIRE); 12705 else if (!strcasecmp(v->name, "rtupdate")) 12706 ast_set2_flag((&globalflags), ast_true(v->value), IAX_RTUPDATE); 12707 else if (!strcasecmp(v->name, "trunktimestamps")) 12708 ast_set2_flag(&globalflags, ast_true(v->value), IAX_TRUNKTIMESTAMPS); 12709 else if (!strcasecmp(v->name, "rtautoclear")) { 12710 int i = atoi(v->value); 12711 if(i > 0) 12712 global_rtautoclear = i; 12713 else 12714 i = 0; 12715 ast_set2_flag((&globalflags), i || ast_true(v->value), IAX_RTAUTOCLEAR); 12716 } else if (!strcasecmp(v->name, "trunkfreq")) { 12717 trunkfreq = atoi(v->value); 12718 if (trunkfreq < 10) 12719 trunkfreq = 10; 12720 } else if (!strcasecmp(v->name, "trunkmtu")) { 12721 mtuv = atoi(v->value); 12722 if (mtuv == 0 ) 12723 global_max_trunk_mtu = 0; 12724 else if (mtuv >= 172 && mtuv < 4000) 12725 global_max_trunk_mtu = mtuv; 12726 else 12727 ast_log(LOG_NOTICE, "trunkmtu value out of bounds (%d) at line %d\n", 12728 mtuv, v->lineno); 12729 } else if (!strcasecmp(v->name, "trunkmaxsize")) { 12730 trunkmaxsize = atoi(v->value); 12731 if (trunkmaxsize == 0) 12732 trunkmaxsize = MAX_TRUNKDATA; 12733 } else if (!strcasecmp(v->name, "autokill")) { 12734 if (sscanf(v->value, "%30d", &x) == 1) { 12735 if (x >= 0) 12736 autokill = x; 12737 else 12738 ast_log(LOG_NOTICE, "Nice try, but autokill has to be >0 or 'yes' or 'no' at line %d\n", v->lineno); 12739 } else if (ast_true(v->value)) { 12740 autokill = DEFAULT_MAXMS; 12741 } else { 12742 autokill = 0; 12743 } 12744 } else if (!strcasecmp(v->name, "bandwidth")) { 12745 if (!strcasecmp(v->value, "low")) { 12746 capability = IAX_CAPABILITY_LOWBANDWIDTH; 12747 } else if (!strcasecmp(v->value, "medium")) { 12748 capability = IAX_CAPABILITY_MEDBANDWIDTH; 12749 } else if (!strcasecmp(v->value, "high")) { 12750 capability = IAX_CAPABILITY_FULLBANDWIDTH; 12751 } else 12752 ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n"); 12753 } else if (!strcasecmp(v->name, "allow")) { 12754 ast_parse_allow_disallow(&prefs, &capability, v->value, 1); 12755 } else if (!strcasecmp(v->name, "disallow")) { 12756 ast_parse_allow_disallow(&prefs, &capability, v->value, 0); 12757 } else if (!strcasecmp(v->name, "register")) { 12758 iax2_register(v->value, v->lineno); 12759 } else if (!strcasecmp(v->name, "iaxcompat")) { 12760 iaxcompat = ast_true(v->value); 12761 } else if (!strcasecmp(v->name, "regcontext")) { 12762 ast_copy_string(regcontext, v->value, sizeof(regcontext)); 12763 /* Create context if it doesn't exist already */ 12764 ast_context_find_or_create(NULL, NULL, regcontext, "IAX2"); 12765 } else if (!strcasecmp(v->name, "tos")) { 12766 if (ast_str2tos(v->value, &qos.tos)) 12767 ast_log(LOG_WARNING, "Invalid tos value at line %d, refer to QoS documentation\n", v->lineno); 12768 } else if (!strcasecmp(v->name, "cos")) { 12769 if (ast_str2cos(v->value, &qos.cos)) 12770 ast_log(LOG_WARNING, "Invalid cos value at line %d, refer to QoS documentation\n", v->lineno); 12771 } else if (!strcasecmp(v->name, "parkinglot")) { 12772 ast_copy_string(default_parkinglot, v->value, sizeof(default_parkinglot)); 12773 } else if (!strcasecmp(v->name, "accountcode")) { 12774 ast_copy_string(accountcode, v->value, sizeof(accountcode)); 12775 } else if (!strcasecmp(v->name, "mohinterpret")) { 12776 ast_copy_string(mohinterpret, v->value, sizeof(mohinterpret)); 12777 } else if (!strcasecmp(v->name, "mohsuggest")) { 12778 ast_copy_string(mohsuggest, v->value, sizeof(mohsuggest)); 12779 } else if (!strcasecmp(v->name, "amaflags")) { 12780 format = ast_cdr_amaflags2int(v->value); 12781 if (format < 0) { 12782 ast_log(LOG_WARNING, "Invalid AMA Flags: %s at line %d\n", v->value, v->lineno); 12783 } else { 12784 amaflags = format; 12785 } 12786 } else if (!strcasecmp(v->name, "language")) { 12787 ast_copy_string(language, v->value, sizeof(language)); 12788 } else if (!strcasecmp(v->name, "maxauthreq")) { 12789 maxauthreq = atoi(v->value); 12790 if (maxauthreq < 0) 12791 maxauthreq = 0; 12792 } else if (!strcasecmp(v->name, "adsi")) { 12793 adsi = ast_true(v->value); 12794 } else if (!strcasecmp(v->name, "srvlookup")) { 12795 srvlookup = ast_true(v->value); 12796 } else if (!strcasecmp(v->name, "maxcallnumbers")) { 12797 if (sscanf(v->value, "%10hu", &global_maxcallno) != 1) { 12798 ast_log(LOG_WARNING, "maxcallnumbers must be set to a valid number. %s is not valid at line %d\n", v->value, v->lineno); 12799 } 12800 } else if (!strcasecmp(v->name, "maxcallnumbers_nonvalidated")) { 12801 if (sscanf(v->value, "%10hu", &global_maxcallno_nonval) != 1) { 12802 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); 12803 } 12804 } else if (!strcasecmp(v->name, "calltokenoptional")) { 12805 if (add_calltoken_ignore(v->value)) { 12806 ast_log(LOG_WARNING, "Invalid calltokenoptional address range - '%s' line %d\n", v->value, v->lineno); 12807 } 12808 } else if (!strcasecmp(v->name, "shrinkcallerid")) { 12809 if (ast_true(v->value)) { 12810 ast_set_flag((&globalflags), IAX_SHRINKCALLERID); 12811 } else if (ast_false(v->value)) { 12812 ast_clear_flag((&globalflags), IAX_SHRINKCALLERID); 12813 } else { 12814 ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno); 12815 } 12816 }/*else if (strcasecmp(v->name,"type")) */ 12817 /* ast_log(LOG_WARNING, "Ignoring %s\n", v->name); */ 12818 v = v->next; 12819 } 12820 12821 if (defaultsockfd < 0) { 12822 if (!(ns = ast_netsock_bind(netsock, io, "0.0.0.0", portno, qos.tos, qos.cos, socket_read, NULL))) { 12823 ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); 12824 } else { 12825 ast_verb(2, "Binding IAX2 to default address 0.0.0.0:%d\n", portno); 12826 defaultsockfd = ast_netsock_sockfd(ns); 12827 ast_netsock_unref(ns); 12828 } 12829 } 12830 if (reload) { 12831 ast_netsock_release(outsock); 12832 outsock = ast_netsock_list_alloc(); 12833 if (!outsock) { 12834 ast_log(LOG_ERROR, "Could not allocate outsock list.\n"); 12835 return -1; 12836 } 12837 ast_netsock_init(outsock); 12838 } 12839 12840 if (min_reg_expire > max_reg_expire) { 12841 ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n", 12842 min_reg_expire, max_reg_expire, max_reg_expire); 12843 min_reg_expire = max_reg_expire; 12844 } 12845 iax2_capability = capability; 12846 12847 if (ucfg) { 12848 struct ast_variable *gen; 12849 int genhasiax; 12850 int genregisteriax; 12851 const char *hasiax, *registeriax; 12852 12853 genhasiax = ast_true(ast_variable_retrieve(ucfg, "general", "hasiax")); 12854 genregisteriax = ast_true(ast_variable_retrieve(ucfg, "general", "registeriax")); 12855 gen = ast_variable_browse(ucfg, "general"); 12856 cat = ast_category_browse(ucfg, NULL); 12857 while (cat) { 12858 if (strcasecmp(cat, "general")) { 12859 hasiax = ast_variable_retrieve(ucfg, cat, "hasiax"); 12860 registeriax = ast_variable_retrieve(ucfg, cat, "registeriax"); 12861 if (ast_true(hasiax) || (!hasiax && genhasiax)) { 12862 /* Start with general parameters, then specific parameters, user and peer */ 12863 user = build_user(cat, gen, ast_variable_browse(ucfg, cat), 0); 12864 if (user) { 12865 ao2_link(users, user); 12866 user = user_unref(user); 12867 } 12868 peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0); 12869 if (peer) { 12870 if (ast_test_flag(peer, IAX_DYNAMIC)) 12871 reg_source_db(peer); 12872 ao2_link(peers, peer); 12873 peer = peer_unref(peer); 12874 } 12875 } 12876 if (ast_true(registeriax) || (!registeriax && genregisteriax)) { 12877 char tmp[256]; 12878 const char *host = ast_variable_retrieve(ucfg, cat, "host"); 12879 const char *username = ast_variable_retrieve(ucfg, cat, "username"); 12880 const char *secret = ast_variable_retrieve(ucfg, cat, "secret"); 12881 if (!host) 12882 host = ast_variable_retrieve(ucfg, "general", "host"); 12883 if (!username) 12884 username = ast_variable_retrieve(ucfg, "general", "username"); 12885 if (!secret) 12886 secret = ast_variable_retrieve(ucfg, "general", "secret"); 12887 if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) { 12888 if (!ast_strlen_zero(secret)) 12889 snprintf(tmp, sizeof(tmp), "%s:%s@%s", username, secret, host); 12890 else 12891 snprintf(tmp, sizeof(tmp), "%s@%s", username, host); 12892 iax2_register(tmp, 0); 12893 } 12894 } 12895 } 12896 cat = ast_category_browse(ucfg, cat); 12897 } 12898 ast_config_destroy(ucfg); 12899 } 12900 12901 cat = ast_category_browse(cfg, NULL); 12902 while(cat) { 12903 if (strcasecmp(cat, "general")) { 12904 utype = ast_variable_retrieve(cfg, cat, "type"); 12905 if (!strcasecmp(cat, "callnumberlimits")) { 12906 build_callno_limits(ast_variable_browse(cfg, cat)); 12907 } else if (utype) { 12908 if (!strcasecmp(utype, "user") || !strcasecmp(utype, "friend")) { 12909 user = build_user(cat, ast_variable_browse(cfg, cat), NULL, 0); 12910 if (user) { 12911 ao2_link(users, user); 12912 user = user_unref(user); 12913 } 12914 } 12915 if (!strcasecmp(utype, "peer") || !strcasecmp(utype, "friend")) { 12916 peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0); 12917 if (peer) { 12918 if (ast_test_flag(peer, IAX_DYNAMIC)) 12919 reg_source_db(peer); 12920 ao2_link(peers, peer); 12921 peer = peer_unref(peer); 12922 } 12923 } else if (strcasecmp(utype, "user")) { 12924 ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, config_file); 12925 } 12926 } else 12927 ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat); 12928 } 12929 cat = ast_category_browse(cfg, cat); 12930 } 12931 ast_config_destroy(cfg); 12932 return 1; 12933 }
| static void set_config_destroy | ( | void | ) | [static] |
Definition at line 12474 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().
12475 { 12476 strcpy(accountcode, ""); 12477 strcpy(language, ""); 12478 strcpy(mohinterpret, "default"); 12479 strcpy(mohsuggest, ""); 12480 trunkmaxsize = MAX_TRUNKDATA; 12481 amaflags = 0; 12482 delayreject = 0; 12483 ast_clear_flag((&globalflags), IAX_NOTRANSFER); 12484 ast_clear_flag((&globalflags), IAX_TRANSFERMEDIA); 12485 ast_clear_flag((&globalflags), IAX_USEJITTERBUF); 12486 ast_clear_flag((&globalflags), IAX_FORCEJITTERBUF); 12487 delete_users(); 12488 ao2_callback(callno_limits, OBJ_NODATA, addr_range_delme_cb, NULL); 12489 ao2_callback(calltoken_ignores, OBJ_NODATA, addr_range_delme_cb, NULL); 12490 }
| static void set_peercnt_limit | ( | struct peercnt * | peercnt | ) | [static] |
Definition at line 2090 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().
02091 { 02092 uint16_t limit = global_maxcallno; 02093 struct addr_range *addr_range; 02094 struct sockaddr_in sin = { 02095 .sin_addr.s_addr = peercnt->addr, 02096 }; 02097 02098 02099 if (peercnt->reg && peercnt->limit) { 02100 return; /* this peercnt has a custom limit set by a registration */ 02101 } 02102 02103 if ((addr_range = ao2_callback(callno_limits, 0, addr_range_match_address_cb, &sin))) { 02104 limit = addr_range->limit; 02105 ast_debug(1, "custom addr_range %d found for %s\n", limit, ast_inet_ntoa(sin.sin_addr)); 02106 ao2_ref(addr_range, -1); 02107 } 02108 02109 peercnt->limit = limit; 02110 }
| static int set_peercnt_limit_all_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 2116 of file chan_iax2.c.
References ast_debug, and set_peercnt_limit().
Referenced by reload_config().
02117 { 02118 struct peercnt *peercnt = obj; 02119 02120 set_peercnt_limit(peercnt); 02121 ast_debug(1, "Reset limits for peercnts table\n"); 02122 02123 return 0; 02124 }
| static void signal_condition | ( | ast_mutex_t * | lock, | |
| ast_cond_t * | cond | |||
| ) | [static] |
Definition at line 994 of file chan_iax2.c.
References ast_cond_signal(), ast_mutex_lock(), and ast_mutex_unlock().
Referenced by __schedule_action(), iax2_process_thread(), and socket_read().
00995 { 00996 ast_mutex_lock(lock); 00997 ast_cond_signal(cond); 00998 ast_mutex_unlock(lock); 00999 }
| static int socket_process | ( | struct iax2_thread * | thread | ) | [static] |
Definition at line 9458 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_thread_del, ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_STATE_RING, 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, ast_var_t::entries, 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_FORCE_ENCRYPT, 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_IMMEDIATE, 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_channel::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(), ast_channel::uniqueid, 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().
09459 { 09460 struct sockaddr_in sin; 09461 int res; 09462 int updatehistory=1; 09463 int new = NEW_PREVENT; 09464 int dcallno = 0; 09465 char decrypted = 0; 09466 struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)thread->buf; 09467 struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)thread->buf; 09468 struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)thread->buf; 09469 struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)thread->buf; 09470 struct iax_frame *fr; 09471 struct iax_frame *cur; 09472 struct ast_frame f = { 0, }; 09473 struct ast_channel *c = NULL; 09474 struct iax2_dpcache *dp; 09475 struct iax2_peer *peer; 09476 struct iax_ies ies; 09477 struct iax_ie_data ied0, ied1; 09478 int format; 09479 int fd; 09480 int exists; 09481 int minivid = 0; 09482 char empty[32]=""; /* Safety measure */ 09483 struct iax_frame *duped_fr; 09484 char host_pref_buf[128]; 09485 char caller_pref_buf[128]; 09486 struct ast_codec_pref pref; 09487 char *using_prefs = "mine"; 09488 09489 /* allocate an iax_frame with 4096 bytes of data buffer */ 09490 fr = alloca(sizeof(*fr) + 4096); 09491 memset(fr, 0, sizeof(*fr)); 09492 fr->afdatalen = 4096; /* From alloca() above */ 09493 09494 /* Copy frequently used parameters to the stack */ 09495 res = thread->buf_len; 09496 fd = thread->iofd; 09497 memcpy(&sin, &thread->iosin, sizeof(sin)); 09498 09499 if (res < sizeof(*mh)) { 09500 ast_log(LOG_WARNING, "midget packet received (%d of %d min)\n", res, (int) sizeof(*mh)); 09501 return 1; 09502 } 09503 if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) { 09504 if (res < sizeof(*vh)) { 09505 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)); 09506 return 1; 09507 } 09508 09509 /* This is a video frame, get call number */ 09510 fr->callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, fd, 0); 09511 minivid = 1; 09512 } else if ((meta->zeros == 0) && !(ntohs(meta->metacmd) & 0x8000)) 09513 return socket_process_meta(res, meta, &sin, fd, fr); 09514 09515 #ifdef DEBUG_SUPPORT 09516 if (res >= sizeof(*fh)) 09517 iax_outputframe(NULL, fh, 1, &sin, res - sizeof(*fh)); 09518 #endif 09519 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09520 if (res < sizeof(*fh)) { 09521 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)); 09522 return 1; 09523 } 09524 09525 /* Get the destination call number */ 09526 dcallno = ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS; 09527 09528 09529 /* check to make sure this full frame isn't encrypted before we attempt 09530 * to look inside of it. If it is encrypted, decrypt it first. Its ok if the 09531 * callno is not found here, that just means one hasn't been allocated for 09532 * this connection yet. */ 09533 if ((dcallno != 1) && (fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, NEW_PREVENT, fd, 1))) { 09534 ast_mutex_lock(&iaxsl[fr->callno]); 09535 if (iaxs[fr->callno] && ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED)) { 09536 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09537 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09538 ast_mutex_unlock(&iaxsl[fr->callno]); 09539 return 1; 09540 } 09541 decrypted = 1; 09542 } 09543 ast_mutex_unlock(&iaxsl[fr->callno]); 09544 } 09545 09546 /* Retrieve the type and subclass */ 09547 f.frametype = fh->type; 09548 if (f.frametype == AST_FRAME_VIDEO) { 09549 f.subclass = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1); 09550 } else { 09551 f.subclass = uncompress_subclass(fh->csub); 09552 } 09553 09554 /* Deal with POKE/PONG without allocating a callno */ 09555 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_POKE) { 09556 /* Reply back with a PONG, but don't care about the result. */ 09557 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_PONG, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09558 return 1; 09559 } else if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_ACK && dcallno == 1) { 09560 /* Ignore */ 09561 return 1; 09562 } 09563 09564 f.datalen = res - sizeof(*fh); 09565 if (f.datalen) { 09566 if (f.frametype == AST_FRAME_IAX) { 09567 if (iax_parse_ies(&ies, thread->buf + sizeof(struct ast_iax2_full_hdr), f.datalen)) { 09568 ast_log(LOG_WARNING, "Undecodable frame received from '%s'\n", ast_inet_ntoa(sin.sin_addr)); 09569 return 1; 09570 } 09571 f.data.ptr = NULL; 09572 f.datalen = 0; 09573 } else { 09574 f.data.ptr = thread->buf + sizeof(struct ast_iax2_full_hdr); 09575 memset(&ies, 0, sizeof(ies)); 09576 } 09577 } else { 09578 if (f.frametype == AST_FRAME_IAX) 09579 f.data.ptr = NULL; 09580 else 09581 f.data.ptr = empty; 09582 memset(&ies, 0, sizeof(ies)); 09583 } 09584 09585 if (!dcallno && iax2_allow_new(f.frametype, f.subclass, 1)) { 09586 /* only set NEW_ALLOW if calltoken checks out */ 09587 if (handle_call_token(fh, &ies, &sin, fd)) { 09588 return 1; 09589 } 09590 09591 if (ies.calltoken && ies.calltokendata) { 09592 /* if we've gotten this far, and the calltoken ie data exists, 09593 * then calltoken validation _MUST_ have taken place. If calltoken 09594 * data is provided, it is always validated reguardless of any 09595 * calltokenoptional or requirecalltoken options */ 09596 new = NEW_ALLOW_CALLTOKEN_VALIDATED; 09597 } else { 09598 new = NEW_ALLOW; 09599 } 09600 } 09601 } else { 09602 /* Don't know anything about it yet */ 09603 f.frametype = AST_FRAME_NULL; 09604 f.subclass = 0; 09605 } 09606 09607 if (!fr->callno) { 09608 int check_dcallno = 0; 09609 09610 /* 09611 * We enforce accurate destination call numbers for ACKs. This forces the other 09612 * end to know the destination call number before call setup can complete. 09613 * 09614 * Discussed in the following thread: 09615 * http://lists.digium.com/pipermail/asterisk-dev/2008-May/033217.html 09616 */ 09617 09618 if ((ntohs(mh->callno) & IAX_FLAG_FULL) && ((f.frametype == AST_FRAME_IAX) && (f.subclass == IAX_COMMAND_ACK))) { 09619 check_dcallno = 1; 09620 } 09621 09622 if (!(fr->callno = find_callno(ntohs(mh->callno) & ~IAX_FLAG_FULL, dcallno, &sin, new, fd, check_dcallno))) { 09623 if (f.frametype == AST_FRAME_IAX && f.subclass == IAX_COMMAND_NEW) { 09624 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REJECT, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09625 } else if (f.frametype == AST_FRAME_IAX && (f.subclass == IAX_COMMAND_REGREQ || f.subclass == IAX_COMMAND_REGREL)) { 09626 send_apathetic_reply(1, ntohs(fh->scallno), &sin, IAX_COMMAND_REGREJ, ntohl(fh->ts), fh->iseqno + 1, fd, NULL); 09627 } 09628 return 1; 09629 } 09630 } 09631 09632 if (fr->callno > 0) 09633 ast_mutex_lock(&iaxsl[fr->callno]); 09634 09635 if (!fr->callno || !iaxs[fr->callno]) { 09636 /* A call arrived for a nonexistent destination. Unless it's an "inval" 09637 frame, reply with an inval */ 09638 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09639 /* We can only raw hangup control frames */ 09640 if (((f.subclass != IAX_COMMAND_INVAL) && 09641 (f.subclass != IAX_COMMAND_TXCNT) && 09642 (f.subclass != IAX_COMMAND_TXACC) && 09643 (f.subclass != IAX_COMMAND_FWDOWNL))|| 09644 (f.frametype != AST_FRAME_IAX)) 09645 raw_hangup(&sin, ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS, ntohs(mh->callno) & ~IAX_FLAG_FULL, 09646 fd); 09647 } 09648 if (fr->callno > 0) 09649 ast_mutex_unlock(&iaxsl[fr->callno]); 09650 return 1; 09651 } 09652 if (ast_test_flag(iaxs[fr->callno], IAX_ENCRYPTED) && !decrypted) { 09653 if (decrypt_frame(fr->callno, fh, &f, &res)) { 09654 ast_log(LOG_NOTICE, "Packet Decrypt Failed!\n"); 09655 ast_mutex_unlock(&iaxsl[fr->callno]); 09656 return 1; 09657 } 09658 decrypted = 1; 09659 } 09660 #ifdef DEBUG_SUPPORT 09661 if (decrypted) { 09662 iax_outputframe(NULL, fh, 3, &sin, res - sizeof(*fh)); 09663 } 09664 #endif 09665 09666 /* count this frame */ 09667 iaxs[fr->callno]->frames_received++; 09668 09669 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && !minivid && 09670 f.subclass != IAX_COMMAND_TXCNT && /* for attended transfer */ 09671 f.subclass != IAX_COMMAND_TXACC) { /* for attended transfer */ 09672 unsigned short new_peercallno; 09673 09674 new_peercallno = (unsigned short) (ntohs(mh->callno) & ~IAX_FLAG_FULL); 09675 if (new_peercallno && new_peercallno != iaxs[fr->callno]->peercallno) { 09676 if (iaxs[fr->callno]->peercallno) { 09677 remove_by_peercallno(iaxs[fr->callno]); 09678 } 09679 iaxs[fr->callno]->peercallno = new_peercallno; 09680 store_by_peercallno(iaxs[fr->callno]); 09681 } 09682 } 09683 if (ntohs(mh->callno) & IAX_FLAG_FULL) { 09684 if (iaxdebug) 09685 ast_debug(1, "Received packet %d, (%d, %d)\n", fh->oseqno, f.frametype, f.subclass); 09686 /* Check if it's out of order (and not an ACK or INVAL) */ 09687 fr->oseqno = fh->oseqno; 09688 fr->iseqno = fh->iseqno; 09689 fr->ts = ntohl(fh->ts); 09690 #ifdef IAXTESTS 09691 if (test_resync) { 09692 ast_debug(1, "Simulating frame ts resync, was %u now %u\n", fr->ts, fr->ts + test_resync); 09693 fr->ts += test_resync; 09694 } 09695 #endif /* IAXTESTS */ 09696 #if 0 09697 if ( (ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || 09698 ( (f.frametype != AST_FRAME_VOICE) && ! (f.frametype == AST_FRAME_IAX && 09699 (f.subclass == IAX_COMMAND_NEW || 09700 f.subclass == IAX_COMMAND_AUTHREQ || 09701 f.subclass == IAX_COMMAND_ACCEPT || 09702 f.subclass == IAX_COMMAND_REJECT)) ) ) 09703 #endif 09704 if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || (f.frametype != AST_FRAME_VOICE)) 09705 updatehistory = 0; 09706 if ((iaxs[fr->callno]->iseqno != fr->oseqno) && 09707 (iaxs[fr->callno]->iseqno || 09708 ((f.subclass != IAX_COMMAND_TXCNT) && 09709 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 09710 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 09711 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 09712 (f.subclass != IAX_COMMAND_TXACC)) || 09713 (f.frametype != AST_FRAME_IAX))) { 09714 if ( 09715 ((f.subclass != IAX_COMMAND_ACK) && 09716 (f.subclass != IAX_COMMAND_INVAL) && 09717 (f.subclass != IAX_COMMAND_TXCNT) && 09718 (f.subclass != IAX_COMMAND_TXREADY) && /* for attended transfer */ 09719 (f.subclass != IAX_COMMAND_TXREL) && /* for attended transfer */ 09720 (f.subclass != IAX_COMMAND_UNQUELCH ) && /* for attended transfer */ 09721 (f.subclass != IAX_COMMAND_TXACC) && 09722 (f.subclass != IAX_COMMAND_VNAK)) || 09723 (f.frametype != AST_FRAME_IAX)) { 09724 /* If it's not an ACK packet, it's out of order. */ 09725 ast_debug(1, "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", 09726 iaxs[fr->callno]->iseqno, fr->oseqno, f.frametype, f.subclass); 09727 /* Check to see if we need to request retransmission, 09728 * and take sequence number wraparound into account */ 09729 if ((unsigned char) (iaxs[fr->callno]->iseqno - fr->oseqno) < 128) { 09730 /* If we've already seen it, ack it XXX There's a border condition here XXX */ 09731 if ((f.frametype != AST_FRAME_IAX) || 09732 ((f.subclass != IAX_COMMAND_ACK) && (f.subclass != IAX_COMMAND_INVAL))) { 09733 ast_debug(1, "Acking anyway\n"); 09734 /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if 09735 we have anything to send, we'll retransmit and get an ACK back anyway XXX */ 09736 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 09737 } 09738 } else { 09739 /* Send a VNAK requesting retransmission */ 09740 iax2_vnak(fr->callno); 09741 } 09742 ast_mutex_unlock(&iaxsl[fr->callno]); 09743 return 1; 09744 } 09745 } else { 09746 /* Increment unless it's an ACK or VNAK */ 09747 if (((f.subclass != IAX_COMMAND_ACK) && 09748 (f.subclass != IAX_COMMAND_INVAL) && 09749 (f.subclass != IAX_COMMAND_TXCNT) && 09750 (f.subclass != IAX_COMMAND_TXACC) && 09751 (f.subclass != IAX_COMMAND_VNAK)) || 09752 (f.frametype != AST_FRAME_IAX)) 09753 iaxs[fr->callno]->iseqno++; 09754 } 09755 /* Ensure text frames are NULL-terminated */ 09756 if (f.frametype == AST_FRAME_TEXT && thread->buf[res - 1] != '\0') { 09757 if (res < thread->buf_size) 09758 thread->buf[res++] = '\0'; 09759 else /* Trims one character from the text message, but that's better than overwriting the end of the buffer. */ 09760 thread->buf[res - 1] = '\0'; 09761 } 09762 09763 /* Handle implicit ACKing unless this is an INVAL, and only if this is 09764 from the real peer, not the transfer peer */ 09765 if (!inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 09766 ((f.subclass != IAX_COMMAND_INVAL) || 09767 (f.frametype != AST_FRAME_IAX))) { 09768 unsigned char x; 09769 int call_to_destroy; 09770 /* First we have to qualify that the ACKed value is within our window */ 09771 if (iaxs[fr->callno]->rseqno >= iaxs[fr->callno]->oseqno || (fr->iseqno >= iaxs[fr->callno]->rseqno && fr->iseqno < iaxs[fr->callno]->oseqno)) 09772 x = fr->iseqno; 09773 else 09774 x = iaxs[fr->callno]->oseqno; 09775 if ((x != iaxs[fr->callno]->oseqno) || (iaxs[fr->callno]->oseqno == fr->iseqno)) { 09776 /* The acknowledgement is within our window. Time to acknowledge everything 09777 that it says to */ 09778 for (x=iaxs[fr->callno]->rseqno; x != fr->iseqno; x++) { 09779 /* Ack the packet with the given timestamp */ 09780 if (iaxdebug) 09781 ast_debug(1, "Cancelling transmission of packet %d\n", x); 09782 call_to_destroy = 0; 09783 AST_LIST_LOCK(&frame_queue); 09784 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 09785 /* If it's our call, and our timestamp, mark -1 retries */ 09786 if ((fr->callno == cur->callno) && (x == cur->oseqno)) { 09787 cur->retries = -1; 09788 /* Destroy call if this is the end */ 09789 if (cur->final) 09790 call_to_destroy = fr->callno; 09791 } 09792 } 09793 AST_LIST_UNLOCK(&frame_queue); 09794 if (call_to_destroy) { 09795 if (iaxdebug) 09796 ast_debug(1, "Really destroying %d, having been acked on final message\n", call_to_destroy); 09797 ast_mutex_lock(&iaxsl[call_to_destroy]); 09798 iax2_destroy(call_to_destroy); 09799 ast_mutex_unlock(&iaxsl[call_to_destroy]); 09800 } 09801 } 09802 /* Note how much we've received acknowledgement for */ 09803 if (iaxs[fr->callno]) 09804 iaxs[fr->callno]->rseqno = fr->iseqno; 09805 else { 09806 /* Stop processing now */ 09807 ast_mutex_unlock(&iaxsl[fr->callno]); 09808 return 1; 09809 } 09810 } else { 09811 ast_debug(1, "Received iseqno %d not within window %d->%d\n", fr->iseqno, iaxs[fr->callno]->rseqno, iaxs[fr->callno]->oseqno); 09812 } 09813 } 09814 if (inaddrcmp(&sin, &iaxs[fr->callno]->addr) && 09815 ((f.frametype != AST_FRAME_IAX) || 09816 ((f.subclass != IAX_COMMAND_TXACC) && 09817 (f.subclass != IAX_COMMAND_TXCNT)))) { 09818 /* Only messages we accept from a transfer host are TXACC and TXCNT */ 09819 ast_mutex_unlock(&iaxsl[fr->callno]); 09820 return 1; 09821 } 09822 09823 /* when we receive the first full frame for a new incoming channel, 09824 it is safe to start the PBX on the channel because we have now 09825 completed a 3-way handshake with the peer */ 09826 if ((f.frametype == AST_FRAME_VOICE) || 09827 (f.frametype == AST_FRAME_VIDEO) || 09828 (f.frametype == AST_FRAME_IAX)) { 09829 if (ast_test_flag(iaxs[fr->callno], IAX_DELAYPBXSTART)) { 09830 ast_clear_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 09831 if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) { 09832 ast_mutex_unlock(&iaxsl[fr->callno]); 09833 return 1; 09834 } 09835 } 09836 09837 if (ies.vars) { 09838 struct ast_datastore *variablestore = NULL; 09839 struct ast_variable *var, *prev = NULL; 09840 AST_LIST_HEAD(, ast_var_t) *varlist; 09841 if ((c = iaxs[fr->callno]->owner)) { 09842 varlist = ast_calloc(1, sizeof(*varlist)); 09843 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 09844 09845 if (variablestore && varlist) { 09846 variablestore->data = varlist; 09847 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 09848 AST_LIST_HEAD_INIT(varlist); 09849 ast_debug(1, "I can haz IAX vars?\n"); 09850 for (var = ies.vars; var; var = var->next) { 09851 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 09852 if (prev) { 09853 ast_free(prev); 09854 } 09855 prev = var; 09856 if (!newvar) { 09857 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 09858 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 09859 } else { 09860 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 09861 } 09862 } 09863 if (prev) { 09864 ast_free(prev); 09865 } 09866 ies.vars = NULL; 09867 ast_channel_datastore_add(c, variablestore); 09868 } else { 09869 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 09870 if (variablestore) { 09871 ast_datastore_free(variablestore); 09872 } 09873 if (varlist) { 09874 ast_free(varlist); 09875 } 09876 } 09877 } else { 09878 /* No channel yet, so transfer the variables directly over to the pvt, 09879 * for later inheritance. */ 09880 ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n"); 09881 for (var = ies.vars; var && var->next; var = var->next); 09882 if (var) { 09883 var->next = iaxs[fr->callno]->iaxvars; 09884 iaxs[fr->callno]->iaxvars = ies.vars; 09885 ies.vars = NULL; 09886 } 09887 } 09888 } 09889 09890 if (ies.vars) { 09891 ast_debug(1, "I have IAX variables, but they were not processed\n"); 09892 } 09893 } 09894 09895 /* once we receive our first IAX Full Frame that is not CallToken related, send all 09896 * queued signaling frames that were being held. */ 09897 if ((f.frametype == AST_FRAME_IAX) && (f.subclass != IAX_COMMAND_CALLTOKEN) && iaxs[fr->callno]->hold_signaling) { 09898 send_signaling(iaxs[fr->callno]); 09899 } 09900 09901 if (f.frametype == AST_FRAME_VOICE) { 09902 if (f.subclass != iaxs[fr->callno]->voiceformat) { 09903 iaxs[fr->callno]->voiceformat = f.subclass; 09904 ast_debug(1, "Ooh, voice format changed to %d\n", f.subclass); 09905 if (iaxs[fr->callno]->owner) { 09906 int orignative; 09907 retryowner: 09908 if (ast_channel_trylock(iaxs[fr->callno]->owner)) { 09909 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 09910 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner; 09911 } 09912 if (iaxs[fr->callno]) { 09913 if (iaxs[fr->callno]->owner) { 09914 orignative = iaxs[fr->callno]->owner->nativeformats; 09915 iaxs[fr->callno]->owner->nativeformats = f.subclass; 09916 if (iaxs[fr->callno]->owner->readformat) 09917 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 09918 iaxs[fr->callno]->owner->nativeformats = orignative; 09919 ast_channel_unlock(iaxs[fr->callno]->owner); 09920 } 09921 } else { 09922 ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n"); 09923 /* Free remote variables (if any) */ 09924 if (ies.vars) { 09925 ast_variables_destroy(ies.vars); 09926 ast_debug(1, "I can haz iaxvars, but they is no good. :-(\n"); 09927 ies.vars = NULL; 09928 } 09929 ast_mutex_unlock(&iaxsl[fr->callno]); 09930 return 1; 09931 } 09932 } 09933 } 09934 } 09935 if (f.frametype == AST_FRAME_VIDEO) { 09936 if (f.subclass != iaxs[fr->callno]->videoformat) { 09937 ast_debug(1, "Ooh, video format changed to %d\n", f.subclass & ~0x1); 09938 iaxs[fr->callno]->videoformat = f.subclass & ~0x1; 09939 } 09940 } 09941 if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) { 09942 if (f.subclass == AST_CONTROL_BUSY) { 09943 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_BUSY; 09944 } else if (f.subclass == AST_CONTROL_CONGESTION) { 09945 iaxs[fr->callno]->owner->hangupcause = AST_CAUSE_CONGESTION; 09946 } 09947 } 09948 if (f.frametype == AST_FRAME_IAX) { 09949 ast_sched_thread_del(sched, iaxs[fr->callno]->initid); 09950 /* Handle the IAX pseudo frame itself */ 09951 if (iaxdebug) 09952 ast_debug(1, "IAX subclass %d received\n", f.subclass); 09953 09954 /* Update last ts unless the frame's timestamp originated with us. */ 09955 if (iaxs[fr->callno]->last < fr->ts && 09956 f.subclass != IAX_COMMAND_ACK && 09957 f.subclass != IAX_COMMAND_PONG && 09958 f.subclass != IAX_COMMAND_LAGRP) { 09959 iaxs[fr->callno]->last = fr->ts; 09960 if (iaxdebug) 09961 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 09962 } 09963 iaxs[fr->callno]->last_iax_message = f.subclass; 09964 if (!iaxs[fr->callno]->first_iax_message) { 09965 iaxs[fr->callno]->first_iax_message = f.subclass; 09966 } 09967 switch(f.subclass) { 09968 case IAX_COMMAND_ACK: 09969 /* Do nothing */ 09970 break; 09971 case IAX_COMMAND_QUELCH: 09972 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09973 /* Generate Manager Hold event, if necessary*/ 09974 if (iaxs[fr->callno]->owner) { 09975 manager_event(EVENT_FLAG_CALL, "Hold", 09976 "Status: On\r\n" 09977 "Channel: %s\r\n" 09978 "Uniqueid: %s\r\n", 09979 iaxs[fr->callno]->owner->name, 09980 iaxs[fr->callno]->owner->uniqueid); 09981 } 09982 09983 ast_set_flag(iaxs[fr->callno], IAX_QUELCH); 09984 if (ies.musiconhold) { 09985 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 09986 const char *moh_suggest = iaxs[fr->callno]->mohsuggest; 09987 iax2_queue_control_data(fr->callno, AST_CONTROL_HOLD, 09988 S_OR(moh_suggest, NULL), 09989 !ast_strlen_zero(moh_suggest) ? strlen(moh_suggest) + 1 : 0); 09990 if (!iaxs[fr->callno]) { 09991 ast_mutex_unlock(&iaxsl[fr->callno]); 09992 return 1; 09993 } 09994 } 09995 } 09996 } 09997 break; 09998 case IAX_COMMAND_UNQUELCH: 09999 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 10000 /* Generate Manager Unhold event, if necessary*/ 10001 if (iaxs[fr->callno]->owner && ast_test_flag(iaxs[fr->callno], IAX_QUELCH)) { 10002 manager_event(EVENT_FLAG_CALL, "Hold", 10003 "Status: Off\r\n" 10004 "Channel: %s\r\n" 10005 "Uniqueid: %s\r\n", 10006 iaxs[fr->callno]->owner->name, 10007 iaxs[fr->callno]->owner->uniqueid); 10008 } 10009 10010 ast_clear_flag(iaxs[fr->callno], IAX_QUELCH); 10011 if (iaxs[fr->callno]->owner && ast_bridged_channel(iaxs[fr->callno]->owner)) { 10012 iax2_queue_control_data(fr->callno, AST_CONTROL_UNHOLD, NULL, 0); 10013 if (!iaxs[fr->callno]) { 10014 ast_mutex_unlock(&iaxsl[fr->callno]); 10015 return 1; 10016 } 10017 } 10018 } 10019 break; 10020 case IAX_COMMAND_TXACC: 10021 if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) { 10022 /* Ack the packet with the given timestamp */ 10023 AST_LIST_LOCK(&frame_queue); 10024 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 10025 /* Cancel any outstanding txcnt's */ 10026 if ((fr->callno == cur->callno) && (cur->transfer)) 10027 cur->retries = -1; 10028 } 10029 AST_LIST_UNLOCK(&frame_queue); 10030 memset(&ied1, 0, sizeof(ied1)); 10031 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->callno); 10032 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied1.buf, ied1.pos, -1); 10033 iaxs[fr->callno]->transferring = TRANSFER_READY; 10034 } 10035 break; 10036 case IAX_COMMAND_NEW: 10037 /* Ignore if it's already up */ 10038 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) 10039 break; 10040 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10041 ast_mutex_unlock(&iaxsl[fr->callno]); 10042 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10043 ast_mutex_lock(&iaxsl[fr->callno]); 10044 if (!iaxs[fr->callno]) { 10045 ast_mutex_unlock(&iaxsl[fr->callno]); 10046 return 1; 10047 } 10048 } 10049 /* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */ 10050 if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) { 10051 int new_callno; 10052 if ((new_callno = make_trunk(fr->callno, 1)) != -1) 10053 fr->callno = new_callno; 10054 } 10055 /* For security, always ack immediately */ 10056 if (delayreject) 10057 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10058 if (check_access(fr->callno, &sin, &ies)) { 10059 /* They're not allowed on */ 10060 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10061 if (authdebug) 10062 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); 10063 break; 10064 } 10065 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_test_flag(iaxs[fr->callno], IAX_FORCE_ENCRYPT)) { 10066 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10067 ast_log(LOG_WARNING, "Rejected connect attempt. No secret present while force encrypt enabled.\n"); 10068 break; 10069 } 10070 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10071 const char *context, *exten, *cid_num; 10072 10073 context = ast_strdupa(iaxs[fr->callno]->context); 10074 exten = ast_strdupa(iaxs[fr->callno]->exten); 10075 cid_num = ast_strdupa(iaxs[fr->callno]->cid_num); 10076 10077 /* This might re-enter the IAX code and need the lock */ 10078 ast_mutex_unlock(&iaxsl[fr->callno]); 10079 exists = ast_exists_extension(NULL, context, exten, 1, cid_num); 10080 ast_mutex_lock(&iaxsl[fr->callno]); 10081 10082 if (!iaxs[fr->callno]) { 10083 ast_mutex_unlock(&iaxsl[fr->callno]); 10084 return 1; 10085 } 10086 } else 10087 exists = 0; 10088 /* Get OSP token if it does exist */ 10089 save_osptoken(fr, &ies); 10090 if (ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) { 10091 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10092 memset(&ied0, 0, sizeof(ied0)); 10093 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10094 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10095 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10096 if (!iaxs[fr->callno]) { 10097 ast_mutex_unlock(&iaxsl[fr->callno]); 10098 return 1; 10099 } 10100 if (authdebug) 10101 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); 10102 } else { 10103 /* Select an appropriate format */ 10104 10105 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10106 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10107 using_prefs = "reqonly"; 10108 } else { 10109 using_prefs = "disabled"; 10110 } 10111 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10112 memset(&pref, 0, sizeof(pref)); 10113 strcpy(caller_pref_buf, "disabled"); 10114 strcpy(host_pref_buf, "disabled"); 10115 } else { 10116 using_prefs = "mine"; 10117 /* If the information elements are in here... use them */ 10118 if (ies.codec_prefs) 10119 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10120 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10121 /* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/ 10122 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10123 pref = iaxs[fr->callno]->rprefs; 10124 using_prefs = "caller"; 10125 } else { 10126 pref = iaxs[fr->callno]->prefs; 10127 } 10128 } else 10129 pref = iaxs[fr->callno]->prefs; 10130 10131 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10132 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10133 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10134 } 10135 if (!format) { 10136 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10137 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10138 if (!format) { 10139 memset(&ied0, 0, sizeof(ied0)); 10140 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10141 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10142 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10143 if (!iaxs[fr->callno]) { 10144 ast_mutex_unlock(&iaxsl[fr->callno]); 10145 return 1; 10146 } 10147 if (authdebug) { 10148 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10149 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); 10150 else 10151 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); 10152 } 10153 } else { 10154 /* Pick one... */ 10155 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10156 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10157 format = 0; 10158 } else { 10159 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10160 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10161 memset(&pref, 0, sizeof(pref)); 10162 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10163 strcpy(caller_pref_buf,"disabled"); 10164 strcpy(host_pref_buf,"disabled"); 10165 } else { 10166 using_prefs = "mine"; 10167 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10168 /* Do the opposite of what we tried above. */ 10169 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10170 pref = iaxs[fr->callno]->prefs; 10171 } else { 10172 pref = iaxs[fr->callno]->rprefs; 10173 using_prefs = "caller"; 10174 } 10175 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10176 10177 } else /* if no codec_prefs IE do it the old way */ 10178 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10179 } 10180 } 10181 10182 if (!format) { 10183 memset(&ied0, 0, sizeof(ied0)); 10184 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10185 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10186 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10187 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10188 if (!iaxs[fr->callno]) { 10189 ast_mutex_unlock(&iaxsl[fr->callno]); 10190 return 1; 10191 } 10192 if (authdebug) 10193 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); 10194 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 10195 break; 10196 } 10197 } 10198 } 10199 if (format) { 10200 /* No authentication required, let them in */ 10201 memset(&ied1, 0, sizeof(ied1)); 10202 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10203 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10204 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10205 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10206 ast_verb(3, "Accepting UNAUTHENTICATED call from %s:\n" 10207 "%srequested format = %s,\n" 10208 "%srequested prefs = %s,\n" 10209 "%sactual format = %s,\n" 10210 "%shost prefs = %s,\n" 10211 "%spriority = %s\n", 10212 ast_inet_ntoa(sin.sin_addr), 10213 VERBOSE_PREFIX_4, 10214 ast_getformatname(iaxs[fr->callno]->peerformat), 10215 VERBOSE_PREFIX_4, 10216 caller_pref_buf, 10217 VERBOSE_PREFIX_4, 10218 ast_getformatname(format), 10219 VERBOSE_PREFIX_4, 10220 host_pref_buf, 10221 VERBOSE_PREFIX_4, 10222 using_prefs); 10223 10224 iaxs[fr->callno]->chosenformat = format; 10225 ast_set_flag(iaxs[fr->callno], IAX_DELAYPBXSTART); 10226 } else { 10227 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10228 /* If this is a TBD call, we're ready but now what... */ 10229 ast_verb(3, "Accepted unauthenticated TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10230 } 10231 } 10232 } 10233 break; 10234 } 10235 if (iaxs[fr->callno]->authmethods & IAX_AUTH_MD5) 10236 merge_encryption(iaxs[fr->callno],ies.encmethods); 10237 else 10238 iaxs[fr->callno]->encmethods = 0; 10239 if (!authenticate_request(fr->callno) && iaxs[fr->callno]) 10240 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED); 10241 if (!iaxs[fr->callno]) { 10242 ast_mutex_unlock(&iaxsl[fr->callno]); 10243 return 1; 10244 } 10245 break; 10246 case IAX_COMMAND_DPREQ: 10247 /* Request status in the dialplan */ 10248 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD) && 10249 !ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED) && ies.called_number) { 10250 if (iaxcompat) { 10251 /* Spawn a thread for the lookup */ 10252 spawn_dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num); 10253 } else { 10254 /* Just look it up */ 10255 dp_lookup(fr->callno, iaxs[fr->callno]->context, ies.called_number, iaxs[fr->callno]->cid_num, 1); 10256 } 10257 } 10258 break; 10259 case IAX_COMMAND_HANGUP: 10260 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 10261 ast_debug(1, "Immediately destroying %d, having received hangup\n", fr->callno); 10262 /* Set hangup cause according to remote */ 10263 if (ies.causecode && iaxs[fr->callno]->owner) 10264 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 10265 /* Send ack immediately, before we destroy */ 10266 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10267 iax2_destroy(fr->callno); 10268 break; 10269 case IAX_COMMAND_REJECT: 10270 /* Set hangup cause according to remote */ 10271 if (ies.causecode && iaxs[fr->callno]->owner) 10272 iaxs[fr->callno]->owner->hangupcause = ies.causecode; 10273 10274 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 10275 if (iaxs[fr->callno]->owner && authdebug) 10276 ast_log(LOG_WARNING, "Call rejected by %s: %s\n", 10277 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), 10278 ies.cause ? ies.cause : "<Unknown>"); 10279 ast_debug(1, "Immediately destroying %d, having received reject\n", 10280 fr->callno); 10281 } 10282 /* Send ack immediately, before we destroy */ 10283 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, 10284 fr->ts, NULL, 0, fr->iseqno); 10285 if (!ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) 10286 iaxs[fr->callno]->error = EPERM; 10287 iax2_destroy(fr->callno); 10288 break; 10289 case IAX_COMMAND_TRANSFER: 10290 { 10291 struct ast_channel *bridged_chan; 10292 10293 if (iaxs[fr->callno]->owner && (bridged_chan = ast_bridged_channel(iaxs[fr->callno]->owner)) && ies.called_number) { 10294 /* Set BLINDTRANSFER channel variables */ 10295 10296 ast_mutex_unlock(&iaxsl[fr->callno]); 10297 pbx_builtin_setvar_helper(iaxs[fr->callno]->owner, "BLINDTRANSFER", bridged_chan->name); 10298 ast_mutex_lock(&iaxsl[fr->callno]); 10299 if (!iaxs[fr->callno]) { 10300 ast_mutex_unlock(&iaxsl[fr->callno]); 10301 return 1; 10302 } 10303 10304 pbx_builtin_setvar_helper(bridged_chan, "BLINDTRANSFER", iaxs[fr->callno]->owner->name); 10305 if (!strcmp(ies.called_number, ast_parking_ext())) { 10306 struct ast_channel *saved_channel = iaxs[fr->callno]->owner; 10307 ast_mutex_unlock(&iaxsl[fr->callno]); 10308 if (iax_park(bridged_chan, saved_channel)) { 10309 ast_log(LOG_WARNING, "Failed to park call on '%s'\n", bridged_chan->name); 10310 } else { 10311 ast_debug(1, "Parked call on '%s'\n", ast_bridged_channel(iaxs[fr->callno]->owner)->name); 10312 } 10313 ast_mutex_lock(&iaxsl[fr->callno]); 10314 } else { 10315 if (ast_async_goto(bridged_chan, iaxs[fr->callno]->context, ies.called_number, 1)) 10316 ast_log(LOG_WARNING, "Async goto of '%s' to '%s@%s' failed\n", bridged_chan->name, 10317 ies.called_number, iaxs[fr->callno]->context); 10318 else { 10319 ast_debug(1, "Async goto of '%s' to '%s@%s' started\n", bridged_chan->name, 10320 ies.called_number, iaxs[fr->callno]->context); 10321 } 10322 } 10323 } else { 10324 ast_debug(1, "Async goto not applicable on call %d\n", fr->callno); 10325 } 10326 10327 break; 10328 } 10329 case IAX_COMMAND_ACCEPT: 10330 /* Ignore if call is already up or needs authentication or is a TBD */ 10331 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD | IAX_STATE_AUTHENTICATED)) 10332 break; 10333 if (ast_test_flag(iaxs[fr->callno], IAX_PROVISION)) { 10334 /* Send ack immediately, before we destroy */ 10335 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10336 iax2_destroy(fr->callno); 10337 break; 10338 } 10339 if (ies.format) { 10340 iaxs[fr->callno]->peerformat = ies.format; 10341 } else { 10342 if (iaxs[fr->callno]->owner) 10343 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats; 10344 else 10345 iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability; 10346 } 10347 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)); 10348 if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) { 10349 memset(&ied0, 0, sizeof(ied0)); 10350 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10351 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10352 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10353 if (!iaxs[fr->callno]) { 10354 ast_mutex_unlock(&iaxsl[fr->callno]); 10355 return 1; 10356 } 10357 if (authdebug) 10358 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); 10359 } else { 10360 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10361 if (iaxs[fr->callno]->owner) { 10362 /* Switch us to use a compatible format */ 10363 iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat; 10364 ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats)); 10365 retryowner2: 10366 if (ast_channel_trylock(iaxs[fr->callno]->owner)) { 10367 DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]); 10368 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) goto retryowner2; 10369 } 10370 10371 if (iaxs[fr->callno] && iaxs[fr->callno]->owner) { 10372 /* Setup read/write formats properly. */ 10373 if (iaxs[fr->callno]->owner->writeformat) 10374 ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat); 10375 if (iaxs[fr->callno]->owner->readformat) 10376 ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat); 10377 ast_channel_unlock(iaxs[fr->callno]->owner); 10378 } 10379 } 10380 } 10381 if (iaxs[fr->callno]) { 10382 AST_LIST_LOCK(&dpcache); 10383 AST_LIST_TRAVERSE(&iaxs[fr->callno]->dpentries, dp, peer_list) 10384 if (!(dp->flags & CACHE_FLAG_TRANSMITTED)) 10385 iax2_dprequest(dp, fr->callno); 10386 AST_LIST_UNLOCK(&dpcache); 10387 } 10388 break; 10389 case IAX_COMMAND_POKE: 10390 /* Send back a pong packet with the original timestamp */ 10391 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, NULL, 0, -1); 10392 if (!iaxs[fr->callno]) { 10393 ast_mutex_unlock(&iaxsl[fr->callno]); 10394 return 1; 10395 } 10396 break; 10397 case IAX_COMMAND_PING: 10398 { 10399 struct iax_ie_data pingied; 10400 construct_rr(iaxs[fr->callno], &pingied); 10401 /* Send back a pong packet with the original timestamp */ 10402 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_PONG, fr->ts, pingied.buf, pingied.pos, -1); 10403 } 10404 break; 10405 case IAX_COMMAND_PONG: 10406 /* Calculate ping time */ 10407 iaxs[fr->callno]->pingtime = calc_timestamp(iaxs[fr->callno], 0, &f) - fr->ts; 10408 /* save RR info */ 10409 save_rr(fr, &ies); 10410 10411 /* Good time to write jb stats for this call */ 10412 log_jitterstats(fr->callno); 10413 10414 if (iaxs[fr->callno]->peerpoke) { 10415 peer = iaxs[fr->callno]->peerpoke; 10416 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) { 10417 if (iaxs[fr->callno]->pingtime <= peer->maxms) { 10418 ast_log(LOG_NOTICE, "Peer '%s' is now REACHABLE! Time: %d\n", peer->name, iaxs[fr->callno]->pingtime); 10419 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); 10420 ast_devstate_changed(AST_DEVICE_NOT_INUSE, "IAX2/%s", peer->name); /* Activate notification */ 10421 } 10422 } else if ((peer->historicms > 0) && (peer->historicms <= peer->maxms)) { 10423 if (iaxs[fr->callno]->pingtime > peer->maxms) { 10424 ast_log(LOG_NOTICE, "Peer '%s' is now TOO LAGGED (%d ms)!\n", peer->name, iaxs[fr->callno]->pingtime); 10425 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); 10426 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", peer->name); /* Activate notification */ 10427 } 10428 } 10429 peer->lastms = iaxs[fr->callno]->pingtime; 10430 if (peer->smoothing && (peer->lastms > -1)) 10431 peer->historicms = (iaxs[fr->callno]->pingtime + peer->historicms) / 2; 10432 else if (peer->smoothing && peer->lastms < 0) 10433 peer->historicms = (0 + peer->historicms) / 2; 10434 else 10435 peer->historicms = iaxs[fr->callno]->pingtime; 10436 10437 /* Remove scheduled iax2_poke_noanswer */ 10438 if (peer->pokeexpire > -1) { 10439 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 10440 peer_unref(peer); 10441 peer->pokeexpire = -1; 10442 } 10443 } 10444 /* Schedule the next cycle */ 10445 if ((peer->lastms < 0) || (peer->historicms > peer->maxms)) 10446 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqnotok, iax2_poke_peer_s, peer_ref(peer)); 10447 else 10448 peer->pokeexpire = iax2_sched_add(sched, peer->pokefreqok, iax2_poke_peer_s, peer_ref(peer)); 10449 if (peer->pokeexpire == -1) 10450 peer_unref(peer); 10451 /* and finally send the ack */ 10452 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10453 /* And wrap up the qualify call */ 10454 iax2_destroy(fr->callno); 10455 peer->callno = 0; 10456 ast_debug(1, "Peer %s: got pong, lastms %d, historicms %d, maxms %d\n", peer->name, peer->lastms, peer->historicms, peer->maxms); 10457 } 10458 break; 10459 case IAX_COMMAND_LAGRQ: 10460 case IAX_COMMAND_LAGRP: 10461 f.src = "LAGRQ"; 10462 f.mallocd = 0; 10463 f.offset = 0; 10464 f.samples = 0; 10465 iax_frame_wrap(fr, &f); 10466 if(f.subclass == IAX_COMMAND_LAGRQ) { 10467 /* Received a LAGRQ - echo back a LAGRP */ 10468 fr->af.subclass = IAX_COMMAND_LAGRP; 10469 iax2_send(iaxs[fr->callno], &fr->af, fr->ts, -1, 0, 0, 0); 10470 } else { 10471 /* Received LAGRP in response to our LAGRQ */ 10472 unsigned int ts; 10473 /* This is a reply we've been given, actually measure the difference */ 10474 ts = calc_timestamp(iaxs[fr->callno], 0, &fr->af); 10475 iaxs[fr->callno]->lag = ts - fr->ts; 10476 if (iaxdebug) 10477 ast_debug(1, "Peer %s lag measured as %dms\n", 10478 ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iaxs[fr->callno]->lag); 10479 } 10480 break; 10481 case IAX_COMMAND_AUTHREQ: 10482 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10483 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>"); 10484 break; 10485 } 10486 if (authenticate_reply(iaxs[fr->callno], &iaxs[fr->callno]->addr, &ies, iaxs[fr->callno]->secret, iaxs[fr->callno]->outkey)) { 10487 struct ast_frame hangup_fr = { .frametype = AST_FRAME_CONTROL, 10488 .subclass = AST_CONTROL_HANGUP, 10489 }; 10490 ast_log(LOG_WARNING, 10491 "I don't know how to authenticate %s to %s\n", 10492 ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr)); 10493 iax2_queue_frame(fr->callno, &hangup_fr); 10494 } 10495 if (!iaxs[fr->callno]) { 10496 ast_mutex_unlock(&iaxsl[fr->callno]); 10497 return 1; 10498 } 10499 break; 10500 case IAX_COMMAND_AUTHREP: 10501 /* For security, always ack immediately */ 10502 if (delayreject) 10503 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10504 /* Ignore once we've started */ 10505 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD)) { 10506 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>"); 10507 break; 10508 } 10509 if (authenticate_verify(iaxs[fr->callno], &ies)) { 10510 if (authdebug) 10511 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); 10512 memset(&ied0, 0, sizeof(ied0)); 10513 auth_fail(fr->callno, IAX_COMMAND_REJECT); 10514 break; 10515 } 10516 if (strcasecmp(iaxs[fr->callno]->exten, "TBD")) { 10517 /* This might re-enter the IAX code and need the lock */ 10518 exists = ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num); 10519 } else 10520 exists = 0; 10521 if (strcmp(iaxs[fr->callno]->exten, "TBD") && !exists) { 10522 if (authdebug) 10523 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); 10524 memset(&ied0, 0, sizeof(ied0)); 10525 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10526 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10527 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10528 if (!iaxs[fr->callno]) { 10529 ast_mutex_unlock(&iaxsl[fr->callno]); 10530 return 1; 10531 } 10532 } else { 10533 /* Select an appropriate format */ 10534 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10535 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10536 using_prefs = "reqonly"; 10537 } else { 10538 using_prefs = "disabled"; 10539 } 10540 format = iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability; 10541 memset(&pref, 0, sizeof(pref)); 10542 strcpy(caller_pref_buf, "disabled"); 10543 strcpy(host_pref_buf, "disabled"); 10544 } else { 10545 using_prefs = "mine"; 10546 if (ies.codec_prefs) 10547 ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0); 10548 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10549 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10550 pref = iaxs[fr->callno]->rprefs; 10551 using_prefs = "caller"; 10552 } else { 10553 pref = iaxs[fr->callno]->prefs; 10554 } 10555 } else /* if no codec_prefs IE do it the old way */ 10556 pref = iaxs[fr->callno]->prefs; 10557 10558 format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0); 10559 ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1); 10560 ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1); 10561 } 10562 if (!format) { 10563 if(!ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10564 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); 10565 format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability; 10566 } 10567 if (!format) { 10568 if (authdebug) { 10569 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10570 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); 10571 else 10572 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); 10573 } 10574 memset(&ied0, 0, sizeof(ied0)); 10575 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10576 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10577 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10578 if (!iaxs[fr->callno]) { 10579 ast_mutex_unlock(&iaxsl[fr->callno]); 10580 return 1; 10581 } 10582 } else { 10583 /* Pick one... */ 10584 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) { 10585 if(!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) 10586 format = 0; 10587 } else { 10588 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOPREFS)) { 10589 using_prefs = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled"; 10590 memset(&pref, 0, sizeof(pref)); 10591 format = ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP) ? 10592 iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10593 strcpy(caller_pref_buf,"disabled"); 10594 strcpy(host_pref_buf,"disabled"); 10595 } else { 10596 using_prefs = "mine"; 10597 if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) { 10598 /* Do the opposite of what we tried above. */ 10599 if (ast_test_flag(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) { 10600 pref = iaxs[fr->callno]->prefs; 10601 } else { 10602 pref = iaxs[fr->callno]->rprefs; 10603 using_prefs = "caller"; 10604 } 10605 format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1); 10606 } else /* if no codec_prefs IE do it the old way */ 10607 format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10608 } 10609 } 10610 if (!format) { 10611 ast_log(LOG_ERROR, "No best format in 0x%x???\n", iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability); 10612 if (authdebug) { 10613 if(ast_test_flag(iaxs[fr->callno], IAX_CODEC_NOCAP)) 10614 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); 10615 else 10616 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); 10617 } 10618 memset(&ied0, 0, sizeof(ied0)); 10619 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec"); 10620 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL); 10621 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10622 if (!iaxs[fr->callno]) { 10623 ast_mutex_unlock(&iaxsl[fr->callno]); 10624 return 1; 10625 } 10626 } 10627 } 10628 } 10629 if (format) { 10630 /* Authentication received */ 10631 memset(&ied1, 0, sizeof(ied1)); 10632 iax_ie_append_int(&ied1, IAX_IE_FORMAT, format); 10633 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied1.buf, ied1.pos, -1); 10634 if (strcmp(iaxs[fr->callno]->exten, "TBD")) { 10635 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10636 ast_verb(3, "Accepting AUTHENTICATED call from %s:\n" 10637 "%srequested format = %s,\n" 10638 "%srequested prefs = %s,\n" 10639 "%sactual format = %s,\n" 10640 "%shost prefs = %s,\n" 10641 "%spriority = %s\n", 10642 ast_inet_ntoa(sin.sin_addr), 10643 VERBOSE_PREFIX_4, 10644 ast_getformatname(iaxs[fr->callno]->peerformat), 10645 VERBOSE_PREFIX_4, 10646 caller_pref_buf, 10647 VERBOSE_PREFIX_4, 10648 ast_getformatname(format), 10649 VERBOSE_PREFIX_4, 10650 host_pref_buf, 10651 VERBOSE_PREFIX_4, 10652 using_prefs); 10653 10654 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10655 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format))) 10656 iax2_destroy(fr->callno); 10657 else if (ies.vars) { 10658 struct ast_datastore *variablestore; 10659 struct ast_variable *var, *prev = NULL; 10660 AST_LIST_HEAD(, ast_var_t) *varlist; 10661 varlist = ast_calloc(1, sizeof(*varlist)); 10662 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10663 if (variablestore && varlist) { 10664 variablestore->data = varlist; 10665 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10666 AST_LIST_HEAD_INIT(varlist); 10667 ast_debug(1, "I can haz IAX vars? w00t\n"); 10668 for (var = ies.vars; var; var = var->next) { 10669 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10670 if (prev) 10671 ast_free(prev); 10672 prev = var; 10673 if (!newvar) { 10674 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10675 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10676 } else { 10677 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10678 } 10679 } 10680 if (prev) 10681 ast_free(prev); 10682 ies.vars = NULL; 10683 ast_channel_datastore_add(c, variablestore); 10684 } else { 10685 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10686 if (variablestore) 10687 ast_datastore_free(variablestore); 10688 if (varlist) 10689 ast_free(varlist); 10690 } 10691 } 10692 } else { 10693 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10694 /* If this is a TBD call, we're ready but now what... */ 10695 ast_verb(3, "Accepted AUTHENTICATED TBD call from %s\n", ast_inet_ntoa(sin.sin_addr)); 10696 if (ast_test_flag(iaxs[fr->callno], IAX_IMMEDIATE)) { 10697 goto immediatedial; 10698 } 10699 } 10700 } 10701 } 10702 break; 10703 case IAX_COMMAND_DIAL: 10704 immediatedial: 10705 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD)) { 10706 ast_clear_flag(&iaxs[fr->callno]->state, IAX_STATE_TBD); 10707 ast_string_field_set(iaxs[fr->callno], exten, ies.called_number ? ies.called_number : "s"); 10708 if (!ast_exists_extension(NULL, iaxs[fr->callno]->context, iaxs[fr->callno]->exten, 1, iaxs[fr->callno]->cid_num)) { 10709 if (authdebug) 10710 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); 10711 memset(&ied0, 0, sizeof(ied0)); 10712 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No such context/extension"); 10713 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_NO_ROUTE_DESTINATION); 10714 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10715 if (!iaxs[fr->callno]) { 10716 ast_mutex_unlock(&iaxsl[fr->callno]); 10717 return 1; 10718 } 10719 } else { 10720 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10721 ast_verb(3, "Accepting DIAL from %s, formats = 0x%x\n", ast_inet_ntoa(sin.sin_addr), iaxs[fr->callno]->peerformat); 10722 ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED); 10723 send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1); 10724 if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat))) 10725 iax2_destroy(fr->callno); 10726 else if (ies.vars) { 10727 struct ast_datastore *variablestore; 10728 struct ast_variable *var, *prev = NULL; 10729 AST_LIST_HEAD(, ast_var_t) *varlist; 10730 varlist = ast_calloc(1, sizeof(*varlist)); 10731 variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL); 10732 ast_debug(1, "I can haz IAX vars? w00t\n"); 10733 if (variablestore && varlist) { 10734 variablestore->data = varlist; 10735 variablestore->inheritance = DATASTORE_INHERIT_FOREVER; 10736 AST_LIST_HEAD_INIT(varlist); 10737 for (var = ies.vars; var; var = var->next) { 10738 struct ast_var_t *newvar = ast_var_assign(var->name, var->value); 10739 if (prev) 10740 ast_free(prev); 10741 prev = var; 10742 if (!newvar) { 10743 /* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */ 10744 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10745 } else { 10746 AST_LIST_INSERT_TAIL(varlist, newvar, entries); 10747 } 10748 } 10749 if (prev) 10750 ast_free(prev); 10751 ies.vars = NULL; 10752 ast_channel_datastore_add(c, variablestore); 10753 } else { 10754 ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n"); 10755 if (variablestore) 10756 ast_datastore_free(variablestore); 10757 if (varlist) 10758 ast_free(varlist); 10759 } 10760 } 10761 } 10762 } 10763 break; 10764 case IAX_COMMAND_INVAL: 10765 iaxs[fr->callno]->error = ENOTCONN; 10766 ast_debug(1, "Immediately destroying %d, having received INVAL\n", fr->callno); 10767 iax2_destroy(fr->callno); 10768 ast_debug(1, "Destroying call %d\n", fr->callno); 10769 break; 10770 case IAX_COMMAND_VNAK: 10771 ast_debug(1, "Received VNAK: resending outstanding frames\n"); 10772 /* Force retransmission */ 10773 vnak_retransmit(fr->callno, fr->iseqno); 10774 break; 10775 case IAX_COMMAND_REGREQ: 10776 case IAX_COMMAND_REGREL: 10777 /* For security, always ack immediately */ 10778 if (delayreject) 10779 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10780 if (register_verify(fr->callno, &sin, &ies)) { 10781 if (!iaxs[fr->callno]) { 10782 ast_mutex_unlock(&iaxsl[fr->callno]); 10783 return 1; 10784 } 10785 /* Send delayed failure */ 10786 auth_fail(fr->callno, IAX_COMMAND_REGREJ); 10787 break; 10788 } 10789 if (!iaxs[fr->callno]) { 10790 ast_mutex_unlock(&iaxsl[fr->callno]); 10791 return 1; 10792 } 10793 if ((ast_strlen_zero(iaxs[fr->callno]->secret) && ast_strlen_zero(iaxs[fr->callno]->inkeys)) || 10794 ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED)) { 10795 10796 if (f.subclass == IAX_COMMAND_REGREL) 10797 memset(&sin, 0, sizeof(sin)); 10798 if (update_registry(&sin, fr->callno, ies.devicetype, fd, ies.refresh)) 10799 ast_log(LOG_WARNING, "Registry error\n"); 10800 if (!iaxs[fr->callno]) { 10801 ast_mutex_unlock(&iaxsl[fr->callno]); 10802 return 1; 10803 } 10804 if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) { 10805 ast_mutex_unlock(&iaxsl[fr->callno]); 10806 check_provisioning(&sin, fd, ies.serviceident, ies.provver); 10807 ast_mutex_lock(&iaxsl[fr->callno]); 10808 if (!iaxs[fr->callno]) { 10809 ast_mutex_unlock(&iaxsl[fr->callno]); 10810 return 1; 10811 } 10812 } 10813 break; 10814 } 10815 registry_authrequest(fr->callno); 10816 if (!iaxs[fr->callno]) { 10817 ast_mutex_unlock(&iaxsl[fr->callno]); 10818 return 1; 10819 } 10820 break; 10821 case IAX_COMMAND_REGACK: 10822 if (iax2_ack_registry(&ies, &sin, fr->callno)) 10823 ast_log(LOG_WARNING, "Registration failure\n"); 10824 /* Send ack immediately, before we destroy */ 10825 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10826 iax2_destroy(fr->callno); 10827 break; 10828 case IAX_COMMAND_REGREJ: 10829 if (iaxs[fr->callno]->reg) { 10830 if (authdebug) { 10831 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)); 10832 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>"); 10833 } 10834 iaxs[fr->callno]->reg->regstate = REG_STATE_REJECTED; 10835 } 10836 /* Send ack immediately, before we destroy */ 10837 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10838 iax2_destroy(fr->callno); 10839 break; 10840 case IAX_COMMAND_REGAUTH: 10841 /* Authentication request */ 10842 if (registry_rerequest(&ies, fr->callno, &sin)) { 10843 memset(&ied0, 0, sizeof(ied0)); 10844 iax_ie_append_str(&ied0, IAX_IE_CAUSE, "No authority found"); 10845 iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_FACILITY_NOT_SUBSCRIBED); 10846 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10847 if (!iaxs[fr->callno]) { 10848 ast_mutex_unlock(&iaxsl[fr->callno]); 10849 return 1; 10850 } 10851 } 10852 break; 10853 case IAX_COMMAND_TXREJ: 10854 iaxs[fr->callno]->transferring = 0; 10855 ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 10856 memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer)); 10857 if (iaxs[fr->callno]->bridgecallno) { 10858 if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) { 10859 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0; 10860 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1); 10861 } 10862 } 10863 break; 10864 case IAX_COMMAND_TXREADY: 10865 if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) || 10866 (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) { 10867 if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) 10868 iaxs[fr->callno]->transferring = TRANSFER_MREADY; 10869 else 10870 iaxs[fr->callno]->transferring = TRANSFER_READY; 10871 ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>"); 10872 if (iaxs[fr->callno]->bridgecallno) { 10873 if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) || 10874 (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) { 10875 /* They're both ready, now release them. */ 10876 if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) { 10877 ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 10878 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 10879 10880 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA; 10881 iaxs[fr->callno]->transferring = TRANSFER_MEDIA; 10882 10883 memset(&ied0, 0, sizeof(ied0)); 10884 memset(&ied1, 0, sizeof(ied1)); 10885 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 10886 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 10887 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1); 10888 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1); 10889 } else { 10890 ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? iaxs[fr->callno]->owner->name : "<Unknown>", 10891 iaxs[iaxs[fr->callno]->bridgecallno]->owner ? iaxs[iaxs[fr->callno]->bridgecallno]->owner->name : "<Unknown>"); 10892 10893 iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED; 10894 iaxs[fr->callno]->transferring = TRANSFER_RELEASED; 10895 ast_set_flag(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE); 10896 ast_set_flag(iaxs[fr->callno], IAX_ALREADYGONE); 10897 10898 /* Stop doing lag & ping requests */ 10899 stop_stuff(fr->callno); 10900 stop_stuff(iaxs[fr->callno]->bridgecallno); 10901 10902 memset(&ied0, 0, sizeof(ied0)); 10903 memset(&ied1, 0, sizeof(ied1)); 10904 iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno); 10905 iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno); 10906 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1); 10907 send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1); 10908 } 10909 10910 } 10911 } 10912 } 10913 break; 10914 case IAX_COMMAND_TXREQ: 10915 try_transfer(iaxs[fr->callno], &ies); 10916 break; 10917 case IAX_COMMAND_TXCNT: 10918 if (iaxs[fr->callno]->transferring) 10919 send_command_transfer(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, NULL, 0); 10920 break; 10921 case IAX_COMMAND_TXREL: 10922 /* Send ack immediately, rather than waiting until we've changed addresses */ 10923 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 10924 complete_transfer(fr->callno, &ies); 10925 stop_stuff(fr->callno); /* for attended transfer to work with libiax */ 10926 break; 10927 case IAX_COMMAND_TXMEDIA: 10928 if (iaxs[fr->callno]->transferring == TRANSFER_READY) { 10929 AST_LIST_LOCK(&frame_queue); 10930 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 10931 /* Cancel any outstanding frames and start anew */ 10932 if ((fr->callno == cur->callno) && (cur->transfer)) 10933 cur->retries = -1; 10934 } 10935 AST_LIST_UNLOCK(&frame_queue); 10936 /* Start sending our media to the transfer address, but otherwise leave the call as-is */ 10937 iaxs[fr->callno]->transferring = TRANSFER_MEDIAPASS; 10938 } 10939 break; 10940 case IAX_COMMAND_RTKEY: 10941 if (!IAX_CALLENCRYPTED(iaxs[fr->callno])) { 10942 ast_log(LOG_WARNING, 10943 "we've been told to rotate our encryption key, " 10944 "but this isn't an encrypted call. bad things will happen.\n" 10945 ); 10946 break; 10947 } 10948 10949 IAX_DEBUGDIGEST("Receiving", ies.challenge); 10950 10951 ast_aes_decrypt_key((unsigned char *) ies.challenge, &iaxs[fr->callno]->dcx); 10952 break; 10953 case IAX_COMMAND_DPREP: 10954 complete_dpreply(iaxs[fr->callno], &ies); 10955 break; 10956 case IAX_COMMAND_UNSUPPORT: 10957 ast_log(LOG_NOTICE, "Peer did not understand our iax command '%d'\n", ies.iax_unknown); 10958 break; 10959 case IAX_COMMAND_FWDOWNL: 10960 /* Firmware download */ 10961 if (!ast_test_flag(&globalflags, IAX_ALLOWFWDOWNLOAD)) { 10962 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, NULL, 0, -1); 10963 break; 10964 } 10965 memset(&ied0, 0, sizeof(ied0)); 10966 res = iax_firmware_append(&ied0, (unsigned char *)ies.devicetype, ies.fwdesc); 10967 if (res < 0) 10968 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1); 10969 else if (res > 0) 10970 send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 10971 else 10972 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_FWDATA, 0, ied0.buf, ied0.pos, -1); 10973 if (!iaxs[fr->callno]) { 10974 ast_mutex_unlock(&iaxsl[fr->callno]); 10975 return 1; 10976 } 10977 break; 10978 case IAX_COMMAND_CALLTOKEN: 10979 { 10980 struct iax_frame *cur; 10981 int found = 0; 10982 AST_LIST_LOCK(&frame_queue); 10983 AST_LIST_TRAVERSE(&frame_queue, cur, list) { 10984 /* find the last sent frame in our frame queue for this callno. 10985 * There are many things to take into account before resending this frame. 10986 * All of these are taken care of in resend_with_token() */ 10987 if (cur->callno == fr->callno) { 10988 found = 1; 10989 break; 10990 } 10991 } 10992 AST_LIST_UNLOCK(&frame_queue); 10993 10994 /* find last sent frame */ 10995 if (cur && found && ies.calltoken && ies.calltokendata) { 10996 resend_with_token(fr->callno, cur, (char *) ies.calltokendata); 10997 } 10998 break; 10999 } 11000 default: 11001 ast_debug(1, "Unknown IAX command %d on %d/%d\n", f.subclass, fr->callno, iaxs[fr->callno]->peercallno); 11002 memset(&ied0, 0, sizeof(ied0)); 11003 iax_ie_append_byte(&ied0, IAX_IE_IAX_UNKNOWN, f.subclass); 11004 send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1); 11005 } 11006 /* Free remote variables (if any) */ 11007 if (ies.vars) { 11008 ast_variables_destroy(ies.vars); 11009 ast_debug(1, "I can haz IAX vars, but they is no good :-(\n"); 11010 ies.vars = NULL; 11011 } 11012 11013 /* Don't actually pass these frames along */ 11014 if ((f.subclass != IAX_COMMAND_ACK) && 11015 (f.subclass != IAX_COMMAND_TXCNT) && 11016 (f.subclass != IAX_COMMAND_TXACC) && 11017 (f.subclass != IAX_COMMAND_INVAL) && 11018 (f.subclass != IAX_COMMAND_VNAK)) { 11019 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11020 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11021 } 11022 ast_mutex_unlock(&iaxsl[fr->callno]); 11023 return 1; 11024 } 11025 /* Unless this is an ACK or INVAL frame, ack it */ 11026 if (iaxs[fr->callno] && iaxs[fr->callno]->aseqno != iaxs[fr->callno]->iseqno) 11027 send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno); 11028 } else if (minivid) { 11029 f.frametype = AST_FRAME_VIDEO; 11030 if (iaxs[fr->callno]->videoformat > 0) 11031 f.subclass = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000 ? 1 : 0); 11032 else { 11033 ast_log(LOG_WARNING, "Received mini frame before first full video frame\n"); 11034 iax2_vnak(fr->callno); 11035 ast_mutex_unlock(&iaxsl[fr->callno]); 11036 return 1; 11037 } 11038 f.datalen = res - sizeof(*vh); 11039 if (f.datalen) 11040 f.data.ptr = thread->buf + sizeof(*vh); 11041 else 11042 f.data.ptr = NULL; 11043 #ifdef IAXTESTS 11044 if (test_resync) { 11045 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | ((ntohs(vh->ts) + test_resync) & 0x7fff); 11046 } else 11047 #endif /* IAXTESTS */ 11048 fr->ts = (iaxs[fr->callno]->last & 0xFFFF8000L) | (ntohs(vh->ts) & 0x7fff); 11049 } else { 11050 /* A mini frame */ 11051 f.frametype = AST_FRAME_VOICE; 11052 if (iaxs[fr->callno]->voiceformat > 0) 11053 f.subclass = iaxs[fr->callno]->voiceformat; 11054 else { 11055 ast_debug(1, "Received mini frame before first full voice frame\n"); 11056 iax2_vnak(fr->callno); 11057 ast_mutex_unlock(&iaxsl[fr->callno]); 11058 return 1; 11059 } 11060 f.datalen = res - sizeof(struct ast_iax2_mini_hdr); 11061 if (f.datalen < 0) { 11062 ast_log(LOG_WARNING, "Datalen < 0?\n"); 11063 ast_mutex_unlock(&iaxsl[fr->callno]); 11064 return 1; 11065 } 11066 if (f.datalen) 11067 f.data.ptr = thread->buf + sizeof(*mh); 11068 else 11069 f.data.ptr = NULL; 11070 #ifdef IAXTESTS 11071 if (test_resync) { 11072 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ((ntohs(mh->ts) + test_resync) & 0xffff); 11073 } else 11074 #endif /* IAXTESTS */ 11075 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | ntohs(mh->ts); 11076 /* FIXME? Surely right here would be the right place to undo timestamp wraparound? */ 11077 } 11078 /* Don't pass any packets until we're started */ 11079 if (!ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 11080 ast_mutex_unlock(&iaxsl[fr->callno]); 11081 return 1; 11082 } 11083 /* Common things */ 11084 f.src = "IAX2"; 11085 f.mallocd = 0; 11086 f.offset = 0; 11087 f.len = 0; 11088 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) { 11089 f.samples = ast_codec_get_samples(&f); 11090 /* We need to byteswap incoming slinear samples from network byte order */ 11091 if (f.subclass == AST_FORMAT_SLINEAR) 11092 ast_frame_byteswap_be(&f); 11093 } else 11094 f.samples = 0; 11095 iax_frame_wrap(fr, &f); 11096 11097 /* If this is our most recent packet, use it as our basis for timestamping */ 11098 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11099 /*iaxs[fr->callno]->last = fr->ts; (do it afterwards cos schedule/forward_delivery needs the last ts too)*/ 11100 fr->outoforder = 0; 11101 } else { 11102 if (iaxdebug && iaxs[fr->callno]) 11103 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); 11104 fr->outoforder = -1; 11105 } 11106 fr->cacheable = ((f.frametype == AST_FRAME_VOICE) || (f.frametype == AST_FRAME_VIDEO)); 11107 duped_fr = iaxfrdup2(fr); 11108 if (duped_fr) { 11109 schedule_delivery(duped_fr, updatehistory, 0, &fr->ts); 11110 } 11111 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) { 11112 iaxs[fr->callno]->last = fr->ts; 11113 #if 1 11114 if (iaxdebug) 11115 ast_debug(1, "For call=%d, set last=%d\n", fr->callno, fr->ts); 11116 #endif 11117 } 11118 11119 /* Always run again */ 11120 ast_mutex_unlock(&iaxsl[fr->callno]); 11121 return 1; 11122 }
| 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 9260 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().
09262 { 09263 unsigned char metatype; 09264 struct ast_iax2_meta_trunk_mini *mtm; 09265 struct ast_iax2_meta_trunk_hdr *mth; 09266 struct ast_iax2_meta_trunk_entry *mte; 09267 struct iax2_trunk_peer *tpeer; 09268 unsigned int ts; 09269 void *ptr; 09270 struct timeval rxtrunktime; 09271 struct ast_frame f = { 0, }; 09272 09273 if (packet_len < sizeof(*meta)) { 09274 ast_log(LOG_WARNING, "Rejecting packet from '%s.%d' that is flagged as a meta frame but is too short\n", 09275 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09276 return 1; 09277 } 09278 09279 if (meta->metacmd != IAX_META_TRUNK) 09280 return 1; 09281 09282 if (packet_len < (sizeof(*meta) + sizeof(*mth))) { 09283 ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", packet_len, 09284 (int) (sizeof(*meta) + sizeof(*mth))); 09285 return 1; 09286 } 09287 mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); 09288 ts = ntohl(mth->ts); 09289 metatype = meta->cmddata; 09290 packet_len -= (sizeof(*meta) + sizeof(*mth)); 09291 ptr = mth->data; 09292 tpeer = find_tpeer(sin, sockfd); 09293 if (!tpeer) { 09294 ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", 09295 ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09296 return 1; 09297 } 09298 tpeer->trunkact = ast_tvnow(); 09299 if (!ts || ast_tvzero(tpeer->rxtrunktime)) 09300 tpeer->rxtrunktime = tpeer->trunkact; 09301 rxtrunktime = tpeer->rxtrunktime; 09302 ast_mutex_unlock(&tpeer->lock); 09303 while (packet_len >= sizeof(*mte)) { 09304 /* Process channels */ 09305 unsigned short callno, trunked_ts, len; 09306 09307 if (metatype == IAX_META_TRUNK_MINI) { 09308 mtm = (struct ast_iax2_meta_trunk_mini *) ptr; 09309 ptr += sizeof(*mtm); 09310 packet_len -= sizeof(*mtm); 09311 len = ntohs(mtm->len); 09312 callno = ntohs(mtm->mini.callno); 09313 trunked_ts = ntohs(mtm->mini.ts); 09314 } else if (metatype == IAX_META_TRUNK_SUPERMINI) { 09315 mte = (struct ast_iax2_meta_trunk_entry *)ptr; 09316 ptr += sizeof(*mte); 09317 packet_len -= sizeof(*mte); 09318 len = ntohs(mte->len); 09319 callno = ntohs(mte->callno); 09320 trunked_ts = 0; 09321 } else { 09322 ast_log(LOG_WARNING, "Unknown meta trunk cmd from '%s:%d': dropping\n", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 09323 break; 09324 } 09325 /* Stop if we don't have enough data */ 09326 if (len > packet_len) 09327 break; 09328 fr->callno = find_callno_locked(callno & ~IAX_FLAG_FULL, 0, sin, NEW_PREVENT, sockfd, 0); 09329 if (!fr->callno) 09330 continue; 09331 09332 /* If it's a valid call, deliver the contents. If not, we 09333 drop it, since we don't have a scallno to use for an INVAL */ 09334 /* Process as a mini frame */ 09335 memset(&f, 0, sizeof(f)); 09336 f.frametype = AST_FRAME_VOICE; 09337 if (!iaxs[fr->callno]) { 09338 /* drop it */ 09339 } else if (iaxs[fr->callno]->voiceformat == 0) { 09340 ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n"); 09341 iax2_vnak(fr->callno); 09342 } else { 09343 f.subclass = iaxs[fr->callno]->voiceformat; 09344 f.datalen = len; 09345 if (f.datalen >= 0) { 09346 if (f.datalen) 09347 f.data.ptr = ptr; 09348 else 09349 f.data.ptr = NULL; 09350 if (trunked_ts) 09351 fr->ts = (iaxs[fr->callno]->last & 0xFFFF0000L) | (trunked_ts & 0xffff); 09352 else 09353 fr->ts = fix_peerts(&rxtrunktime, fr->callno, ts); 09354 /* Don't pass any packets until we're started */ 09355 if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED)) { 09356 struct iax_frame *duped_fr; 09357 09358 /* Common things */ 09359 f.src = "IAX2"; 09360 f.mallocd = 0; 09361 f.offset = 0; 09362 if (f.datalen && (f.frametype == AST_FRAME_VOICE)) 09363 f.samples = ast_codec_get_samples(&f); 09364 else 09365 f.samples = 0; 09366 fr->outoforder = 0; 09367 iax_frame_wrap(fr, &f); 09368 duped_fr = iaxfrdup2(fr); 09369 if (duped_fr) 09370 schedule_delivery(duped_fr, 1, 1, &fr->ts); 09371 if (iaxs[fr->callno] && iaxs[fr->callno]->last < fr->ts) 09372 iaxs[fr->callno]->last = fr->ts; 09373 } 09374 } else { 09375 ast_log(LOG_WARNING, "Datalen < 0?\n"); 09376 } 09377 } 09378 ast_mutex_unlock(&iaxsl[fr->callno]); 09379 ptr += len; 09380 packet_len -= len; 09381 } 09382 09383 return 1; 09384 }
| static int socket_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 9182 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().
09183 { 09184 struct iax2_thread *thread; 09185 socklen_t len; 09186 time_t t; 09187 static time_t last_errtime = 0; 09188 struct ast_iax2_full_hdr *fh; 09189 09190 if (!(thread = find_idle_thread())) { 09191 time(&t); 09192 if (t != last_errtime) 09193 ast_debug(1, "Out of idle IAX2 threads for I/O, pausing!\n"); 09194 last_errtime = t; 09195 usleep(1); 09196 return 1; 09197 } 09198 09199 len = sizeof(thread->iosin); 09200 thread->iofd = fd; 09201 thread->buf_len = recvfrom(fd, thread->readbuf, sizeof(thread->readbuf), 0, (struct sockaddr *) &thread->iosin, &len); 09202 thread->buf_size = sizeof(thread->readbuf); 09203 thread->buf = thread->readbuf; 09204 if (thread->buf_len < 0) { 09205 if (errno != ECONNREFUSED && errno != EAGAIN) 09206 ast_log(LOG_WARNING, "Error: %s\n", strerror(errno)); 09207 handle_error(); 09208 thread->iostate = IAX_IOSTATE_IDLE; 09209 signal_condition(&thread->lock, &thread->cond); 09210 return 1; 09211 } 09212 if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */ 09213 thread->iostate = IAX_IOSTATE_IDLE; 09214 signal_condition(&thread->lock, &thread->cond); 09215 return 1; 09216 } 09217 09218 /* Determine if this frame is a full frame; if so, and any thread is currently 09219 processing a full frame for the same callno from this peer, then drop this 09220 frame (and the peer will retransmit it) */ 09221 fh = (struct ast_iax2_full_hdr *) thread->buf; 09222 if (ntohs(fh->scallno) & IAX_FLAG_FULL) { 09223 struct iax2_thread *cur = NULL; 09224 uint16_t callno = ntohs(fh->scallno) & ~IAX_FLAG_FULL; 09225 09226 AST_LIST_LOCK(&active_list); 09227 AST_LIST_TRAVERSE(&active_list, cur, list) { 09228 if ((cur->ffinfo.callno == callno) && 09229 !inaddrcmp(&cur->ffinfo.sin, &thread->iosin)) 09230 break; 09231 } 09232 if (cur) { 09233 /* we found another thread processing a full frame for this call, 09234 so queue it up for processing later. */ 09235 defer_full_frame(thread, cur); 09236 AST_LIST_UNLOCK(&active_list); 09237 thread->iostate = IAX_IOSTATE_IDLE; 09238 signal_condition(&thread->lock, &thread->cond); 09239 return 1; 09240 } else { 09241 /* this thread is going to process this frame, so mark it */ 09242 thread->ffinfo.callno = callno; 09243 memcpy(&thread->ffinfo.sin, &thread->iosin, sizeof(thread->ffinfo.sin)); 09244 thread->ffinfo.type = fh->type; 09245 thread->ffinfo.csub = fh->csub; 09246 } 09247 AST_LIST_UNLOCK(&active_list); 09248 } 09249 09250 /* Mark as ready and send on its way */ 09251 thread->iostate = IAX_IOSTATE_READY; 09252 #ifdef DEBUG_SCHED_MULTITHREAD 09253 ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc)); 09254 #endif 09255 signal_condition(&thread->lock, &thread->cond); 09256 09257 return 1; 09258 }
| static void spawn_dp_lookup | ( | int | callno, | |
| const char * | context, | |||
| const char * | callednum, | |||
| const char * | callerid | |||
| ) | [static] |
Definition at line 8898 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().
08899 { 08900 pthread_t newthread; 08901 struct dpreq_data *dpr; 08902 08903 if (!(dpr = ast_calloc(1, sizeof(*dpr)))) 08904 return; 08905 08906 dpr->callno = callno; 08907 ast_copy_string(dpr->context, context, sizeof(dpr->context)); 08908 ast_copy_string(dpr->callednum, callednum, sizeof(dpr->callednum)); 08909 if (callerid) 08910 dpr->callerid = ast_strdup(callerid); 08911 if (ast_pthread_create_detached(&newthread, NULL, dp_lookup_thread, dpr)) { 08912 ast_log(LOG_WARNING, "Unable to start lookup thread!\n"); 08913 } 08914 }
| static int start_network_thread | ( | void | ) | [static] |
Definition at line 11705 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(), thread, iax2_thread::threadid, iax2_thread::threadnum, and iax2_thread::type.
Referenced by load_module().
11706 { 11707 struct iax2_thread *thread; 11708 int threadcount = 0; 11709 int x; 11710 for (x = 0; x < iaxthreadcount; x++) { 11711 thread = ast_calloc(1, sizeof(*thread)); 11712 if (thread) { 11713 thread->type = IAX_THREAD_TYPE_POOL; 11714 thread->threadnum = ++threadcount; 11715 ast_mutex_init(&thread->lock); 11716 ast_cond_init(&thread->cond, NULL); 11717 if (ast_pthread_create_detached(&thread->threadid, NULL, iax2_process_thread, thread)) { 11718 ast_log(LOG_WARNING, "Failed to create new thread!\n"); 11719 ast_free(thread); 11720 thread = NULL; 11721 } 11722 AST_LIST_LOCK(&idle_list); 11723 AST_LIST_INSERT_TAIL(&idle_list, thread, list); 11724 AST_LIST_UNLOCK(&idle_list); 11725 } 11726 } 11727 ast_pthread_create_background(&netthreadid, NULL, network_thread, NULL); 11728 ast_verb(2, "%d helper threads started\n", threadcount); 11729 return 0; 11730 }
| static void stop_stuff | ( | int | callno | ) | [static] |
Definition at line 8601 of file chan_iax2.c.
References iax2_destroy_helper().
Referenced by socket_process().
08602 { 08603 iax2_destroy_helper(iaxs[callno]); 08604 }
| static void store_by_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1962 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().
01963 { 01964 if (!pvt->peercallno) { 01965 ast_log(LOG_ERROR, "This should not be called without a peer call number.\n"); 01966 return; 01967 } 01968 01969 ao2_link(iax_peercallno_pvts, pvt); 01970 }
| static void store_by_transfercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 1943 of file chan_iax2.c.
References ao2_link, ast_log(), LOG_ERROR, and chan_iax2_pvt::transfercallno.
Referenced by try_transfer().
01944 { 01945 if (!pvt->transfercallno) { 01946 ast_log(LOG_ERROR, "This should not be called without a transfer call number.\n"); 01947 return; 01948 } 01949 01950 ao2_link(iax_transfercallno_pvts, pvt); 01951 }
| static int timing_read | ( | int * | id, | |
| int | fd, | |||
| short | events, | |||
| void * | cbdata | |||
| ) | [static] |
Definition at line 8787 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().
08788 { 08789 int res, processed = 0, totalcalls = 0; 08790 struct iax2_trunk_peer *tpeer = NULL, *drop = NULL; 08791 struct timeval now = ast_tvnow(); 08792 08793 if (iaxtrunkdebug) 08794 ast_verbose("Beginning trunk processing. Trunk queue ceiling is %d bytes per host\n", trunkmaxsize); 08795 08796 if (timer) { 08797 ast_timer_ack(timer, 1); 08798 } 08799 08800 /* For each peer that supports trunking... */ 08801 AST_LIST_LOCK(&tpeers); 08802 AST_LIST_TRAVERSE_SAFE_BEGIN(&tpeers, tpeer, list) { 08803 processed++; 08804 res = 0; 08805 ast_mutex_lock(&tpeer->lock); 08806 /* We can drop a single tpeer per pass. That makes all this logic 08807 substantially easier */ 08808 if (!drop && iax2_trunk_expired(tpeer, &now)) { 08809 /* Take it out of the list, but don't free it yet, because it 08810 could be in use */ 08811 AST_LIST_REMOVE_CURRENT(list); 08812 drop = tpeer; 08813 } else { 08814 res = send_trunk(tpeer, &now); 08815 trunk_timed++; 08816 if (iaxtrunkdebug) 08817 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); 08818 } 08819 totalcalls += res; 08820 res = 0; 08821 ast_mutex_unlock(&tpeer->lock); 08822 } 08823 AST_LIST_TRAVERSE_SAFE_END; 08824 AST_LIST_UNLOCK(&tpeers); 08825 08826 if (drop) { 08827 ast_mutex_lock(&drop->lock); 08828 /* Once we have this lock, we're sure nobody else is using it or could use it once we release it, 08829 because by the time they could get tpeerlock, we've already grabbed it */ 08830 ast_debug(1, "Dropping unused iax2 trunk peer '%s:%d'\n", ast_inet_ntoa(drop->addr.sin_addr), ntohs(drop->addr.sin_port)); 08831 if (drop->trunkdata) { 08832 ast_free(drop->trunkdata); 08833 drop->trunkdata = NULL; 08834 } 08835 ast_mutex_unlock(&drop->lock); 08836 ast_mutex_destroy(&drop->lock); 08837 ast_free(drop); 08838 08839 } 08840 08841 if (iaxtrunkdebug) 08842 ast_verbose("Ending trunk processing with %d peers and %d call chunks processed\n", processed, totalcalls); 08843 iaxtrunkdebug = 0; 08844 08845 return 1; 08846 }
| static int transfercallno_pvt_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 13735 of file chan_iax2.c.
References CMP_MATCH, CMP_STOP, chan_iax2_pvt::frames_received, and match().
Referenced by load_objects().
13736 { 13737 struct chan_iax2_pvt *pvt = obj, *pvt2 = arg; 13738 13739 /* The frames_received field is used to hold whether we're matching 13740 * against a full frame or not ... */ 13741 13742 return match(&pvt2->transfer, pvt2->transfercallno, pvt2->callno, pvt, 13743 pvt2->frames_received) ? CMP_MATCH | CMP_STOP : 0; 13744 }
| static int transfercallno_pvt_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 13728 of file chan_iax2.c.
References chan_iax2_pvt::transfercallno.
Referenced by load_objects().
13729 { 13730 const struct chan_iax2_pvt *pvt = obj; 13731 13732 return pvt->transfercallno; 13733 }
| static int transmit_trunk | ( | struct iax_frame * | f, | |
| struct sockaddr_in * | sin, | |||
| int | sockfd | |||
| ) | [static] |
Definition at line 3151 of file chan_iax2.c.
References ast_debug, iax_frame::data, iax_frame::datalen, errno, and handle_error().
Referenced by send_trunk().
03152 { 03153 int res; 03154 res = sendto(sockfd, f->data, f->datalen, 0,(struct sockaddr *)sin, 03155 sizeof(*sin)); 03156 if (res < 0) { 03157 ast_debug(1, "Received error: %s\n", strerror(errno)); 03158 handle_error(); 03159 } else 03160 res = 0; 03161 return res; 03162 }
| static int try_firmware | ( | char * | s | ) | [static] |
Definition at line 2853 of file chan_iax2.c.
References ast_calloc, 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().
02854 { 02855 struct stat stbuf; 02856 struct iax_firmware *cur = NULL; 02857 int ifd, fd, res, len, chunk; 02858 struct ast_iax2_firmware_header *fwh, fwh2; 02859 struct MD5Context md5; 02860 unsigned char sum[16], buf[1024]; 02861 char *s2, *last; 02862 02863 if (!(s2 = alloca(strlen(s) + 100))) { 02864 ast_log(LOG_WARNING, "Alloca failed!\n"); 02865 return -1; 02866 } 02867 02868 last = strrchr(s, '/'); 02869 if (last) 02870 last++; 02871 else 02872 last = s; 02873 02874 snprintf(s2, strlen(s) + 100, "/var/tmp/%s-%ld", last, (unsigned long)ast_random()); 02875 02876 if ((res = stat(s, &stbuf) < 0)) { 02877 ast_log(LOG_WARNING, "Failed to stat '%s': %s\n", s, strerror(errno)); 02878 return -1; 02879 } 02880 02881 /* Make sure it's not a directory */ 02882 if (S_ISDIR(stbuf.st_mode)) 02883 return -1; 02884 ifd = open(s, O_RDONLY); 02885 if (ifd < 0) { 02886 ast_log(LOG_WARNING, "Cannot open '%s': %s\n", s, strerror(errno)); 02887 return -1; 02888 } 02889 fd = open(s2, O_RDWR | O_CREAT | O_EXCL, AST_FILE_MODE); 02890 if (fd < 0) { 02891 ast_log(LOG_WARNING, "Cannot open '%s' for writing: %s\n", s2, strerror(errno)); 02892 close(ifd); 02893 return -1; 02894 } 02895 /* Unlink our newly created file */ 02896 unlink(s2); 02897 02898 /* Now copy the firmware into it */ 02899 len = stbuf.st_size; 02900 while(len) { 02901 chunk = len; 02902 if (chunk > sizeof(buf)) 02903 chunk = sizeof(buf); 02904 res = read(ifd, buf, chunk); 02905 if (res != chunk) { 02906 ast_log(LOG_WARNING, "Only read %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02907 close(ifd); 02908 close(fd); 02909 return -1; 02910 } 02911 res = write(fd, buf, chunk); 02912 if (res != chunk) { 02913 ast_log(LOG_WARNING, "Only write %d of %d bytes of data :(: %s\n", res, chunk, strerror(errno)); 02914 close(ifd); 02915 close(fd); 02916 return -1; 02917 } 02918 len -= chunk; 02919 } 02920 close(ifd); 02921 /* Return to the beginning */ 02922 lseek(fd, 0, SEEK_SET); 02923 if ((res = read(fd, &fwh2, sizeof(fwh2))) != sizeof(fwh2)) { 02924 ast_log(LOG_WARNING, "Unable to read firmware header in '%s'\n", s); 02925 close(fd); 02926 return -1; 02927 } 02928 if (ntohl(fwh2.magic) != IAX_FIRMWARE_MAGIC) { 02929 ast_log(LOG_WARNING, "'%s' is not a valid firmware file\n", s); 02930 close(fd); 02931 return -1; 02932 } 02933 if (ntohl(fwh2.datalen) != (stbuf.st_size - sizeof(fwh2))) { 02934 ast_log(LOG_WARNING, "Invalid data length in firmware '%s'\n", s); 02935 close(fd); 02936 return -1; 02937 } 02938 if (fwh2.devname[sizeof(fwh2.devname) - 1] || ast_strlen_zero((char *)fwh2.devname)) { 02939 ast_log(LOG_WARNING, "No or invalid device type specified for '%s'\n", s); 02940 close(fd); 02941 return -1; 02942 } 02943 fwh = (struct ast_iax2_firmware_header*)mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); 02944 if (fwh == (void *) -1) { 02945 ast_log(LOG_WARNING, "mmap failed: %s\n", strerror(errno)); 02946 close(fd); 02947 return -1; 02948 } 02949 MD5Init(&md5); 02950 MD5Update(&md5, fwh->data, ntohl(fwh->datalen)); 02951 MD5Final(sum, &md5); 02952 if (memcmp(sum, fwh->chksum, sizeof(sum))) { 02953 ast_log(LOG_WARNING, "Firmware file '%s' fails checksum\n", s); 02954 munmap((void*)fwh, stbuf.st_size); 02955 close(fd); 02956 return -1; 02957 } 02958 02959 AST_LIST_TRAVERSE(&firmwares, cur, list) { 02960 if (!strcmp((char *)cur->fwh->devname, (char *)fwh->devname)) { 02961 /* Found a candidate */ 02962 if (cur->dead || (ntohs(cur->fwh->version) < ntohs(fwh->version))) 02963 /* The version we have on loaded is older, load this one instead */ 02964 break; 02965 /* This version is no newer than what we have. Don't worry about it. 02966 We'll consider it a proper load anyhow though */ 02967 munmap((void*)fwh, stbuf.st_size); 02968 close(fd); 02969 return 0; 02970 } 02971 } 02972 02973 if (!cur && ((cur = ast_calloc(1, sizeof(*cur))))) { 02974 cur->fd = -1; 02975 AST_LIST_INSERT_TAIL(&firmwares, cur, list); 02976 } 02977 02978 if (cur) { 02979 if (cur->fwh) 02980 munmap((void*)cur->fwh, cur->mmaplen); 02981 if (cur->fd > -1) 02982 close(cur->fd); 02983 cur->fwh = fwh; 02984 cur->fd = fd; 02985 cur->mmaplen = stbuf.st_size; 02986 cur->dead = 0; 02987 } 02988 02989 return 0; 02990 }
| static int try_transfer | ( | struct chan_iax2_pvt * | pvt, | |
| struct iax_ies * | ies | |||
| ) | [static] |
Definition at line 7944 of file chan_iax2.c.
References iax_ies::apparent_addr, AST_FRAME_IAX, ast_log(), iax_ie_data::buf, iax_ies::callno, IAX_COMMAND_TXCNT, iax_ie_append_int(), IAX_IE_TRANSFERID, LOG_WARNING, iax_ie_data::pos, send_command_transfer(), store_by_transfercallno(), chan_iax2_pvt::transfer, TRANSFER_BEGIN, TRANSFER_NONE, chan_iax2_pvt::transfercallno, iax_ies::transferid, chan_iax2_pvt::transferid, and chan_iax2_pvt::transferring.
Referenced by socket_process().
07945 { 07946 int newcall = 0; 07947 char newip[256]; 07948 struct iax_ie_data ied; 07949 struct sockaddr_in new; 07950 07951 07952 memset(&ied, 0, sizeof(ied)); 07953 if (ies->apparent_addr) 07954 memmove(&new, ies->apparent_addr, sizeof(new)); 07955 if (ies->callno) 07956 newcall = ies->callno; 07957 if (!newcall || !new.sin_addr.s_addr || !new.sin_port) { 07958 ast_log(LOG_WARNING, "Invalid transfer request\n"); 07959 return -1; 07960 } 07961 pvt->transfercallno = newcall; 07962 memcpy(&pvt->transfer, &new, sizeof(pvt->transfer)); 07963 inet_aton(newip, &pvt->transfer.sin_addr); 07964 pvt->transfer.sin_family = AF_INET; 07965 pvt->transferid = ies->transferid; 07966 /* only store by transfercallno if this is a new transfer, 07967 * just in case we get a duplicate TXREQ */ 07968 if (pvt->transferring == TRANSFER_NONE) { 07969 store_by_transfercallno(pvt); 07970 } 07971 pvt->transferring = TRANSFER_BEGIN; 07972 07973 if (ies->transferid) 07974 iax_ie_append_int(&ied, IAX_IE_TRANSFERID, ies->transferid); 07975 send_command_transfer(pvt, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); 07976 return 0; 07977 }
| static int uncompress_subclass | ( | unsigned char | csub | ) | [static] |
Definition at line 1484 of file chan_iax2.c.
References IAX_FLAG_SC_LOG, and IAX_MAX_SHIFT.
Referenced by decode_frame(), handle_call_token(), and socket_process().
01485 { 01486 /* If the SC_LOG flag is set, return 2^csub otherwise csub */ 01487 if (csub & IAX_FLAG_SC_LOG) { 01488 /* special case for 'compressed' -1 */ 01489 if (csub == 0xff) 01490 return -1; 01491 else 01492 return 1 << (csub & ~IAX_FLAG_SC_LOG & IAX_MAX_SHIFT); 01493 } 01494 else 01495 return csub; 01496 }
| static void unlink_peer | ( | struct iax2_peer * | peer | ) | [static] |
Definition at line 8235 of file chan_iax2.c.
References ao2_unlink, ast_sched_thread_del, iax2_peer::expire, peer_unref(), and iax2_peer::pokeexpire.
Referenced by __expire_registry(), build_peer(), and prune_peers().
08236 { 08237 if (peer->expire > -1) { 08238 if (!ast_sched_thread_del(sched, peer->expire)) { 08239 peer->expire = -1; 08240 peer_unref(peer); 08241 } 08242 } 08243 08244 if (peer->pokeexpire > -1) { 08245 if (!ast_sched_thread_del(sched, peer->pokeexpire)) { 08246 peer->pokeexpire = -1; 08247 peer_unref(peer); 08248 } 08249 } 08250 08251 ao2_unlink(peers, peer); 08252 }
| static int unload_module | ( | void | ) | [static] |
Definition at line 13693 of file chan_iax2.c.
References __unload_module(), and ast_custom_function_unregister().
13694 { 13695 ast_custom_function_unregister(&iaxpeer_function); 13696 ast_custom_function_unregister(&iaxvar_function); 13697 return __unload_module(); 13698 }
| static void unlock_both | ( | unsigned short | callno0, | |
| unsigned short | callno1 | |||
| ) | [static] |
Definition at line 5164 of file chan_iax2.c.
References ast_mutex_unlock().
Referenced by iax2_bridge().
05165 { 05166 ast_mutex_unlock(&iaxsl[callno1]); 05167 ast_mutex_unlock(&iaxsl[callno0]); 05168 }
| static void unwrap_timestamp | ( | struct iax_frame * | fr | ) | [static] |
Definition at line 3827 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().
03828 { 03829 /* Video mini frames only encode the lower 15 bits of the session 03830 * timestamp, but other frame types (e.g. audio) encode 16 bits. */ 03831 const int ts_shift = (fr->af.frametype == AST_FRAME_VIDEO) ? 15 : 16; 03832 const int lower_mask = (1 << ts_shift) - 1; 03833 const int upper_mask = ~lower_mask; 03834 const int last_upper = iaxs[fr->callno]->last & upper_mask; 03835 03836 if ( (fr->ts & upper_mask) == last_upper ) { 03837 const int x = fr->ts - iaxs[fr->callno]->last; 03838 const int threshold = (ts_shift == 15) ? 25000 : 50000; 03839 03840 if (x < -threshold) { 03841 /* Sudden big jump backwards in timestamp: 03842 What likely happened here is that miniframe timestamp has circled but we haven't 03843 gotten the update from the main packet. We'll just pretend that we did, and 03844 update the timestamp appropriately. */ 03845 fr->ts = (last_upper + (1 << ts_shift)) | (fr->ts & lower_mask); 03846 if (iaxdebug) 03847 ast_debug(1, "schedule_delivery: pushed forward timestamp\n"); 03848 } else if (x > threshold) { 03849 /* Sudden apparent big jump forwards in timestamp: 03850 What's likely happened is this is an old miniframe belonging to the previous 03851 top 15 or 16-bit timestamp that has turned up out of order. 03852 Adjust the timestamp appropriately. */ 03853 fr->ts = (last_upper - (1 << ts_shift)) | (fr->ts & lower_mask); 03854 if (iaxdebug) 03855 ast_debug(1, "schedule_delivery: pushed back timestamp\n"); 03856 } 03857 } 03858 }
| static void update_jbsched | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 3862 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().
03863 { 03864 int when; 03865 03866 when = ast_tvdiff_ms(ast_tvnow(), pvt->rxcore); 03867 03868 when = jb_next(pvt->jb) - when; 03869 03870 if (when <= 0) { 03871 /* XXX should really just empty until when > 0.. */ 03872 when = 1; 03873 } 03874 03875 pvt->jbid = iax2_sched_replace(pvt->jbid, sched, when, get_from_jb, 03876 CALLNO_TO_PTR(pvt->callno)); 03877 }
| static void update_max_nontrunk | ( | void | ) | [static] |
Definition at line 1871 of file chan_iax2.c.
References ast_debug, and TRUNK_CALL_START.
Referenced by __find_callno(), and make_trunk().
01872 { 01873 int max = 1; 01874 int x; 01875 /* XXX Prolly don't need locks here XXX */ 01876 for (x=1;x<TRUNK_CALL_START - 1; x++) { 01877 if (iaxs[x]) 01878 max = x + 1; 01879 } 01880 maxnontrunkcall = max; 01881 if (iaxdebug) 01882 ast_debug(1, "New max nontrunk callno is %d\n", max); 01883 }
| static void update_max_trunk | ( | void | ) | [static] |
Definition at line 1854 of file chan_iax2.c.
References ARRAY_LEN, ast_debug, and TRUNK_CALL_START.
Referenced by iax2_destroy(), and make_trunk().
01855 { 01856 int max = TRUNK_CALL_START; 01857 int x; 01858 01859 /* XXX Prolly don't need locks here XXX */ 01860 for (x = TRUNK_CALL_START; x < ARRAY_LEN(iaxs) - 1; x++) { 01861 if (iaxs[x]) { 01862 max = x + 1; 01863 } 01864 } 01865 01866 maxtrunkcall = max; 01867 if (iaxdebug) 01868 ast_debug(1, "New max trunk callno is %d\n", max); 01869 }
| static int update_packet | ( | struct iax_frame * | f | ) | [static] |
Definition at line 3280 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().
03281 { 03282 /* Called with iaxsl lock held, and iaxs[callno] non-NULL */ 03283 struct ast_iax2_full_hdr *fh = f->data; 03284 struct ast_frame af; 03285 03286 /* if frame is encrypted. decrypt before updating it. */ 03287 if (f->encmethods) { 03288 decode_frame(&f->mydcx, fh, &af, &f->datalen); 03289 } 03290 /* Mark this as a retransmission */ 03291 fh->dcallno = ntohs(IAX_FLAG_RETRANS | f->dcallno); 03292 /* Update iseqno */ 03293 f->iseqno = iaxs[f->callno]->iseqno; 03294 fh->iseqno = f->iseqno; 03295 03296 /* Now re-encrypt the frame */ 03297 if (f->encmethods) { 03298 /* since this is a retransmit frame, create a new random padding 03299 * before re-encrypting. */ 03300 build_rand_pad(f->semirand, sizeof(f->semirand)); 03301 encrypt_frame(&f->ecx, fh, f->semirand, &f->datalen); 03302 } 03303 return 0; 03304 }
| static int update_registry | ( | struct sockaddr_in * | sin, | |
| int | callno, | |||
| char * | devtype, | |||
| int | fd, | |||
| unsigned short | refresh | |||
| ) | [static] |
Definition at line 8346 of file chan_iax2.c.
References iax2_peer::addr, ast_app_inboxcount(), ast_db_del(), ast_db_put(), AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_FRAME_IAX, ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_thread_del, ast_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, version, and iax2_peer::zonetag.
Referenced by socket_process().
08347 { 08348 /* Called from IAX thread only, with proper iaxsl lock */ 08349 struct iax_ie_data ied; 08350 struct iax2_peer *p; 08351 int msgcount; 08352 char data[80]; 08353 int version; 08354 const char *peer_name; 08355 int res = -1; 08356 08357 memset(&ied, 0, sizeof(ied)); 08358 08359 peer_name = ast_strdupa(iaxs[callno]->peer); 08360 08361 /* SLD: Another find_peer call during registration - this time when we are really updating our registration */ 08362 ast_mutex_unlock(&iaxsl[callno]); 08363 if (!(p = find_peer(peer_name, 1))) { 08364 ast_mutex_lock(&iaxsl[callno]); 08365 ast_log(LOG_WARNING, "No such peer '%s'\n", peer_name); 08366 return -1; 08367 } 08368 ast_mutex_lock(&iaxsl[callno]); 08369 if (!iaxs[callno]) 08370 goto return_unref; 08371 08372 if (ast_test_flag((&globalflags), IAX_RTUPDATE) && (ast_test_flag(p, IAX_TEMPONLY|IAX_RTCACHEFRIENDS))) { 08373 if (sin->sin_addr.s_addr) { 08374 time_t nowtime; 08375 time(&nowtime); 08376 realtime_update_peer(peer_name, sin, nowtime); 08377 } else { 08378 realtime_update_peer(peer_name, sin, 0); 08379 } 08380 } 08381 if (inaddrcmp(&p->addr, sin)) { 08382 if (iax2_regfunk) 08383 iax2_regfunk(p->name, 1); 08384 08385 /* modify entry in peercnts table as _not_ registered */ 08386 peercnt_modify(0, 0, &p->addr); 08387 08388 /* Stash the IP address from which they registered */ 08389 memcpy(&p->addr, sin, sizeof(p->addr)); 08390 08391 snprintf(data, sizeof(data), "%s:%d:%d", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port), p->expiry); 08392 if (!ast_test_flag(p, IAX_TEMPONLY) && sin->sin_addr.s_addr) { 08393 ast_db_put("IAX/Registry", p->name, data); 08394 ast_verb(3, "Registered IAX2 '%s' (%s) at %s:%d\n", p->name, 08395 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED", ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port)); 08396 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Registered\r\n", p->name); 08397 register_peer_exten(p, 1); 08398 ast_devstate_changed(AST_DEVICE_UNKNOWN, "IAX2/%s", p->name); /* Activate notification */ 08399 } else if (!ast_test_flag(p, IAX_TEMPONLY)) { 08400 ast_verb(3, "Unregistered IAX2 '%s' (%s)\n", p->name, 08401 ast_test_flag(&iaxs[callno]->state, IAX_STATE_AUTHENTICATED) ? "AUTHENTICATED" : "UNAUTHENTICATED"); 08402 manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: IAX2\r\nPeer: IAX2/%s\r\nPeerStatus: Unregistered\r\n", p->name); 08403 register_peer_exten(p, 0); 08404 ast_db_del("IAX/Registry", p->name); 08405 ast_devstate_changed(AST_DEVICE_UNAVAILABLE, "IAX2/%s", p->name); /* Activate notification */ 08406 } 08407 /* Update the host */ 08408 /* Verify that the host is really there */ 08409 iax2_poke_peer(p, callno); 08410 } 08411 08412 /* modify entry in peercnts table as registered */ 08413 if (p->maxcallno) { 08414 peercnt_modify(1, p->maxcallno, &p->addr); 08415 } 08416 08417 /* Make sure our call still exists, an INVAL at the right point may make it go away */ 08418 if (!iaxs[callno]) { 08419 res = -1; 08420 goto return_unref; 08421 } 08422 08423 /* Store socket fd */ 08424 p->sockfd = fd; 08425 /* Setup the expiry */ 08426 if (p->expire > -1) { 08427 if (!ast_sched_thread_del(sched, p->expire)) { 08428 p->expire = -1; 08429 peer_unref(p); 08430 } 08431 } 08432 /* treat an unspecified refresh interval as the minimum */ 08433 if (!refresh) 08434 refresh = min_reg_expire; 08435 if (refresh > max_reg_expire) { 08436 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08437 p->name, max_reg_expire, refresh); 08438 p->expiry = max_reg_expire; 08439 } else if (refresh < min_reg_expire) { 08440 ast_log(LOG_NOTICE, "Restricting registration for peer '%s' to %d seconds (requested %d)\n", 08441 p->name, min_reg_expire, refresh); 08442 p->expiry = min_reg_expire; 08443 } else { 08444 p->expiry = refresh; 08445 } 08446 if (p->expiry && sin->sin_addr.s_addr) { 08447 p->expire = iax2_sched_add(sched, (p->expiry + 10) * 1000, expire_registry, peer_ref(p)); 08448 if (p->expire == -1) 08449 peer_unref(p); 08450 } 08451 iax_ie_append_str(&ied, IAX_IE_USERNAME, p->name); 08452 iax_ie_append_int(&ied, IAX_IE_DATETIME, iax2_datetime(p->zonetag)); 08453 if (sin->sin_addr.s_addr) { 08454 iax_ie_append_short(&ied, IAX_IE_REFRESH, p->expiry); 08455 iax_ie_append_addr(&ied, IAX_IE_APPARENT_ADDR, &p->addr); 08456 if (!ast_strlen_zero(p->mailbox)) { 08457 struct ast_event *event; 08458 int new, old; 08459 char *mailbox, *context; 08460 08461 context = mailbox = ast_strdupa(p->mailbox); 08462 strsep(&context, "@"); 08463 if (ast_strlen_zero(context)) 08464 context = "default"; 08465 08466 event = ast_event_get_cached(AST_EVENT_MWI, 08467 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox, 08468 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context, 08469 AST_EVENT_IE_END); 08470 if (event) { 08471 new = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS); 08472 old = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS); 08473 ast_event_destroy(event); 08474 } else { /* Fall back on checking the mailbox directly */ 08475 ast_app_inboxcount(p->mailbox, &new, &old); 08476 } 08477 08478 if (new > 255) { 08479 new = 255; 08480 } 08481 if (old > 255) { 08482 old = 255; 08483 } 08484 msgcount = (old << 8) | new; 08485 08486 iax_ie_append_short(&ied, IAX_IE_MSGCOUNT, msgcount); 08487 } 08488 if (ast_test_flag(p, IAX_HASCALLERID)) { 08489 iax_ie_append_str(&ied, IAX_IE_CALLING_NUMBER, p->cid_num); 08490 iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->cid_name); 08491 } 08492 } 08493 version = iax_check_version(devtype); 08494 if (version) 08495 iax_ie_append_short(&ied, IAX_IE_FIRMWAREVER, version); 08496 08497 res = 0; 08498 08499 return_unref: 08500 peer_unref(p); 08501 08502 return res ? res : send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1); 08503 }
| static int user_cmp_cb | ( | void * | obj, | |
| void * | arg, | |||
| int | flags | |||
| ) | [static] |
Definition at line 1531 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 12405 of file chan_iax2.c.
References ast_set_flag, and IAX_DELME.
Referenced by delete_users().
12406 { 12407 struct iax2_user *user = obj; 12408 12409 ast_set_flag(user, IAX_DELME); 12410 12411 return 0; 12412 }
| static void user_destructor | ( | void * | obj | ) | [static] |
Definition at line 12142 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().
12143 { 12144 struct iax2_user *user = obj; 12145 12146 ast_free_ha(user->ha); 12147 free_context(user->contexts); 12148 if(user->vars) { 12149 ast_variables_destroy(user->vars); 12150 user->vars = NULL; 12151 } 12152 ast_string_field_free_memory(user); 12153 }
| static int user_hash_cb | ( | const void * | obj, | |
| const int | flags | |||
| ) | [static] |
Definition at line 1521 of file chan_iax2.c.
References ast_str_hash(), and iax2_user::name.
Referenced by load_objects().
01522 { 01523 const struct iax2_user *user = obj; 01524 01525 return ast_str_hash(user->name); 01526 }
Definition at line 1578 of file chan_iax2.c.
References ao2_ref.
01579 { 01580 ao2_ref(user, +1); 01581 return user; 01582 }
Definition at line 1584 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().
01585 { 01586 ao2_ref(user, -1); 01587 return NULL; 01588 }
| static void vnak_retransmit | ( | int | callno, | |
| int | last | |||
| ) | [static] |
Definition at line 8702 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().
08703 { 08704 struct iax_frame *f; 08705 08706 AST_LIST_LOCK(&frame_queue); 08707 AST_LIST_TRAVERSE(&frame_queue, f, list) { 08708 /* Send a copy immediately */ 08709 if ((f->callno == callno) && iaxs[f->callno] && 08710 ((unsigned char ) (f->oseqno - last) < 128) && 08711 (f->retries >= 0)) { 08712 send_packet(f); 08713 } 08714 } 08715 AST_LIST_UNLOCK(&frame_queue); 08716 }
| static int wait_for_peercallno | ( | struct chan_iax2_pvt * | pvt | ) | [static] |
Definition at line 5018 of file chan_iax2.c.
References chan_iax2_pvt::callno, DEADLOCK_AVOIDANCE, and chan_iax2_pvt::peercallno.
Referenced by iax2_indicate(), and iax2_setoption().
05019 { 05020 unsigned short callno = pvt->callno; 05021 05022 if (!pvt->peercallno) { 05023 /* We don't know the remote side's call number, yet. :( */ 05024 int count = 10; 05025 while (count-- && pvt && !pvt->peercallno) { 05026 DEADLOCK_AVOIDANCE(&iaxsl[callno]); 05027 pvt = iaxs[callno]; 05028 } 05029 if (!pvt->peercallno) { 05030 return -1; 05031 } 05032 } 05033 05034 return 0; 05035 }
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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, .reload = reload, } [static] |
Definition at line 13915 of file chan_iax2.c.
char accountcode[AST_MAX_ACCOUNT_CODE] [static] |
Definition at line 328 of file chan_iax2.c.
Referenced by __ast_channel_alloc_ap(), __oh323_new(), ast_call_forward(), ast_cdr_setaccount(), begin_dial_channel(), build_peer(), check_peer_ok(), dahdi_new(), dial_exec_full(), disa_exec(), do_forward(), findmeexec(), gtalk_new(), jingle_new(), local_call(), sip_new(), skinny_new(), tds_log(), and wait_for_answer().
int adsi = 0 [static] |
Definition at line 332 of file chan_iax2.c.
int amaflags = 0 [static] |
Definition at line 331 of file chan_iax2.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 13915 of file chan_iax2.c.
int authdebug = 1 [static] |
Definition at line 242 of file chan_iax2.c.
int autokill = 0 [static] |
Definition at line 243 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 837 of file chan_iax2.c.
struct ao2_container* callno_pool [static] |
table of available call numbers
Definition at line 796 of file chan_iax2.c.
const unsigned int CALLNO_POOL_BUCKETS = 2699 [static] |
Definition at line 801 of file chan_iax2.c.
struct ao2_container* callno_pool_trunk [static] |
table of available trunk call numbers
Definition at line 799 of file chan_iax2.c.
struct ao2_container* calltoken_ignores [static] |
Table containing ip addresses not requiring calltoken validation
Definition at line 840 of file chan_iax2.c.
struct ast_cli_entry cli_iax2[] [static] |
Definition at line 13583 of file chan_iax2.c.
| unsigned int cos |
Definition at line 253 of file chan_iax2.c.
struct sockaddr_in debugaddr [static] |
Definition at line 1043 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 842 of file chan_iax2.c.
uint16_t DEFAULT_MAXCALLNO_LIMIT_NONVAL = 8192 [static] |
Definition at line 844 of file chan_iax2.c.
char default_parkinglot[AST_MAX_CONTEXT] [static] |
Definition at line 223 of file chan_iax2.c.
int defaultsockfd = -1 [static] |
Definition at line 265 of file chan_iax2.c.
int delayreject = 0 [static] |
Definition at line 333 of file chan_iax2.c.
int global_max_trunk_mtu [static] |
Maximum MTU, 0 if not used
Definition at line 218 of file chan_iax2.c.
uint16_t global_maxcallno [static] |
Definition at line 846 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 849 of file chan_iax2.c.
int global_rtautoclear = 120 [static] |
Definition at line 386 of file chan_iax2.c.
struct ast_flags globalflags = { 0 } [static] |
Definition at line 336 of file chan_iax2.c.
int iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH [static] |
Definition at line 314 of file chan_iax2.c.
int iax2_encryption = 0 [static] |
Definition at line 334 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 13469 of file chan_iax2.c.
struct ast_channel_tech iax2_tech [static] |
Definition at line 1157 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 1201 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 1020 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 1036 of file chan_iax2.c.
int iaxactivethreadcount = 0 [static] |
Definition at line 585 of file chan_iax2.c.
Referenced by __unload_module(), iax2_process_thread(), and iax2_process_thread_cleanup().
int iaxcompat = 0 [static] |
Definition at line 244 of file chan_iax2.c.
int iaxdebug = 0 [static] |
Definition at line 316 of file chan_iax2.c.
int iaxdefaultdpcache = 10 * 60 [static] |
Definition at line 247 of file chan_iax2.c.
int iaxdefaulttimeout = 5 [static] |
Definition at line 249 of file chan_iax2.c.
int iaxdynamicthreadcount = 0 [static] |
Definition at line 583 of file chan_iax2.c.
Referenced by find_idle_thread(), and iax2_process_thread().
int iaxdynamicthreadnum = 0 [static] |
Definition at line 584 of file chan_iax2.c.
Referenced by find_idle_thread().
int iaxmaxthreadcount = DEFAULT_MAX_THREAD_COUNT [static] |
Definition at line 582 of file chan_iax2.c.
Referenced by find_idle_thread(), and set_config().
{
.name = "IAXPEER",
.read = function_iaxpeer,
}
Definition at line 13391 of file chan_iax2.c.
struct chan_iax2_pvt* iaxs[IAX_MAX_CALLS+1] [static] |
an array of iax2 pvt structures
The container for active chan_iax2_pvt structures is implemented as an array for extremely quick direct access to the correct pvt structure based on the local call number. The local call number is used as the index into the array where the associated pvt structure is stored.
Definition at line 1009 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 1029 of file chan_iax2.c.
int iaxthreadcount = DEFAULT_THREAD_COUNT [static] |
Definition at line 581 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 318 of file chan_iax2.c.
struct ast_custom_function iaxvar_function [static] |
{
.name = "IAXVAR",
.read = acf_iaxvar_read,
.write = acf_iaxvar_write,
}
Definition at line 9452 of file chan_iax2.c.
struct io_context* io [static] |
Definition at line 311 of file chan_iax2.c.
int jittertargetextra = 40 [static] |
Definition at line 235 of file chan_iax2.c.
int lagrq_time = 10 [static] |
Definition at line 231 of file chan_iax2.c.
char language[MAX_LANGUAGE] = "" [static] |
Definition at line 225 of file chan_iax2.c.
int last_authmethod = 0 [static] |
Definition at line 245 of file chan_iax2.c.
const time_t MAX_CALLTOKEN_DELAY = 10 [static] |
Definition at line 814 of file chan_iax2.c.
int max_reg_expire [static] |
Definition at line 257 of file chan_iax2.c.
int max_retries = 4 [static] |
Definition at line 229 of file chan_iax2.c.
int maxauthreq = 3 [static] |
Definition at line 228 of file chan_iax2.c.
int maxjitterbuffer = 1000 [static] |
Definition at line 232 of file chan_iax2.c.
int maxjitterinterps = 10 [static] |
Definition at line 234 of file chan_iax2.c.
int maxnontrunkcall = 1 [static] |
Definition at line 1110 of file chan_iax2.c.
int maxtrunkcall = TRUNK_CALL_START [static] |
Definition at line 1109 of file chan_iax2.c.
int min_reg_expire [static] |
Definition at line 256 of file chan_iax2.c.
char mohinterpret[MAX_MUSICCLASS] [static] |
Definition at line 329 of file chan_iax2.c.
char mohsuggest[MAX_MUSICCLASS] [static] |
Definition at line 330 of file chan_iax2.c.
Referenced by build_peer(), check_peer_ok(), create_addr_from_peer(), set_peer_defaults(), and sip_alloc().
struct ast_netsock_list* netsock [static] |
Definition at line 263 of file chan_iax2.c.
pthread_t netthreadid = AST_PTHREADT_NULL [static] |
Definition at line 338 of file chan_iax2.c.
struct ast_netsock_list* outsock [static] |
used if sourceaddress specified and bindaddr == INADDR_ANY
Definition at line 264 of file chan_iax2.c.
char* papp = "IAX2Provision" [static] |
Definition at line 11368 of file chan_iax2.c.
struct ao2_container* peercnts [static] |
Table containing peercnt objects for every ip address consuming a callno
Definition at line 834 of file chan_iax2.c.
struct ao2_container* peers [static] |
Definition at line 828 of file chan_iax2.c.
int ping_time = 21 [static] |
Definition at line 230 of file chan_iax2.c.
struct ast_codec_pref prefs [static] |
Definition at line 209 of file chan_iax2.c.
Referenced by ast_best_codec(), build_peer(), build_user(), check_access(), create_addr(), new_iax(), and set_config().
struct { ... } qos [static] |
Referenced by peer_set_srcaddr(), and set_config().
int randomcalltokendata [static] |
Definition at line 812 of file chan_iax2.c.
char regcontext[AST_MAX_CONTEXT] = "" [static] |
Definition at line 226 of file chan_iax2.c.
int resyncthreshold = 1000 [static] |
Definition at line 233 of file chan_iax2.c.
struct ast_sched_thread* sched [static] |
Definition at line 312 of file chan_iax2.c.
int srvlookup = 0 [static] |
Definition at line 259 of file chan_iax2.c.
Referenced by build_peer().
const char tdesc[] = "Inter Asterisk eXchange Driver (Ver 2)" [static] |
Definition at line 211 of file chan_iax2.c.
int test_losspct = 0 [static] |
Definition at line 320 of file chan_iax2.c.
Definition at line 261 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(), softmix_bridge_create(), softmix_bridge_thread(), timer_destroy(), timerfd_timer_hash(), timerfd_timer_open(), and timing_test().
| unsigned int tos |
Definition at line 252 of file chan_iax2.c.
uint16_t total_nonval_callno_used = 0 [static] |
Definition at line 851 of file chan_iax2.c.
int trunk_maxmtu [static] |
Definition at line 219 of file chan_iax2.c.
int trunk_nmaxmtu [static] |
Trunk MTU statistics
Definition at line 219 of file chan_iax2.c.
int trunk_timed [static] |
Definition at line 219 of file chan_iax2.c.
int trunk_untimed [static] |
Definition at line 219 of file chan_iax2.c.
int trunkfreq = 20 [static] |
Definition at line 239 of file chan_iax2.c.
int trunkmaxsize = MAX_TRUNKDATA [static] |
Definition at line 240 of file chan_iax2.c.
struct ao2_container* users [static] |
Definition at line 831 of file chan_iax2.c.
1.6.2